summaryrefslogtreecommitdiff
path: root/vendor/github.com/ugorji/go/codec/helper.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/ugorji/go/codec/helper.go')
-rw-r--r--vendor/github.com/ugorji/go/codec/helper.go102
1 files changed, 68 insertions, 34 deletions
diff --git a/vendor/github.com/ugorji/go/codec/helper.go b/vendor/github.com/ugorji/go/codec/helper.go
index dc485a5ef..19df27b60 100644
--- a/vendor/github.com/ugorji/go/codec/helper.go
+++ b/vendor/github.com/ugorji/go/codec/helper.go
@@ -215,7 +215,8 @@ import (
// Note: Negative tests that check for errors will fail, so only use this
// when debugging, and run only one test at a time preferably.
//
-// Note: RPC tests espeially fail, as they depend on getting the error from an Encode/Decode call.
+// Note: RPC tests depend on getting the error from an Encode/Decode call.
+// Consequently, they will always fail if debugging = true.
const debugging = false
const (
@@ -617,6 +618,10 @@ func (e *codecError) Cause() error {
return e.err
}
+func (e *codecError) Unwrap() error {
+ return e.err
+}
+
func (e *codecError) Error() string {
if e.encode {
return fmt.Sprintf("%s encode error: %v", e.name, e.err)
@@ -715,9 +720,10 @@ var SelfExt = &extFailWrapper{}
// By definition, it is not allowed for a Selfer to directly call Encode or Decode on itself.
// If that is done, Encode/Decode will rightfully fail with a Stack Overflow style error.
// For example, the snippet below will cause such an error.
-// type testSelferRecur struct{}
-// func (s *testSelferRecur) CodecEncodeSelf(e *Encoder) { e.MustEncode(s) }
-// func (s *testSelferRecur) CodecDecodeSelf(d *Decoder) { d.MustDecode(s) }
+//
+// type testSelferRecur struct{}
+// func (s *testSelferRecur) CodecEncodeSelf(e *Encoder) { e.MustEncode(s) }
+// func (s *testSelferRecur) CodecDecodeSelf(d *Decoder) { d.MustDecode(s) }
//
// Note: *the first set of bytes of any value MUST NOT represent nil in the format*.
// This is because, during each decode, we first check the the next set of bytes
@@ -761,13 +767,14 @@ type MissingFielder interface {
// This affords storing a map in a specific sequence in the stream.
//
// Example usage:
-// type T1 []string // or []int or []Point or any other "slice" type
-// func (_ T1) MapBySlice{} // T1 now implements MapBySlice, and will be encoded as a map
-// type T2 struct { KeyValues T1 }
//
-// var kvs = []string{"one", "1", "two", "2", "three", "3"}
-// var v2 = T2{ KeyValues: T1(kvs) }
-// // v2 will be encoded like the map: {"KeyValues": {"one": "1", "two": "2", "three": "3"} }
+// type T1 []string // or []int or []Point or any other "slice" type
+// func (_ T1) MapBySlice{} // T1 now implements MapBySlice, and will be encoded as a map
+// type T2 struct { KeyValues T1 }
+//
+// var kvs = []string{"one", "1", "two", "2", "three", "3"}
+// var v2 = T2{ KeyValues: T1(kvs) }
+// // v2 will be encoded like the map: {"KeyValues": {"one": "1", "two": "2", "three": "3"} }
//
// The support of MapBySlice affords the following:
// - A slice or array type which implements MapBySlice will be encoded as a map
@@ -969,6 +976,7 @@ func (x *basicHandleRuntimeState) setExt(rt reflect.Type, tag uint64, ext Ext) (
// initHandle should be called only from codec.initHandle global function.
// make it uninlineable, as it is called at most once for each handle.
+//
//go:noinline
func (x *BasicHandle) initHandle(hh Handle) {
handleInitMu.Lock()
@@ -1554,6 +1562,10 @@ func (z bigenHelper) writeUint16(w *encWr, v uint16) {
}
func (z bigenHelper) writeUint32(w *encWr, v uint32) {
+ // w.writeb((z.PutUint32(v))[:])
+ // x := z.PutUint32(v)
+ // w.writeb(x[:])
+ // w.writen4(x[0], x[1], x[2], x[3])
w.writen4(z.PutUint32(v))
}
@@ -1731,7 +1743,7 @@ func (path *structFieldInfoPathNode) fieldAlloc(v reflect.Value) (rv2 reflect.Va
v = parent.fieldAlloc(v)
for j, k := uint8(0), parent.numderef; j < k; j++ {
if rvIsNil(v) {
- rvSetDirect(v, reflect.New(rvType(v).Elem()))
+ rvSetDirect(v, reflect.New(v.Type().Elem()))
}
v = v.Elem()
}
@@ -1863,10 +1875,10 @@ type typeInfo struct {
keykind, elemkind uint8
flagHasPkgPath bool // Type.PackagePath != ""
- flagCustom bool // does this have custom implementation?
flagComparable bool
flagCanTransient bool
+ flagMarshalInterface bool // does this have custom (un)marshal implementation?
flagSelferViaCodecgen bool
// custom implementation flags
@@ -2128,7 +2140,6 @@ func (x *TypeInfos) load(rt reflect.Type) (pti *typeInfo) {
bset := func(when bool, b *bool) {
if when {
*b = true
- ti.flagCustom = true
}
}
@@ -2168,6 +2179,15 @@ func (x *TypeInfos) load(rt reflect.Type) (pti *typeInfo) {
b1, b2 = implIntf(rt, isSelferViaCodecgenerTyp)
ti.flagSelferViaCodecgen = b1 || b2
+ ti.flagMarshalInterface = ti.flagSelfer || ti.flagSelferPtr ||
+ ti.flagSelferViaCodecgen ||
+ ti.flagBinaryMarshaler || ti.flagBinaryMarshalerPtr ||
+ ti.flagBinaryUnmarshaler || ti.flagBinaryUnmarshalerPtr ||
+ ti.flagTextMarshaler || ti.flagTextMarshalerPtr ||
+ ti.flagTextUnmarshaler || ti.flagTextUnmarshalerPtr ||
+ ti.flagJsonMarshaler || ti.flagJsonMarshalerPtr ||
+ ti.flagJsonUnmarshaler || ti.flagJsonUnmarshalerPtr
+
b1 = rt.Comparable()
// bset(b1, &ti.flagComparable)
ti.flagComparable = b1
@@ -2443,6 +2463,14 @@ func implIntf(rt, iTyp reflect.Type) (base bool, indir bool) {
return
}
+func bool2int(b bool) (v uint8) {
+ // MARKER: optimized to be a single instruction
+ if b {
+ v = 1
+ }
+ return
+}
+
func isSliceBoundsError(s string) bool {
return strings.Contains(s, "index out of range") ||
strings.Contains(s, "slice bounds out of range")
@@ -2581,17 +2609,22 @@ func (checkOverflow) Uint2Int(v uint64, neg bool) (overflow bool) {
func (checkOverflow) SignedInt(v uint64) (overflow bool) {
//e.g. -127 to 128 for int8
- pos := (v >> 63) == 0
- ui2 := v & 0x7fffffffffffffff
- if pos {
- if ui2 > math.MaxInt64 {
- overflow = true
- }
- } else {
- if ui2 > math.MaxInt64-1 {
- overflow = true
- }
- }
+ // pos := (v >> 63) == 0
+ // ui2 := v & 0x7fffffffffffffff
+ // if pos {
+ // if ui2 > math.MaxInt64 {
+ // overflow = true
+ // }
+ // } else {
+ // if ui2 > math.MaxInt64-1 {
+ // overflow = true
+ // }
+ // }
+
+ // a signed integer has overflow if the sign (first) bit is 1 (negative)
+ // and the numbers after the sign bit is > maxint64 - 1
+ overflow = (v>>63) != 0 && v&0x7fffffffffffffff > math.MaxInt64-1
+
return
}
@@ -2774,22 +2807,23 @@ func freelistCapacity(length int) (capacity int) {
// without bounds checking is sufficient.
//
// Typical usage model:
-// peek may go together with put, iff pop=true. peek gets largest byte slice temporarily.
-// check is used to switch a []byte if necessary
-// get/put go together
+//
+// peek may go together with put, iff pop=true. peek gets largest byte slice temporarily.
+// check is used to switch a []byte if necessary
+// get/put go together
//
// Given that folks may get a []byte, and then append to it a lot which may re-allocate
// a new []byte, we should try to return both (one received from blist and new one allocated).
//
// Typical usage model for get/put, when we don't know whether we may need more than requested
-// v0 := blist.get()
-// v1 := v0
-// ... use v1 ...
-// blist.put(v1)
-// if byteSliceAddr(v0) != byteSliceAddr(v1) {
-// blist.put(v0)
-// }
//
+// v0 := blist.get()
+// v1 := v0
+// ... use v1 ...
+// blist.put(v1)
+// if byteSliceAddr(v0) != byteSliceAddr(v1) {
+// blist.put(v0)
+// }
type bytesFreelist [][]byte
// peek returns a slice of possibly non-zero'ed bytes, with len=0,