Browse code

bump tinylib/msgp v1.1.0

full diff: https://github.com/tinylib/msgp/compare/3b556c64540842d4f82967be066a7f7fffc3adad...v1.1.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>

Sebastiaan van Stijn authored on 2019/04/15 09:15:25
Showing 10 changed files
... ...
@@ -97,7 +97,7 @@ github.com/Graylog2/go-gelf                         4143646226541087117ff2f83334
97 97
 # fluent-logger-golang deps
98 98
 github.com/fluent/fluent-logger-golang              7a6c9dcd7f14c2ed5d8c55c11b894e5455ee311b # v1.4.0
99 99
 github.com/philhofer/fwd                            bb6d471dc95d4fe11e432687f8b70ff496cf3136 # v1.0.0
100
-github.com/tinylib/msgp                             3b556c64540842d4f82967be066a7f7fffc3adad
100
+github.com/tinylib/msgp                             af6442a0fcf6e2a1b824f70dd0c734f01e817751 # v1.1.0
101 101
 
102 102
 # fsnotify
103 103
 github.com/fsnotify/fsnotify                        1485a34d5d5723fea214f5710708e19a831720e4 # v1.4.7-11-g1485a34
104 104
deleted file mode 100644
... ...
@@ -1,15 +0,0 @@
1
-// +build appengine
2
-
3
-package msgp
4
-
5
-// let's just assume appengine
6
-// uses 64-bit hardware...
7
-const smallint = false
8
-
9
-func UnsafeString(b []byte) string {
10
-	return string(b)
11
-}
12
-
13
-func UnsafeBytes(s string) []byte {
14
-	return []byte(s)
15
-}
... ...
@@ -198,6 +198,7 @@ func resizeMap(raw []byte, delta int64) []byte {
198 198
 		if cap(raw)-len(raw) >= 2 {
199 199
 			raw = raw[0 : len(raw)+2]
200 200
 			copy(raw[5:], raw[3:])
201
+			raw[0] = mmap32
201 202
 			big.PutUint32(raw[1:], uint32(sz+delta))
202 203
 			return raw
203 204
 		}
... ...
@@ -5,6 +5,8 @@ import (
5 5
 	"reflect"
6 6
 )
7 7
 
8
+const resumableDefault = false
9
+
8 10
 var (
9 11
 	// ErrShortBytes is returned when the
10 12
 	// slice being decoded is too short to
... ...
@@ -26,84 +28,240 @@ type Error interface {
26 26
 	// Resumable returns whether
27 27
 	// or not the error means that
28 28
 	// the stream of data is malformed
29
-	// and  the information is unrecoverable.
29
+	// and the information is unrecoverable.
30 30
 	Resumable() bool
31 31
 }
32 32
 
33
+// contextError allows msgp Error instances to be enhanced with additional
34
+// context about their origin.
35
+type contextError interface {
36
+	Error
37
+
38
+	// withContext must not modify the error instance - it must clone and
39
+	// return a new error with the context added.
40
+	withContext(ctx string) error
41
+}
42
+
43
+// Cause returns the underlying cause of an error that has been wrapped
44
+// with additional context.
45
+func Cause(e error) error {
46
+	out := e
47
+	if e, ok := e.(errWrapped); ok && e.cause != nil {
48
+		out = e.cause
49
+	}
50
+	return out
51
+}
52
+
53
+// Resumable returns whether or not the error means that the stream of data is
54
+// malformed and the information is unrecoverable.
55
+func Resumable(e error) bool {
56
+	if e, ok := e.(Error); ok {
57
+		return e.Resumable()
58
+	}
59
+	return resumableDefault
60
+}
61
+
62
+// WrapError wraps an error with additional context that allows the part of the
63
+// serialized type that caused the problem to be identified. Underlying errors
64
+// can be retrieved using Cause()
65
+//
66
+// The input error is not modified - a new error should be returned.
67
+//
68
+// ErrShortBytes is not wrapped with any context due to backward compatibility
69
+// issues with the public API.
70
+//
71
+func WrapError(err error, ctx ...interface{}) error {
72
+	switch e := err.(type) {
73
+	case errShort:
74
+		return e
75
+	case contextError:
76
+		return e.withContext(ctxString(ctx))
77
+	default:
78
+		return errWrapped{cause: err, ctx: ctxString(ctx)}
79
+	}
80
+}
81
+
82
+// ctxString converts the incoming interface{} slice into a single string.
83
+func ctxString(ctx []interface{}) string {
84
+	out := ""
85
+	for idx, cv := range ctx {
86
+		if idx > 0 {
87
+			out += "/"
88
+		}
89
+		out += fmt.Sprintf("%v", cv)
90
+	}
91
+	return out
92
+}
93
+
94
+func addCtx(ctx, add string) string {
95
+	if ctx != "" {
96
+		return add + "/" + ctx
97
+	} else {
98
+		return add
99
+	}
100
+}
101
+
102
+// errWrapped allows arbitrary errors passed to WrapError to be enhanced with
103
+// context and unwrapped with Cause()
104
+type errWrapped struct {
105
+	cause error
106
+	ctx   string
107
+}
108
+
109
+func (e errWrapped) Error() string {
110
+	if e.ctx != "" {
111
+		return fmt.Sprintf("%s at %s", e.cause, e.ctx)
112
+	} else {
113
+		return e.cause.Error()
114
+	}
115
+}
116
+
117
+func (e errWrapped) Resumable() bool {
118
+	if e, ok := e.cause.(Error); ok {
119
+		return e.Resumable()
120
+	}
121
+	return resumableDefault
122
+}
123
+
33 124
 type errShort struct{}
34 125
 
35 126
 func (e errShort) Error() string   { return "msgp: too few bytes left to read object" }
36 127
 func (e errShort) Resumable() bool { return false }
37 128
 
38
-type errFatal struct{}
129
+type errFatal struct {
130
+	ctx string
131
+}
132
+
133
+func (f errFatal) Error() string {
134
+	out := "msgp: fatal decoding error (unreachable code)"
135
+	if f.ctx != "" {
136
+		out += " at " + f.ctx
137
+	}
138
+	return out
139
+}
39 140
 
40
-func (f errFatal) Error() string   { return "msgp: fatal decoding error (unreachable code)" }
41 141
 func (f errFatal) Resumable() bool { return false }
42 142
 
143
+func (f errFatal) withContext(ctx string) error { f.ctx = addCtx(f.ctx, ctx); return f }
144
+
43 145
 // ArrayError is an error returned
44 146
 // when decoding a fix-sized array
45 147
 // of the wrong size
46 148
 type ArrayError struct {
47 149
 	Wanted uint32
48 150
 	Got    uint32
151
+	ctx    string
49 152
 }
50 153
 
51 154
 // Error implements the error interface
52 155
 func (a ArrayError) Error() string {
53
-	return fmt.Sprintf("msgp: wanted array of size %d; got %d", a.Wanted, a.Got)
156
+	out := fmt.Sprintf("msgp: wanted array of size %d; got %d", a.Wanted, a.Got)
157
+	if a.ctx != "" {
158
+		out += " at " + a.ctx
159
+	}
160
+	return out
54 161
 }
55 162
 
56 163
 // Resumable is always 'true' for ArrayErrors
57 164
 func (a ArrayError) Resumable() bool { return true }
58 165
 
166
+func (a ArrayError) withContext(ctx string) error { a.ctx = addCtx(a.ctx, ctx); return a }
167
+
59 168
 // IntOverflow is returned when a call
60 169
 // would downcast an integer to a type
61 170
 // with too few bits to hold its value.
62 171
 type IntOverflow struct {
63 172
 	Value         int64 // the value of the integer
64 173
 	FailedBitsize int   // the bit size that the int64 could not fit into
174
+	ctx           string
65 175
 }
66 176
 
67 177
 // Error implements the error interface
68 178
 func (i IntOverflow) Error() string {
69
-	return fmt.Sprintf("msgp: %d overflows int%d", i.Value, i.FailedBitsize)
179
+	str := fmt.Sprintf("msgp: %d overflows int%d", i.Value, i.FailedBitsize)
180
+	if i.ctx != "" {
181
+		str += " at " + i.ctx
182
+	}
183
+	return str
70 184
 }
71 185
 
72 186
 // Resumable is always 'true' for overflows
73 187
 func (i IntOverflow) Resumable() bool { return true }
74 188
 
189
+func (i IntOverflow) withContext(ctx string) error { i.ctx = addCtx(i.ctx, ctx); return i }
190
+
75 191
 // UintOverflow is returned when a call
76 192
 // would downcast an unsigned integer to a type
77 193
 // with too few bits to hold its value
78 194
 type UintOverflow struct {
79 195
 	Value         uint64 // value of the uint
80 196
 	FailedBitsize int    // the bit size that couldn't fit the value
197
+	ctx           string
81 198
 }
82 199
 
83 200
 // Error implements the error interface
84 201
 func (u UintOverflow) Error() string {
85
-	return fmt.Sprintf("msgp: %d overflows uint%d", u.Value, u.FailedBitsize)
202
+	str := fmt.Sprintf("msgp: %d overflows uint%d", u.Value, u.FailedBitsize)
203
+	if u.ctx != "" {
204
+		str += " at " + u.ctx
205
+	}
206
+	return str
86 207
 }
87 208
 
88 209
 // Resumable is always 'true' for overflows
89 210
 func (u UintOverflow) Resumable() bool { return true }
90 211
 
212
+func (u UintOverflow) withContext(ctx string) error { u.ctx = addCtx(u.ctx, ctx); return u }
213
+
214
+// UintBelowZero is returned when a call
215
+// would cast a signed integer below zero
216
+// to an unsigned integer.
217
+type UintBelowZero struct {
218
+	Value int64 // value of the incoming int
219
+	ctx   string
220
+}
221
+
222
+// Error implements the error interface
223
+func (u UintBelowZero) Error() string {
224
+	str := fmt.Sprintf("msgp: attempted to cast int %d to unsigned", u.Value)
225
+	if u.ctx != "" {
226
+		str += " at " + u.ctx
227
+	}
228
+	return str
229
+}
230
+
231
+// Resumable is always 'true' for overflows
232
+func (u UintBelowZero) Resumable() bool { return true }
233
+
234
+func (u UintBelowZero) withContext(ctx string) error {
235
+	u.ctx = ctx
236
+	return u
237
+}
238
+
91 239
 // A TypeError is returned when a particular
92 240
 // decoding method is unsuitable for decoding
93 241
 // a particular MessagePack value.
94 242
 type TypeError struct {
95 243
 	Method  Type // Type expected by method
96 244
 	Encoded Type // Type actually encoded
245
+
246
+	ctx string
97 247
 }
98 248
 
99 249
 // Error implements the error interface
100 250
 func (t TypeError) Error() string {
101
-	return fmt.Sprintf("msgp: attempted to decode type %q with method for %q", t.Encoded, t.Method)
251
+	out := fmt.Sprintf("msgp: attempted to decode type %q with method for %q", t.Encoded, t.Method)
252
+	if t.ctx != "" {
253
+		out += " at " + t.ctx
254
+	}
255
+	return out
102 256
 }
103 257
 
104 258
 // Resumable returns 'true' for TypeErrors
105 259
 func (t TypeError) Resumable() bool { return true }
106 260
 
261
+func (t TypeError) withContext(ctx string) error { t.ctx = addCtx(t.ctx, ctx); return t }
262
+
107 263
 // returns either InvalidPrefixError or
108 264
 // TypeError depending on whether or not
109 265
 // the prefix is recognized
... ...
@@ -133,10 +291,24 @@ func (i InvalidPrefixError) Resumable() bool { return false }
133 133
 // to a function that takes `interface{}`.
134 134
 type ErrUnsupportedType struct {
135 135
 	T reflect.Type
136
+
137
+	ctx string
136 138
 }
137 139
 
138 140
 // Error implements error
139
-func (e *ErrUnsupportedType) Error() string { return fmt.Sprintf("msgp: type %q not supported", e.T) }
141
+func (e *ErrUnsupportedType) Error() string {
142
+	out := fmt.Sprintf("msgp: type %q not supported", e.T)
143
+	if e.ctx != "" {
144
+		out += " at " + e.ctx
145
+	}
146
+	return out
147
+}
140 148
 
141 149
 // Resumable returns 'true' for ErrUnsupportedType
142 150
 func (e *ErrUnsupportedType) Resumable() bool { return true }
151
+
152
+func (e *ErrUnsupportedType) withContext(ctx string) error {
153
+	o := *e
154
+	o.ctx = addCtx(o.ctx, ctx)
155
+	return &o
156
+}
... ...
@@ -445,26 +445,27 @@ func AppendExtension(b []byte, e Extension) ([]byte, error) {
445 445
 		o[n] = mfixext16
446 446
 		o[n+1] = byte(e.ExtensionType())
447 447
 		n += 2
448
-	}
449
-	switch {
450
-	case l < math.MaxUint8:
451
-		o, n = ensure(b, l+3)
452
-		o[n] = mext8
453
-		o[n+1] = byte(uint8(l))
454
-		o[n+2] = byte(e.ExtensionType())
455
-		n += 3
456
-	case l < math.MaxUint16:
457
-		o, n = ensure(b, l+4)
458
-		o[n] = mext16
459
-		big.PutUint16(o[n+1:], uint16(l))
460
-		o[n+3] = byte(e.ExtensionType())
461
-		n += 4
462 448
 	default:
463
-		o, n = ensure(b, l+6)
464
-		o[n] = mext32
465
-		big.PutUint32(o[n+1:], uint32(l))
466
-		o[n+5] = byte(e.ExtensionType())
467
-		n += 6
449
+		switch {
450
+		case l < math.MaxUint8:
451
+			o, n = ensure(b, l+3)
452
+			o[n] = mext8
453
+			o[n+1] = byte(uint8(l))
454
+			o[n+2] = byte(e.ExtensionType())
455
+			n += 3
456
+		case l < math.MaxUint16:
457
+			o, n = ensure(b, l+4)
458
+			o[n] = mext16
459
+			big.PutUint16(o[n+1:], uint16(l))
460
+			o[n+3] = byte(e.ExtensionType())
461
+			n += 4
462
+		default:
463
+			o, n = ensure(b, l+6)
464
+			o[n] = mext32
465
+			big.PutUint32(o[n+1:], uint32(l))
466
+			o[n+5] = byte(e.ExtensionType())
467
+			n += 6
468
+		}
468 469
 	}
469 470
 	return o, e.MarshalBinaryTo(o[n:])
470 471
 }
471 472
new file mode 100644
... ...
@@ -0,0 +1,15 @@
0
+// +build purego appengine
1
+
2
+package msgp
3
+
4
+// let's just assume appengine
5
+// uses 64-bit hardware...
6
+const smallint = false
7
+
8
+func UnsafeString(b []byte) string {
9
+	return string(b)
10
+}
11
+
12
+func UnsafeBytes(s string) []byte {
13
+	return []byte(s)
14
+}
... ...
@@ -583,6 +583,14 @@ func (m *Reader) ReadInt64() (i int64, err error) {
583 583
 		i = int64(getMint8(p))
584 584
 		return
585 585
 
586
+	case muint8:
587
+		p, err = m.R.Next(2)
588
+		if err != nil {
589
+			return
590
+		}
591
+		i = int64(getMuint8(p))
592
+		return
593
+
586 594
 	case mint16:
587 595
 		p, err = m.R.Next(3)
588 596
 		if err != nil {
... ...
@@ -591,6 +599,14 @@ func (m *Reader) ReadInt64() (i int64, err error) {
591 591
 		i = int64(getMint16(p))
592 592
 		return
593 593
 
594
+	case muint16:
595
+		p, err = m.R.Next(3)
596
+		if err != nil {
597
+			return
598
+		}
599
+		i = int64(getMuint16(p))
600
+		return
601
+
594 602
 	case mint32:
595 603
 		p, err = m.R.Next(5)
596 604
 		if err != nil {
... ...
@@ -599,6 +615,14 @@ func (m *Reader) ReadInt64() (i int64, err error) {
599 599
 		i = int64(getMint32(p))
600 600
 		return
601 601
 
602
+	case muint32:
603
+		p, err = m.R.Next(5)
604
+		if err != nil {
605
+			return
606
+		}
607
+		i = int64(getMuint32(p))
608
+		return
609
+
602 610
 	case mint64:
603 611
 		p, err = m.R.Next(9)
604 612
 		if err != nil {
... ...
@@ -607,6 +631,19 @@ func (m *Reader) ReadInt64() (i int64, err error) {
607 607
 		i = getMint64(p)
608 608
 		return
609 609
 
610
+	case muint64:
611
+		p, err = m.R.Next(9)
612
+		if err != nil {
613
+			return
614
+		}
615
+		u := getMuint64(p)
616
+		if u > math.MaxInt64 {
617
+			err = UintOverflow{Value: u, FailedBitsize: 64}
618
+			return
619
+		}
620
+		i = int64(u)
621
+		return
622
+
610 623
 	default:
611 624
 		err = badPrefix(IntType, lead)
612 625
 		return
... ...
@@ -678,6 +715,19 @@ func (m *Reader) ReadUint64() (u uint64, err error) {
678 678
 		return
679 679
 	}
680 680
 	switch lead {
681
+	case mint8:
682
+		p, err = m.R.Next(2)
683
+		if err != nil {
684
+			return
685
+		}
686
+		v := int64(getMint8(p))
687
+		if v < 0 {
688
+			err = UintBelowZero{Value: v}
689
+			return
690
+		}
691
+		u = uint64(v)
692
+		return
693
+
681 694
 	case muint8:
682 695
 		p, err = m.R.Next(2)
683 696
 		if err != nil {
... ...
@@ -686,6 +736,19 @@ func (m *Reader) ReadUint64() (u uint64, err error) {
686 686
 		u = uint64(getMuint8(p))
687 687
 		return
688 688
 
689
+	case mint16:
690
+		p, err = m.R.Next(3)
691
+		if err != nil {
692
+			return
693
+		}
694
+		v := int64(getMint16(p))
695
+		if v < 0 {
696
+			err = UintBelowZero{Value: v}
697
+			return
698
+		}
699
+		u = uint64(v)
700
+		return
701
+
689 702
 	case muint16:
690 703
 		p, err = m.R.Next(3)
691 704
 		if err != nil {
... ...
@@ -694,6 +757,19 @@ func (m *Reader) ReadUint64() (u uint64, err error) {
694 694
 		u = uint64(getMuint16(p))
695 695
 		return
696 696
 
697
+	case mint32:
698
+		p, err = m.R.Next(5)
699
+		if err != nil {
700
+			return
701
+		}
702
+		v := int64(getMint32(p))
703
+		if v < 0 {
704
+			err = UintBelowZero{Value: v}
705
+			return
706
+		}
707
+		u = uint64(v)
708
+		return
709
+
697 710
 	case muint32:
698 711
 		p, err = m.R.Next(5)
699 712
 		if err != nil {
... ...
@@ -702,6 +778,19 @@ func (m *Reader) ReadUint64() (u uint64, err error) {
702 702
 		u = uint64(getMuint32(p))
703 703
 		return
704 704
 
705
+	case mint64:
706
+		p, err = m.R.Next(9)
707
+		if err != nil {
708
+			return
709
+		}
710
+		v := int64(getMint64(p))
711
+		if v < 0 {
712
+			err = UintBelowZero{Value: v}
713
+			return
714
+		}
715
+		u = uint64(v)
716
+		return
717
+
705 718
 	case muint64:
706 719
 		p, err = m.R.Next(9)
707 720
 		if err != nil {
... ...
@@ -711,7 +800,11 @@ func (m *Reader) ReadUint64() (u uint64, err error) {
711 711
 		return
712 712
 
713 713
 	default:
714
-		err = badPrefix(UintType, lead)
714
+		if isnfixint(lead) {
715
+			err = UintBelowZero{Value: int64(rnfixint(lead))}
716
+		} else {
717
+			err = badPrefix(UintType, lead)
718
+		}
715 719
 		return
716 720
 
717 721
 	}
... ...
@@ -79,6 +79,9 @@ func (r *Raw) UnmarshalMsg(b []byte) ([]byte, error) {
79 79
 		return b, err
80 80
 	}
81 81
 	rlen := l - len(out)
82
+	if IsNil(b[:rlen]) {
83
+		rlen = 0
84
+	}
82 85
 	if cap(*r) < rlen {
83 86
 		*r = make(Raw, rlen)
84 87
 	} else {
... ...
@@ -104,7 +107,11 @@ func (r Raw) EncodeMsg(w *Writer) error {
104 104
 // next object on the wire.
105 105
 func (r *Raw) DecodeMsg(f *Reader) error {
106 106
 	*r = (*r)[:0]
107
-	return appendNext(f, (*[]byte)(r))
107
+	err := appendNext(f, (*[]byte)(r))
108
+	if IsNil(*r) {
109
+		*r = (*r)[:0]
110
+	}
111
+	return err
108 112
 }
109 113
 
110 114
 // Msgsize implements msgp.Sizer
... ...
@@ -368,6 +375,15 @@ func ReadInt64Bytes(b []byte) (i int64, o []byte, err error) {
368 368
 		o = b[2:]
369 369
 		return
370 370
 
371
+	case muint8:
372
+		if l < 2 {
373
+			err = ErrShortBytes
374
+			return
375
+		}
376
+		i = int64(getMuint8(b))
377
+		o = b[2:]
378
+		return
379
+
371 380
 	case mint16:
372 381
 		if l < 3 {
373 382
 			err = ErrShortBytes
... ...
@@ -377,6 +393,15 @@ func ReadInt64Bytes(b []byte) (i int64, o []byte, err error) {
377 377
 		o = b[3:]
378 378
 		return
379 379
 
380
+	case muint16:
381
+		if l < 3 {
382
+			err = ErrShortBytes
383
+			return
384
+		}
385
+		i = int64(getMuint16(b))
386
+		o = b[3:]
387
+		return
388
+
380 389
 	case mint32:
381 390
 		if l < 5 {
382 391
 			err = ErrShortBytes
... ...
@@ -386,12 +411,35 @@ func ReadInt64Bytes(b []byte) (i int64, o []byte, err error) {
386 386
 		o = b[5:]
387 387
 		return
388 388
 
389
+	case muint32:
390
+		if l < 5 {
391
+			err = ErrShortBytes
392
+			return
393
+		}
394
+		i = int64(getMuint32(b))
395
+		o = b[5:]
396
+		return
397
+
389 398
 	case mint64:
390 399
 		if l < 9 {
391 400
 			err = ErrShortBytes
392 401
 			return
393 402
 		}
394
-		i = getMint64(b)
403
+		i = int64(getMint64(b))
404
+		o = b[9:]
405
+		return
406
+
407
+	case muint64:
408
+		if l < 9 {
409
+			err = ErrShortBytes
410
+			return
411
+		}
412
+		u := getMuint64(b)
413
+		if u > math.MaxInt64 {
414
+			err = UintOverflow{Value: u, FailedBitsize: 64}
415
+			return
416
+		}
417
+		i = int64(u)
395 418
 		o = b[9:]
396 419
 		return
397 420
 
... ...
@@ -477,6 +525,20 @@ func ReadUint64Bytes(b []byte) (u uint64, o []byte, err error) {
477 477
 	}
478 478
 
479 479
 	switch lead {
480
+	case mint8:
481
+		if l < 2 {
482
+			err = ErrShortBytes
483
+			return
484
+		}
485
+		v := int64(getMint8(b))
486
+		if v < 0 {
487
+			err = UintBelowZero{Value: v}
488
+			return
489
+		}
490
+		u = uint64(v)
491
+		o = b[2:]
492
+		return
493
+
480 494
 	case muint8:
481 495
 		if l < 2 {
482 496
 			err = ErrShortBytes
... ...
@@ -486,6 +548,20 @@ func ReadUint64Bytes(b []byte) (u uint64, o []byte, err error) {
486 486
 		o = b[2:]
487 487
 		return
488 488
 
489
+	case mint16:
490
+		if l < 3 {
491
+			err = ErrShortBytes
492
+			return
493
+		}
494
+		v := int64(getMint16(b))
495
+		if v < 0 {
496
+			err = UintBelowZero{Value: v}
497
+			return
498
+		}
499
+		u = uint64(v)
500
+		o = b[3:]
501
+		return
502
+
489 503
 	case muint16:
490 504
 		if l < 3 {
491 505
 			err = ErrShortBytes
... ...
@@ -495,6 +571,20 @@ func ReadUint64Bytes(b []byte) (u uint64, o []byte, err error) {
495 495
 		o = b[3:]
496 496
 		return
497 497
 
498
+	case mint32:
499
+		if l < 5 {
500
+			err = ErrShortBytes
501
+			return
502
+		}
503
+		v := int64(getMint32(b))
504
+		if v < 0 {
505
+			err = UintBelowZero{Value: v}
506
+			return
507
+		}
508
+		u = uint64(v)
509
+		o = b[5:]
510
+		return
511
+
498 512
 	case muint32:
499 513
 		if l < 5 {
500 514
 			err = ErrShortBytes
... ...
@@ -504,6 +594,20 @@ func ReadUint64Bytes(b []byte) (u uint64, o []byte, err error) {
504 504
 		o = b[5:]
505 505
 		return
506 506
 
507
+	case mint64:
508
+		if l < 9 {
509
+			err = ErrShortBytes
510
+			return
511
+		}
512
+		v := int64(getMint64(b))
513
+		if v < 0 {
514
+			err = UintBelowZero{Value: v}
515
+			return
516
+		}
517
+		u = uint64(v)
518
+		o = b[9:]
519
+		return
520
+
507 521
 	case muint64:
508 522
 		if l < 9 {
509 523
 			err = ErrShortBytes
... ...
@@ -514,7 +618,11 @@ func ReadUint64Bytes(b []byte) (u uint64, o []byte, err error) {
514 514
 		return
515 515
 
516 516
 	default:
517
-		err = badPrefix(UintType, lead)
517
+		if isnfixint(lead) {
518
+			err = UintBelowZero{Value: int64(rnfixint(lead))}
519
+		} else {
520
+			err = badPrefix(UintType, lead)
521
+		}
518 522
 		return
519 523
 	}
520 524
 }
... ...
@@ -1,4 +1,4 @@
1
-// +build !appengine
1
+// +build !purego,!appengine
2 2
 
3 3
 package msgp
4 4
 
... ...
@@ -685,7 +685,7 @@ func (mw *Writer) WriteIntf(v interface{}) error {
685 685
 	case reflect.Map:
686 686
 		return mw.writeMap(val)
687 687
 	}
688
-	return &ErrUnsupportedType{val.Type()}
688
+	return &ErrUnsupportedType{T: val.Type()}
689 689
 }
690 690
 
691 691
 func (mw *Writer) writeMap(v reflect.Value) (err error) {