mirror of
https://github.com/kubernetes-sigs/prometheus-adapter.git
synced 2026-04-06 01:38:10 +00:00
Check in the vendor directory
Travis seems to be having issues pulling deps, so we'll have to check in the vendor directory and prevent the makefile from trying to regenerate it normally.
This commit is contained in:
parent
98e16bc315
commit
a293b2bf94
2526 changed files with 930931 additions and 4 deletions
22
vendor/github.com/ugorji/go/LICENSE
generated
vendored
Normal file
22
vendor/github.com/ugorji/go/LICENSE
generated
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2012-2015 Ugorji Nwoke.
|
||||
All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
264
vendor/github.com/ugorji/go/codec/0doc.go
generated
vendored
Normal file
264
vendor/github.com/ugorji/go/codec/0doc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
/*
|
||||
Package codec provides a
|
||||
High Performance, Feature-Rich Idiomatic Go 1.4+ codec/encoding library
|
||||
for binc, msgpack, cbor, json.
|
||||
|
||||
Supported Serialization formats are:
|
||||
|
||||
- msgpack: https://github.com/msgpack/msgpack
|
||||
- binc: http://github.com/ugorji/binc
|
||||
- cbor: http://cbor.io http://tools.ietf.org/html/rfc7049
|
||||
- json: http://json.org http://tools.ietf.org/html/rfc7159
|
||||
- simple:
|
||||
|
||||
To install:
|
||||
|
||||
go get github.com/ugorji/go/codec
|
||||
|
||||
This package will carefully use 'unsafe' for performance reasons in specific places.
|
||||
You can build without unsafe use by passing the safe or appengine tag
|
||||
i.e. 'go install -tags=safe ...'. Note that unsafe is only supported for the last 3
|
||||
go sdk versions e.g. current go release is go 1.9, so we support unsafe use only from
|
||||
go 1.7+ . This is because supporting unsafe requires knowledge of implementation details.
|
||||
|
||||
For detailed usage information, read the primer at http://ugorji.net/blog/go-codec-primer .
|
||||
|
||||
The idiomatic Go support is as seen in other encoding packages in
|
||||
the standard library (ie json, xml, gob, etc).
|
||||
|
||||
Rich Feature Set includes:
|
||||
|
||||
- Simple but extremely powerful and feature-rich API
|
||||
- Support for go1.4 and above, while selectively using newer APIs for later releases
|
||||
- Excellent code coverage ( > 90% )
|
||||
- Very High Performance.
|
||||
Our extensive benchmarks show us outperforming Gob, Json, Bson, etc by 2-4X.
|
||||
- Careful selected use of 'unsafe' for targeted performance gains.
|
||||
100% mode exists where 'unsafe' is not used at all.
|
||||
- Lock-free (sans mutex) concurrency for scaling to 100's of cores
|
||||
- Coerce types where appropriate
|
||||
e.g. decode an int in the stream into a float, decode numbers from formatted strings, etc
|
||||
- Corner Cases:
|
||||
Overflows, nil maps/slices, nil values in streams are handled correctly
|
||||
- Standard field renaming via tags
|
||||
- Support for omitting empty fields during an encoding
|
||||
- Encoding from any value and decoding into pointer to any value
|
||||
(struct, slice, map, primitives, pointers, interface{}, etc)
|
||||
- Extensions to support efficient encoding/decoding of any named types
|
||||
- Support encoding.(Binary|Text)(M|Unm)arshaler interfaces
|
||||
- Support IsZero() bool to determine if a value is a zero value.
|
||||
Analogous to time.Time.IsZero() bool.
|
||||
- Decoding without a schema (into a interface{}).
|
||||
Includes Options to configure what specific map or slice type to use
|
||||
when decoding an encoded list or map into a nil interface{}
|
||||
- Mapping a non-interface type to an interface, so we can decode appropriately
|
||||
into any interface type with a correctly configured non-interface value.
|
||||
- Encode a struct as an array, and decode struct from an array in the data stream
|
||||
- Option to encode struct keys as numbers (instead of strings)
|
||||
(to support structured streams with fields encoded as numeric codes)
|
||||
- Comprehensive support for anonymous fields
|
||||
- Fast (no-reflection) encoding/decoding of common maps and slices
|
||||
- Code-generation for faster performance.
|
||||
- Support binary (e.g. messagepack, cbor) and text (e.g. json) formats
|
||||
- Support indefinite-length formats to enable true streaming
|
||||
(for formats which support it e.g. json, cbor)
|
||||
- Support canonical encoding, where a value is ALWAYS encoded as same sequence of bytes.
|
||||
This mostly applies to maps, where iteration order is non-deterministic.
|
||||
- NIL in data stream decoded as zero value
|
||||
- Never silently skip data when decoding.
|
||||
User decides whether to return an error or silently skip data when keys or indexes
|
||||
in the data stream do not map to fields in the struct.
|
||||
- Detect and error when encoding a cyclic reference (instead of stack overflow shutdown)
|
||||
- Encode/Decode from/to chan types (for iterative streaming support)
|
||||
- Drop-in replacement for encoding/json. `json:` key in struct tag supported.
|
||||
- Provides a RPC Server and Client Codec for net/rpc communication protocol.
|
||||
- Handle unique idiosyncrasies of codecs e.g.
|
||||
- For messagepack, configure how ambiguities in handling raw bytes are resolved
|
||||
- For messagepack, provide rpc server/client codec to support
|
||||
msgpack-rpc protocol defined at:
|
||||
https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md
|
||||
|
||||
Extension Support
|
||||
|
||||
Users can register a function to handle the encoding or decoding of
|
||||
their custom types.
|
||||
|
||||
There are no restrictions on what the custom type can be. Some examples:
|
||||
|
||||
type BisSet []int
|
||||
type BitSet64 uint64
|
||||
type UUID string
|
||||
type MyStructWithUnexportedFields struct { a int; b bool; c []int; }
|
||||
type GifImage struct { ... }
|
||||
|
||||
As an illustration, MyStructWithUnexportedFields would normally be
|
||||
encoded as an empty map because it has no exported fields, while UUID
|
||||
would be encoded as a string. However, with extension support, you can
|
||||
encode any of these however you like.
|
||||
|
||||
Custom Encoding and Decoding
|
||||
|
||||
This package maintains symmetry in the encoding and decoding halfs.
|
||||
We determine how to encode or decode by walking this decision tree
|
||||
|
||||
- is type a codec.Selfer?
|
||||
- is there an extension registered for the type?
|
||||
- is format binary, and is type a encoding.BinaryMarshaler and BinaryUnmarshaler?
|
||||
- is format specifically json, and is type a encoding/json.Marshaler and Unmarshaler?
|
||||
- is format text-based, and type an encoding.TextMarshaler?
|
||||
- else we use a pair of functions based on the "kind" of the type e.g. map, slice, int64, etc
|
||||
|
||||
This symmetry is important to reduce chances of issues happening because the
|
||||
encoding and decoding sides are out of sync e.g. decoded via very specific
|
||||
encoding.TextUnmarshaler but encoded via kind-specific generalized mode.
|
||||
|
||||
Consequently, if a type only defines one-half of the symmetry
|
||||
(e.g. it implements UnmarshalJSON() but not MarshalJSON() ),
|
||||
then that type doesn't satisfy the check and we will continue walking down the
|
||||
decision tree.
|
||||
|
||||
RPC
|
||||
|
||||
RPC Client and Server Codecs are implemented, so the codecs can be used
|
||||
with the standard net/rpc package.
|
||||
|
||||
Usage
|
||||
|
||||
The Handle is SAFE for concurrent READ, but NOT SAFE for concurrent modification.
|
||||
|
||||
The Encoder and Decoder are NOT safe for concurrent use.
|
||||
|
||||
Consequently, the usage model is basically:
|
||||
|
||||
- Create and initialize the Handle before any use.
|
||||
Once created, DO NOT modify it.
|
||||
- Multiple Encoders or Decoders can now use the Handle concurrently.
|
||||
They only read information off the Handle (never write).
|
||||
- However, each Encoder or Decoder MUST not be used concurrently
|
||||
- To re-use an Encoder/Decoder, call Reset(...) on it first.
|
||||
This allows you use state maintained on the Encoder/Decoder.
|
||||
|
||||
Sample usage model:
|
||||
|
||||
// create and configure Handle
|
||||
var (
|
||||
bh codec.BincHandle
|
||||
mh codec.MsgpackHandle
|
||||
ch codec.CborHandle
|
||||
)
|
||||
|
||||
mh.MapType = reflect.TypeOf(map[string]interface{}(nil))
|
||||
|
||||
// configure extensions
|
||||
// e.g. for msgpack, define functions and enable Time support for tag 1
|
||||
// mh.SetExt(reflect.TypeOf(time.Time{}), 1, myExt)
|
||||
|
||||
// create and use decoder/encoder
|
||||
var (
|
||||
r io.Reader
|
||||
w io.Writer
|
||||
b []byte
|
||||
h = &bh // or mh to use msgpack
|
||||
)
|
||||
|
||||
dec = codec.NewDecoder(r, h)
|
||||
dec = codec.NewDecoderBytes(b, h)
|
||||
err = dec.Decode(&v)
|
||||
|
||||
enc = codec.NewEncoder(w, h)
|
||||
enc = codec.NewEncoderBytes(&b, h)
|
||||
err = enc.Encode(v)
|
||||
|
||||
//RPC Server
|
||||
go func() {
|
||||
for {
|
||||
conn, err := listener.Accept()
|
||||
rpcCodec := codec.GoRpc.ServerCodec(conn, h)
|
||||
//OR rpcCodec := codec.MsgpackSpecRpc.ServerCodec(conn, h)
|
||||
rpc.ServeCodec(rpcCodec)
|
||||
}
|
||||
}()
|
||||
|
||||
//RPC Communication (client side)
|
||||
conn, err = net.Dial("tcp", "localhost:5555")
|
||||
rpcCodec := codec.GoRpc.ClientCodec(conn, h)
|
||||
//OR rpcCodec := codec.MsgpackSpecRpc.ClientCodec(conn, h)
|
||||
client := rpc.NewClientWithCodec(rpcCodec)
|
||||
|
||||
Running Tests
|
||||
|
||||
To run tests, use the following:
|
||||
|
||||
go test
|
||||
|
||||
To run the full suite of tests, use the following:
|
||||
|
||||
go test -tags alltests -run Suite
|
||||
|
||||
You can run the tag 'safe' to run tests or build in safe mode. e.g.
|
||||
|
||||
go test -tags safe -run Json
|
||||
go test -tags "alltests safe" -run Suite
|
||||
|
||||
Running Benchmarks
|
||||
|
||||
Please see http://github.com/ugorji/go-codec-bench .
|
||||
|
||||
Caveats
|
||||
|
||||
Struct fields matching the following are ignored during encoding and decoding
|
||||
- struct tag value set to -
|
||||
- func, complex numbers, unsafe pointers
|
||||
- unexported and not embedded
|
||||
- unexported and embedded and not struct kind
|
||||
- unexported and embedded pointers (from go1.10)
|
||||
|
||||
Every other field in a struct will be encoded/decoded.
|
||||
|
||||
Embedded fields are encoded as if they exist in the top-level struct,
|
||||
with some caveats. See Encode documentation.
|
||||
|
||||
*/
|
||||
package codec
|
||||
|
||||
// TODO:
|
||||
// - For Go 1.11, when mid-stack inlining is enabled,
|
||||
// we should use committed functions for writeXXX and readXXX calls.
|
||||
// This involves uncommenting the methods for decReaderSwitch and encWriterSwitch
|
||||
// and using those (decReaderSwitch and encWriterSwitch) in all handles
|
||||
// instead of encWriter and decReader.
|
||||
// The benefit is that, for the (En|De)coder over []byte, the encWriter/decReader
|
||||
// will be inlined, giving a performance bump for that typical case.
|
||||
// However, it will only be inlined if mid-stack inlining is enabled,
|
||||
// as we call panic to raise errors, and panic currently prevents inlining.
|
||||
//
|
||||
// PUNTED:
|
||||
// - To make Handle comparable, make extHandle in BasicHandle a non-embedded pointer,
|
||||
// and use overlay methods on *BasicHandle to call through to extHandle after initializing
|
||||
// the "xh *extHandle" to point to a real slice.
|
||||
//
|
||||
// BEFORE EACH RELEASE:
|
||||
// - Look through and fix padding for each type, to eliminate false sharing
|
||||
// - critical shared objects that are read many times
|
||||
// TypeInfos
|
||||
// - pooled objects:
|
||||
// decNaked, decNakedContainers, codecFner, typeInfoLoadArray,
|
||||
// - small objects allocated independently, that we read/use much across threads:
|
||||
// codecFn, typeInfo
|
||||
// - Objects allocated independently and used a lot
|
||||
// Decoder, Encoder,
|
||||
// xxxHandle, xxxEncDriver, xxxDecDriver (xxx = json, msgpack, cbor, binc, simple)
|
||||
// - In all above, arrange values modified together to be close to each other.
|
||||
//
|
||||
// For all of these, either ensure that they occupy full cache lines,
|
||||
// or ensure that the things just past the cache line boundary are hardly read/written
|
||||
// e.g. JsonHandle.RawBytesExt - which is copied into json(En|De)cDriver at init
|
||||
//
|
||||
// Occupying full cache lines means they occupy 8*N words (where N is an integer).
|
||||
// Check this out by running: ./run.sh -z
|
||||
// - look at those tagged ****, meaning they are not occupying full cache lines
|
||||
// - look at those tagged <<<<, meaning they are larger than 32 words (something to watch)
|
||||
// - Run "golint -min_confidence 0.81"
|
||||
206
vendor/github.com/ugorji/go/codec/README.md
generated
vendored
Normal file
206
vendor/github.com/ugorji/go/codec/README.md
generated
vendored
Normal file
|
|
@ -0,0 +1,206 @@
|
|||
# Codec
|
||||
|
||||
High Performance, Feature-Rich Idiomatic Go codec/encoding library for
|
||||
binc, msgpack, cbor, json.
|
||||
|
||||
Supported Serialization formats are:
|
||||
|
||||
- msgpack: https://github.com/msgpack/msgpack
|
||||
- binc: http://github.com/ugorji/binc
|
||||
- cbor: http://cbor.io http://tools.ietf.org/html/rfc7049
|
||||
- json: http://json.org http://tools.ietf.org/html/rfc7159
|
||||
- simple:
|
||||
|
||||
To install:
|
||||
|
||||
go get github.com/ugorji/go/codec
|
||||
|
||||
This package will carefully use 'unsafe' for performance reasons in specific places.
|
||||
You can build without unsafe use by passing the safe or appengine tag
|
||||
i.e. 'go install -tags=safe ...'. Note that unsafe is only supported for the last 3
|
||||
go sdk versions e.g. current go release is go 1.9, so we support unsafe use only from
|
||||
go 1.7+ . This is because supporting unsafe requires knowledge of implementation details.
|
||||
|
||||
Online documentation: http://godoc.org/github.com/ugorji/go/codec
|
||||
Detailed Usage/How-to Primer: http://ugorji.net/blog/go-codec-primer
|
||||
|
||||
The idiomatic Go support is as seen in other encoding packages in
|
||||
the standard library (ie json, xml, gob, etc).
|
||||
|
||||
Rich Feature Set includes:
|
||||
|
||||
- Simple but extremely powerful and feature-rich API
|
||||
- Support for go1.4 and above, while selectively using newer APIs for later releases
|
||||
- Excellent code coverage ( > 90% )
|
||||
- Very High Performance.
|
||||
Our extensive benchmarks show us outperforming Gob, Json, Bson, etc by 2-4X.
|
||||
- Careful selected use of 'unsafe' for targeted performance gains.
|
||||
100% mode exists where 'unsafe' is not used at all.
|
||||
- Lock-free (sans mutex) concurrency for scaling to 100's of cores
|
||||
- Coerce types where appropriate
|
||||
e.g. decode an int in the stream into a float, decode numbers from formatted strings, etc
|
||||
- Corner Cases:
|
||||
Overflows, nil maps/slices, nil values in streams are handled correctly
|
||||
- Standard field renaming via tags
|
||||
- Support for omitting empty fields during an encoding
|
||||
- Encoding from any value and decoding into pointer to any value
|
||||
(struct, slice, map, primitives, pointers, interface{}, etc)
|
||||
- Extensions to support efficient encoding/decoding of any named types
|
||||
- Support encoding.(Binary|Text)(M|Unm)arshaler interfaces
|
||||
- Support IsZero() bool to determine if a value is a zero value.
|
||||
Analogous to time.Time.IsZero() bool.
|
||||
- Decoding without a schema (into a interface{}).
|
||||
Includes Options to configure what specific map or slice type to use
|
||||
when decoding an encoded list or map into a nil interface{}
|
||||
- Mapping a non-interface type to an interface, so we can decode appropriately
|
||||
into any interface type with a correctly configured non-interface value.
|
||||
- Encode a struct as an array, and decode struct from an array in the data stream
|
||||
- Option to encode struct keys as numbers (instead of strings)
|
||||
(to support structured streams with fields encoded as numeric codes)
|
||||
- Comprehensive support for anonymous fields
|
||||
- Fast (no-reflection) encoding/decoding of common maps and slices
|
||||
- Code-generation for faster performance.
|
||||
- Support binary (e.g. messagepack, cbor) and text (e.g. json) formats
|
||||
- Support indefinite-length formats to enable true streaming
|
||||
(for formats which support it e.g. json, cbor)
|
||||
- Support canonical encoding, where a value is ALWAYS encoded as same sequence of bytes.
|
||||
This mostly applies to maps, where iteration order is non-deterministic.
|
||||
- NIL in data stream decoded as zero value
|
||||
- Never silently skip data when decoding.
|
||||
User decides whether to return an error or silently skip data when keys or indexes
|
||||
in the data stream do not map to fields in the struct.
|
||||
- Encode/Decode from/to chan types (for iterative streaming support)
|
||||
- Drop-in replacement for encoding/json. `json:` key in struct tag supported.
|
||||
- Provides a RPC Server and Client Codec for net/rpc communication protocol.
|
||||
- Handle unique idiosyncrasies of codecs e.g.
|
||||
- For messagepack, configure how ambiguities in handling raw bytes are resolved
|
||||
- For messagepack, provide rpc server/client codec to support
|
||||
msgpack-rpc protocol defined at:
|
||||
https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md
|
||||
|
||||
## Extension Support
|
||||
|
||||
Users can register a function to handle the encoding or decoding of
|
||||
their custom types.
|
||||
|
||||
There are no restrictions on what the custom type can be. Some examples:
|
||||
|
||||
type BisSet []int
|
||||
type BitSet64 uint64
|
||||
type UUID string
|
||||
type MyStructWithUnexportedFields struct { a int; b bool; c []int; }
|
||||
type GifImage struct { ... }
|
||||
|
||||
As an illustration, MyStructWithUnexportedFields would normally be
|
||||
encoded as an empty map because it has no exported fields, while UUID
|
||||
would be encoded as a string. However, with extension support, you can
|
||||
encode any of these however you like.
|
||||
|
||||
## Custom Encoding and Decoding
|
||||
|
||||
This package maintains symmetry in the encoding and decoding halfs.
|
||||
We determine how to encode or decode by walking this decision tree
|
||||
|
||||
- is type a codec.Selfer?
|
||||
- is there an extension registered for the type?
|
||||
- is format binary, and is type a encoding.BinaryMarshaler and BinaryUnmarshaler?
|
||||
- is format specifically json, and is type a encoding/json.Marshaler and Unmarshaler?
|
||||
- is format text-based, and type an encoding.TextMarshaler?
|
||||
- else we use a pair of functions based on the "kind" of the type e.g. map, slice, int64, etc
|
||||
|
||||
This symmetry is important to reduce chances of issues happening because the
|
||||
encoding and decoding sides are out of sync e.g. decoded via very specific
|
||||
encoding.TextUnmarshaler but encoded via kind-specific generalized mode.
|
||||
|
||||
Consequently, if a type only defines one-half of the symmetry
|
||||
(e.g. it implements UnmarshalJSON() but not MarshalJSON() ),
|
||||
then that type doesn't satisfy the check and we will continue walking down the
|
||||
decision tree.
|
||||
|
||||
## RPC
|
||||
|
||||
RPC Client and Server Codecs are implemented, so the codecs can be used
|
||||
with the standard net/rpc package.
|
||||
|
||||
## Usage
|
||||
|
||||
Typical usage model:
|
||||
|
||||
// create and configure Handle
|
||||
var (
|
||||
bh codec.BincHandle
|
||||
mh codec.MsgpackHandle
|
||||
ch codec.CborHandle
|
||||
)
|
||||
|
||||
mh.MapType = reflect.TypeOf(map[string]interface{}(nil))
|
||||
|
||||
// configure extensions
|
||||
// e.g. for msgpack, define functions and enable Time support for tag 1
|
||||
// mh.SetExt(reflect.TypeOf(time.Time{}), 1, myExt)
|
||||
|
||||
// create and use decoder/encoder
|
||||
var (
|
||||
r io.Reader
|
||||
w io.Writer
|
||||
b []byte
|
||||
h = &bh // or mh to use msgpack
|
||||
)
|
||||
|
||||
dec = codec.NewDecoder(r, h)
|
||||
dec = codec.NewDecoderBytes(b, h)
|
||||
err = dec.Decode(&v)
|
||||
|
||||
enc = codec.NewEncoder(w, h)
|
||||
enc = codec.NewEncoderBytes(&b, h)
|
||||
err = enc.Encode(v)
|
||||
|
||||
//RPC Server
|
||||
go func() {
|
||||
for {
|
||||
conn, err := listener.Accept()
|
||||
rpcCodec := codec.GoRpc.ServerCodec(conn, h)
|
||||
//OR rpcCodec := codec.MsgpackSpecRpc.ServerCodec(conn, h)
|
||||
rpc.ServeCodec(rpcCodec)
|
||||
}
|
||||
}()
|
||||
|
||||
//RPC Communication (client side)
|
||||
conn, err = net.Dial("tcp", "localhost:5555")
|
||||
rpcCodec := codec.GoRpc.ClientCodec(conn, h)
|
||||
//OR rpcCodec := codec.MsgpackSpecRpc.ClientCodec(conn, h)
|
||||
client := rpc.NewClientWithCodec(rpcCodec)
|
||||
|
||||
## Running Tests
|
||||
|
||||
To run tests, use the following:
|
||||
|
||||
go test
|
||||
|
||||
To run the full suite of tests, use the following:
|
||||
|
||||
go test -tags alltests -run Suite
|
||||
|
||||
You can run the tag 'safe' to run tests or build in safe mode. e.g.
|
||||
|
||||
go test -tags safe -run Json
|
||||
go test -tags "alltests safe" -run Suite
|
||||
|
||||
## Running Benchmarks
|
||||
|
||||
Please see http://github.com/ugorji/go-codec-bench .
|
||||
|
||||
## Caveats
|
||||
|
||||
Struct fields matching the following are ignored during encoding and decoding
|
||||
|
||||
- struct tag value set to -
|
||||
- func, complex numbers, unsafe pointers
|
||||
- unexported and not embedded
|
||||
- unexported and embedded and not struct kind
|
||||
- unexported and embedded pointers (from go1.10)
|
||||
|
||||
Every other field in a struct will be encoded/decoded.
|
||||
|
||||
Embedded fields are encoded as if they exist in the top-level struct,
|
||||
with some caveats. See Encode documentation.
|
||||
1168
vendor/github.com/ugorji/go/codec/binc.go
generated
vendored
Normal file
1168
vendor/github.com/ugorji/go/codec/binc.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
756
vendor/github.com/ugorji/go/codec/cbor.go
generated
vendored
Normal file
756
vendor/github.com/ugorji/go/codec/cbor.go
generated
vendored
Normal file
|
|
@ -0,0 +1,756 @@
|
|||
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
package codec
|
||||
|
||||
import (
|
||||
"math"
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
cborMajorUint byte = iota
|
||||
cborMajorNegInt
|
||||
cborMajorBytes
|
||||
cborMajorText
|
||||
cborMajorArray
|
||||
cborMajorMap
|
||||
cborMajorTag
|
||||
cborMajorOther
|
||||
)
|
||||
|
||||
const (
|
||||
cborBdFalse byte = 0xf4 + iota
|
||||
cborBdTrue
|
||||
cborBdNil
|
||||
cborBdUndefined
|
||||
cborBdExt
|
||||
cborBdFloat16
|
||||
cborBdFloat32
|
||||
cborBdFloat64
|
||||
)
|
||||
|
||||
const (
|
||||
cborBdIndefiniteBytes byte = 0x5f
|
||||
cborBdIndefiniteString = 0x7f
|
||||
cborBdIndefiniteArray = 0x9f
|
||||
cborBdIndefiniteMap = 0xbf
|
||||
cborBdBreak = 0xff
|
||||
)
|
||||
|
||||
// These define some in-stream descriptors for
|
||||
// manual encoding e.g. when doing explicit indefinite-length
|
||||
const (
|
||||
CborStreamBytes byte = 0x5f
|
||||
CborStreamString = 0x7f
|
||||
CborStreamArray = 0x9f
|
||||
CborStreamMap = 0xbf
|
||||
CborStreamBreak = 0xff
|
||||
)
|
||||
|
||||
const (
|
||||
cborBaseUint byte = 0x00
|
||||
cborBaseNegInt = 0x20
|
||||
cborBaseBytes = 0x40
|
||||
cborBaseString = 0x60
|
||||
cborBaseArray = 0x80
|
||||
cborBaseMap = 0xa0
|
||||
cborBaseTag = 0xc0
|
||||
cborBaseSimple = 0xe0
|
||||
)
|
||||
|
||||
func cbordesc(bd byte) string {
|
||||
switch bd {
|
||||
case cborBdNil:
|
||||
return "nil"
|
||||
case cborBdFalse:
|
||||
return "false"
|
||||
case cborBdTrue:
|
||||
return "true"
|
||||
case cborBdFloat16, cborBdFloat32, cborBdFloat64:
|
||||
return "float"
|
||||
case cborBdIndefiniteBytes:
|
||||
return "bytes*"
|
||||
case cborBdIndefiniteString:
|
||||
return "string*"
|
||||
case cborBdIndefiniteArray:
|
||||
return "array*"
|
||||
case cborBdIndefiniteMap:
|
||||
return "map*"
|
||||
default:
|
||||
switch {
|
||||
case bd >= cborBaseUint && bd < cborBaseNegInt:
|
||||
return "(u)int"
|
||||
case bd >= cborBaseNegInt && bd < cborBaseBytes:
|
||||
return "int"
|
||||
case bd >= cborBaseBytes && bd < cborBaseString:
|
||||
return "bytes"
|
||||
case bd >= cborBaseString && bd < cborBaseArray:
|
||||
return "string"
|
||||
case bd >= cborBaseArray && bd < cborBaseMap:
|
||||
return "array"
|
||||
case bd >= cborBaseMap && bd < cborBaseTag:
|
||||
return "map"
|
||||
case bd >= cborBaseTag && bd < cborBaseSimple:
|
||||
return "ext"
|
||||
default:
|
||||
return "unknown"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------
|
||||
|
||||
type cborEncDriver struct {
|
||||
noBuiltInTypes
|
||||
encDriverNoopContainerWriter
|
||||
// encNoSeparator
|
||||
e *Encoder
|
||||
w encWriter
|
||||
h *CborHandle
|
||||
x [8]byte
|
||||
_ [3]uint64 // padding
|
||||
}
|
||||
|
||||
func (e *cborEncDriver) EncodeNil() {
|
||||
e.w.writen1(cborBdNil)
|
||||
}
|
||||
|
||||
func (e *cborEncDriver) EncodeBool(b bool) {
|
||||
if b {
|
||||
e.w.writen1(cborBdTrue)
|
||||
} else {
|
||||
e.w.writen1(cborBdFalse)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *cborEncDriver) EncodeFloat32(f float32) {
|
||||
e.w.writen1(cborBdFloat32)
|
||||
bigenHelper{e.x[:4], e.w}.writeUint32(math.Float32bits(f))
|
||||
}
|
||||
|
||||
func (e *cborEncDriver) EncodeFloat64(f float64) {
|
||||
e.w.writen1(cborBdFloat64)
|
||||
bigenHelper{e.x[:8], e.w}.writeUint64(math.Float64bits(f))
|
||||
}
|
||||
|
||||
func (e *cborEncDriver) encUint(v uint64, bd byte) {
|
||||
if v <= 0x17 {
|
||||
e.w.writen1(byte(v) + bd)
|
||||
} else if v <= math.MaxUint8 {
|
||||
e.w.writen2(bd+0x18, uint8(v))
|
||||
} else if v <= math.MaxUint16 {
|
||||
e.w.writen1(bd + 0x19)
|
||||
bigenHelper{e.x[:2], e.w}.writeUint16(uint16(v))
|
||||
} else if v <= math.MaxUint32 {
|
||||
e.w.writen1(bd + 0x1a)
|
||||
bigenHelper{e.x[:4], e.w}.writeUint32(uint32(v))
|
||||
} else { // if v <= math.MaxUint64 {
|
||||
e.w.writen1(bd + 0x1b)
|
||||
bigenHelper{e.x[:8], e.w}.writeUint64(v)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *cborEncDriver) EncodeInt(v int64) {
|
||||
if v < 0 {
|
||||
e.encUint(uint64(-1-v), cborBaseNegInt)
|
||||
} else {
|
||||
e.encUint(uint64(v), cborBaseUint)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *cborEncDriver) EncodeUint(v uint64) {
|
||||
e.encUint(v, cborBaseUint)
|
||||
}
|
||||
|
||||
func (e *cborEncDriver) encLen(bd byte, length int) {
|
||||
e.encUint(uint64(length), bd)
|
||||
}
|
||||
|
||||
func (e *cborEncDriver) EncodeTime(t time.Time) {
|
||||
if t.IsZero() {
|
||||
e.EncodeNil()
|
||||
} else if e.h.TimeRFC3339 {
|
||||
e.encUint(0, cborBaseTag)
|
||||
e.EncodeString(cUTF8, t.Format(time.RFC3339Nano))
|
||||
} else {
|
||||
e.encUint(1, cborBaseTag)
|
||||
t = t.UTC().Round(time.Microsecond)
|
||||
sec, nsec := t.Unix(), uint64(t.Nanosecond())
|
||||
if nsec == 0 {
|
||||
e.EncodeInt(sec)
|
||||
} else {
|
||||
e.EncodeFloat64(float64(sec) + float64(nsec)/1e9)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (e *cborEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, en *Encoder) {
|
||||
e.encUint(uint64(xtag), cborBaseTag)
|
||||
if v := ext.ConvertExt(rv); v == nil {
|
||||
e.EncodeNil()
|
||||
} else {
|
||||
en.encode(v)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *cborEncDriver) EncodeRawExt(re *RawExt, en *Encoder) {
|
||||
e.encUint(uint64(re.Tag), cborBaseTag)
|
||||
if false && re.Data != nil {
|
||||
en.encode(re.Data)
|
||||
} else if re.Value != nil {
|
||||
en.encode(re.Value)
|
||||
} else {
|
||||
e.EncodeNil()
|
||||
}
|
||||
}
|
||||
|
||||
func (e *cborEncDriver) WriteArrayStart(length int) {
|
||||
if e.h.IndefiniteLength {
|
||||
e.w.writen1(cborBdIndefiniteArray)
|
||||
} else {
|
||||
e.encLen(cborBaseArray, length)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *cborEncDriver) WriteMapStart(length int) {
|
||||
if e.h.IndefiniteLength {
|
||||
e.w.writen1(cborBdIndefiniteMap)
|
||||
} else {
|
||||
e.encLen(cborBaseMap, length)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *cborEncDriver) WriteMapEnd() {
|
||||
if e.h.IndefiniteLength {
|
||||
e.w.writen1(cborBdBreak)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *cborEncDriver) WriteArrayEnd() {
|
||||
if e.h.IndefiniteLength {
|
||||
e.w.writen1(cborBdBreak)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *cborEncDriver) EncodeString(c charEncoding, v string) {
|
||||
e.encStringBytesS(cborBaseString, v)
|
||||
}
|
||||
|
||||
func (e *cborEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
|
||||
if v == nil {
|
||||
e.EncodeNil()
|
||||
} else if c == cRAW {
|
||||
e.encStringBytesS(cborBaseBytes, stringView(v))
|
||||
} else {
|
||||
e.encStringBytesS(cborBaseString, stringView(v))
|
||||
}
|
||||
}
|
||||
|
||||
func (e *cborEncDriver) encStringBytesS(bb byte, v string) {
|
||||
if e.h.IndefiniteLength {
|
||||
if bb == cborBaseBytes {
|
||||
e.w.writen1(cborBdIndefiniteBytes)
|
||||
} else {
|
||||
e.w.writen1(cborBdIndefiniteString)
|
||||
}
|
||||
blen := len(v) / 4
|
||||
if blen == 0 {
|
||||
blen = 64
|
||||
} else if blen > 1024 {
|
||||
blen = 1024
|
||||
}
|
||||
for i := 0; i < len(v); {
|
||||
var v2 string
|
||||
i2 := i + blen
|
||||
if i2 < len(v) {
|
||||
v2 = v[i:i2]
|
||||
} else {
|
||||
v2 = v[i:]
|
||||
}
|
||||
e.encLen(bb, len(v2))
|
||||
e.w.writestr(v2)
|
||||
i = i2
|
||||
}
|
||||
e.w.writen1(cborBdBreak)
|
||||
} else {
|
||||
e.encLen(bb, len(v))
|
||||
e.w.writestr(v)
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------
|
||||
|
||||
type cborDecDriver struct {
|
||||
d *Decoder
|
||||
h *CborHandle
|
||||
r decReader
|
||||
// b [scratchByteArrayLen]byte
|
||||
br bool // bytes reader
|
||||
bdRead bool
|
||||
bd byte
|
||||
noBuiltInTypes
|
||||
// decNoSeparator
|
||||
decDriverNoopContainerReader
|
||||
_ [3]uint64 // padding
|
||||
}
|
||||
|
||||
func (d *cborDecDriver) readNextBd() {
|
||||
d.bd = d.r.readn1()
|
||||
d.bdRead = true
|
||||
}
|
||||
|
||||
func (d *cborDecDriver) uncacheRead() {
|
||||
if d.bdRead {
|
||||
d.r.unreadn1()
|
||||
d.bdRead = false
|
||||
}
|
||||
}
|
||||
|
||||
func (d *cborDecDriver) ContainerType() (vt valueType) {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
if d.bd == cborBdNil {
|
||||
return valueTypeNil
|
||||
} else if d.bd == cborBdIndefiniteBytes || (d.bd >= cborBaseBytes && d.bd < cborBaseString) {
|
||||
return valueTypeBytes
|
||||
} else if d.bd == cborBdIndefiniteString || (d.bd >= cborBaseString && d.bd < cborBaseArray) {
|
||||
return valueTypeString
|
||||
} else if d.bd == cborBdIndefiniteArray || (d.bd >= cborBaseArray && d.bd < cborBaseMap) {
|
||||
return valueTypeArray
|
||||
} else if d.bd == cborBdIndefiniteMap || (d.bd >= cborBaseMap && d.bd < cborBaseTag) {
|
||||
return valueTypeMap
|
||||
}
|
||||
// else {
|
||||
// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
|
||||
// }
|
||||
return valueTypeUnset
|
||||
}
|
||||
|
||||
func (d *cborDecDriver) TryDecodeAsNil() bool {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
// treat Nil and Undefined as nil values
|
||||
if d.bd == cborBdNil || d.bd == cborBdUndefined {
|
||||
d.bdRead = false
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (d *cborDecDriver) CheckBreak() bool {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
if d.bd == cborBdBreak {
|
||||
d.bdRead = false
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (d *cborDecDriver) decUint() (ui uint64) {
|
||||
v := d.bd & 0x1f
|
||||
if v <= 0x17 {
|
||||
ui = uint64(v)
|
||||
} else {
|
||||
if v == 0x18 {
|
||||
ui = uint64(d.r.readn1())
|
||||
} else if v == 0x19 {
|
||||
ui = uint64(bigen.Uint16(d.r.readx(2)))
|
||||
} else if v == 0x1a {
|
||||
ui = uint64(bigen.Uint32(d.r.readx(4)))
|
||||
} else if v == 0x1b {
|
||||
ui = uint64(bigen.Uint64(d.r.readx(8)))
|
||||
} else {
|
||||
d.d.errorf("invalid descriptor decoding uint: %x/%s", d.bd, cbordesc(d.bd))
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *cborDecDriver) decCheckInteger() (neg bool) {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
major := d.bd >> 5
|
||||
if major == cborMajorUint {
|
||||
} else if major == cborMajorNegInt {
|
||||
neg = true
|
||||
} else {
|
||||
d.d.errorf("not an integer - invalid major %v from descriptor %x/%s", major, d.bd, cbordesc(d.bd))
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *cborDecDriver) DecodeInt64() (i int64) {
|
||||
neg := d.decCheckInteger()
|
||||
ui := d.decUint()
|
||||
// check if this number can be converted to an int without overflow
|
||||
if neg {
|
||||
i = -(chkOvf.SignedIntV(ui + 1))
|
||||
} else {
|
||||
i = chkOvf.SignedIntV(ui)
|
||||
}
|
||||
d.bdRead = false
|
||||
return
|
||||
}
|
||||
|
||||
func (d *cborDecDriver) DecodeUint64() (ui uint64) {
|
||||
if d.decCheckInteger() {
|
||||
d.d.errorf("assigning negative signed value to unsigned type")
|
||||
return
|
||||
}
|
||||
ui = d.decUint()
|
||||
d.bdRead = false
|
||||
return
|
||||
}
|
||||
|
||||
func (d *cborDecDriver) DecodeFloat64() (f float64) {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
if bd := d.bd; bd == cborBdFloat16 {
|
||||
f = float64(math.Float32frombits(halfFloatToFloatBits(bigen.Uint16(d.r.readx(2)))))
|
||||
} else if bd == cborBdFloat32 {
|
||||
f = float64(math.Float32frombits(bigen.Uint32(d.r.readx(4))))
|
||||
} else if bd == cborBdFloat64 {
|
||||
f = math.Float64frombits(bigen.Uint64(d.r.readx(8)))
|
||||
} else if bd >= cborBaseUint && bd < cborBaseBytes {
|
||||
f = float64(d.DecodeInt64())
|
||||
} else {
|
||||
d.d.errorf("float only valid from float16/32/64 - invalid descriptor %x/%s", bd, cbordesc(bd))
|
||||
return
|
||||
}
|
||||
d.bdRead = false
|
||||
return
|
||||
}
|
||||
|
||||
// bool can be decoded from bool only (single byte).
|
||||
func (d *cborDecDriver) DecodeBool() (b bool) {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
if bd := d.bd; bd == cborBdTrue {
|
||||
b = true
|
||||
} else if bd == cborBdFalse {
|
||||
} else {
|
||||
d.d.errorf("not bool - %s %x/%s", msgBadDesc, d.bd, cbordesc(d.bd))
|
||||
return
|
||||
}
|
||||
d.bdRead = false
|
||||
return
|
||||
}
|
||||
|
||||
func (d *cborDecDriver) ReadMapStart() (length int) {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
d.bdRead = false
|
||||
if d.bd == cborBdIndefiniteMap {
|
||||
return -1
|
||||
}
|
||||
return d.decLen()
|
||||
}
|
||||
|
||||
func (d *cborDecDriver) ReadArrayStart() (length int) {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
d.bdRead = false
|
||||
if d.bd == cborBdIndefiniteArray {
|
||||
return -1
|
||||
}
|
||||
return d.decLen()
|
||||
}
|
||||
|
||||
func (d *cborDecDriver) decLen() int {
|
||||
return int(d.decUint())
|
||||
}
|
||||
|
||||
func (d *cborDecDriver) decAppendIndefiniteBytes(bs []byte) []byte {
|
||||
d.bdRead = false
|
||||
for {
|
||||
if d.CheckBreak() {
|
||||
break
|
||||
}
|
||||
if major := d.bd >> 5; major != cborMajorBytes && major != cborMajorText {
|
||||
d.d.errorf("expect bytes/string major type in indefinite string/bytes;"+
|
||||
" got major %v from descriptor %x/%x", major, d.bd, cbordesc(d.bd))
|
||||
return nil
|
||||
}
|
||||
n := d.decLen()
|
||||
oldLen := len(bs)
|
||||
newLen := oldLen + n
|
||||
if newLen > cap(bs) {
|
||||
bs2 := make([]byte, newLen, 2*cap(bs)+n)
|
||||
copy(bs2, bs)
|
||||
bs = bs2
|
||||
} else {
|
||||
bs = bs[:newLen]
|
||||
}
|
||||
d.r.readb(bs[oldLen:newLen])
|
||||
// bs = append(bs, d.r.readn()...)
|
||||
d.bdRead = false
|
||||
}
|
||||
d.bdRead = false
|
||||
return bs
|
||||
}
|
||||
|
||||
func (d *cborDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
if d.bd == cborBdNil || d.bd == cborBdUndefined {
|
||||
d.bdRead = false
|
||||
return nil
|
||||
}
|
||||
if d.bd == cborBdIndefiniteBytes || d.bd == cborBdIndefiniteString {
|
||||
d.bdRead = false
|
||||
if bs == nil {
|
||||
if zerocopy {
|
||||
return d.decAppendIndefiniteBytes(d.d.b[:0])
|
||||
}
|
||||
return d.decAppendIndefiniteBytes(zeroByteSlice)
|
||||
}
|
||||
return d.decAppendIndefiniteBytes(bs[:0])
|
||||
}
|
||||
// check if an "array" of uint8's (see ContainerType for how to infer if an array)
|
||||
if d.bd == cborBdIndefiniteArray || (d.bd >= cborBaseArray && d.bd < cborBaseMap) {
|
||||
bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
|
||||
return
|
||||
}
|
||||
clen := d.decLen()
|
||||
d.bdRead = false
|
||||
if zerocopy {
|
||||
if d.br {
|
||||
return d.r.readx(clen)
|
||||
} else if len(bs) == 0 {
|
||||
bs = d.d.b[:]
|
||||
}
|
||||
}
|
||||
return decByteSlice(d.r, clen, d.h.MaxInitLen, bs)
|
||||
}
|
||||
|
||||
func (d *cborDecDriver) DecodeString() (s string) {
|
||||
return string(d.DecodeBytes(d.d.b[:], true))
|
||||
}
|
||||
|
||||
func (d *cborDecDriver) DecodeStringAsBytes() (s []byte) {
|
||||
return d.DecodeBytes(d.d.b[:], true)
|
||||
}
|
||||
|
||||
func (d *cborDecDriver) DecodeTime() (t time.Time) {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
if d.bd == cborBdNil || d.bd == cborBdUndefined {
|
||||
d.bdRead = false
|
||||
return
|
||||
}
|
||||
xtag := d.decUint()
|
||||
d.bdRead = false
|
||||
return d.decodeTime(xtag)
|
||||
}
|
||||
|
||||
func (d *cborDecDriver) decodeTime(xtag uint64) (t time.Time) {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
switch xtag {
|
||||
case 0:
|
||||
var err error
|
||||
if t, err = time.Parse(time.RFC3339, stringView(d.DecodeStringAsBytes())); err != nil {
|
||||
d.d.errorv(err)
|
||||
}
|
||||
case 1:
|
||||
// decode an int64 or a float, and infer time.Time from there.
|
||||
// for floats, round to microseconds, as that is what is guaranteed to fit well.
|
||||
switch {
|
||||
case d.bd == cborBdFloat16, d.bd == cborBdFloat32:
|
||||
f1, f2 := math.Modf(d.DecodeFloat64())
|
||||
t = time.Unix(int64(f1), int64(f2*1e9))
|
||||
case d.bd == cborBdFloat64:
|
||||
f1, f2 := math.Modf(d.DecodeFloat64())
|
||||
t = time.Unix(int64(f1), int64(f2*1e9))
|
||||
case d.bd >= cborBaseUint && d.bd < cborBaseNegInt,
|
||||
d.bd >= cborBaseNegInt && d.bd < cborBaseBytes:
|
||||
t = time.Unix(d.DecodeInt64(), 0)
|
||||
default:
|
||||
d.d.errorf("time.Time can only be decoded from a number (or RFC3339 string)")
|
||||
}
|
||||
default:
|
||||
d.d.errorf("invalid tag for time.Time - expecting 0 or 1, got 0x%x", xtag)
|
||||
}
|
||||
t = t.UTC().Round(time.Microsecond)
|
||||
return
|
||||
}
|
||||
|
||||
func (d *cborDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
u := d.decUint()
|
||||
d.bdRead = false
|
||||
realxtag = u
|
||||
if ext == nil {
|
||||
re := rv.(*RawExt)
|
||||
re.Tag = realxtag
|
||||
d.d.decode(&re.Value)
|
||||
} else if xtag != realxtag {
|
||||
d.d.errorf("Wrong extension tag. Got %b. Expecting: %v", realxtag, xtag)
|
||||
return
|
||||
} else {
|
||||
var v interface{}
|
||||
d.d.decode(&v)
|
||||
ext.UpdateExt(rv, v)
|
||||
}
|
||||
d.bdRead = false
|
||||
return
|
||||
}
|
||||
|
||||
func (d *cborDecDriver) DecodeNaked() {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
|
||||
n := d.d.n
|
||||
var decodeFurther bool
|
||||
|
||||
switch d.bd {
|
||||
case cborBdNil:
|
||||
n.v = valueTypeNil
|
||||
case cborBdFalse:
|
||||
n.v = valueTypeBool
|
||||
n.b = false
|
||||
case cborBdTrue:
|
||||
n.v = valueTypeBool
|
||||
n.b = true
|
||||
case cborBdFloat16, cborBdFloat32, cborBdFloat64:
|
||||
n.v = valueTypeFloat
|
||||
n.f = d.DecodeFloat64()
|
||||
case cborBdIndefiniteBytes:
|
||||
n.v = valueTypeBytes
|
||||
n.l = d.DecodeBytes(nil, false)
|
||||
case cborBdIndefiniteString:
|
||||
n.v = valueTypeString
|
||||
n.s = d.DecodeString()
|
||||
case cborBdIndefiniteArray:
|
||||
n.v = valueTypeArray
|
||||
decodeFurther = true
|
||||
case cborBdIndefiniteMap:
|
||||
n.v = valueTypeMap
|
||||
decodeFurther = true
|
||||
default:
|
||||
switch {
|
||||
case d.bd >= cborBaseUint && d.bd < cborBaseNegInt:
|
||||
if d.h.SignedInteger {
|
||||
n.v = valueTypeInt
|
||||
n.i = d.DecodeInt64()
|
||||
} else {
|
||||
n.v = valueTypeUint
|
||||
n.u = d.DecodeUint64()
|
||||
}
|
||||
case d.bd >= cborBaseNegInt && d.bd < cborBaseBytes:
|
||||
n.v = valueTypeInt
|
||||
n.i = d.DecodeInt64()
|
||||
case d.bd >= cborBaseBytes && d.bd < cborBaseString:
|
||||
n.v = valueTypeBytes
|
||||
n.l = d.DecodeBytes(nil, false)
|
||||
case d.bd >= cborBaseString && d.bd < cborBaseArray:
|
||||
n.v = valueTypeString
|
||||
n.s = d.DecodeString()
|
||||
case d.bd >= cborBaseArray && d.bd < cborBaseMap:
|
||||
n.v = valueTypeArray
|
||||
decodeFurther = true
|
||||
case d.bd >= cborBaseMap && d.bd < cborBaseTag:
|
||||
n.v = valueTypeMap
|
||||
decodeFurther = true
|
||||
case d.bd >= cborBaseTag && d.bd < cborBaseSimple:
|
||||
n.v = valueTypeExt
|
||||
n.u = d.decUint()
|
||||
n.l = nil
|
||||
if n.u == 0 || n.u == 1 {
|
||||
d.bdRead = false
|
||||
n.v = valueTypeTime
|
||||
n.t = d.decodeTime(n.u)
|
||||
}
|
||||
// d.bdRead = false
|
||||
// d.d.decode(&re.Value) // handled by decode itself.
|
||||
// decodeFurther = true
|
||||
default:
|
||||
d.d.errorf("decodeNaked: Unrecognized d.bd: 0x%x", d.bd)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if !decodeFurther {
|
||||
d.bdRead = false
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// -------------------------
|
||||
|
||||
// CborHandle is a Handle for the CBOR encoding format,
|
||||
// defined at http://tools.ietf.org/html/rfc7049 and documented further at http://cbor.io .
|
||||
//
|
||||
// CBOR is comprehensively supported, including support for:
|
||||
// - indefinite-length arrays/maps/bytes/strings
|
||||
// - (extension) tags in range 0..0xffff (0 .. 65535)
|
||||
// - half, single and double-precision floats
|
||||
// - all numbers (1, 2, 4 and 8-byte signed and unsigned integers)
|
||||
// - nil, true, false, ...
|
||||
// - arrays and maps, bytes and text strings
|
||||
//
|
||||
// None of the optional extensions (with tags) defined in the spec are supported out-of-the-box.
|
||||
// Users can implement them as needed (using SetExt), including spec-documented ones:
|
||||
// - timestamp, BigNum, BigFloat, Decimals,
|
||||
// - Encoded Text (e.g. URL, regexp, base64, MIME Message), etc.
|
||||
type CborHandle struct {
|
||||
binaryEncodingType
|
||||
noElemSeparators
|
||||
BasicHandle
|
||||
|
||||
// IndefiniteLength=true, means that we encode using indefinitelength
|
||||
IndefiniteLength bool
|
||||
|
||||
// TimeRFC3339 says to encode time.Time using RFC3339 format.
|
||||
// If unset, we encode time.Time using seconds past epoch.
|
||||
TimeRFC3339 bool
|
||||
|
||||
// _ [1]uint64 // padding
|
||||
}
|
||||
|
||||
// Name returns the name of the handle: cbor
|
||||
func (h *CborHandle) Name() string { return "cbor" }
|
||||
|
||||
// SetInterfaceExt sets an extension
|
||||
func (h *CborHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) {
|
||||
return h.SetExt(rt, tag, &extWrapper{bytesExtFailer{}, ext})
|
||||
}
|
||||
|
||||
func (h *CborHandle) newEncDriver(e *Encoder) encDriver {
|
||||
return &cborEncDriver{e: e, w: e.w, h: h}
|
||||
}
|
||||
|
||||
func (h *CborHandle) newDecDriver(d *Decoder) decDriver {
|
||||
return &cborDecDriver{d: d, h: h, r: d.r, br: d.bytes}
|
||||
}
|
||||
|
||||
func (e *cborEncDriver) reset() {
|
||||
e.w = e.e.w
|
||||
}
|
||||
|
||||
func (d *cborDecDriver) reset() {
|
||||
d.r, d.br = d.d.r, d.d.bytes
|
||||
d.bd, d.bdRead = 0, false
|
||||
}
|
||||
|
||||
var _ decDriver = (*cborDecDriver)(nil)
|
||||
var _ encDriver = (*cborEncDriver)(nil)
|
||||
2552
vendor/github.com/ugorji/go/codec/decode.go
generated
vendored
Normal file
2552
vendor/github.com/ugorji/go/codec/decode.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
1375
vendor/github.com/ugorji/go/codec/encode.go
generated
vendored
Normal file
1375
vendor/github.com/ugorji/go/codec/encode.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
34522
vendor/github.com/ugorji/go/codec/fast-path.generated.go
generated
vendored
Normal file
34522
vendor/github.com/ugorji/go/codec/fast-path.generated.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
544
vendor/github.com/ugorji/go/codec/fast-path.go.tmpl
generated
vendored
Normal file
544
vendor/github.com/ugorji/go/codec/fast-path.go.tmpl
generated
vendored
Normal file
|
|
@ -0,0 +1,544 @@
|
|||
// +build !notfastpath
|
||||
|
||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
// Code generated from fast-path.go.tmpl - DO NOT EDIT.
|
||||
|
||||
package codec
|
||||
|
||||
// Fast path functions try to create a fast path encode or decode implementation
|
||||
// for common maps and slices.
|
||||
//
|
||||
// We define the functions and register then in this single file
|
||||
// so as not to pollute the encode.go and decode.go, and create a dependency in there.
|
||||
// This file can be omitted without causing a build failure.
|
||||
//
|
||||
// The advantage of fast paths is:
|
||||
// - Many calls bypass reflection altogether
|
||||
//
|
||||
// Currently support
|
||||
// - slice of all builtin types,
|
||||
// - map of all builtin types to string or interface value
|
||||
// - symmetrical maps of all builtin types (e.g. str-str, uint8-uint8)
|
||||
// This should provide adequate "typical" implementations.
|
||||
//
|
||||
// Note that fast track decode functions must handle values for which an address cannot be obtained.
|
||||
// For example:
|
||||
// m2 := map[string]int{}
|
||||
// p2 := []interface{}{m2}
|
||||
// // decoding into p2 will bomb if fast track functions do not treat like unaddressable.
|
||||
//
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sort"
|
||||
)
|
||||
|
||||
const fastpathEnabled = true
|
||||
|
||||
type fastpathT struct {}
|
||||
|
||||
var fastpathTV fastpathT
|
||||
|
||||
type fastpathE struct {
|
||||
rtid uintptr
|
||||
rt reflect.Type
|
||||
encfn func(*Encoder, *codecFnInfo, reflect.Value)
|
||||
decfn func(*Decoder, *codecFnInfo, reflect.Value)
|
||||
}
|
||||
|
||||
type fastpathA [{{ .FastpathLen }}]fastpathE
|
||||
|
||||
func (x *fastpathA) index(rtid uintptr) int {
|
||||
// use binary search to grab the index (adapted from sort/search.go)
|
||||
h, i, j := 0, 0, {{ .FastpathLen }} // len(x)
|
||||
for i < j {
|
||||
h = i + (j-i)/2
|
||||
if x[h].rtid < rtid {
|
||||
i = h + 1
|
||||
} else {
|
||||
j = h
|
||||
}
|
||||
}
|
||||
if i < {{ .FastpathLen }} && x[i].rtid == rtid {
|
||||
return i
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
type fastpathAslice []fastpathE
|
||||
|
||||
func (x fastpathAslice) Len() int { return len(x) }
|
||||
func (x fastpathAslice) Less(i, j int) bool { return x[i].rtid < x[j].rtid }
|
||||
func (x fastpathAslice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
|
||||
|
||||
var fastpathAV fastpathA
|
||||
|
||||
// due to possible initialization loop error, make fastpath in an init()
|
||||
func init() {
|
||||
i := 0
|
||||
fn := func(v interface{},
|
||||
fe func(*Encoder, *codecFnInfo, reflect.Value),
|
||||
fd func(*Decoder, *codecFnInfo, reflect.Value)) (f fastpathE) {
|
||||
xrt := reflect.TypeOf(v)
|
||||
xptr := rt2id(xrt)
|
||||
fastpathAV[i] = fastpathE{xptr, xrt, fe, fd}
|
||||
i++
|
||||
return
|
||||
}
|
||||
{{/* do not register []uint8 in fast-path */}}
|
||||
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}{{if ne .Elem "uint8"}}
|
||||
fn([]{{ .Elem }}(nil), (*Encoder).{{ .MethodNamePfx "fastpathEnc" false }}R, (*Decoder).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}}{{end}}
|
||||
|
||||
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
|
||||
fn(map[{{ .MapKey }}]{{ .Elem }}(nil), (*Encoder).{{ .MethodNamePfx "fastpathEnc" false }}R, (*Decoder).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}}
|
||||
|
||||
sort.Sort(fastpathAslice(fastpathAV[:]))
|
||||
}
|
||||
|
||||
// -- encode
|
||||
|
||||
// -- -- fast path type switch
|
||||
func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool {
|
||||
switch v := iv.(type) {
|
||||
|
||||
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}{{if ne .Elem "uint8"}}
|
||||
case []{{ .Elem }}:
|
||||
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
|
||||
case *[]{{ .Elem }}:
|
||||
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e){{/*
|
||||
*/}}{{end}}{{end}}{{end}}{{end}}
|
||||
|
||||
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
|
||||
case map[{{ .MapKey }}]{{ .Elem }}:
|
||||
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
|
||||
case *map[{{ .MapKey }}]{{ .Elem }}:
|
||||
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e){{/*
|
||||
*/}}{{end}}{{end}}{{end}}
|
||||
|
||||
default:
|
||||
_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
{{/*
|
||||
**** removing this block, as they are never called directly ****
|
||||
|
||||
|
||||
|
||||
**** removing this block, as they are never called directly ****
|
||||
|
||||
|
||||
|
||||
func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool {
|
||||
switch v := iv.(type) {
|
||||
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
|
||||
case []{{ .Elem }}:
|
||||
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
|
||||
case *[]{{ .Elem }}:
|
||||
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e)
|
||||
{{end}}{{end}}{{end}}
|
||||
default:
|
||||
_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool {
|
||||
switch v := iv.(type) {
|
||||
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
|
||||
case map[{{ .MapKey }}]{{ .Elem }}:
|
||||
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
|
||||
case *map[{{ .MapKey }}]{{ .Elem }}:
|
||||
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e)
|
||||
{{end}}{{end}}{{end}}
|
||||
default:
|
||||
_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
|
||||
**** removing this block, as they are never called directly ****
|
||||
|
||||
|
||||
|
||||
**** removing this block, as they are never called directly ****
|
||||
*/}}
|
||||
|
||||
// -- -- fast path functions
|
||||
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
|
||||
func (e *Encoder) {{ .MethodNamePfx "fastpathEnc" false }}R(f *codecFnInfo, rv reflect.Value) {
|
||||
if f.ti.mbs {
|
||||
fastpathTV.{{ .MethodNamePfx "EncAsMap" false }}V(rv2i(rv).([]{{ .Elem }}), e)
|
||||
} else {
|
||||
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv2i(rv).([]{{ .Elem }}), e)
|
||||
}
|
||||
}
|
||||
func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v []{{ .Elem }}, e *Encoder) {
|
||||
if v == nil { e.e.EncodeNil(); return }
|
||||
ee, esep := e.e, e.hh.hasElemSeparators()
|
||||
ee.WriteArrayStart(len(v))
|
||||
if esep {
|
||||
for _, v2 := range v {
|
||||
ee.WriteArrayElem()
|
||||
{{ encmd .Elem "v2"}}
|
||||
}
|
||||
} else {
|
||||
for _, v2 := range v {
|
||||
{{ encmd .Elem "v2"}}
|
||||
}
|
||||
} {{/*
|
||||
for _, v2 := range v {
|
||||
if esep { ee.WriteArrayElem() }
|
||||
{{ encmd .Elem "v2"}}
|
||||
} */}}
|
||||
ee.WriteArrayEnd()
|
||||
}
|
||||
func (_ fastpathT) {{ .MethodNamePfx "EncAsMap" false }}V(v []{{ .Elem }}, e *Encoder) {
|
||||
ee, esep := e.e, e.hh.hasElemSeparators()
|
||||
if len(v)%2 == 1 {
|
||||
e.errorf("mapBySlice requires even slice length, but got %v", len(v))
|
||||
return
|
||||
}
|
||||
ee.WriteMapStart(len(v) / 2)
|
||||
if esep {
|
||||
for j, v2 := range v {
|
||||
if j%2 == 0 {
|
||||
ee.WriteMapElemKey()
|
||||
} else {
|
||||
ee.WriteMapElemValue()
|
||||
}
|
||||
{{ encmd .Elem "v2"}}
|
||||
}
|
||||
} else {
|
||||
for _, v2 := range v {
|
||||
{{ encmd .Elem "v2"}}
|
||||
}
|
||||
} {{/*
|
||||
for j, v2 := range v {
|
||||
if esep {
|
||||
if j%2 == 0 {
|
||||
ee.WriteMapElemKey()
|
||||
} else {
|
||||
ee.WriteMapElemValue()
|
||||
}
|
||||
}
|
||||
{{ encmd .Elem "v2"}}
|
||||
} */}}
|
||||
ee.WriteMapEnd()
|
||||
}
|
||||
{{end}}{{end}}{{end}}
|
||||
|
||||
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
|
||||
func (e *Encoder) {{ .MethodNamePfx "fastpathEnc" false }}R(f *codecFnInfo, rv reflect.Value) {
|
||||
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv2i(rv).(map[{{ .MapKey }}]{{ .Elem }}), e)
|
||||
}
|
||||
func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v map[{{ .MapKey }}]{{ .Elem }}, e *Encoder) {
|
||||
if v == nil { e.e.EncodeNil(); return }
|
||||
ee, esep := e.e, e.hh.hasElemSeparators()
|
||||
ee.WriteMapStart(len(v))
|
||||
if e.h.Canonical {
|
||||
{{if eq .MapKey "interface{}"}}{{/* out of band
|
||||
*/}}var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
|
||||
e2 := NewEncoderBytes(&mksv, e.hh)
|
||||
v2 := make([]bytesI, len(v))
|
||||
var i, l int
|
||||
var vp *bytesI {{/* put loop variables outside. seems currently needed for better perf */}}
|
||||
for k2, _ := range v {
|
||||
l = len(mksv)
|
||||
e2.MustEncode(k2)
|
||||
vp = &v2[i]
|
||||
vp.v = mksv[l:]
|
||||
vp.i = k2
|
||||
i++
|
||||
}
|
||||
sort.Sort(bytesISlice(v2))
|
||||
if esep {
|
||||
for j := range v2 {
|
||||
ee.WriteMapElemKey()
|
||||
e.asis(v2[j].v)
|
||||
ee.WriteMapElemValue()
|
||||
e.encode(v[v2[j].i])
|
||||
}
|
||||
} else {
|
||||
for j := range v2 {
|
||||
e.asis(v2[j].v)
|
||||
e.encode(v[v2[j].i])
|
||||
}
|
||||
} {{/*
|
||||
for j := range v2 {
|
||||
if esep { ee.WriteMapElemKey() }
|
||||
e.asis(v2[j].v)
|
||||
if esep { ee.WriteMapElemValue() }
|
||||
e.encode(v[v2[j].i])
|
||||
} */}} {{else}}{{ $x := sorttype .MapKey true}}v2 := make([]{{ $x }}, len(v))
|
||||
var i int
|
||||
for k, _ := range v {
|
||||
v2[i] = {{ $x }}(k)
|
||||
i++
|
||||
}
|
||||
sort.Sort({{ sorttype .MapKey false}}(v2))
|
||||
if esep {
|
||||
for _, k2 := range v2 {
|
||||
ee.WriteMapElemKey()
|
||||
{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ $y := printf "%s(k2)" .MapKey }}{{ encmd .MapKey $y }}{{end}}
|
||||
ee.WriteMapElemValue()
|
||||
{{ $y := printf "v[%s(k2)]" .MapKey }}{{ encmd .Elem $y }}
|
||||
}
|
||||
} else {
|
||||
for _, k2 := range v2 {
|
||||
{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ $y := printf "%s(k2)" .MapKey }}{{ encmd .MapKey $y }}{{end}}
|
||||
{{ $y := printf "v[%s(k2)]" .MapKey }}{{ encmd .Elem $y }}
|
||||
}
|
||||
} {{/*
|
||||
for _, k2 := range v2 {
|
||||
if esep { ee.WriteMapElemKey() }
|
||||
{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ $y := printf "%s(k2)" .MapKey }}{{ encmd .MapKey $y }}{{end}}
|
||||
if esep { ee.WriteMapElemValue() }
|
||||
{{ $y := printf "v[%s(k2)]" .MapKey }}{{ encmd .Elem $y }}
|
||||
} */}} {{end}}
|
||||
} else {
|
||||
if esep {
|
||||
for k2, v2 := range v {
|
||||
ee.WriteMapElemKey()
|
||||
{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ encmd .MapKey "k2"}}{{end}}
|
||||
ee.WriteMapElemValue()
|
||||
{{ encmd .Elem "v2"}}
|
||||
}
|
||||
} else {
|
||||
for k2, v2 := range v {
|
||||
{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ encmd .MapKey "k2"}}{{end}}
|
||||
{{ encmd .Elem "v2"}}
|
||||
}
|
||||
} {{/*
|
||||
for k2, v2 := range v {
|
||||
if esep { ee.WriteMapElemKey() }
|
||||
{{if eq .MapKey "string"}}ee.EncodeString(cUTF8, k2){{else}}{{ encmd .MapKey "k2"}}{{end}}
|
||||
if esep { ee.WriteMapElemValue() }
|
||||
{{ encmd .Elem "v2"}}
|
||||
} */}}
|
||||
}
|
||||
ee.WriteMapEnd()
|
||||
}
|
||||
{{end}}{{end}}{{end}}
|
||||
|
||||
// -- decode
|
||||
|
||||
// -- -- fast path type switch
|
||||
func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool {
|
||||
var changed bool
|
||||
switch v := iv.(type) {
|
||||
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}{{if ne .Elem "uint8"}}
|
||||
case []{{ .Elem }}:
|
||||
var v2 []{{ .Elem }}
|
||||
v2, changed = fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, false, d)
|
||||
if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
|
||||
copy(v, v2)
|
||||
}
|
||||
case *[]{{ .Elem }}:
|
||||
var v2 []{{ .Elem }}
|
||||
v2, changed = fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*v, true, d)
|
||||
if changed {
|
||||
*v = v2
|
||||
}{{/*
|
||||
*/}}{{end}}{{end}}{{end}}{{end}}
|
||||
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}{{/*
|
||||
// maps only change if nil, and in that case, there's no point copying
|
||||
*/}}
|
||||
case map[{{ .MapKey }}]{{ .Elem }}:
|
||||
fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, false, d)
|
||||
case *map[{{ .MapKey }}]{{ .Elem }}:
|
||||
var v2 map[{{ .MapKey }}]{{ .Elem }}
|
||||
v2, changed = fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*v, true, d)
|
||||
if changed {
|
||||
*v = v2
|
||||
}{{/*
|
||||
*/}}{{end}}{{end}}{{end}}
|
||||
default:
|
||||
_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func fastpathDecodeSetZeroTypeSwitch(iv interface{}) bool {
|
||||
switch v := iv.(type) {
|
||||
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
|
||||
case *[]{{ .Elem }}:
|
||||
*v = nil {{/*
|
||||
*/}}{{end}}{{end}}{{end}}
|
||||
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
|
||||
case *map[{{ .MapKey }}]{{ .Elem }}:
|
||||
*v = nil {{/*
|
||||
*/}}{{end}}{{end}}{{end}}
|
||||
default:
|
||||
_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// -- -- fast path functions
|
||||
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
|
||||
{{/*
|
||||
Slices can change if they
|
||||
- did not come from an array
|
||||
- are addressable (from a ptr)
|
||||
- are settable (e.g. contained in an interface{})
|
||||
*/}}
|
||||
func (d *Decoder) {{ .MethodNamePfx "fastpathDec" false }}R(f *codecFnInfo, rv reflect.Value) {
|
||||
if array := f.seq == seqTypeArray; !array && rv.Kind() == reflect.Ptr {
|
||||
vp := rv2i(rv).(*[]{{ .Elem }})
|
||||
v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, !array, d)
|
||||
if changed { *vp = v }
|
||||
} else {
|
||||
v := rv2i(rv).([]{{ .Elem }})
|
||||
v2, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, !array, d)
|
||||
if changed && len(v) > 0 && len(v2) > 0 && !(len(v2) == len(v) && &v2[0] == &v[0]) {
|
||||
copy(v, v2)
|
||||
}
|
||||
}
|
||||
}
|
||||
func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *[]{{ .Elem }}, d *Decoder) {
|
||||
v, changed := f.{{ .MethodNamePfx "Dec" false }}V(*vp, true, d)
|
||||
if changed { *vp = v }
|
||||
}
|
||||
func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, canChange bool, d *Decoder) (_ []{{ .Elem }}, changed bool) {
|
||||
dd := d.d{{/*
|
||||
// if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil()
|
||||
*/}}
|
||||
slh, containerLenS := d.decSliceHelperStart()
|
||||
if containerLenS == 0 {
|
||||
if canChange {
|
||||
if v == nil { v = []{{ .Elem }}{} } else if len(v) != 0 { v = v[:0] }
|
||||
changed = true
|
||||
}
|
||||
slh.End()
|
||||
return v, changed
|
||||
}
|
||||
hasLen := containerLenS > 0
|
||||
var xlen int
|
||||
if hasLen && canChange {
|
||||
if containerLenS > cap(v) {
|
||||
xlen = decInferLen(containerLenS, d.h.MaxInitLen, {{ .Size }})
|
||||
if xlen <= cap(v) {
|
||||
v = v[:xlen]
|
||||
} else {
|
||||
v = make([]{{ .Elem }}, xlen)
|
||||
}
|
||||
changed = true
|
||||
} else if containerLenS != len(v) {
|
||||
v = v[:containerLenS]
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
j := 0
|
||||
for ; (hasLen && j < containerLenS) || !(hasLen || dd.CheckBreak()); j++ {
|
||||
if j == 0 && len(v) == 0 && canChange {
|
||||
if hasLen {
|
||||
xlen = decInferLen(containerLenS, d.h.MaxInitLen, {{ .Size }})
|
||||
} else {
|
||||
xlen = 8
|
||||
}
|
||||
v = make([]{{ .Elem }}, xlen)
|
||||
changed = true
|
||||
}
|
||||
// if indefinite, etc, then expand the slice if necessary
|
||||
var decodeIntoBlank bool
|
||||
if j >= len(v) {
|
||||
if canChange {
|
||||
v = append(v, {{ zerocmd .Elem }})
|
||||
changed = true
|
||||
} else {
|
||||
d.arrayCannotExpand(len(v), j+1)
|
||||
decodeIntoBlank = true
|
||||
}
|
||||
}
|
||||
slh.ElemContainerState(j)
|
||||
if decodeIntoBlank {
|
||||
d.swallow()
|
||||
} else if dd.TryDecodeAsNil() {
|
||||
v[j] = {{ zerocmd .Elem }}
|
||||
} else {
|
||||
{{ if eq .Elem "interface{}" }}d.decode(&v[j]){{ else }}v[j] = {{ decmd .Elem }}{{ end }}
|
||||
}
|
||||
}
|
||||
if canChange {
|
||||
if j < len(v) {
|
||||
v = v[:j]
|
||||
changed = true
|
||||
} else if j == 0 && v == nil {
|
||||
v = make([]{{ .Elem }}, 0)
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
slh.End()
|
||||
return v, changed
|
||||
}
|
||||
{{end}}{{end}}{{end}}
|
||||
|
||||
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
|
||||
{{/*
|
||||
Maps can change if they are
|
||||
- addressable (from a ptr)
|
||||
- settable (e.g. contained in an interface{})
|
||||
*/}}
|
||||
func (d *Decoder) {{ .MethodNamePfx "fastpathDec" false }}R(f *codecFnInfo, rv reflect.Value) {
|
||||
if rv.Kind() == reflect.Ptr {
|
||||
vp := rv2i(rv).(*map[{{ .MapKey }}]{{ .Elem }})
|
||||
v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, true, d);
|
||||
if changed { *vp = v }
|
||||
} else {
|
||||
fastpathTV.{{ .MethodNamePfx "Dec" false }}V(rv2i(rv).(map[{{ .MapKey }}]{{ .Elem }}), false, d)
|
||||
}
|
||||
}
|
||||
func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *map[{{ .MapKey }}]{{ .Elem }}, d *Decoder) {
|
||||
v, changed := f.{{ .MethodNamePfx "Dec" false }}V(*vp, true, d)
|
||||
if changed { *vp = v }
|
||||
}
|
||||
func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v map[{{ .MapKey }}]{{ .Elem }}, canChange bool,
|
||||
d *Decoder) (_ map[{{ .MapKey }}]{{ .Elem }}, changed bool) {
|
||||
dd, esep := d.d, d.hh.hasElemSeparators(){{/*
|
||||
// if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil()
|
||||
*/}}
|
||||
containerLen := dd.ReadMapStart()
|
||||
if canChange && v == nil {
|
||||
xlen := decInferLen(containerLen, d.h.MaxInitLen, {{ .Size }})
|
||||
v = make(map[{{ .MapKey }}]{{ .Elem }}, xlen)
|
||||
changed = true
|
||||
}
|
||||
if containerLen == 0 {
|
||||
dd.ReadMapEnd()
|
||||
return v, changed
|
||||
}
|
||||
{{ if eq .Elem "interface{}" }}mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
|
||||
{{end}}var mk {{ .MapKey }}
|
||||
var mv {{ .Elem }}
|
||||
hasLen := containerLen > 0
|
||||
for j := 0; (hasLen && j < containerLen) || !(hasLen || dd.CheckBreak()); j++ {
|
||||
if esep { dd.ReadMapElemKey() }
|
||||
{{ if eq .MapKey "interface{}" }}mk = nil
|
||||
d.decode(&mk)
|
||||
if bv, bok := mk.([]byte); bok {
|
||||
mk = d.string(bv) {{/* // maps cannot have []byte as key. switch to string. */}}
|
||||
}{{ else }}mk = {{ decmd .MapKey }}{{ end }}
|
||||
if esep { dd.ReadMapElemValue() }
|
||||
if dd.TryDecodeAsNil() {
|
||||
if v == nil {} else if d.h.DeleteOnNilMapValue { delete(v, mk) } else { v[mk] = {{ zerocmd .Elem }} }
|
||||
continue
|
||||
}
|
||||
{{ if eq .Elem "interface{}" }}if mapGet { mv = v[mk] } else { mv = nil }
|
||||
d.decode(&mv){{ else }}mv = {{ decmd .Elem }}{{ end }}
|
||||
if v != nil { v[mk] = mv }
|
||||
}
|
||||
dd.ReadMapEnd()
|
||||
return v, changed
|
||||
}
|
||||
{{end}}{{end}}{{end}}
|
||||
47
vendor/github.com/ugorji/go/codec/fast-path.not.go
generated
vendored
Normal file
47
vendor/github.com/ugorji/go/codec/fast-path.not.go
generated
vendored
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
// +build notfastpath
|
||||
|
||||
package codec
|
||||
|
||||
import "reflect"
|
||||
|
||||
const fastpathEnabled = false
|
||||
|
||||
// The generated fast-path code is very large, and adds a few seconds to the build time.
|
||||
// This causes test execution, execution of small tools which use codec, etc
|
||||
// to take a long time.
|
||||
//
|
||||
// To mitigate, we now support the notfastpath tag.
|
||||
// This tag disables fastpath during build, allowing for faster build, test execution,
|
||||
// short-program runs, etc.
|
||||
|
||||
func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { return false }
|
||||
func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { return false }
|
||||
func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool { return false }
|
||||
func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { return false }
|
||||
func fastpathDecodeSetZeroTypeSwitch(iv interface{}) bool { return false }
|
||||
|
||||
type fastpathT struct{}
|
||||
type fastpathE struct {
|
||||
rtid uintptr
|
||||
rt reflect.Type
|
||||
encfn func(*Encoder, *codecFnInfo, reflect.Value)
|
||||
decfn func(*Decoder, *codecFnInfo, reflect.Value)
|
||||
}
|
||||
type fastpathA [0]fastpathE
|
||||
|
||||
func (x fastpathA) index(rtid uintptr) int { return -1 }
|
||||
|
||||
func (_ fastpathT) DecSliceUint8V(v []uint8, canChange bool, d *Decoder) (_ []uint8, changed bool) {
|
||||
fn := d.cfer().get(uint8SliceTyp, true, true)
|
||||
d.kSlice(&fn.i, reflect.ValueOf(&v).Elem())
|
||||
return v, true
|
||||
}
|
||||
|
||||
var fastpathAV fastpathA
|
||||
var fastpathTV fastpathT
|
||||
|
||||
// ----
|
||||
type TestMammoth2Wrapper struct{} // to allow testMammoth work in notfastpath mode
|
||||
78
vendor/github.com/ugorji/go/codec/gen-dec-array.go.tmpl
generated
vendored
Normal file
78
vendor/github.com/ugorji/go/codec/gen-dec-array.go.tmpl
generated
vendored
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
{{var "v"}} := {{if not isArray}}*{{end}}{{ .Varname }}
|
||||
{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}{{if not isArray}}
|
||||
var {{var "c"}} bool {{/* // changed */}}
|
||||
_ = {{var "c"}}{{end}}
|
||||
if {{var "l"}} == 0 {
|
||||
{{if isSlice }}if {{var "v"}} == nil {
|
||||
{{var "v"}} = []{{ .Typ }}{}
|
||||
{{var "c"}} = true
|
||||
} else if len({{var "v"}}) != 0 {
|
||||
{{var "v"}} = {{var "v"}}[:0]
|
||||
{{var "c"}} = true
|
||||
} {{else if isChan }}if {{var "v"}} == nil {
|
||||
{{var "v"}} = make({{ .CTyp }}, 0)
|
||||
{{var "c"}} = true
|
||||
} {{end}}
|
||||
} else {
|
||||
{{var "hl"}} := {{var "l"}} > 0
|
||||
var {{var "rl"}} int
|
||||
_ = {{var "rl"}}
|
||||
{{if isSlice }} if {{var "hl"}} {
|
||||
if {{var "l"}} > cap({{var "v"}}) {
|
||||
{{var "rl"}} = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
|
||||
if {{var "rl"}} <= cap({{var "v"}}) {
|
||||
{{var "v"}} = {{var "v"}}[:{{var "rl"}}]
|
||||
} else {
|
||||
{{var "v"}} = make([]{{ .Typ }}, {{var "rl"}})
|
||||
}
|
||||
{{var "c"}} = true
|
||||
} else if {{var "l"}} != len({{var "v"}}) {
|
||||
{{var "v"}} = {{var "v"}}[:{{var "l"}}]
|
||||
{{var "c"}} = true
|
||||
}
|
||||
} {{end}}
|
||||
var {{var "j"}} int
|
||||
// var {{var "dn"}} bool
|
||||
for ; ({{var "hl"}} && {{var "j"}} < {{var "l"}}) || !({{var "hl"}} || r.CheckBreak()); {{var "j"}}++ {
|
||||
{{if not isArray}} if {{var "j"}} == 0 && {{var "v"}} == nil {
|
||||
if {{var "hl"}} {
|
||||
{{var "rl"}} = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
|
||||
} else {
|
||||
{{var "rl"}} = {{if isSlice}}8{{else if isChan}}64{{end}}
|
||||
}
|
||||
{{var "v"}} = make({{if isSlice}}[]{{ .Typ }}{{else if isChan}}{{.CTyp}}{{end}}, {{var "rl"}})
|
||||
{{var "c"}} = true
|
||||
}{{end}}
|
||||
{{var "h"}}.ElemContainerState({{var "j"}})
|
||||
{{/* {{var "dn"}} = r.TryDecodeAsNil() */}}{{/* commented out, as decLineVar handles this already each time */}}
|
||||
{{if isChan}}{{ $x := printf "%[1]vvcx%[2]v" .TempVar .Rand }}var {{$x}} {{ .Typ }}
|
||||
{{ decLineVar $x }}
|
||||
{{var "v"}} <- {{ $x }}
|
||||
// println(">>>> sending ", {{ $x }}, " into ", {{var "v"}}) // TODO: remove this
|
||||
{{else}}{{/* // if indefinite, etc, then expand the slice if necessary */}}
|
||||
var {{var "db"}} bool
|
||||
if {{var "j"}} >= len({{var "v"}}) {
|
||||
{{if isSlice }} {{var "v"}} = append({{var "v"}}, {{ zero }})
|
||||
{{var "c"}} = true
|
||||
{{else}} z.DecArrayCannotExpand(len(v), {{var "j"}}+1); {{var "db"}} = true
|
||||
{{end}}
|
||||
}
|
||||
if {{var "db"}} {
|
||||
z.DecSwallow()
|
||||
} else {
|
||||
{{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x }}
|
||||
}
|
||||
{{end}}
|
||||
}
|
||||
{{if isSlice}} if {{var "j"}} < len({{var "v"}}) {
|
||||
{{var "v"}} = {{var "v"}}[:{{var "j"}}]
|
||||
{{var "c"}} = true
|
||||
} else if {{var "j"}} == 0 && {{var "v"}} == nil {
|
||||
{{var "v"}} = make([]{{ .Typ }}, 0)
|
||||
{{var "c"}} = true
|
||||
} {{end}}
|
||||
}
|
||||
{{var "h"}}.End()
|
||||
{{if not isArray }}if {{var "c"}} {
|
||||
*{{ .Varname }} = {{var "v"}}
|
||||
}{{end}}
|
||||
42
vendor/github.com/ugorji/go/codec/gen-dec-map.go.tmpl
generated
vendored
Normal file
42
vendor/github.com/ugorji/go/codec/gen-dec-map.go.tmpl
generated
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
{{var "v"}} := *{{ .Varname }}
|
||||
{{var "l"}} := r.ReadMapStart()
|
||||
{{var "bh"}} := z.DecBasicHandle()
|
||||
if {{var "v"}} == nil {
|
||||
{{var "rl"}} := z.DecInferLen({{var "l"}}, {{var "bh"}}.MaxInitLen, {{ .Size }})
|
||||
{{var "v"}} = make(map[{{ .KTyp }}]{{ .Typ }}, {{var "rl"}})
|
||||
*{{ .Varname }} = {{var "v"}}
|
||||
}
|
||||
var {{var "mk"}} {{ .KTyp }}
|
||||
var {{var "mv"}} {{ .Typ }}
|
||||
var {{var "mg"}}, {{var "mdn"}} {{if decElemKindPtr}}, {{var "ms"}}, {{var "mok"}}{{end}} bool
|
||||
if {{var "bh"}}.MapValueReset {
|
||||
{{if decElemKindPtr}}{{var "mg"}} = true
|
||||
{{else if decElemKindIntf}}if !{{var "bh"}}.InterfaceReset { {{var "mg"}} = true }
|
||||
{{else if not decElemKindImmutable}}{{var "mg"}} = true
|
||||
{{end}} }
|
||||
if {{var "l"}} != 0 {
|
||||
{{var "hl"}} := {{var "l"}} > 0
|
||||
for {{var "j"}} := 0; ({{var "hl"}} && {{var "j"}} < {{var "l"}}) || !({{var "hl"}} || r.CheckBreak()); {{var "j"}}++ {
|
||||
r.ReadMapElemKey() {{/* z.DecSendContainerState(codecSelfer_containerMapKey{{ .Sfx }}) */}}
|
||||
{{ $x := printf "%vmk%v" .TempVar .Rand }}{{ decLineVarK $x }}
|
||||
{{ if eq .KTyp "interface{}" }}{{/* // special case if a byte array. */}}if {{var "bv"}}, {{var "bok"}} := {{var "mk"}}.([]byte); {{var "bok"}} {
|
||||
{{var "mk"}} = string({{var "bv"}})
|
||||
}{{ end }}{{if decElemKindPtr}}
|
||||
{{var "ms"}} = true{{end}}
|
||||
if {{var "mg"}} {
|
||||
{{if decElemKindPtr}}{{var "mv"}}, {{var "mok"}} = {{var "v"}}[{{var "mk"}}]
|
||||
if {{var "mok"}} {
|
||||
{{var "ms"}} = false
|
||||
} {{else}}{{var "mv"}} = {{var "v"}}[{{var "mk"}}] {{end}}
|
||||
} {{if not decElemKindImmutable}}else { {{var "mv"}} = {{decElemZero}} }{{end}}
|
||||
r.ReadMapElemValue() {{/* z.DecSendContainerState(codecSelfer_containerMapValue{{ .Sfx }}) */}}
|
||||
{{var "mdn"}} = false
|
||||
{{ $x := printf "%vmv%v" .TempVar .Rand }}{{ $y := printf "%vmdn%v" .TempVar .Rand }}{{ decLineVar $x $y }}
|
||||
if {{var "mdn"}} {
|
||||
if {{ var "bh" }}.DeleteOnNilMapValue { delete({{var "v"}}, {{var "mk"}}) } else { {{var "v"}}[{{var "mk"}}] = {{decElemZero}} }
|
||||
} else if {{if decElemKindPtr}} {{var "ms"}} && {{end}} {{var "v"}} != nil {
|
||||
{{var "v"}}[{{var "mk"}}] = {{var "mv"}}
|
||||
}
|
||||
}
|
||||
} // else len==0: TODO: Should we clear map entries?
|
||||
r.ReadMapEnd() {{/* z.DecSendContainerState(codecSelfer_containerMapEnd{{ .Sfx }}) */}}
|
||||
27
vendor/github.com/ugorji/go/codec/gen-enc-chan.go.tmpl
generated
vendored
Normal file
27
vendor/github.com/ugorji/go/codec/gen-enc-chan.go.tmpl
generated
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
{{.Label}}:
|
||||
switch timeout{{.Sfx}} := z.EncBasicHandle().ChanRecvTimeout; {
|
||||
case timeout{{.Sfx}} == 0: // only consume available
|
||||
for {
|
||||
select {
|
||||
case b{{.Sfx}} := <-{{.Chan}}:
|
||||
{{ .Slice }} = append({{.Slice}}, b{{.Sfx}})
|
||||
default:
|
||||
break {{.Label}}
|
||||
}
|
||||
}
|
||||
case timeout{{.Sfx}} > 0: // consume until timeout
|
||||
tt{{.Sfx}} := time.NewTimer(timeout{{.Sfx}})
|
||||
for {
|
||||
select {
|
||||
case b{{.Sfx}} := <-{{.Chan}}:
|
||||
{{.Slice}} = append({{.Slice}}, b{{.Sfx}})
|
||||
case <-tt{{.Sfx}}.C:
|
||||
// close(tt.C)
|
||||
break {{.Label}}
|
||||
}
|
||||
}
|
||||
default: // consume until close
|
||||
for b{{.Sfx}} := range {{.Chan}} {
|
||||
{{.Slice}} = append({{.Slice}}, b{{.Sfx}})
|
||||
}
|
||||
}
|
||||
335
vendor/github.com/ugorji/go/codec/gen-helper.generated.go
generated
vendored
Normal file
335
vendor/github.com/ugorji/go/codec/gen-helper.generated.go
generated
vendored
Normal file
|
|
@ -0,0 +1,335 @@
|
|||
/* // +build ignore */
|
||||
|
||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
// Code generated from gen-helper.go.tmpl - DO NOT EDIT.
|
||||
|
||||
package codec
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// GenVersion is the current version of codecgen.
|
||||
const GenVersion = 8
|
||||
|
||||
// This file is used to generate helper code for codecgen.
|
||||
// The values here i.e. genHelper(En|De)coder are not to be used directly by
|
||||
// library users. They WILL change continuously and without notice.
|
||||
//
|
||||
// To help enforce this, we create an unexported type with exported members.
|
||||
// The only way to get the type is via the one exported type that we control (somewhat).
|
||||
//
|
||||
// When static codecs are created for types, they will use this value
|
||||
// to perform encoding or decoding of primitives or known slice or map types.
|
||||
|
||||
// GenHelperEncoder is exported so that it can be used externally by codecgen.
|
||||
//
|
||||
// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
|
||||
func GenHelperEncoder(e *Encoder) (ge genHelperEncoder, ee genHelperEncDriver) {
|
||||
ge = genHelperEncoder{e: e}
|
||||
ee = genHelperEncDriver{encDriver: e.e}
|
||||
return
|
||||
}
|
||||
|
||||
// GenHelperDecoder is exported so that it can be used externally by codecgen.
|
||||
//
|
||||
// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
|
||||
func GenHelperDecoder(d *Decoder) (gd genHelperDecoder, dd genHelperDecDriver) {
|
||||
gd = genHelperDecoder{d: d}
|
||||
dd = genHelperDecDriver{decDriver: d.d}
|
||||
return
|
||||
}
|
||||
|
||||
type genHelperEncDriver struct {
|
||||
encDriver
|
||||
}
|
||||
|
||||
func (x genHelperEncDriver) EncodeBuiltin(rt uintptr, v interface{}) {}
|
||||
func (x genHelperEncDriver) EncStructFieldKey(keyType valueType, s string) {
|
||||
encStructFieldKey(x.encDriver, keyType, s)
|
||||
}
|
||||
func (x genHelperEncDriver) EncodeSymbol(s string) {
|
||||
x.encDriver.EncodeString(cUTF8, s)
|
||||
}
|
||||
|
||||
type genHelperDecDriver struct {
|
||||
decDriver
|
||||
C checkOverflow
|
||||
}
|
||||
|
||||
func (x genHelperDecDriver) DecodeBuiltin(rt uintptr, v interface{}) {}
|
||||
func (x genHelperDecDriver) DecStructFieldKey(keyType valueType, buf *[decScratchByteArrayLen]byte) []byte {
|
||||
return decStructFieldKey(x.decDriver, keyType, buf)
|
||||
}
|
||||
func (x genHelperDecDriver) DecodeInt(bitsize uint8) (i int64) {
|
||||
return x.C.IntV(x.decDriver.DecodeInt64(), bitsize)
|
||||
}
|
||||
func (x genHelperDecDriver) DecodeUint(bitsize uint8) (ui uint64) {
|
||||
return x.C.UintV(x.decDriver.DecodeUint64(), bitsize)
|
||||
}
|
||||
func (x genHelperDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
|
||||
f = x.DecodeFloat64()
|
||||
if chkOverflow32 && chkOvf.Float32(f) {
|
||||
panicv.errorf("float32 overflow: %v", f)
|
||||
}
|
||||
return
|
||||
}
|
||||
func (x genHelperDecDriver) DecodeFloat32As64() (f float64) {
|
||||
f = x.DecodeFloat64()
|
||||
if chkOvf.Float32(f) {
|
||||
panicv.errorf("float32 overflow: %v", f)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
type genHelperEncoder struct {
|
||||
M must
|
||||
e *Encoder
|
||||
F fastpathT
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
type genHelperDecoder struct {
|
||||
C checkOverflow
|
||||
d *Decoder
|
||||
F fastpathT
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperEncoder) EncBasicHandle() *BasicHandle {
|
||||
return f.e.h
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperEncoder) EncBinary() bool {
|
||||
return f.e.be // f.e.hh.isBinaryEncoding()
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperEncoder) IsJSONHandle() bool {
|
||||
return f.e.js
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperEncoder) EncFallback(iv interface{}) {
|
||||
// println(">>>>>>>>> EncFallback")
|
||||
// f.e.encodeI(iv, false, false)
|
||||
f.e.encodeValue(reflect.ValueOf(iv), nil, false)
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperEncoder) EncTextMarshal(iv encoding.TextMarshaler) {
|
||||
bs, fnerr := iv.MarshalText()
|
||||
f.e.marshal(bs, fnerr, false, cUTF8)
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperEncoder) EncJSONMarshal(iv jsonMarshaler) {
|
||||
bs, fnerr := iv.MarshalJSON()
|
||||
f.e.marshal(bs, fnerr, true, cUTF8)
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperEncoder) EncBinaryMarshal(iv encoding.BinaryMarshaler) {
|
||||
bs, fnerr := iv.MarshalBinary()
|
||||
f.e.marshal(bs, fnerr, false, cRAW)
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperEncoder) EncRaw(iv Raw) { f.e.rawBytes(iv) }
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
//
|
||||
// Deprecated: builtin no longer supported - so we make this method a no-op,
|
||||
// but leave in-place so that old generated files continue to work without regeneration.
|
||||
func (f genHelperEncoder) TimeRtidIfBinc() (v uintptr) { return }
|
||||
|
||||
// func (f genHelperEncoder) TimeRtidIfBinc() uintptr {
|
||||
// if _, ok := f.e.hh.(*BincHandle); ok {
|
||||
// return timeTypId
|
||||
// }
|
||||
// }
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperEncoder) I2Rtid(v interface{}) uintptr {
|
||||
return i2rtid(v)
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperEncoder) Extension(rtid uintptr) (xfn *extTypeTagFn) {
|
||||
return f.e.h.getExt(rtid)
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperEncoder) EncExtension(v interface{}, xfFn *extTypeTagFn) {
|
||||
f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
//
|
||||
// Deprecated: No longer used,
|
||||
// but leave in-place so that old generated files continue to work without regeneration.
|
||||
func (f genHelperEncoder) HasExtensions() bool {
|
||||
return len(f.e.h.extHandle) != 0
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
//
|
||||
// Deprecated: No longer used,
|
||||
// but leave in-place so that old generated files continue to work without regeneration.
|
||||
func (f genHelperEncoder) EncExt(v interface{}) (r bool) {
|
||||
if xfFn := f.e.h.getExt(i2rtid(v)); xfFn != nil {
|
||||
f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ---------------- DECODER FOLLOWS -----------------
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecBasicHandle() *BasicHandle {
|
||||
return f.d.h
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecBinary() bool {
|
||||
return f.d.be // f.d.hh.isBinaryEncoding()
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecSwallow() { f.d.swallow() }
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecScratchBuffer() []byte {
|
||||
return f.d.b[:]
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecScratchArrayBuffer() *[decScratchByteArrayLen]byte {
|
||||
return &f.d.b
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecFallback(iv interface{}, chkPtr bool) {
|
||||
// println(">>>>>>>>> DecFallback")
|
||||
rv := reflect.ValueOf(iv)
|
||||
if chkPtr {
|
||||
rv = f.d.ensureDecodeable(rv)
|
||||
}
|
||||
f.d.decodeValue(rv, nil, false)
|
||||
// f.d.decodeValueFallback(rv)
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecSliceHelperStart() (decSliceHelper, int) {
|
||||
return f.d.decSliceHelperStart()
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecStructFieldNotFound(index int, name string) {
|
||||
f.d.structFieldNotFound(index, name)
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecArrayCannotExpand(sliceLen, streamLen int) {
|
||||
f.d.arrayCannotExpand(sliceLen, streamLen)
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecTextUnmarshal(tm encoding.TextUnmarshaler) {
|
||||
fnerr := tm.UnmarshalText(f.d.d.DecodeStringAsBytes())
|
||||
if fnerr != nil {
|
||||
panic(fnerr)
|
||||
}
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecJSONUnmarshal(tm jsonUnmarshaler) {
|
||||
// bs := f.dd.DecodeStringAsBytes()
|
||||
// grab the bytes to be read, as UnmarshalJSON needs the full JSON so as to unmarshal it itself.
|
||||
fnerr := tm.UnmarshalJSON(f.d.nextValueBytes())
|
||||
if fnerr != nil {
|
||||
panic(fnerr)
|
||||
}
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecBinaryUnmarshal(bm encoding.BinaryUnmarshaler) {
|
||||
fnerr := bm.UnmarshalBinary(f.d.d.DecodeBytes(nil, true))
|
||||
if fnerr != nil {
|
||||
panic(fnerr)
|
||||
}
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecRaw() []byte { return f.d.rawBytes() }
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
//
|
||||
// Deprecated: builtin no longer supported - so we make this method a no-op,
|
||||
// but leave in-place so that old generated files continue to work without regeneration.
|
||||
func (f genHelperDecoder) TimeRtidIfBinc() (v uintptr) { return }
|
||||
|
||||
// func (f genHelperDecoder) TimeRtidIfBinc() uintptr {
|
||||
// // Note: builtin is no longer supported - so make this a no-op
|
||||
// if _, ok := f.d.hh.(*BincHandle); ok {
|
||||
// return timeTypId
|
||||
// }
|
||||
// return 0
|
||||
// }
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) IsJSONHandle() bool {
|
||||
return f.d.js
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) I2Rtid(v interface{}) uintptr {
|
||||
return i2rtid(v)
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) Extension(rtid uintptr) (xfn *extTypeTagFn) {
|
||||
return f.d.h.getExt(rtid)
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecExtension(v interface{}, xfFn *extTypeTagFn) {
|
||||
f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
//
|
||||
// Deprecated: No longer used,
|
||||
// but leave in-place so that old generated files continue to work without regeneration.
|
||||
func (f genHelperDecoder) HasExtensions() bool {
|
||||
return len(f.d.h.extHandle) != 0
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
//
|
||||
// Deprecated: No longer used,
|
||||
// but leave in-place so that old generated files continue to work without regeneration.
|
||||
func (f genHelperDecoder) DecExt(v interface{}) (r bool) {
|
||||
if xfFn := f.d.h.getExt(i2rtid(v)); xfFn != nil {
|
||||
f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecInferLen(clen, maxlen, unit int) (rvlen int) {
|
||||
return decInferLen(clen, maxlen, unit)
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
//
|
||||
// Deprecated: no longer used,
|
||||
// but leave in-place so that old generated files continue to work without regeneration.
|
||||
func (f genHelperDecoder) StringView(v []byte) string { return stringView(v) }
|
||||
302
vendor/github.com/ugorji/go/codec/gen-helper.go.tmpl
generated
vendored
Normal file
302
vendor/github.com/ugorji/go/codec/gen-helper.go.tmpl
generated
vendored
Normal file
|
|
@ -0,0 +1,302 @@
|
|||
/* // +build ignore */
|
||||
|
||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
// Code generated from gen-helper.go.tmpl - DO NOT EDIT.
|
||||
|
||||
package codec
|
||||
|
||||
import (
|
||||
"encoding"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// GenVersion is the current version of codecgen.
|
||||
const GenVersion = {{ .Version }}
|
||||
|
||||
// This file is used to generate helper code for codecgen.
|
||||
// The values here i.e. genHelper(En|De)coder are not to be used directly by
|
||||
// library users. They WILL change continuously and without notice.
|
||||
//
|
||||
// To help enforce this, we create an unexported type with exported members.
|
||||
// The only way to get the type is via the one exported type that we control (somewhat).
|
||||
//
|
||||
// When static codecs are created for types, they will use this value
|
||||
// to perform encoding or decoding of primitives or known slice or map types.
|
||||
|
||||
// GenHelperEncoder is exported so that it can be used externally by codecgen.
|
||||
//
|
||||
// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
|
||||
func GenHelperEncoder(e *Encoder) (ge genHelperEncoder, ee genHelperEncDriver) {
|
||||
ge = genHelperEncoder{e: e}
|
||||
ee = genHelperEncDriver{encDriver: e.e}
|
||||
return
|
||||
}
|
||||
|
||||
// GenHelperDecoder is exported so that it can be used externally by codecgen.
|
||||
//
|
||||
// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
|
||||
func GenHelperDecoder(d *Decoder) (gd genHelperDecoder, dd genHelperDecDriver) {
|
||||
gd = genHelperDecoder{d: d}
|
||||
dd = genHelperDecDriver{decDriver: d.d}
|
||||
return
|
||||
}
|
||||
|
||||
type genHelperEncDriver struct {
|
||||
encDriver
|
||||
}
|
||||
|
||||
func (x genHelperEncDriver) EncodeBuiltin(rt uintptr, v interface{}) {}
|
||||
func (x genHelperEncDriver) EncStructFieldKey(keyType valueType, s string) {
|
||||
encStructFieldKey(x.encDriver, keyType, s)
|
||||
}
|
||||
func (x genHelperEncDriver) EncodeSymbol(s string) {
|
||||
x.encDriver.EncodeString(cUTF8, s)
|
||||
}
|
||||
|
||||
type genHelperDecDriver struct {
|
||||
decDriver
|
||||
C checkOverflow
|
||||
}
|
||||
|
||||
func (x genHelperDecDriver) DecodeBuiltin(rt uintptr, v interface{}) {}
|
||||
func (x genHelperDecDriver) DecStructFieldKey(keyType valueType, buf *[decScratchByteArrayLen]byte) []byte {
|
||||
return decStructFieldKey(x.decDriver, keyType, buf)
|
||||
}
|
||||
func (x genHelperDecDriver) DecodeInt(bitsize uint8) (i int64) {
|
||||
return x.C.IntV(x.decDriver.DecodeInt64(), bitsize)
|
||||
}
|
||||
func (x genHelperDecDriver) DecodeUint(bitsize uint8) (ui uint64) {
|
||||
return x.C.UintV(x.decDriver.DecodeUint64(), bitsize)
|
||||
}
|
||||
func (x genHelperDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) {
|
||||
f = x.DecodeFloat64()
|
||||
if chkOverflow32 && chkOvf.Float32(f) {
|
||||
panicv.errorf("float32 overflow: %v", f)
|
||||
}
|
||||
return
|
||||
}
|
||||
func (x genHelperDecDriver) DecodeFloat32As64() (f float64) {
|
||||
f = x.DecodeFloat64()
|
||||
if chkOvf.Float32(f) {
|
||||
panicv.errorf("float32 overflow: %v", f)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
type genHelperEncoder struct {
|
||||
M must
|
||||
e *Encoder
|
||||
F fastpathT
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
type genHelperDecoder struct {
|
||||
C checkOverflow
|
||||
d *Decoder
|
||||
F fastpathT
|
||||
}
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperEncoder) EncBasicHandle() *BasicHandle {
|
||||
return f.e.h
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperEncoder) EncBinary() bool {
|
||||
return f.e.be // f.e.hh.isBinaryEncoding()
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperEncoder) IsJSONHandle() bool {
|
||||
return f.e.js
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperEncoder) EncFallback(iv interface{}) {
|
||||
// println(">>>>>>>>> EncFallback")
|
||||
// f.e.encodeI(iv, false, false)
|
||||
f.e.encodeValue(reflect.ValueOf(iv), nil, false)
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperEncoder) EncTextMarshal(iv encoding.TextMarshaler) {
|
||||
bs, fnerr := iv.MarshalText()
|
||||
f.e.marshal(bs, fnerr, false, cUTF8)
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperEncoder) EncJSONMarshal(iv jsonMarshaler) {
|
||||
bs, fnerr := iv.MarshalJSON()
|
||||
f.e.marshal(bs, fnerr, true, cUTF8)
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperEncoder) EncBinaryMarshal(iv encoding.BinaryMarshaler) {
|
||||
bs, fnerr := iv.MarshalBinary()
|
||||
f.e.marshal(bs, fnerr, false, cRAW)
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperEncoder) EncRaw(iv Raw) { f.e.rawBytes(iv) }
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
//
|
||||
// Deprecated: builtin no longer supported - so we make this method a no-op,
|
||||
// but leave in-place so that old generated files continue to work without regeneration.
|
||||
func (f genHelperEncoder) TimeRtidIfBinc() (v uintptr) { return }
|
||||
// func (f genHelperEncoder) TimeRtidIfBinc() uintptr {
|
||||
// if _, ok := f.e.hh.(*BincHandle); ok {
|
||||
// return timeTypId
|
||||
// }
|
||||
// }
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperEncoder) I2Rtid(v interface{}) uintptr {
|
||||
return i2rtid(v)
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperEncoder) Extension(rtid uintptr) (xfn *extTypeTagFn) {
|
||||
return f.e.h.getExt(rtid)
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperEncoder) EncExtension(v interface{}, xfFn *extTypeTagFn) {
|
||||
f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
//
|
||||
// Deprecated: No longer used,
|
||||
// but leave in-place so that old generated files continue to work without regeneration.
|
||||
func (f genHelperEncoder) HasExtensions() bool {
|
||||
return len(f.e.h.extHandle) != 0
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
//
|
||||
// Deprecated: No longer used,
|
||||
// but leave in-place so that old generated files continue to work without regeneration.
|
||||
func (f genHelperEncoder) EncExt(v interface{}) (r bool) {
|
||||
if xfFn := f.e.h.getExt(i2rtid(v)); xfFn != nil {
|
||||
f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ---------------- DECODER FOLLOWS -----------------
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecBasicHandle() *BasicHandle {
|
||||
return f.d.h
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecBinary() bool {
|
||||
return f.d.be // f.d.hh.isBinaryEncoding()
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecSwallow() { f.d.swallow() }
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecScratchBuffer() []byte {
|
||||
return f.d.b[:]
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecScratchArrayBuffer() *[decScratchByteArrayLen]byte {
|
||||
return &f.d.b
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecFallback(iv interface{}, chkPtr bool) {
|
||||
// println(">>>>>>>>> DecFallback")
|
||||
rv := reflect.ValueOf(iv)
|
||||
if chkPtr {
|
||||
rv = f.d.ensureDecodeable(rv)
|
||||
}
|
||||
f.d.decodeValue(rv, nil, false)
|
||||
// f.d.decodeValueFallback(rv)
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecSliceHelperStart() (decSliceHelper, int) {
|
||||
return f.d.decSliceHelperStart()
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecStructFieldNotFound(index int, name string) {
|
||||
f.d.structFieldNotFound(index, name)
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecArrayCannotExpand(sliceLen, streamLen int) {
|
||||
f.d.arrayCannotExpand(sliceLen, streamLen)
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecTextUnmarshal(tm encoding.TextUnmarshaler) {
|
||||
fnerr := tm.UnmarshalText(f.d.d.DecodeStringAsBytes())
|
||||
if fnerr != nil {
|
||||
panic(fnerr)
|
||||
}
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecJSONUnmarshal(tm jsonUnmarshaler) {
|
||||
// bs := f.dd.DecodeStringAsBytes()
|
||||
// grab the bytes to be read, as UnmarshalJSON needs the full JSON so as to unmarshal it itself.
|
||||
fnerr := tm.UnmarshalJSON(f.d.nextValueBytes())
|
||||
if fnerr != nil {
|
||||
panic(fnerr)
|
||||
}
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecBinaryUnmarshal(bm encoding.BinaryUnmarshaler) {
|
||||
fnerr := bm.UnmarshalBinary(f.d.d.DecodeBytes(nil, true))
|
||||
if fnerr != nil {
|
||||
panic(fnerr)
|
||||
}
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecRaw() []byte { return f.d.rawBytes() }
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
//
|
||||
// Deprecated: builtin no longer supported - so we make this method a no-op,
|
||||
// but leave in-place so that old generated files continue to work without regeneration.
|
||||
func (f genHelperDecoder) TimeRtidIfBinc() (v uintptr) { return }
|
||||
// func (f genHelperDecoder) TimeRtidIfBinc() uintptr {
|
||||
// // Note: builtin is no longer supported - so make this a no-op
|
||||
// if _, ok := f.d.hh.(*BincHandle); ok {
|
||||
// return timeTypId
|
||||
// }
|
||||
// return 0
|
||||
// }
|
||||
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) IsJSONHandle() bool {
|
||||
return f.d.js
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) I2Rtid(v interface{}) uintptr {
|
||||
return i2rtid(v)
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) Extension(rtid uintptr) (xfn *extTypeTagFn) {
|
||||
return f.d.h.getExt(rtid)
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecExtension(v interface{}, xfFn *extTypeTagFn) {
|
||||
f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
//
|
||||
// Deprecated: No longer used,
|
||||
// but leave in-place so that old generated files continue to work without regeneration.
|
||||
func (f genHelperDecoder) HasExtensions() bool {
|
||||
return len(f.d.h.extHandle) != 0
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
//
|
||||
// Deprecated: No longer used,
|
||||
// but leave in-place so that old generated files continue to work without regeneration.
|
||||
func (f genHelperDecoder) DecExt(v interface{}) (r bool) {
|
||||
if xfFn := f.d.h.getExt(i2rtid(v)); xfFn != nil {
|
||||
f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
func (f genHelperDecoder) DecInferLen(clen, maxlen, unit int) (rvlen int) {
|
||||
return decInferLen(clen, maxlen, unit)
|
||||
}
|
||||
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
|
||||
//
|
||||
// Deprecated: no longer used,
|
||||
// but leave in-place so that old generated files continue to work without regeneration.
|
||||
func (f genHelperDecoder) StringView(v []byte) string { return stringView(v) }
|
||||
|
||||
164
vendor/github.com/ugorji/go/codec/gen.generated.go
generated
vendored
Normal file
164
vendor/github.com/ugorji/go/codec/gen.generated.go
generated
vendored
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
// +build codecgen.exec
|
||||
|
||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
package codec
|
||||
|
||||
// DO NOT EDIT. THIS FILE IS AUTO-GENERATED FROM gen-dec-(map|array).go.tmpl
|
||||
|
||||
const genDecMapTmpl = `
|
||||
{{var "v"}} := *{{ .Varname }}
|
||||
{{var "l"}} := r.ReadMapStart()
|
||||
{{var "bh"}} := z.DecBasicHandle()
|
||||
if {{var "v"}} == nil {
|
||||
{{var "rl"}} := z.DecInferLen({{var "l"}}, {{var "bh"}}.MaxInitLen, {{ .Size }})
|
||||
{{var "v"}} = make(map[{{ .KTyp }}]{{ .Typ }}, {{var "rl"}})
|
||||
*{{ .Varname }} = {{var "v"}}
|
||||
}
|
||||
var {{var "mk"}} {{ .KTyp }}
|
||||
var {{var "mv"}} {{ .Typ }}
|
||||
var {{var "mg"}}, {{var "mdn"}} {{if decElemKindPtr}}, {{var "ms"}}, {{var "mok"}}{{end}} bool
|
||||
if {{var "bh"}}.MapValueReset {
|
||||
{{if decElemKindPtr}}{{var "mg"}} = true
|
||||
{{else if decElemKindIntf}}if !{{var "bh"}}.InterfaceReset { {{var "mg"}} = true }
|
||||
{{else if not decElemKindImmutable}}{{var "mg"}} = true
|
||||
{{end}} }
|
||||
if {{var "l"}} != 0 {
|
||||
{{var "hl"}} := {{var "l"}} > 0
|
||||
for {{var "j"}} := 0; ({{var "hl"}} && {{var "j"}} < {{var "l"}}) || !({{var "hl"}} || r.CheckBreak()); {{var "j"}}++ {
|
||||
r.ReadMapElemKey() {{/* z.DecSendContainerState(codecSelfer_containerMapKey{{ .Sfx }}) */}}
|
||||
{{ $x := printf "%vmk%v" .TempVar .Rand }}{{ decLineVarK $x }}
|
||||
{{ if eq .KTyp "interface{}" }}{{/* // special case if a byte array. */}}if {{var "bv"}}, {{var "bok"}} := {{var "mk"}}.([]byte); {{var "bok"}} {
|
||||
{{var "mk"}} = string({{var "bv"}})
|
||||
}{{ end }}{{if decElemKindPtr}}
|
||||
{{var "ms"}} = true{{end}}
|
||||
if {{var "mg"}} {
|
||||
{{if decElemKindPtr}}{{var "mv"}}, {{var "mok"}} = {{var "v"}}[{{var "mk"}}]
|
||||
if {{var "mok"}} {
|
||||
{{var "ms"}} = false
|
||||
} {{else}}{{var "mv"}} = {{var "v"}}[{{var "mk"}}] {{end}}
|
||||
} {{if not decElemKindImmutable}}else { {{var "mv"}} = {{decElemZero}} }{{end}}
|
||||
r.ReadMapElemValue() {{/* z.DecSendContainerState(codecSelfer_containerMapValue{{ .Sfx }}) */}}
|
||||
{{var "mdn"}} = false
|
||||
{{ $x := printf "%vmv%v" .TempVar .Rand }}{{ $y := printf "%vmdn%v" .TempVar .Rand }}{{ decLineVar $x $y }}
|
||||
if {{var "mdn"}} {
|
||||
if {{ var "bh" }}.DeleteOnNilMapValue { delete({{var "v"}}, {{var "mk"}}) } else { {{var "v"}}[{{var "mk"}}] = {{decElemZero}} }
|
||||
} else if {{if decElemKindPtr}} {{var "ms"}} && {{end}} {{var "v"}} != nil {
|
||||
{{var "v"}}[{{var "mk"}}] = {{var "mv"}}
|
||||
}
|
||||
}
|
||||
} // else len==0: TODO: Should we clear map entries?
|
||||
r.ReadMapEnd() {{/* z.DecSendContainerState(codecSelfer_containerMapEnd{{ .Sfx }}) */}}
|
||||
`
|
||||
|
||||
const genDecListTmpl = `
|
||||
{{var "v"}} := {{if not isArray}}*{{end}}{{ .Varname }}
|
||||
{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}{{if not isArray}}
|
||||
var {{var "c"}} bool {{/* // changed */}}
|
||||
_ = {{var "c"}}{{end}}
|
||||
if {{var "l"}} == 0 {
|
||||
{{if isSlice }}if {{var "v"}} == nil {
|
||||
{{var "v"}} = []{{ .Typ }}{}
|
||||
{{var "c"}} = true
|
||||
} else if len({{var "v"}}) != 0 {
|
||||
{{var "v"}} = {{var "v"}}[:0]
|
||||
{{var "c"}} = true
|
||||
} {{else if isChan }}if {{var "v"}} == nil {
|
||||
{{var "v"}} = make({{ .CTyp }}, 0)
|
||||
{{var "c"}} = true
|
||||
} {{end}}
|
||||
} else {
|
||||
{{var "hl"}} := {{var "l"}} > 0
|
||||
var {{var "rl"}} int
|
||||
_ = {{var "rl"}}
|
||||
{{if isSlice }} if {{var "hl"}} {
|
||||
if {{var "l"}} > cap({{var "v"}}) {
|
||||
{{var "rl"}} = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
|
||||
if {{var "rl"}} <= cap({{var "v"}}) {
|
||||
{{var "v"}} = {{var "v"}}[:{{var "rl"}}]
|
||||
} else {
|
||||
{{var "v"}} = make([]{{ .Typ }}, {{var "rl"}})
|
||||
}
|
||||
{{var "c"}} = true
|
||||
} else if {{var "l"}} != len({{var "v"}}) {
|
||||
{{var "v"}} = {{var "v"}}[:{{var "l"}}]
|
||||
{{var "c"}} = true
|
||||
}
|
||||
} {{end}}
|
||||
var {{var "j"}} int
|
||||
// var {{var "dn"}} bool
|
||||
for ; ({{var "hl"}} && {{var "j"}} < {{var "l"}}) || !({{var "hl"}} || r.CheckBreak()); {{var "j"}}++ {
|
||||
{{if not isArray}} if {{var "j"}} == 0 && {{var "v"}} == nil {
|
||||
if {{var "hl"}} {
|
||||
{{var "rl"}} = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
|
||||
} else {
|
||||
{{var "rl"}} = {{if isSlice}}8{{else if isChan}}64{{end}}
|
||||
}
|
||||
{{var "v"}} = make({{if isSlice}}[]{{ .Typ }}{{else if isChan}}{{.CTyp}}{{end}}, {{var "rl"}})
|
||||
{{var "c"}} = true
|
||||
}{{end}}
|
||||
{{var "h"}}.ElemContainerState({{var "j"}})
|
||||
{{/* {{var "dn"}} = r.TryDecodeAsNil() */}}{{/* commented out, as decLineVar handles this already each time */}}
|
||||
{{if isChan}}{{ $x := printf "%[1]vvcx%[2]v" .TempVar .Rand }}var {{$x}} {{ .Typ }}
|
||||
{{ decLineVar $x }}
|
||||
{{var "v"}} <- {{ $x }}
|
||||
// println(">>>> sending ", {{ $x }}, " into ", {{var "v"}}) // TODO: remove this
|
||||
{{else}}{{/* // if indefinite, etc, then expand the slice if necessary */}}
|
||||
var {{var "db"}} bool
|
||||
if {{var "j"}} >= len({{var "v"}}) {
|
||||
{{if isSlice }} {{var "v"}} = append({{var "v"}}, {{ zero }})
|
||||
{{var "c"}} = true
|
||||
{{else}} z.DecArrayCannotExpand(len(v), {{var "j"}}+1); {{var "db"}} = true
|
||||
{{end}}
|
||||
}
|
||||
if {{var "db"}} {
|
||||
z.DecSwallow()
|
||||
} else {
|
||||
{{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x }}
|
||||
}
|
||||
{{end}}
|
||||
}
|
||||
{{if isSlice}} if {{var "j"}} < len({{var "v"}}) {
|
||||
{{var "v"}} = {{var "v"}}[:{{var "j"}}]
|
||||
{{var "c"}} = true
|
||||
} else if {{var "j"}} == 0 && {{var "v"}} == nil {
|
||||
{{var "v"}} = make([]{{ .Typ }}, 0)
|
||||
{{var "c"}} = true
|
||||
} {{end}}
|
||||
}
|
||||
{{var "h"}}.End()
|
||||
{{if not isArray }}if {{var "c"}} {
|
||||
*{{ .Varname }} = {{var "v"}}
|
||||
}{{end}}
|
||||
`
|
||||
|
||||
const genEncChanTmpl = `
|
||||
{{.Label}}:
|
||||
switch timeout{{.Sfx}} := z.EncBasicHandle().ChanRecvTimeout; {
|
||||
case timeout{{.Sfx}} == 0: // only consume available
|
||||
for {
|
||||
select {
|
||||
case b{{.Sfx}} := <-{{.Chan}}:
|
||||
{{ .Slice }} = append({{.Slice}}, b{{.Sfx}})
|
||||
default:
|
||||
break {{.Label}}
|
||||
}
|
||||
}
|
||||
case timeout{{.Sfx}} > 0: // consume until timeout
|
||||
tt{{.Sfx}} := time.NewTimer(timeout{{.Sfx}})
|
||||
for {
|
||||
select {
|
||||
case b{{.Sfx}} := <-{{.Chan}}:
|
||||
{{.Slice}} = append({{.Slice}}, b{{.Sfx}})
|
||||
case <-tt{{.Sfx}}.C:
|
||||
// close(tt.C)
|
||||
break {{.Label}}
|
||||
}
|
||||
}
|
||||
default: // consume until close
|
||||
for b{{.Sfx}} := range {{.Chan}} {
|
||||
{{.Slice}} = append({{.Slice}}, b{{.Sfx}})
|
||||
}
|
||||
}
|
||||
`
|
||||
2139
vendor/github.com/ugorji/go/codec/gen.go
generated
vendored
Normal file
2139
vendor/github.com/ugorji/go/codec/gen.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
14
vendor/github.com/ugorji/go/codec/goversion_arrayof_gte_go15.go
generated
vendored
Normal file
14
vendor/github.com/ugorji/go/codec/goversion_arrayof_gte_go15.go
generated
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
// +build go1.5
|
||||
|
||||
package codec
|
||||
|
||||
import "reflect"
|
||||
|
||||
const reflectArrayOfSupported = true
|
||||
|
||||
func reflectArrayOf(count int, elem reflect.Type) reflect.Type {
|
||||
return reflect.ArrayOf(count, elem)
|
||||
}
|
||||
14
vendor/github.com/ugorji/go/codec/goversion_arrayof_lt_go15.go
generated
vendored
Normal file
14
vendor/github.com/ugorji/go/codec/goversion_arrayof_lt_go15.go
generated
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
// +build !go1.5
|
||||
|
||||
package codec
|
||||
|
||||
import "reflect"
|
||||
|
||||
const reflectArrayOfSupported = false
|
||||
|
||||
func reflectArrayOf(count int, elem reflect.Type) reflect.Type {
|
||||
panic("codec: reflect.ArrayOf unsupported in this go version")
|
||||
}
|
||||
15
vendor/github.com/ugorji/go/codec/goversion_makemap_gte_go19.go
generated
vendored
Normal file
15
vendor/github.com/ugorji/go/codec/goversion_makemap_gte_go19.go
generated
vendored
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
// +build go1.9
|
||||
|
||||
package codec
|
||||
|
||||
import "reflect"
|
||||
|
||||
func makeMapReflect(t reflect.Type, size int) reflect.Value {
|
||||
if size < 0 {
|
||||
return reflect.MakeMapWithSize(t, 4)
|
||||
}
|
||||
return reflect.MakeMapWithSize(t, size)
|
||||
}
|
||||
12
vendor/github.com/ugorji/go/codec/goversion_makemap_lt_go19.go
generated
vendored
Normal file
12
vendor/github.com/ugorji/go/codec/goversion_makemap_lt_go19.go
generated
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
// +build !go1.9
|
||||
|
||||
package codec
|
||||
|
||||
import "reflect"
|
||||
|
||||
func makeMapReflect(t reflect.Type, size int) reflect.Value {
|
||||
return reflect.MakeMap(t)
|
||||
}
|
||||
8
vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_gte_go110.go
generated
vendored
Normal file
8
vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_gte_go110.go
generated
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
// +build go1.10
|
||||
|
||||
package codec
|
||||
|
||||
const allowSetUnexportedEmbeddedPtr = false
|
||||
8
vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_lt_go110.go
generated
vendored
Normal file
8
vendor/github.com/ugorji/go/codec/goversion_unexportedembeddedptr_lt_go110.go
generated
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
// +build !go1.10
|
||||
|
||||
package codec
|
||||
|
||||
const allowSetUnexportedEmbeddedPtr = true
|
||||
17
vendor/github.com/ugorji/go/codec/goversion_unsupported_lt_go14.go
generated
vendored
Normal file
17
vendor/github.com/ugorji/go/codec/goversion_unsupported_lt_go14.go
generated
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
// +build !go1.4
|
||||
|
||||
package codec
|
||||
|
||||
// This codec package will only work for go1.4 and above.
|
||||
// This is for the following reasons:
|
||||
// - go 1.4 was released in 2014
|
||||
// - go runtime is written fully in go
|
||||
// - interface only holds pointers
|
||||
// - reflect.Value is stabilized as 3 words
|
||||
|
||||
func init() {
|
||||
panic("codec: go 1.3 and below are not supported")
|
||||
}
|
||||
10
vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go15.go
generated
vendored
Normal file
10
vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go15.go
generated
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
// +build go1.5,!go1.6
|
||||
|
||||
package codec
|
||||
|
||||
import "os"
|
||||
|
||||
var genCheckVendor = os.Getenv("GO15VENDOREXPERIMENT") == "1"
|
||||
10
vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go16.go
generated
vendored
Normal file
10
vendor/github.com/ugorji/go/codec/goversion_vendor_eq_go16.go
generated
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
// +build go1.6,!go1.7
|
||||
|
||||
package codec
|
||||
|
||||
import "os"
|
||||
|
||||
var genCheckVendor = os.Getenv("GO15VENDOREXPERIMENT") != "0"
|
||||
8
vendor/github.com/ugorji/go/codec/goversion_vendor_gte_go17.go
generated
vendored
Normal file
8
vendor/github.com/ugorji/go/codec/goversion_vendor_gte_go17.go
generated
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
// +build go1.7
|
||||
|
||||
package codec
|
||||
|
||||
const genCheckVendor = true
|
||||
8
vendor/github.com/ugorji/go/codec/goversion_vendor_lt_go15.go
generated
vendored
Normal file
8
vendor/github.com/ugorji/go/codec/goversion_vendor_lt_go15.go
generated
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
// +build !go1.5
|
||||
|
||||
package codec
|
||||
|
||||
var genCheckVendor = false
|
||||
2414
vendor/github.com/ugorji/go/codec/helper.go
generated
vendored
Normal file
2414
vendor/github.com/ugorji/go/codec/helper.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
121
vendor/github.com/ugorji/go/codec/helper_internal.go
generated
vendored
Normal file
121
vendor/github.com/ugorji/go/codec/helper_internal.go
generated
vendored
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
package codec
|
||||
|
||||
// All non-std package dependencies live in this file,
|
||||
// so porting to different environment is easy (just update functions).
|
||||
|
||||
func pruneSignExt(v []byte, pos bool) (n int) {
|
||||
if len(v) < 2 {
|
||||
} else if pos && v[0] == 0 {
|
||||
for ; v[n] == 0 && n+1 < len(v) && (v[n+1]&(1<<7) == 0); n++ {
|
||||
}
|
||||
} else if !pos && v[0] == 0xff {
|
||||
for ; v[n] == 0xff && n+1 < len(v) && (v[n+1]&(1<<7) != 0); n++ {
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// validate that this function is correct ...
|
||||
// culled from OGRE (Object-Oriented Graphics Rendering Engine)
|
||||
// function: halfToFloatI (http://stderr.org/doc/ogre-doc/api/OgreBitwise_8h-source.html)
|
||||
func halfFloatToFloatBits(yy uint16) (d uint32) {
|
||||
y := uint32(yy)
|
||||
s := (y >> 15) & 0x01
|
||||
e := (y >> 10) & 0x1f
|
||||
m := y & 0x03ff
|
||||
|
||||
if e == 0 {
|
||||
if m == 0 { // plu or minus 0
|
||||
return s << 31
|
||||
}
|
||||
// Denormalized number -- renormalize it
|
||||
for (m & 0x00000400) == 0 {
|
||||
m <<= 1
|
||||
e -= 1
|
||||
}
|
||||
e += 1
|
||||
const zz uint32 = 0x0400
|
||||
m &= ^zz
|
||||
} else if e == 31 {
|
||||
if m == 0 { // Inf
|
||||
return (s << 31) | 0x7f800000
|
||||
}
|
||||
return (s << 31) | 0x7f800000 | (m << 13) // NaN
|
||||
}
|
||||
e = e + (127 - 15)
|
||||
m = m << 13
|
||||
return (s << 31) | (e << 23) | m
|
||||
}
|
||||
|
||||
// GrowCap will return a new capacity for a slice, given the following:
|
||||
// - oldCap: current capacity
|
||||
// - unit: in-memory size of an element
|
||||
// - num: number of elements to add
|
||||
func growCap(oldCap, unit, num int) (newCap int) {
|
||||
// appendslice logic (if cap < 1024, *2, else *1.25):
|
||||
// leads to many copy calls, especially when copying bytes.
|
||||
// bytes.Buffer model (2*cap + n): much better for bytes.
|
||||
// smarter way is to take the byte-size of the appended element(type) into account
|
||||
|
||||
// maintain 3 thresholds:
|
||||
// t1: if cap <= t1, newcap = 2x
|
||||
// t2: if cap <= t2, newcap = 1.75x
|
||||
// t3: if cap <= t3, newcap = 1.5x
|
||||
// else newcap = 1.25x
|
||||
//
|
||||
// t1, t2, t3 >= 1024 always.
|
||||
// i.e. if unit size >= 16, then always do 2x or 1.25x (ie t1, t2, t3 are all same)
|
||||
//
|
||||
// With this, appending for bytes increase by:
|
||||
// 100% up to 4K
|
||||
// 75% up to 8K
|
||||
// 50% up to 16K
|
||||
// 25% beyond that
|
||||
|
||||
// unit can be 0 e.g. for struct{}{}; handle that appropriately
|
||||
var t1, t2, t3 int // thresholds
|
||||
if unit <= 1 {
|
||||
t1, t2, t3 = 4*1024, 8*1024, 16*1024
|
||||
} else if unit < 16 {
|
||||
t3 = 16 / unit * 1024
|
||||
t1 = t3 * 1 / 4
|
||||
t2 = t3 * 2 / 4
|
||||
} else {
|
||||
t1, t2, t3 = 1024, 1024, 1024
|
||||
}
|
||||
|
||||
var x int // temporary variable
|
||||
|
||||
// x is multiplier here: one of 5, 6, 7 or 8; incr of 25%, 50%, 75% or 100% respectively
|
||||
if oldCap <= t1 { // [0,t1]
|
||||
x = 8
|
||||
} else if oldCap > t3 { // (t3,infinity]
|
||||
x = 5
|
||||
} else if oldCap <= t2 { // (t1,t2]
|
||||
x = 7
|
||||
} else { // (t2,t3]
|
||||
x = 6
|
||||
}
|
||||
newCap = x * oldCap / 4
|
||||
|
||||
if num > 0 {
|
||||
newCap += num
|
||||
}
|
||||
|
||||
// ensure newCap is a multiple of 64 (if it is > 64) or 16.
|
||||
if newCap > 64 {
|
||||
if x = newCap % 64; x != 0 {
|
||||
x = newCap / 64
|
||||
newCap = 64 * (x + 1)
|
||||
}
|
||||
} else {
|
||||
if x = newCap % 16; x != 0 {
|
||||
x = newCap / 16
|
||||
newCap = 16 * (x + 1)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
272
vendor/github.com/ugorji/go/codec/helper_not_unsafe.go
generated
vendored
Normal file
272
vendor/github.com/ugorji/go/codec/helper_not_unsafe.go
generated
vendored
Normal file
|
|
@ -0,0 +1,272 @@
|
|||
// +build !go1.7 safe appengine
|
||||
|
||||
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
package codec
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
const safeMode = true
|
||||
|
||||
// stringView returns a view of the []byte as a string.
|
||||
// In unsafe mode, it doesn't incur allocation and copying caused by conversion.
|
||||
// In regular safe mode, it is an allocation and copy.
|
||||
//
|
||||
// Usage: Always maintain a reference to v while result of this call is in use,
|
||||
// and call keepAlive4BytesView(v) at point where done with view.
|
||||
func stringView(v []byte) string {
|
||||
return string(v)
|
||||
}
|
||||
|
||||
// bytesView returns a view of the string as a []byte.
|
||||
// In unsafe mode, it doesn't incur allocation and copying caused by conversion.
|
||||
// In regular safe mode, it is an allocation and copy.
|
||||
//
|
||||
// Usage: Always maintain a reference to v while result of this call is in use,
|
||||
// and call keepAlive4BytesView(v) at point where done with view.
|
||||
func bytesView(v string) []byte {
|
||||
return []byte(v)
|
||||
}
|
||||
|
||||
func definitelyNil(v interface{}) bool {
|
||||
// this is a best-effort option.
|
||||
// We just return false, so we don't unnecessarily incur the cost of reflection this early.
|
||||
return false
|
||||
}
|
||||
|
||||
func rv2i(rv reflect.Value) interface{} {
|
||||
return rv.Interface()
|
||||
}
|
||||
|
||||
func rt2id(rt reflect.Type) uintptr {
|
||||
return reflect.ValueOf(rt).Pointer()
|
||||
}
|
||||
|
||||
func rv2rtid(rv reflect.Value) uintptr {
|
||||
return reflect.ValueOf(rv.Type()).Pointer()
|
||||
}
|
||||
|
||||
func i2rtid(i interface{}) uintptr {
|
||||
return reflect.ValueOf(reflect.TypeOf(i)).Pointer()
|
||||
}
|
||||
|
||||
// --------------------------
|
||||
|
||||
func isEmptyValue(v reflect.Value, tinfos *TypeInfos, deref, checkStruct bool) bool {
|
||||
switch v.Kind() {
|
||||
case reflect.Invalid:
|
||||
return true
|
||||
case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
|
||||
return v.Len() == 0
|
||||
case reflect.Bool:
|
||||
return !v.Bool()
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return v.Int() == 0
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||
return v.Uint() == 0
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return v.Float() == 0
|
||||
case reflect.Interface, reflect.Ptr:
|
||||
if deref {
|
||||
if v.IsNil() {
|
||||
return true
|
||||
}
|
||||
return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
|
||||
}
|
||||
return v.IsNil()
|
||||
case reflect.Struct:
|
||||
return isEmptyStruct(v, tinfos, deref, checkStruct)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// --------------------------
|
||||
// type ptrToRvMap struct{}
|
||||
|
||||
// func (*ptrToRvMap) init() {}
|
||||
// func (*ptrToRvMap) get(i interface{}) reflect.Value {
|
||||
// return reflect.ValueOf(i).Elem()
|
||||
// }
|
||||
|
||||
// --------------------------
|
||||
type atomicTypeInfoSlice struct { // expected to be 2 words
|
||||
v atomic.Value
|
||||
}
|
||||
|
||||
func (x *atomicTypeInfoSlice) load() []rtid2ti {
|
||||
i := x.v.Load()
|
||||
if i == nil {
|
||||
return nil
|
||||
}
|
||||
return i.([]rtid2ti)
|
||||
}
|
||||
|
||||
func (x *atomicTypeInfoSlice) store(p []rtid2ti) {
|
||||
x.v.Store(p)
|
||||
}
|
||||
|
||||
// --------------------------
|
||||
func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
|
||||
rv.SetBytes(d.rawBytes())
|
||||
}
|
||||
|
||||
func (d *Decoder) kString(f *codecFnInfo, rv reflect.Value) {
|
||||
rv.SetString(d.d.DecodeString())
|
||||
}
|
||||
|
||||
func (d *Decoder) kBool(f *codecFnInfo, rv reflect.Value) {
|
||||
rv.SetBool(d.d.DecodeBool())
|
||||
}
|
||||
|
||||
func (d *Decoder) kTime(f *codecFnInfo, rv reflect.Value) {
|
||||
rv.Set(reflect.ValueOf(d.d.DecodeTime()))
|
||||
}
|
||||
|
||||
func (d *Decoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
|
||||
fv := d.d.DecodeFloat64()
|
||||
if chkOvf.Float32(fv) {
|
||||
d.errorf("float32 overflow: %v", fv)
|
||||
}
|
||||
rv.SetFloat(fv)
|
||||
}
|
||||
|
||||
func (d *Decoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
|
||||
rv.SetFloat(d.d.DecodeFloat64())
|
||||
}
|
||||
|
||||
func (d *Decoder) kInt(f *codecFnInfo, rv reflect.Value) {
|
||||
rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), intBitsize))
|
||||
}
|
||||
|
||||
func (d *Decoder) kInt8(f *codecFnInfo, rv reflect.Value) {
|
||||
rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), 8))
|
||||
}
|
||||
|
||||
func (d *Decoder) kInt16(f *codecFnInfo, rv reflect.Value) {
|
||||
rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), 16))
|
||||
}
|
||||
|
||||
func (d *Decoder) kInt32(f *codecFnInfo, rv reflect.Value) {
|
||||
rv.SetInt(chkOvf.IntV(d.d.DecodeInt64(), 32))
|
||||
}
|
||||
|
||||
func (d *Decoder) kInt64(f *codecFnInfo, rv reflect.Value) {
|
||||
rv.SetInt(d.d.DecodeInt64())
|
||||
}
|
||||
|
||||
func (d *Decoder) kUint(f *codecFnInfo, rv reflect.Value) {
|
||||
rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
|
||||
}
|
||||
|
||||
func (d *Decoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
|
||||
rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
|
||||
}
|
||||
|
||||
func (d *Decoder) kUint8(f *codecFnInfo, rv reflect.Value) {
|
||||
rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), 8))
|
||||
}
|
||||
|
||||
func (d *Decoder) kUint16(f *codecFnInfo, rv reflect.Value) {
|
||||
rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), 16))
|
||||
}
|
||||
|
||||
func (d *Decoder) kUint32(f *codecFnInfo, rv reflect.Value) {
|
||||
rv.SetUint(chkOvf.UintV(d.d.DecodeUint64(), 32))
|
||||
}
|
||||
|
||||
func (d *Decoder) kUint64(f *codecFnInfo, rv reflect.Value) {
|
||||
rv.SetUint(d.d.DecodeUint64())
|
||||
}
|
||||
|
||||
// ----------------
|
||||
|
||||
func (e *Encoder) kBool(f *codecFnInfo, rv reflect.Value) {
|
||||
e.e.EncodeBool(rv.Bool())
|
||||
}
|
||||
|
||||
func (e *Encoder) kTime(f *codecFnInfo, rv reflect.Value) {
|
||||
e.e.EncodeTime(rv2i(rv).(time.Time))
|
||||
}
|
||||
|
||||
func (e *Encoder) kString(f *codecFnInfo, rv reflect.Value) {
|
||||
e.e.EncodeString(cUTF8, rv.String())
|
||||
}
|
||||
|
||||
func (e *Encoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
|
||||
e.e.EncodeFloat64(rv.Float())
|
||||
}
|
||||
|
||||
func (e *Encoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
|
||||
e.e.EncodeFloat32(float32(rv.Float()))
|
||||
}
|
||||
|
||||
func (e *Encoder) kInt(f *codecFnInfo, rv reflect.Value) {
|
||||
e.e.EncodeInt(rv.Int())
|
||||
}
|
||||
|
||||
func (e *Encoder) kInt8(f *codecFnInfo, rv reflect.Value) {
|
||||
e.e.EncodeInt(rv.Int())
|
||||
}
|
||||
|
||||
func (e *Encoder) kInt16(f *codecFnInfo, rv reflect.Value) {
|
||||
e.e.EncodeInt(rv.Int())
|
||||
}
|
||||
|
||||
func (e *Encoder) kInt32(f *codecFnInfo, rv reflect.Value) {
|
||||
e.e.EncodeInt(rv.Int())
|
||||
}
|
||||
|
||||
func (e *Encoder) kInt64(f *codecFnInfo, rv reflect.Value) {
|
||||
e.e.EncodeInt(rv.Int())
|
||||
}
|
||||
|
||||
func (e *Encoder) kUint(f *codecFnInfo, rv reflect.Value) {
|
||||
e.e.EncodeUint(rv.Uint())
|
||||
}
|
||||
|
||||
func (e *Encoder) kUint8(f *codecFnInfo, rv reflect.Value) {
|
||||
e.e.EncodeUint(rv.Uint())
|
||||
}
|
||||
|
||||
func (e *Encoder) kUint16(f *codecFnInfo, rv reflect.Value) {
|
||||
e.e.EncodeUint(rv.Uint())
|
||||
}
|
||||
|
||||
func (e *Encoder) kUint32(f *codecFnInfo, rv reflect.Value) {
|
||||
e.e.EncodeUint(rv.Uint())
|
||||
}
|
||||
|
||||
func (e *Encoder) kUint64(f *codecFnInfo, rv reflect.Value) {
|
||||
e.e.EncodeUint(rv.Uint())
|
||||
}
|
||||
|
||||
func (e *Encoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
|
||||
e.e.EncodeUint(rv.Uint())
|
||||
}
|
||||
|
||||
// // keepAlive4BytesView maintains a reference to the input parameter for bytesView.
|
||||
// //
|
||||
// // Usage: call this at point where done with the bytes view.
|
||||
// func keepAlive4BytesView(v string) {}
|
||||
|
||||
// // keepAlive4BytesView maintains a reference to the input parameter for stringView.
|
||||
// //
|
||||
// // Usage: call this at point where done with the string view.
|
||||
// func keepAlive4StringView(v []byte) {}
|
||||
|
||||
// func definitelyNil(v interface{}) bool {
|
||||
// rv := reflect.ValueOf(v)
|
||||
// switch rv.Kind() {
|
||||
// case reflect.Invalid:
|
||||
// return true
|
||||
// case reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Slice, reflect.Map, reflect.Func:
|
||||
// return rv.IsNil()
|
||||
// default:
|
||||
// return false
|
||||
// }
|
||||
// }
|
||||
639
vendor/github.com/ugorji/go/codec/helper_unsafe.go
generated
vendored
Normal file
639
vendor/github.com/ugorji/go/codec/helper_unsafe.go
generated
vendored
Normal file
|
|
@ -0,0 +1,639 @@
|
|||
// +build !safe
|
||||
// +build !appengine
|
||||
// +build go1.7
|
||||
|
||||
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
package codec
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// This file has unsafe variants of some helper methods.
|
||||
// NOTE: See helper_not_unsafe.go for the usage information.
|
||||
|
||||
// var zeroRTv [4]uintptr
|
||||
|
||||
const safeMode = false
|
||||
const unsafeFlagIndir = 1 << 7 // keep in sync with GO_ROOT/src/reflect/value.go
|
||||
|
||||
type unsafeString struct {
|
||||
Data unsafe.Pointer
|
||||
Len int
|
||||
}
|
||||
|
||||
type unsafeSlice struct {
|
||||
Data unsafe.Pointer
|
||||
Len int
|
||||
Cap int
|
||||
}
|
||||
|
||||
type unsafeIntf struct {
|
||||
typ unsafe.Pointer
|
||||
word unsafe.Pointer
|
||||
}
|
||||
|
||||
type unsafeReflectValue struct {
|
||||
typ unsafe.Pointer
|
||||
ptr unsafe.Pointer
|
||||
flag uintptr
|
||||
}
|
||||
|
||||
func stringView(v []byte) string {
|
||||
if len(v) == 0 {
|
||||
return ""
|
||||
}
|
||||
bx := (*unsafeSlice)(unsafe.Pointer(&v))
|
||||
return *(*string)(unsafe.Pointer(&unsafeString{bx.Data, bx.Len}))
|
||||
}
|
||||
|
||||
func bytesView(v string) []byte {
|
||||
if len(v) == 0 {
|
||||
return zeroByteSlice
|
||||
}
|
||||
sx := (*unsafeString)(unsafe.Pointer(&v))
|
||||
return *(*[]byte)(unsafe.Pointer(&unsafeSlice{sx.Data, sx.Len, sx.Len}))
|
||||
}
|
||||
|
||||
func definitelyNil(v interface{}) bool {
|
||||
// There is no global way of checking if an interface is nil.
|
||||
// For true references (map, ptr, func, chan), you can just look
|
||||
// at the word of the interface. However, for slices, you have to dereference
|
||||
// the word, and get a pointer to the 3-word interface value.
|
||||
//
|
||||
// However, the following are cheap calls
|
||||
// - TypeOf(interface): cheap 2-line call.
|
||||
// - ValueOf(interface{}): expensive
|
||||
// - type.Kind: cheap call through an interface
|
||||
// - Value.Type(): cheap call
|
||||
// except it's a method value (e.g. r.Read, which implies that it is a Func)
|
||||
|
||||
return ((*unsafeIntf)(unsafe.Pointer(&v))).word == nil
|
||||
}
|
||||
|
||||
func rv2i(rv reflect.Value) interface{} {
|
||||
// TODO: consider a more generally-known optimization for reflect.Value ==> Interface
|
||||
//
|
||||
// Currently, we use this fragile method that taps into implememtation details from
|
||||
// the source go stdlib reflect/value.go, and trims the implementation.
|
||||
|
||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
// true references (map, func, chan, ptr - NOT slice) may be double-referenced as flagIndir
|
||||
var ptr unsafe.Pointer
|
||||
if refBitset.isset(byte(urv.flag&(1<<5-1))) && urv.flag&unsafeFlagIndir != 0 {
|
||||
ptr = *(*unsafe.Pointer)(urv.ptr)
|
||||
} else {
|
||||
ptr = urv.ptr
|
||||
}
|
||||
return *(*interface{})(unsafe.Pointer(&unsafeIntf{typ: urv.typ, word: ptr}))
|
||||
}
|
||||
|
||||
func rt2id(rt reflect.Type) uintptr {
|
||||
return uintptr(((*unsafeIntf)(unsafe.Pointer(&rt))).word)
|
||||
}
|
||||
|
||||
func rv2rtid(rv reflect.Value) uintptr {
|
||||
return uintptr((*unsafeReflectValue)(unsafe.Pointer(&rv)).typ)
|
||||
}
|
||||
|
||||
func i2rtid(i interface{}) uintptr {
|
||||
return uintptr(((*unsafeIntf)(unsafe.Pointer(&i))).typ)
|
||||
}
|
||||
|
||||
// --------------------------
|
||||
|
||||
func isEmptyValue(v reflect.Value, tinfos *TypeInfos, deref, checkStruct bool) bool {
|
||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&v))
|
||||
if urv.flag == 0 {
|
||||
return true
|
||||
}
|
||||
switch v.Kind() {
|
||||
case reflect.Invalid:
|
||||
return true
|
||||
case reflect.String:
|
||||
return (*unsafeString)(urv.ptr).Len == 0
|
||||
case reflect.Slice:
|
||||
return (*unsafeSlice)(urv.ptr).Len == 0
|
||||
case reflect.Bool:
|
||||
return !*(*bool)(urv.ptr)
|
||||
case reflect.Int:
|
||||
return *(*int)(urv.ptr) == 0
|
||||
case reflect.Int8:
|
||||
return *(*int8)(urv.ptr) == 0
|
||||
case reflect.Int16:
|
||||
return *(*int16)(urv.ptr) == 0
|
||||
case reflect.Int32:
|
||||
return *(*int32)(urv.ptr) == 0
|
||||
case reflect.Int64:
|
||||
return *(*int64)(urv.ptr) == 0
|
||||
case reflect.Uint:
|
||||
return *(*uint)(urv.ptr) == 0
|
||||
case reflect.Uint8:
|
||||
return *(*uint8)(urv.ptr) == 0
|
||||
case reflect.Uint16:
|
||||
return *(*uint16)(urv.ptr) == 0
|
||||
case reflect.Uint32:
|
||||
return *(*uint32)(urv.ptr) == 0
|
||||
case reflect.Uint64:
|
||||
return *(*uint64)(urv.ptr) == 0
|
||||
case reflect.Uintptr:
|
||||
return *(*uintptr)(urv.ptr) == 0
|
||||
case reflect.Float32:
|
||||
return *(*float32)(urv.ptr) == 0
|
||||
case reflect.Float64:
|
||||
return *(*float64)(urv.ptr) == 0
|
||||
case reflect.Interface:
|
||||
isnil := urv.ptr == nil || *(*unsafe.Pointer)(urv.ptr) == nil
|
||||
if deref {
|
||||
if isnil {
|
||||
return true
|
||||
}
|
||||
return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
|
||||
}
|
||||
return isnil
|
||||
case reflect.Ptr:
|
||||
// isnil := urv.ptr == nil (not sufficient, as a pointer value encodes the type)
|
||||
isnil := urv.ptr == nil || *(*unsafe.Pointer)(urv.ptr) == nil
|
||||
if deref {
|
||||
if isnil {
|
||||
return true
|
||||
}
|
||||
return isEmptyValue(v.Elem(), tinfos, deref, checkStruct)
|
||||
}
|
||||
return isnil
|
||||
case reflect.Struct:
|
||||
return isEmptyStruct(v, tinfos, deref, checkStruct)
|
||||
case reflect.Map, reflect.Array, reflect.Chan:
|
||||
return v.Len() == 0
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// --------------------------
|
||||
|
||||
// atomicTypeInfoSlice contains length and pointer to the array for a slice.
|
||||
// It is expected to be 2 words.
|
||||
//
|
||||
// Previously, we atomically loaded and stored the length and array pointer separately,
|
||||
// which could lead to some races.
|
||||
// We now just atomically store and load the pointer to the value directly.
|
||||
|
||||
type atomicTypeInfoSlice struct { // expected to be 2 words
|
||||
l int // length of the data array (must be first in struct, for 64-bit alignment necessary for 386)
|
||||
v unsafe.Pointer // data array - Pointer (not uintptr) to maintain GC reference
|
||||
}
|
||||
|
||||
func (x *atomicTypeInfoSlice) load() []rtid2ti {
|
||||
xp := unsafe.Pointer(x)
|
||||
x2 := *(*atomicTypeInfoSlice)(atomic.LoadPointer(&xp))
|
||||
if x2.l == 0 {
|
||||
return nil
|
||||
}
|
||||
return *(*[]rtid2ti)(unsafe.Pointer(&unsafeSlice{Data: x2.v, Len: x2.l, Cap: x2.l}))
|
||||
}
|
||||
|
||||
func (x *atomicTypeInfoSlice) store(p []rtid2ti) {
|
||||
s := (*unsafeSlice)(unsafe.Pointer(&p))
|
||||
xp := unsafe.Pointer(x)
|
||||
atomic.StorePointer(&xp, unsafe.Pointer(&atomicTypeInfoSlice{l: s.Len, v: s.Data}))
|
||||
}
|
||||
|
||||
// --------------------------
|
||||
func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
|
||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
*(*[]byte)(urv.ptr) = d.rawBytes()
|
||||
}
|
||||
|
||||
func (d *Decoder) kString(f *codecFnInfo, rv reflect.Value) {
|
||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
*(*string)(urv.ptr) = d.d.DecodeString()
|
||||
}
|
||||
|
||||
func (d *Decoder) kBool(f *codecFnInfo, rv reflect.Value) {
|
||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
*(*bool)(urv.ptr) = d.d.DecodeBool()
|
||||
}
|
||||
|
||||
func (d *Decoder) kTime(f *codecFnInfo, rv reflect.Value) {
|
||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
*(*time.Time)(urv.ptr) = d.d.DecodeTime()
|
||||
}
|
||||
|
||||
func (d *Decoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
|
||||
fv := d.d.DecodeFloat64()
|
||||
if chkOvf.Float32(fv) {
|
||||
d.errorf("float32 overflow: %v", fv)
|
||||
}
|
||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
*(*float32)(urv.ptr) = float32(fv)
|
||||
}
|
||||
|
||||
func (d *Decoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
|
||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
*(*float64)(urv.ptr) = d.d.DecodeFloat64()
|
||||
}
|
||||
|
||||
func (d *Decoder) kInt(f *codecFnInfo, rv reflect.Value) {
|
||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
*(*int)(urv.ptr) = int(chkOvf.IntV(d.d.DecodeInt64(), intBitsize))
|
||||
}
|
||||
|
||||
func (d *Decoder) kInt8(f *codecFnInfo, rv reflect.Value) {
|
||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
*(*int8)(urv.ptr) = int8(chkOvf.IntV(d.d.DecodeInt64(), 8))
|
||||
}
|
||||
|
||||
func (d *Decoder) kInt16(f *codecFnInfo, rv reflect.Value) {
|
||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
*(*int16)(urv.ptr) = int16(chkOvf.IntV(d.d.DecodeInt64(), 16))
|
||||
}
|
||||
|
||||
func (d *Decoder) kInt32(f *codecFnInfo, rv reflect.Value) {
|
||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
*(*int32)(urv.ptr) = int32(chkOvf.IntV(d.d.DecodeInt64(), 32))
|
||||
}
|
||||
|
||||
func (d *Decoder) kInt64(f *codecFnInfo, rv reflect.Value) {
|
||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
*(*int64)(urv.ptr) = d.d.DecodeInt64()
|
||||
}
|
||||
|
||||
func (d *Decoder) kUint(f *codecFnInfo, rv reflect.Value) {
|
||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
*(*uint)(urv.ptr) = uint(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
|
||||
}
|
||||
|
||||
func (d *Decoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
|
||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
*(*uintptr)(urv.ptr) = uintptr(chkOvf.UintV(d.d.DecodeUint64(), uintBitsize))
|
||||
}
|
||||
|
||||
func (d *Decoder) kUint8(f *codecFnInfo, rv reflect.Value) {
|
||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
*(*uint8)(urv.ptr) = uint8(chkOvf.UintV(d.d.DecodeUint64(), 8))
|
||||
}
|
||||
|
||||
func (d *Decoder) kUint16(f *codecFnInfo, rv reflect.Value) {
|
||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
*(*uint16)(urv.ptr) = uint16(chkOvf.UintV(d.d.DecodeUint64(), 16))
|
||||
}
|
||||
|
||||
func (d *Decoder) kUint32(f *codecFnInfo, rv reflect.Value) {
|
||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
*(*uint32)(urv.ptr) = uint32(chkOvf.UintV(d.d.DecodeUint64(), 32))
|
||||
}
|
||||
|
||||
func (d *Decoder) kUint64(f *codecFnInfo, rv reflect.Value) {
|
||||
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
*(*uint64)(urv.ptr) = d.d.DecodeUint64()
|
||||
}
|
||||
|
||||
// ------------
|
||||
|
||||
func (e *Encoder) kBool(f *codecFnInfo, rv reflect.Value) {
|
||||
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
e.e.EncodeBool(*(*bool)(v.ptr))
|
||||
}
|
||||
|
||||
func (e *Encoder) kTime(f *codecFnInfo, rv reflect.Value) {
|
||||
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
e.e.EncodeTime(*(*time.Time)(v.ptr))
|
||||
}
|
||||
|
||||
func (e *Encoder) kString(f *codecFnInfo, rv reflect.Value) {
|
||||
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
e.e.EncodeString(cUTF8, *(*string)(v.ptr))
|
||||
}
|
||||
|
||||
func (e *Encoder) kFloat64(f *codecFnInfo, rv reflect.Value) {
|
||||
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
e.e.EncodeFloat64(*(*float64)(v.ptr))
|
||||
}
|
||||
|
||||
func (e *Encoder) kFloat32(f *codecFnInfo, rv reflect.Value) {
|
||||
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
e.e.EncodeFloat32(*(*float32)(v.ptr))
|
||||
}
|
||||
|
||||
func (e *Encoder) kInt(f *codecFnInfo, rv reflect.Value) {
|
||||
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
e.e.EncodeInt(int64(*(*int)(v.ptr)))
|
||||
}
|
||||
|
||||
func (e *Encoder) kInt8(f *codecFnInfo, rv reflect.Value) {
|
||||
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
e.e.EncodeInt(int64(*(*int8)(v.ptr)))
|
||||
}
|
||||
|
||||
func (e *Encoder) kInt16(f *codecFnInfo, rv reflect.Value) {
|
||||
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
e.e.EncodeInt(int64(*(*int16)(v.ptr)))
|
||||
}
|
||||
|
||||
func (e *Encoder) kInt32(f *codecFnInfo, rv reflect.Value) {
|
||||
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
e.e.EncodeInt(int64(*(*int32)(v.ptr)))
|
||||
}
|
||||
|
||||
func (e *Encoder) kInt64(f *codecFnInfo, rv reflect.Value) {
|
||||
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
e.e.EncodeInt(int64(*(*int64)(v.ptr)))
|
||||
}
|
||||
|
||||
func (e *Encoder) kUint(f *codecFnInfo, rv reflect.Value) {
|
||||
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
e.e.EncodeUint(uint64(*(*uint)(v.ptr)))
|
||||
}
|
||||
|
||||
func (e *Encoder) kUint8(f *codecFnInfo, rv reflect.Value) {
|
||||
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
e.e.EncodeUint(uint64(*(*uint8)(v.ptr)))
|
||||
}
|
||||
|
||||
func (e *Encoder) kUint16(f *codecFnInfo, rv reflect.Value) {
|
||||
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
e.e.EncodeUint(uint64(*(*uint16)(v.ptr)))
|
||||
}
|
||||
|
||||
func (e *Encoder) kUint32(f *codecFnInfo, rv reflect.Value) {
|
||||
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
e.e.EncodeUint(uint64(*(*uint32)(v.ptr)))
|
||||
}
|
||||
|
||||
func (e *Encoder) kUint64(f *codecFnInfo, rv reflect.Value) {
|
||||
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
e.e.EncodeUint(uint64(*(*uint64)(v.ptr)))
|
||||
}
|
||||
|
||||
func (e *Encoder) kUintptr(f *codecFnInfo, rv reflect.Value) {
|
||||
v := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
e.e.EncodeUint(uint64(*(*uintptr)(v.ptr)))
|
||||
}
|
||||
|
||||
// ------------
|
||||
|
||||
// func (d *Decoder) raw(f *codecFnInfo, rv reflect.Value) {
|
||||
// urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
// // if urv.flag&unsafeFlagIndir != 0 {
|
||||
// // urv.ptr = *(*unsafe.Pointer)(urv.ptr)
|
||||
// // }
|
||||
// *(*[]byte)(urv.ptr) = d.rawBytes()
|
||||
// }
|
||||
|
||||
// func rv0t(rt reflect.Type) reflect.Value {
|
||||
// ut := (*unsafeIntf)(unsafe.Pointer(&rt))
|
||||
// // we need to determine whether ifaceIndir, and then whether to just pass 0 as the ptr
|
||||
// uv := unsafeReflectValue{ut.word, &zeroRTv, flag(rt.Kind())}
|
||||
// return *(*reflect.Value)(unsafe.Pointer(&uv})
|
||||
// }
|
||||
|
||||
// func rv2i(rv reflect.Value) interface{} {
|
||||
// urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
// // true references (map, func, chan, ptr - NOT slice) may be double-referenced as flagIndir
|
||||
// var ptr unsafe.Pointer
|
||||
// // kk := reflect.Kind(urv.flag & (1<<5 - 1))
|
||||
// // if (kk == reflect.Map || kk == reflect.Ptr || kk == reflect.Chan || kk == reflect.Func) && urv.flag&unsafeFlagIndir != 0 {
|
||||
// if refBitset.isset(byte(urv.flag&(1<<5-1))) && urv.flag&unsafeFlagIndir != 0 {
|
||||
// ptr = *(*unsafe.Pointer)(urv.ptr)
|
||||
// } else {
|
||||
// ptr = urv.ptr
|
||||
// }
|
||||
// return *(*interface{})(unsafe.Pointer(&unsafeIntf{typ: urv.typ, word: ptr}))
|
||||
// // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
|
||||
// // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
|
||||
// }
|
||||
|
||||
// func definitelyNil(v interface{}) bool {
|
||||
// var ui *unsafeIntf = (*unsafeIntf)(unsafe.Pointer(&v))
|
||||
// if ui.word == nil {
|
||||
// return true
|
||||
// }
|
||||
// var tk = reflect.TypeOf(v).Kind()
|
||||
// return (tk == reflect.Interface || tk == reflect.Slice) && *(*unsafe.Pointer)(ui.word) == nil
|
||||
// fmt.Printf(">>>> definitely nil: isnil: %v, TYPE: \t%T, word: %v, *word: %v, type: %v, nil: %v\n",
|
||||
// v == nil, v, word, *((*unsafe.Pointer)(word)), ui.typ, nil)
|
||||
// }
|
||||
|
||||
// func keepAlive4BytesView(v string) {
|
||||
// runtime.KeepAlive(v)
|
||||
// }
|
||||
|
||||
// func keepAlive4StringView(v []byte) {
|
||||
// runtime.KeepAlive(v)
|
||||
// }
|
||||
|
||||
// func rt2id(rt reflect.Type) uintptr {
|
||||
// return uintptr(((*unsafeIntf)(unsafe.Pointer(&rt))).word)
|
||||
// // var i interface{} = rt
|
||||
// // // ui := (*unsafeIntf)(unsafe.Pointer(&i))
|
||||
// // return ((*unsafeIntf)(unsafe.Pointer(&i))).word
|
||||
// }
|
||||
|
||||
// func rv2i(rv reflect.Value) interface{} {
|
||||
// urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
// // non-reference type: already indir
|
||||
// // reference type: depend on flagIndir property ('cos maybe was double-referenced)
|
||||
// // const (unsafeRvFlagKindMask = 1<<5 - 1 , unsafeRvFlagIndir = 1 << 7 )
|
||||
// // rvk := reflect.Kind(urv.flag & (1<<5 - 1))
|
||||
// // if (rvk == reflect.Chan ||
|
||||
// // rvk == reflect.Func ||
|
||||
// // rvk == reflect.Interface ||
|
||||
// // rvk == reflect.Map ||
|
||||
// // rvk == reflect.Ptr ||
|
||||
// // rvk == reflect.UnsafePointer) && urv.flag&(1<<8) != 0 {
|
||||
// // fmt.Printf(">>>>> ---- double indirect reference: %v, %v\n", rvk, rv.Type())
|
||||
// // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
|
||||
// // }
|
||||
// if urv.flag&(1<<5-1) == uintptr(reflect.Map) && urv.flag&(1<<7) != 0 {
|
||||
// // fmt.Printf(">>>>> ---- double indirect reference: %v, %v\n", rvk, rv.Type())
|
||||
// return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
|
||||
// }
|
||||
// // fmt.Printf(">>>>> ++++ direct reference: %v, %v\n", rvk, rv.Type())
|
||||
// return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
|
||||
// }
|
||||
|
||||
// const (
|
||||
// unsafeRvFlagKindMask = 1<<5 - 1
|
||||
// unsafeRvKindDirectIface = 1 << 5
|
||||
// unsafeRvFlagIndir = 1 << 7
|
||||
// unsafeRvFlagAddr = 1 << 8
|
||||
// unsafeRvFlagMethod = 1 << 9
|
||||
|
||||
// _USE_RV_INTERFACE bool = false
|
||||
// _UNSAFE_RV_DEBUG = true
|
||||
// )
|
||||
|
||||
// type unsafeRtype struct {
|
||||
// _ [2]uintptr
|
||||
// _ uint32
|
||||
// _ uint8
|
||||
// _ uint8
|
||||
// _ uint8
|
||||
// kind uint8
|
||||
// _ [2]uintptr
|
||||
// _ int32
|
||||
// }
|
||||
|
||||
// func _rv2i(rv reflect.Value) interface{} {
|
||||
// // Note: From use,
|
||||
// // - it's never an interface
|
||||
// // - the only calls here are for ifaceIndir types.
|
||||
// // (though that conditional is wrong)
|
||||
// // To know for sure, we need the value of t.kind (which is not exposed).
|
||||
// //
|
||||
// // Need to validate the path: type is indirect ==> only value is indirect ==> default (value is direct)
|
||||
// // - Type indirect, Value indirect: ==> numbers, boolean, slice, struct, array, string
|
||||
// // - Type Direct, Value indirect: ==> map???
|
||||
// // - Type Direct, Value direct: ==> pointers, unsafe.Pointer, func, chan, map
|
||||
// //
|
||||
// // TRANSLATES TO:
|
||||
// // if typeIndirect { } else if valueIndirect { } else { }
|
||||
// //
|
||||
// // Since we don't deal with funcs, then "flagNethod" is unset, and can be ignored.
|
||||
|
||||
// if _USE_RV_INTERFACE {
|
||||
// return rv.Interface()
|
||||
// }
|
||||
// urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
|
||||
// // if urv.flag&unsafeRvFlagMethod != 0 || urv.flag&unsafeRvFlagKindMask == uintptr(reflect.Interface) {
|
||||
// // println("***** IS flag method or interface: delegating to rv.Interface()")
|
||||
// // return rv.Interface()
|
||||
// // }
|
||||
|
||||
// // if urv.flag&unsafeRvFlagKindMask == uintptr(reflect.Interface) {
|
||||
// // println("***** IS Interface: delegate to rv.Interface")
|
||||
// // return rv.Interface()
|
||||
// // }
|
||||
// // if urv.flag&unsafeRvFlagKindMask&unsafeRvKindDirectIface == 0 {
|
||||
// // if urv.flag&unsafeRvFlagAddr == 0 {
|
||||
// // println("***** IS ifaceIndir typ")
|
||||
// // // ui := unsafeIntf{word: urv.ptr, typ: urv.typ}
|
||||
// // // return *(*interface{})(unsafe.Pointer(&ui))
|
||||
// // // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
|
||||
// // }
|
||||
// // } else if urv.flag&unsafeRvFlagIndir != 0 {
|
||||
// // println("***** IS flagindir")
|
||||
// // // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
|
||||
// // } else {
|
||||
// // println("***** NOT flagindir")
|
||||
// // return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
|
||||
// // }
|
||||
// // println("***** default: delegate to rv.Interface")
|
||||
|
||||
// urt := (*unsafeRtype)(unsafe.Pointer(urv.typ))
|
||||
// if _UNSAFE_RV_DEBUG {
|
||||
// fmt.Printf(">>>> start: %v: ", rv.Type())
|
||||
// fmt.Printf("%v - %v\n", *urv, *urt)
|
||||
// }
|
||||
// if urt.kind&unsafeRvKindDirectIface == 0 {
|
||||
// if _UNSAFE_RV_DEBUG {
|
||||
// fmt.Printf("**** +ifaceIndir type: %v\n", rv.Type())
|
||||
// }
|
||||
// // println("***** IS ifaceIndir typ")
|
||||
// // if true || urv.flag&unsafeRvFlagAddr == 0 {
|
||||
// // // println(" ***** IS NOT addr")
|
||||
// return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
|
||||
// // }
|
||||
// } else if urv.flag&unsafeRvFlagIndir != 0 {
|
||||
// if _UNSAFE_RV_DEBUG {
|
||||
// fmt.Printf("**** +flagIndir type: %v\n", rv.Type())
|
||||
// }
|
||||
// // println("***** IS flagindir")
|
||||
// return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: *(*unsafe.Pointer)(urv.ptr), typ: urv.typ}))
|
||||
// } else {
|
||||
// if _UNSAFE_RV_DEBUG {
|
||||
// fmt.Printf("**** -flagIndir type: %v\n", rv.Type())
|
||||
// }
|
||||
// // println("***** NOT flagindir")
|
||||
// return *(*interface{})(unsafe.Pointer(&unsafeIntf{word: urv.ptr, typ: urv.typ}))
|
||||
// }
|
||||
// // println("***** default: delegating to rv.Interface()")
|
||||
// // return rv.Interface()
|
||||
// }
|
||||
|
||||
// var staticM0 = make(map[string]uint64)
|
||||
// var staticI0 = (int32)(-5)
|
||||
|
||||
// func staticRv2iTest() {
|
||||
// i0 := (int32)(-5)
|
||||
// m0 := make(map[string]uint16)
|
||||
// m0["1"] = 1
|
||||
// for _, i := range []interface{}{
|
||||
// (int)(7),
|
||||
// (uint)(8),
|
||||
// (int16)(-9),
|
||||
// (uint16)(19),
|
||||
// (uintptr)(77),
|
||||
// (bool)(true),
|
||||
// float32(-32.7),
|
||||
// float64(64.9),
|
||||
// complex(float32(19), 5),
|
||||
// complex(float64(-32), 7),
|
||||
// [4]uint64{1, 2, 3, 4},
|
||||
// (chan<- int)(nil), // chan,
|
||||
// rv2i, // func
|
||||
// io.Writer(ioutil.Discard),
|
||||
// make(map[string]uint),
|
||||
// (map[string]uint)(nil),
|
||||
// staticM0,
|
||||
// m0,
|
||||
// &m0,
|
||||
// i0,
|
||||
// &i0,
|
||||
// &staticI0,
|
||||
// &staticM0,
|
||||
// []uint32{6, 7, 8},
|
||||
// "abc",
|
||||
// Raw{},
|
||||
// RawExt{},
|
||||
// &Raw{},
|
||||
// &RawExt{},
|
||||
// unsafe.Pointer(&i0),
|
||||
// } {
|
||||
// i2 := rv2i(reflect.ValueOf(i))
|
||||
// eq := reflect.DeepEqual(i, i2)
|
||||
// fmt.Printf(">>>> %v == %v? %v\n", i, i2, eq)
|
||||
// }
|
||||
// // os.Exit(0)
|
||||
// }
|
||||
|
||||
// func init() {
|
||||
// staticRv2iTest()
|
||||
// }
|
||||
|
||||
// func rv2i(rv reflect.Value) interface{} {
|
||||
// if _USE_RV_INTERFACE || rv.Kind() == reflect.Interface || rv.CanAddr() {
|
||||
// return rv.Interface()
|
||||
// }
|
||||
// // var i interface{}
|
||||
// // ui := (*unsafeIntf)(unsafe.Pointer(&i))
|
||||
// var ui unsafeIntf
|
||||
// urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
|
||||
// // fmt.Printf("urv: flag: %b, typ: %b, ptr: %b\n", urv.flag, uintptr(urv.typ), uintptr(urv.ptr))
|
||||
// if (urv.flag&unsafeRvFlagKindMask)&unsafeRvKindDirectIface == 0 {
|
||||
// if urv.flag&unsafeRvFlagAddr != 0 {
|
||||
// println("***** indirect and addressable! Needs typed move - delegate to rv.Interface()")
|
||||
// return rv.Interface()
|
||||
// }
|
||||
// println("****** indirect type/kind")
|
||||
// ui.word = urv.ptr
|
||||
// } else if urv.flag&unsafeRvFlagIndir != 0 {
|
||||
// println("****** unsafe rv flag indir")
|
||||
// ui.word = *(*unsafe.Pointer)(urv.ptr)
|
||||
// } else {
|
||||
// println("****** default: assign prt to word directly")
|
||||
// ui.word = urv.ptr
|
||||
// }
|
||||
// // ui.word = urv.ptr
|
||||
// ui.typ = urv.typ
|
||||
// // fmt.Printf("(pointers) ui.typ: %p, word: %p\n", ui.typ, ui.word)
|
||||
// // fmt.Printf("(binary) ui.typ: %b, word: %b\n", uintptr(ui.typ), uintptr(ui.word))
|
||||
// return *(*interface{})(unsafe.Pointer(&ui))
|
||||
// // return i
|
||||
// }
|
||||
1423
vendor/github.com/ugorji/go/codec/json.go
generated
vendored
Normal file
1423
vendor/github.com/ugorji/go/codec/json.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
154
vendor/github.com/ugorji/go/codec/mammoth-test.go.tmpl
generated
vendored
Normal file
154
vendor/github.com/ugorji/go/codec/mammoth-test.go.tmpl
generated
vendored
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
// Code generated from mammoth-test.go.tmpl - DO NOT EDIT.
|
||||
|
||||
package codec
|
||||
|
||||
import "testing"
|
||||
import "fmt"
|
||||
import "reflect"
|
||||
|
||||
// TestMammoth has all the different paths optimized in fast-path
|
||||
// It has all the primitives, slices and maps.
|
||||
//
|
||||
// For each of those types, it has a pointer and a non-pointer field.
|
||||
|
||||
func init() { _ = fmt.Printf } // so we can include fmt as needed
|
||||
|
||||
type TestMammoth struct {
|
||||
|
||||
{{range .Values }}{{if .Primitive }}{{/*
|
||||
*/}}{{ .MethodNamePfx "F" true }} {{ .Primitive }}
|
||||
{{ .MethodNamePfx "Fptr" true }} *{{ .Primitive }}
|
||||
{{end}}{{end}}
|
||||
|
||||
{{range .Values }}{{if not .Primitive }}{{if not .MapKey }}{{/*
|
||||
*/}}{{ .MethodNamePfx "F" false }} []{{ .Elem }}
|
||||
{{ .MethodNamePfx "Fptr" false }} *[]{{ .Elem }}
|
||||
{{end}}{{end}}{{end}}
|
||||
|
||||
{{range .Values }}{{if not .Primitive }}{{if .MapKey }}{{/*
|
||||
*/}}{{ .MethodNamePfx "F" false }} map[{{ .MapKey }}]{{ .Elem }}
|
||||
{{ .MethodNamePfx "Fptr" false }} *map[{{ .MapKey }}]{{ .Elem }}
|
||||
{{end}}{{end}}{{end}}
|
||||
|
||||
}
|
||||
|
||||
{{range .Values }}{{if not .Primitive }}{{if not .MapKey }}{{/*
|
||||
*/}} type {{ .MethodNamePfx "typMbs" false }} []{{ .Elem }}
|
||||
func (_ {{ .MethodNamePfx "typMbs" false }}) MapBySlice() { }
|
||||
{{end}}{{end}}{{end}}
|
||||
|
||||
{{range .Values }}{{if not .Primitive }}{{if .MapKey }}{{/*
|
||||
*/}} type {{ .MethodNamePfx "typMap" false }} map[{{ .MapKey }}]{{ .Elem }}
|
||||
{{end}}{{end}}{{end}}
|
||||
|
||||
func doTestMammothSlices(t *testing.T, h Handle) {
|
||||
{{range $i, $e := .Values }}{{if not .Primitive }}{{if not .MapKey }}{{/*
|
||||
*/}}
|
||||
var v{{$i}}va [8]{{ .Elem }}
|
||||
for _, v := range [][]{{ .Elem }}{ nil, {}, { {{ nonzerocmd .Elem }}, {{ zerocmd .Elem }}, {{ zerocmd .Elem }}, {{ nonzerocmd .Elem }} } } { {{/*
|
||||
// fmt.Printf(">>>> running mammoth slice v{{$i}}: %v\n", v)
|
||||
// - encode value to some []byte
|
||||
// - decode into a length-wise-equal []byte
|
||||
// - check if equal to initial slice
|
||||
// - encode ptr to the value
|
||||
// - check if encode bytes are same
|
||||
// - decode into ptrs to: nil, then 1-elem slice, equal-length, then large len slice
|
||||
// - decode into non-addressable slice of equal length, then larger len
|
||||
// - for each decode, compare elem-by-elem to the original slice
|
||||
// -
|
||||
// - rinse and repeat for a MapBySlice version
|
||||
// -
|
||||
*/}}
|
||||
var v{{$i}}v1, v{{$i}}v2 []{{ .Elem }}
|
||||
v{{$i}}v1 = v
|
||||
bs{{$i}} := testMarshalErr(v{{$i}}v1, h, t, "enc-slice-v{{$i}}")
|
||||
if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make([]{{ .Elem }}, len(v)) }
|
||||
testUnmarshalErr(v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}")
|
||||
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}")
|
||||
if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make([]{{ .Elem }}, len(v)) }
|
||||
testUnmarshalErr(reflect.ValueOf(v{{$i}}v2), bs{{$i}}, h, t, "dec-slice-v{{$i}}-noaddr") // non-addressable value
|
||||
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}-noaddr")
|
||||
// ...
|
||||
bs{{$i}} = testMarshalErr(&v{{$i}}v1, h, t, "enc-slice-v{{$i}}-p")
|
||||
v{{$i}}v2 = nil
|
||||
testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}-p")
|
||||
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}-p")
|
||||
v{{$i}}va = [8]{{ .Elem }}{} // clear the array
|
||||
v{{$i}}v2 = v{{$i}}va[:1:1]
|
||||
testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}-p-1")
|
||||
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}-p-1")
|
||||
v{{$i}}va = [8]{{ .Elem }}{} // clear the array
|
||||
v{{$i}}v2 = v{{$i}}va[:len(v{{$i}}v1):len(v{{$i}}v1)]
|
||||
testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}-p-len")
|
||||
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}-p-len")
|
||||
v{{$i}}va = [8]{{ .Elem }}{} // clear the array
|
||||
v{{$i}}v2 = v{{$i}}va[:]
|
||||
testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}-p-cap")
|
||||
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-slice-v{{$i}}-p-cap")
|
||||
if len(v{{$i}}v1) > 1 {
|
||||
v{{$i}}va = [8]{{ .Elem }}{} // clear the array
|
||||
testUnmarshalErr((&v{{$i}}va)[:len(v{{$i}}v1)], bs{{$i}}, h, t, "dec-slice-v{{$i}}-p-len-noaddr")
|
||||
testDeepEqualErr(v{{$i}}v1, v{{$i}}va[:len(v{{$i}}v1)], t, "equal-slice-v{{$i}}-p-len-noaddr")
|
||||
v{{$i}}va = [8]{{ .Elem }}{} // clear the array
|
||||
testUnmarshalErr((&v{{$i}}va)[:], bs{{$i}}, h, t, "dec-slice-v{{$i}}-p-cap-noaddr")
|
||||
testDeepEqualErr(v{{$i}}v1, v{{$i}}va[:len(v{{$i}}v1)], t, "equal-slice-v{{$i}}-p-cap-noaddr")
|
||||
}
|
||||
// ...
|
||||
var v{{$i}}v3, v{{$i}}v4 {{ .MethodNamePfx "typMbs" false }}
|
||||
v{{$i}}v2 = nil
|
||||
if v != nil { v{{$i}}v2 = make([]{{ .Elem }}, len(v)) }
|
||||
v{{$i}}v3 = {{ .MethodNamePfx "typMbs" false }}(v{{$i}}v1)
|
||||
v{{$i}}v4 = {{ .MethodNamePfx "typMbs" false }}(v{{$i}}v2)
|
||||
bs{{$i}} = testMarshalErr(v{{$i}}v3, h, t, "enc-slice-v{{$i}}-custom")
|
||||
testUnmarshalErr(v{{$i}}v4, bs{{$i}}, h, t, "dec-slice-v{{$i}}-custom")
|
||||
testDeepEqualErr(v{{$i}}v3, v{{$i}}v4, t, "equal-slice-v{{$i}}-custom")
|
||||
bs{{$i}} = testMarshalErr(&v{{$i}}v3, h, t, "enc-slice-v{{$i}}-custom-p")
|
||||
v{{$i}}v2 = nil
|
||||
v{{$i}}v4 = {{ .MethodNamePfx "typMbs" false }}(v{{$i}}v2)
|
||||
testUnmarshalErr(&v{{$i}}v4, bs{{$i}}, h, t, "dec-slice-v{{$i}}-custom-p")
|
||||
testDeepEqualErr(v{{$i}}v3, v{{$i}}v4, t, "equal-slice-v{{$i}}-custom-p")
|
||||
}
|
||||
{{end}}{{end}}{{end}}
|
||||
}
|
||||
|
||||
func doTestMammothMaps(t *testing.T, h Handle) {
|
||||
{{range $i, $e := .Values }}{{if not .Primitive }}{{if .MapKey }}{{/*
|
||||
*/}}
|
||||
for _, v := range []map[{{ .MapKey }}]{{ .Elem }}{ nil, {}, { {{ nonzerocmd .MapKey }}:{{ zerocmd .Elem }} {{if ne "bool" .MapKey}}, {{ nonzerocmd .MapKey }}:{{ nonzerocmd .Elem }} {{end}} } } {
|
||||
// fmt.Printf(">>>> running mammoth map v{{$i}}: %v\n", v)
|
||||
var v{{$i}}v1, v{{$i}}v2 map[{{ .MapKey }}]{{ .Elem }}
|
||||
v{{$i}}v1 = v
|
||||
bs{{$i}} := testMarshalErr(v{{$i}}v1, h, t, "enc-map-v{{$i}}")
|
||||
if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make(map[{{ .MapKey }}]{{ .Elem }}, len(v)) } // reset map
|
||||
testUnmarshalErr(v{{$i}}v2, bs{{$i}}, h, t, "dec-map-v{{$i}}")
|
||||
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-map-v{{$i}}")
|
||||
if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make(map[{{ .MapKey }}]{{ .Elem }}, len(v)) } // reset map
|
||||
testUnmarshalErr(reflect.ValueOf(v{{$i}}v2), bs{{$i}}, h, t, "dec-map-v{{$i}}-noaddr") // decode into non-addressable map value
|
||||
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-map-v{{$i}}-noaddr")
|
||||
if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make(map[{{ .MapKey }}]{{ .Elem }}, len(v)) } // reset map
|
||||
testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-map-v{{$i}}-p-len")
|
||||
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-map-v{{$i}}-p-len")
|
||||
bs{{$i}} = testMarshalErr(&v{{$i}}v1, h, t, "enc-map-v{{$i}}-p")
|
||||
v{{$i}}v2 = nil
|
||||
testUnmarshalErr(&v{{$i}}v2, bs{{$i}}, h, t, "dec-map-v{{$i}}-p-nil")
|
||||
testDeepEqualErr(v{{$i}}v1, v{{$i}}v2, t, "equal-map-v{{$i}}-p-nil")
|
||||
// ...
|
||||
if v == nil { v{{$i}}v2 = nil } else { v{{$i}}v2 = make(map[{{ .MapKey }}]{{ .Elem }}, len(v)) } // reset map
|
||||
var v{{$i}}v3, v{{$i}}v4 {{ .MethodNamePfx "typMap" false }}
|
||||
v{{$i}}v3 = {{ .MethodNamePfx "typMap" false }}(v{{$i}}v1)
|
||||
v{{$i}}v4 = {{ .MethodNamePfx "typMap" false }}(v{{$i}}v2)
|
||||
bs{{$i}} = testMarshalErr(v{{$i}}v3, h, t, "enc-map-v{{$i}}-custom")
|
||||
testUnmarshalErr(v{{$i}}v4, bs{{$i}}, h, t, "dec-map-v{{$i}}-p-len")
|
||||
testDeepEqualErr(v{{$i}}v3, v{{$i}}v4, t, "equal-map-v{{$i}}-p-len")
|
||||
}
|
||||
{{end}}{{end}}{{end}}
|
||||
|
||||
}
|
||||
|
||||
func doTestMammothMapsAndSlices(t *testing.T, h Handle) {
|
||||
doTestMammothSlices(t, h)
|
||||
doTestMammothMaps(t, h)
|
||||
}
|
||||
94
vendor/github.com/ugorji/go/codec/mammoth2-test.go.tmpl
generated
vendored
Normal file
94
vendor/github.com/ugorji/go/codec/mammoth2-test.go.tmpl
generated
vendored
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
// +build !notfastpath
|
||||
|
||||
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
// Code generated from mammoth2-test.go.tmpl - DO NOT EDIT.
|
||||
|
||||
package codec
|
||||
|
||||
// Increase codecoverage by covering all the codecgen paths, in fast-path and gen-helper.go....
|
||||
//
|
||||
// Add:
|
||||
// - test file for creating a mammoth generated file as _mammoth_generated.go
|
||||
// - generate a second mammoth files in a different file: mammoth2_generated_test.go
|
||||
// - mammoth-test.go.tmpl will do this
|
||||
// - run codecgen on it, into mammoth2_codecgen_generated_test.go (no build tags)
|
||||
// - as part of TestMammoth, run it also
|
||||
// - this will cover all the codecgen, gen-helper, etc in one full run
|
||||
// - check in mammoth* files into github also
|
||||
// - then
|
||||
//
|
||||
// Now, add some types:
|
||||
// - some that implement BinaryMarshal, TextMarshal, JSONMarshal, and one that implements none of it
|
||||
// - create a wrapper type that includes TestMammoth2, with it in slices, and maps, and the custom types
|
||||
// - this wrapper object is what we work encode/decode (so that the codecgen methods are called)
|
||||
|
||||
|
||||
// import "encoding/binary"
|
||||
import "fmt"
|
||||
|
||||
type TestMammoth2 struct {
|
||||
|
||||
{{range .Values }}{{if .Primitive }}{{/*
|
||||
*/}}{{ .MethodNamePfx "F" true }} {{ .Primitive }}
|
||||
{{ .MethodNamePfx "Fptr" true }} *{{ .Primitive }}
|
||||
{{end}}{{end}}
|
||||
|
||||
{{range .Values }}{{if not .Primitive }}{{if not .MapKey }}{{/*
|
||||
*/}}{{ .MethodNamePfx "F" false }} []{{ .Elem }}
|
||||
{{ .MethodNamePfx "Fptr" false }} *[]{{ .Elem }}
|
||||
{{end}}{{end}}{{end}}
|
||||
|
||||
{{range .Values }}{{if not .Primitive }}{{if .MapKey }}{{/*
|
||||
*/}}{{ .MethodNamePfx "F" false }} map[{{ .MapKey }}]{{ .Elem }}
|
||||
{{ .MethodNamePfx "Fptr" false }} *map[{{ .MapKey }}]{{ .Elem }}
|
||||
{{end}}{{end}}{{end}}
|
||||
|
||||
}
|
||||
|
||||
// -----------
|
||||
|
||||
type testMammoth2Binary uint64
|
||||
func (x testMammoth2Binary) MarshalBinary() (data []byte, err error) {
|
||||
data = make([]byte, 8)
|
||||
bigen.PutUint64(data, uint64(x))
|
||||
return
|
||||
}
|
||||
func (x *testMammoth2Binary) UnmarshalBinary(data []byte) (err error) {
|
||||
*x = testMammoth2Binary(bigen.Uint64(data))
|
||||
return
|
||||
}
|
||||
|
||||
type testMammoth2Text uint64
|
||||
func (x testMammoth2Text) MarshalText() (data []byte, err error) {
|
||||
data = []byte(fmt.Sprintf("%b", uint64(x)))
|
||||
return
|
||||
}
|
||||
func (x *testMammoth2Text) UnmarshalText(data []byte) (err error) {
|
||||
_, err = fmt.Sscanf(string(data), "%b", (*uint64)(x))
|
||||
return
|
||||
}
|
||||
|
||||
type testMammoth2Json uint64
|
||||
func (x testMammoth2Json) MarshalJSON() (data []byte, err error) {
|
||||
data = []byte(fmt.Sprintf("%v", uint64(x)))
|
||||
return
|
||||
}
|
||||
func (x *testMammoth2Json) UnmarshalJSON(data []byte) (err error) {
|
||||
_, err = fmt.Sscanf(string(data), "%v", (*uint64)(x))
|
||||
return
|
||||
}
|
||||
|
||||
type testMammoth2Basic [4]uint64
|
||||
|
||||
type TestMammoth2Wrapper struct {
|
||||
V TestMammoth2
|
||||
T testMammoth2Text
|
||||
B testMammoth2Binary
|
||||
J testMammoth2Json
|
||||
C testMammoth2Basic
|
||||
M map[testMammoth2Basic]TestMammoth2
|
||||
L []TestMammoth2
|
||||
A [4]int64
|
||||
}
|
||||
1092
vendor/github.com/ugorji/go/codec/msgpack.go
generated
vendored
Normal file
1092
vendor/github.com/ugorji/go/codec/msgpack.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
232
vendor/github.com/ugorji/go/codec/rpc.go
generated
vendored
Normal file
232
vendor/github.com/ugorji/go/codec/rpc.go
generated
vendored
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
package codec
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"io"
|
||||
"net/rpc"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Rpc provides a rpc Server or Client Codec for rpc communication.
|
||||
type Rpc interface {
|
||||
ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec
|
||||
ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec
|
||||
}
|
||||
|
||||
// RPCOptions holds options specific to rpc functionality
|
||||
type RPCOptions struct {
|
||||
// RPCNoBuffer configures whether we attempt to buffer reads and writes during RPC calls.
|
||||
//
|
||||
// Set RPCNoBuffer=true to turn buffering off.
|
||||
// Buffering can still be done if buffered connections are passed in, or
|
||||
// buffering is configured on the handle.
|
||||
RPCNoBuffer bool
|
||||
}
|
||||
|
||||
// rpcCodec defines the struct members and common methods.
|
||||
type rpcCodec struct {
|
||||
c io.Closer
|
||||
r io.Reader
|
||||
w io.Writer
|
||||
f ioFlusher
|
||||
|
||||
dec *Decoder
|
||||
enc *Encoder
|
||||
// bw *bufio.Writer
|
||||
// br *bufio.Reader
|
||||
mu sync.Mutex
|
||||
h Handle
|
||||
|
||||
cls bool
|
||||
clsmu sync.RWMutex
|
||||
clsErr error
|
||||
}
|
||||
|
||||
func newRPCCodec(conn io.ReadWriteCloser, h Handle) rpcCodec {
|
||||
// return newRPCCodec2(bufio.NewReader(conn), bufio.NewWriter(conn), conn, h)
|
||||
return newRPCCodec2(conn, conn, conn, h)
|
||||
}
|
||||
|
||||
func newRPCCodec2(r io.Reader, w io.Writer, c io.Closer, h Handle) rpcCodec {
|
||||
// defensive: ensure that jsonH has TermWhitespace turned on.
|
||||
if jsonH, ok := h.(*JsonHandle); ok && !jsonH.TermWhitespace {
|
||||
panic(errors.New("rpc requires a JsonHandle with TermWhitespace set to true"))
|
||||
}
|
||||
// always ensure that we use a flusher, and always flush what was written to the connection.
|
||||
// we lose nothing by using a buffered writer internally.
|
||||
f, ok := w.(ioFlusher)
|
||||
bh := h.getBasicHandle()
|
||||
if !bh.RPCNoBuffer {
|
||||
if bh.WriterBufferSize <= 0 {
|
||||
if !ok {
|
||||
bw := bufio.NewWriter(w)
|
||||
f, w = bw, bw
|
||||
}
|
||||
}
|
||||
if bh.ReaderBufferSize <= 0 {
|
||||
if _, ok = w.(ioPeeker); !ok {
|
||||
if _, ok = w.(ioBuffered); !ok {
|
||||
br := bufio.NewReader(r)
|
||||
r = br
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return rpcCodec{
|
||||
c: c,
|
||||
w: w,
|
||||
r: r,
|
||||
f: f,
|
||||
h: h,
|
||||
enc: NewEncoder(w, h),
|
||||
dec: NewDecoder(r, h),
|
||||
}
|
||||
}
|
||||
|
||||
func (c *rpcCodec) write(obj1, obj2 interface{}, writeObj2 bool) (err error) {
|
||||
if c.isClosed() {
|
||||
return c.clsErr
|
||||
}
|
||||
err = c.enc.Encode(obj1)
|
||||
if err == nil {
|
||||
if writeObj2 {
|
||||
err = c.enc.Encode(obj2)
|
||||
}
|
||||
// if err == nil && c.f != nil {
|
||||
// err = c.f.Flush()
|
||||
// }
|
||||
}
|
||||
if c.f != nil {
|
||||
if err == nil {
|
||||
err = c.f.Flush()
|
||||
} else {
|
||||
_ = c.f.Flush() // swallow flush error, so we maintain prior error on write
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *rpcCodec) swallow(err *error) {
|
||||
defer panicToErr(c.dec, err)
|
||||
c.dec.swallow()
|
||||
}
|
||||
|
||||
func (c *rpcCodec) read(obj interface{}) (err error) {
|
||||
if c.isClosed() {
|
||||
return c.clsErr
|
||||
}
|
||||
//If nil is passed in, we should read and discard
|
||||
if obj == nil {
|
||||
// var obj2 interface{}
|
||||
// return c.dec.Decode(&obj2)
|
||||
c.swallow(&err)
|
||||
return
|
||||
}
|
||||
return c.dec.Decode(obj)
|
||||
}
|
||||
|
||||
func (c *rpcCodec) isClosed() (b bool) {
|
||||
if c.c != nil {
|
||||
c.clsmu.RLock()
|
||||
b = c.cls
|
||||
c.clsmu.RUnlock()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *rpcCodec) Close() error {
|
||||
if c.c == nil || c.isClosed() {
|
||||
return c.clsErr
|
||||
}
|
||||
c.clsmu.Lock()
|
||||
c.cls = true
|
||||
c.clsErr = c.c.Close()
|
||||
c.clsmu.Unlock()
|
||||
return c.clsErr
|
||||
}
|
||||
|
||||
func (c *rpcCodec) ReadResponseBody(body interface{}) error {
|
||||
return c.read(body)
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
|
||||
type goRpcCodec struct {
|
||||
rpcCodec
|
||||
}
|
||||
|
||||
func (c *goRpcCodec) WriteRequest(r *rpc.Request, body interface{}) error {
|
||||
// Must protect for concurrent access as per API
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
return c.write(r, body, true)
|
||||
}
|
||||
|
||||
func (c *goRpcCodec) WriteResponse(r *rpc.Response, body interface{}) error {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
return c.write(r, body, true)
|
||||
}
|
||||
|
||||
func (c *goRpcCodec) ReadResponseHeader(r *rpc.Response) error {
|
||||
return c.read(r)
|
||||
}
|
||||
|
||||
func (c *goRpcCodec) ReadRequestHeader(r *rpc.Request) error {
|
||||
return c.read(r)
|
||||
}
|
||||
|
||||
func (c *goRpcCodec) ReadRequestBody(body interface{}) error {
|
||||
return c.read(body)
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
|
||||
// goRpc is the implementation of Rpc that uses the communication protocol
|
||||
// as defined in net/rpc package.
|
||||
type goRpc struct{}
|
||||
|
||||
// GoRpc implements Rpc using the communication protocol defined in net/rpc package.
|
||||
//
|
||||
// Note: network connection (from net.Dial, of type io.ReadWriteCloser) is not buffered.
|
||||
//
|
||||
// For performance, you should configure WriterBufferSize and ReaderBufferSize on the handle.
|
||||
// This ensures we use an adequate buffer during reading and writing.
|
||||
// If not configured, we will internally initialize and use a buffer during reads and writes.
|
||||
// This can be turned off via the RPCNoBuffer option on the Handle.
|
||||
// var handle codec.JsonHandle
|
||||
// handle.RPCNoBuffer = true // turns off attempt by rpc module to initialize a buffer
|
||||
//
|
||||
// Example 1: one way of configuring buffering explicitly:
|
||||
// var handle codec.JsonHandle // codec handle
|
||||
// handle.ReaderBufferSize = 1024
|
||||
// handle.WriterBufferSize = 1024
|
||||
// var conn io.ReadWriteCloser // connection got from a socket
|
||||
// var serverCodec = GoRpc.ServerCodec(conn, handle)
|
||||
// var clientCodec = GoRpc.ClientCodec(conn, handle)
|
||||
//
|
||||
// Example 2: you can also explicitly create a buffered connection yourself,
|
||||
// and not worry about configuring the buffer sizes in the Handle.
|
||||
// var handle codec.Handle // codec handle
|
||||
// var conn io.ReadWriteCloser // connection got from a socket
|
||||
// var bufconn = struct { // bufconn here is a buffered io.ReadWriteCloser
|
||||
// io.Closer
|
||||
// *bufio.Reader
|
||||
// *bufio.Writer
|
||||
// }{conn, bufio.NewReader(conn), bufio.NewWriter(conn)}
|
||||
// var serverCodec = GoRpc.ServerCodec(bufconn, handle)
|
||||
// var clientCodec = GoRpc.ClientCodec(bufconn, handle)
|
||||
//
|
||||
var GoRpc goRpc
|
||||
|
||||
func (x goRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec {
|
||||
return &goRpcCodec{newRPCCodec(conn, h)}
|
||||
}
|
||||
|
||||
func (x goRpc) ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec {
|
||||
return &goRpcCodec{newRPCCodec(conn, h)}
|
||||
}
|
||||
652
vendor/github.com/ugorji/go/codec/simple.go
generated
vendored
Normal file
652
vendor/github.com/ugorji/go/codec/simple.go
generated
vendored
Normal file
|
|
@ -0,0 +1,652 @@
|
|||
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
package codec
|
||||
|
||||
import (
|
||||
"math"
|
||||
"reflect"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
_ uint8 = iota
|
||||
simpleVdNil = 1
|
||||
simpleVdFalse = 2
|
||||
simpleVdTrue = 3
|
||||
simpleVdFloat32 = 4
|
||||
simpleVdFloat64 = 5
|
||||
|
||||
// each lasts for 4 (ie n, n+1, n+2, n+3)
|
||||
simpleVdPosInt = 8
|
||||
simpleVdNegInt = 12
|
||||
|
||||
simpleVdTime = 24
|
||||
|
||||
// containers: each lasts for 4 (ie n, n+1, n+2, ... n+7)
|
||||
simpleVdString = 216
|
||||
simpleVdByteArray = 224
|
||||
simpleVdArray = 232
|
||||
simpleVdMap = 240
|
||||
simpleVdExt = 248
|
||||
)
|
||||
|
||||
type simpleEncDriver struct {
|
||||
noBuiltInTypes
|
||||
// encNoSeparator
|
||||
e *Encoder
|
||||
h *SimpleHandle
|
||||
w encWriter
|
||||
b [8]byte
|
||||
// c containerState
|
||||
encDriverTrackContainerWriter
|
||||
// encDriverNoopContainerWriter
|
||||
_ [2]uint64 // padding
|
||||
}
|
||||
|
||||
func (e *simpleEncDriver) EncodeNil() {
|
||||
e.w.writen1(simpleVdNil)
|
||||
}
|
||||
|
||||
func (e *simpleEncDriver) EncodeBool(b bool) {
|
||||
if e.h.EncZeroValuesAsNil && e.c != containerMapKey && !b {
|
||||
e.EncodeNil()
|
||||
return
|
||||
}
|
||||
if b {
|
||||
e.w.writen1(simpleVdTrue)
|
||||
} else {
|
||||
e.w.writen1(simpleVdFalse)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *simpleEncDriver) EncodeFloat32(f float32) {
|
||||
if e.h.EncZeroValuesAsNil && e.c != containerMapKey && f == 0.0 {
|
||||
e.EncodeNil()
|
||||
return
|
||||
}
|
||||
e.w.writen1(simpleVdFloat32)
|
||||
bigenHelper{e.b[:4], e.w}.writeUint32(math.Float32bits(f))
|
||||
}
|
||||
|
||||
func (e *simpleEncDriver) EncodeFloat64(f float64) {
|
||||
if e.h.EncZeroValuesAsNil && e.c != containerMapKey && f == 0.0 {
|
||||
e.EncodeNil()
|
||||
return
|
||||
}
|
||||
e.w.writen1(simpleVdFloat64)
|
||||
bigenHelper{e.b[:8], e.w}.writeUint64(math.Float64bits(f))
|
||||
}
|
||||
|
||||
func (e *simpleEncDriver) EncodeInt(v int64) {
|
||||
if v < 0 {
|
||||
e.encUint(uint64(-v), simpleVdNegInt)
|
||||
} else {
|
||||
e.encUint(uint64(v), simpleVdPosInt)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *simpleEncDriver) EncodeUint(v uint64) {
|
||||
e.encUint(v, simpleVdPosInt)
|
||||
}
|
||||
|
||||
func (e *simpleEncDriver) encUint(v uint64, bd uint8) {
|
||||
if e.h.EncZeroValuesAsNil && e.c != containerMapKey && v == 0 {
|
||||
e.EncodeNil()
|
||||
return
|
||||
}
|
||||
if v <= math.MaxUint8 {
|
||||
e.w.writen2(bd, uint8(v))
|
||||
} else if v <= math.MaxUint16 {
|
||||
e.w.writen1(bd + 1)
|
||||
bigenHelper{e.b[:2], e.w}.writeUint16(uint16(v))
|
||||
} else if v <= math.MaxUint32 {
|
||||
e.w.writen1(bd + 2)
|
||||
bigenHelper{e.b[:4], e.w}.writeUint32(uint32(v))
|
||||
} else { // if v <= math.MaxUint64 {
|
||||
e.w.writen1(bd + 3)
|
||||
bigenHelper{e.b[:8], e.w}.writeUint64(v)
|
||||
}
|
||||
}
|
||||
|
||||
func (e *simpleEncDriver) encLen(bd byte, length int) {
|
||||
if length == 0 {
|
||||
e.w.writen1(bd)
|
||||
} else if length <= math.MaxUint8 {
|
||||
e.w.writen1(bd + 1)
|
||||
e.w.writen1(uint8(length))
|
||||
} else if length <= math.MaxUint16 {
|
||||
e.w.writen1(bd + 2)
|
||||
bigenHelper{e.b[:2], e.w}.writeUint16(uint16(length))
|
||||
} else if int64(length) <= math.MaxUint32 {
|
||||
e.w.writen1(bd + 3)
|
||||
bigenHelper{e.b[:4], e.w}.writeUint32(uint32(length))
|
||||
} else {
|
||||
e.w.writen1(bd + 4)
|
||||
bigenHelper{e.b[:8], e.w}.writeUint64(uint64(length))
|
||||
}
|
||||
}
|
||||
|
||||
func (e *simpleEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, _ *Encoder) {
|
||||
bs := ext.WriteExt(rv)
|
||||
if bs == nil {
|
||||
e.EncodeNil()
|
||||
return
|
||||
}
|
||||
e.encodeExtPreamble(uint8(xtag), len(bs))
|
||||
e.w.writeb(bs)
|
||||
}
|
||||
|
||||
func (e *simpleEncDriver) EncodeRawExt(re *RawExt, _ *Encoder) {
|
||||
e.encodeExtPreamble(uint8(re.Tag), len(re.Data))
|
||||
e.w.writeb(re.Data)
|
||||
}
|
||||
|
||||
func (e *simpleEncDriver) encodeExtPreamble(xtag byte, length int) {
|
||||
e.encLen(simpleVdExt, length)
|
||||
e.w.writen1(xtag)
|
||||
}
|
||||
|
||||
func (e *simpleEncDriver) WriteArrayStart(length int) {
|
||||
e.c = containerArrayStart
|
||||
e.encLen(simpleVdArray, length)
|
||||
}
|
||||
|
||||
func (e *simpleEncDriver) WriteMapStart(length int) {
|
||||
e.c = containerMapStart
|
||||
e.encLen(simpleVdMap, length)
|
||||
}
|
||||
|
||||
func (e *simpleEncDriver) EncodeString(c charEncoding, v string) {
|
||||
if false && e.h.EncZeroValuesAsNil && e.c != containerMapKey && v == "" {
|
||||
e.EncodeNil()
|
||||
return
|
||||
}
|
||||
e.encLen(simpleVdString, len(v))
|
||||
e.w.writestr(v)
|
||||
}
|
||||
|
||||
// func (e *simpleEncDriver) EncodeSymbol(v string) {
|
||||
// e.EncodeString(cUTF8, v)
|
||||
// }
|
||||
|
||||
func (e *simpleEncDriver) EncodeStringBytes(c charEncoding, v []byte) {
|
||||
// if e.h.EncZeroValuesAsNil && e.c != containerMapKey && v == nil {
|
||||
if v == nil {
|
||||
e.EncodeNil()
|
||||
return
|
||||
}
|
||||
e.encLen(simpleVdByteArray, len(v))
|
||||
e.w.writeb(v)
|
||||
}
|
||||
|
||||
func (e *simpleEncDriver) EncodeTime(t time.Time) {
|
||||
// if e.h.EncZeroValuesAsNil && e.c != containerMapKey && t.IsZero() {
|
||||
if t.IsZero() {
|
||||
e.EncodeNil()
|
||||
return
|
||||
}
|
||||
v, err := t.MarshalBinary()
|
||||
if err != nil {
|
||||
e.e.errorv(err)
|
||||
return
|
||||
}
|
||||
// time.Time marshalbinary takes about 14 bytes.
|
||||
e.w.writen2(simpleVdTime, uint8(len(v)))
|
||||
e.w.writeb(v)
|
||||
}
|
||||
|
||||
//------------------------------------
|
||||
|
||||
type simpleDecDriver struct {
|
||||
d *Decoder
|
||||
h *SimpleHandle
|
||||
r decReader
|
||||
bdRead bool
|
||||
bd byte
|
||||
br bool // a bytes reader?
|
||||
c containerState
|
||||
// b [scratchByteArrayLen]byte
|
||||
noBuiltInTypes
|
||||
// noStreamingCodec
|
||||
decDriverNoopContainerReader
|
||||
_ [3]uint64 // padding
|
||||
}
|
||||
|
||||
func (d *simpleDecDriver) readNextBd() {
|
||||
d.bd = d.r.readn1()
|
||||
d.bdRead = true
|
||||
}
|
||||
|
||||
func (d *simpleDecDriver) uncacheRead() {
|
||||
if d.bdRead {
|
||||
d.r.unreadn1()
|
||||
d.bdRead = false
|
||||
}
|
||||
}
|
||||
|
||||
func (d *simpleDecDriver) ContainerType() (vt valueType) {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
switch d.bd {
|
||||
case simpleVdNil:
|
||||
return valueTypeNil
|
||||
case simpleVdByteArray, simpleVdByteArray + 1,
|
||||
simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4:
|
||||
return valueTypeBytes
|
||||
case simpleVdString, simpleVdString + 1,
|
||||
simpleVdString + 2, simpleVdString + 3, simpleVdString + 4:
|
||||
return valueTypeString
|
||||
case simpleVdArray, simpleVdArray + 1,
|
||||
simpleVdArray + 2, simpleVdArray + 3, simpleVdArray + 4:
|
||||
return valueTypeArray
|
||||
case simpleVdMap, simpleVdMap + 1,
|
||||
simpleVdMap + 2, simpleVdMap + 3, simpleVdMap + 4:
|
||||
return valueTypeMap
|
||||
// case simpleVdTime:
|
||||
// return valueTypeTime
|
||||
}
|
||||
// else {
|
||||
// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
|
||||
// }
|
||||
return valueTypeUnset
|
||||
}
|
||||
|
||||
func (d *simpleDecDriver) TryDecodeAsNil() bool {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
if d.bd == simpleVdNil {
|
||||
d.bdRead = false
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (d *simpleDecDriver) decCheckInteger() (ui uint64, neg bool) {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
switch d.bd {
|
||||
case simpleVdPosInt:
|
||||
ui = uint64(d.r.readn1())
|
||||
case simpleVdPosInt + 1:
|
||||
ui = uint64(bigen.Uint16(d.r.readx(2)))
|
||||
case simpleVdPosInt + 2:
|
||||
ui = uint64(bigen.Uint32(d.r.readx(4)))
|
||||
case simpleVdPosInt + 3:
|
||||
ui = uint64(bigen.Uint64(d.r.readx(8)))
|
||||
case simpleVdNegInt:
|
||||
ui = uint64(d.r.readn1())
|
||||
neg = true
|
||||
case simpleVdNegInt + 1:
|
||||
ui = uint64(bigen.Uint16(d.r.readx(2)))
|
||||
neg = true
|
||||
case simpleVdNegInt + 2:
|
||||
ui = uint64(bigen.Uint32(d.r.readx(4)))
|
||||
neg = true
|
||||
case simpleVdNegInt + 3:
|
||||
ui = uint64(bigen.Uint64(d.r.readx(8)))
|
||||
neg = true
|
||||
default:
|
||||
d.d.errorf("integer only valid from pos/neg integer1..8. Invalid descriptor: %v", d.bd)
|
||||
return
|
||||
}
|
||||
// don't do this check, because callers may only want the unsigned value.
|
||||
// if ui > math.MaxInt64 {
|
||||
// d.d.errorf("decIntAny: Integer out of range for signed int64: %v", ui)
|
||||
// return
|
||||
// }
|
||||
return
|
||||
}
|
||||
|
||||
func (d *simpleDecDriver) DecodeInt64() (i int64) {
|
||||
ui, neg := d.decCheckInteger()
|
||||
i = chkOvf.SignedIntV(ui)
|
||||
if neg {
|
||||
i = -i
|
||||
}
|
||||
d.bdRead = false
|
||||
return
|
||||
}
|
||||
|
||||
func (d *simpleDecDriver) DecodeUint64() (ui uint64) {
|
||||
ui, neg := d.decCheckInteger()
|
||||
if neg {
|
||||
d.d.errorf("assigning negative signed value to unsigned type")
|
||||
return
|
||||
}
|
||||
d.bdRead = false
|
||||
return
|
||||
}
|
||||
|
||||
func (d *simpleDecDriver) DecodeFloat64() (f float64) {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
if d.bd == simpleVdFloat32 {
|
||||
f = float64(math.Float32frombits(bigen.Uint32(d.r.readx(4))))
|
||||
} else if d.bd == simpleVdFloat64 {
|
||||
f = math.Float64frombits(bigen.Uint64(d.r.readx(8)))
|
||||
} else {
|
||||
if d.bd >= simpleVdPosInt && d.bd <= simpleVdNegInt+3 {
|
||||
f = float64(d.DecodeInt64())
|
||||
} else {
|
||||
d.d.errorf("float only valid from float32/64: Invalid descriptor: %v", d.bd)
|
||||
return
|
||||
}
|
||||
}
|
||||
d.bdRead = false
|
||||
return
|
||||
}
|
||||
|
||||
// bool can be decoded from bool only (single byte).
|
||||
func (d *simpleDecDriver) DecodeBool() (b bool) {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
if d.bd == simpleVdTrue {
|
||||
b = true
|
||||
} else if d.bd == simpleVdFalse {
|
||||
} else {
|
||||
d.d.errorf("cannot decode bool - %s: %x", msgBadDesc, d.bd)
|
||||
return
|
||||
}
|
||||
d.bdRead = false
|
||||
return
|
||||
}
|
||||
|
||||
func (d *simpleDecDriver) ReadMapStart() (length int) {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
d.bdRead = false
|
||||
d.c = containerMapStart
|
||||
return d.decLen()
|
||||
}
|
||||
|
||||
func (d *simpleDecDriver) ReadArrayStart() (length int) {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
d.bdRead = false
|
||||
d.c = containerArrayStart
|
||||
return d.decLen()
|
||||
}
|
||||
|
||||
func (d *simpleDecDriver) ReadArrayElem() {
|
||||
d.c = containerArrayElem
|
||||
}
|
||||
|
||||
func (d *simpleDecDriver) ReadArrayEnd() {
|
||||
d.c = containerArrayEnd
|
||||
}
|
||||
|
||||
func (d *simpleDecDriver) ReadMapElemKey() {
|
||||
d.c = containerMapKey
|
||||
}
|
||||
|
||||
func (d *simpleDecDriver) ReadMapElemValue() {
|
||||
d.c = containerMapValue
|
||||
}
|
||||
|
||||
func (d *simpleDecDriver) ReadMapEnd() {
|
||||
d.c = containerMapEnd
|
||||
}
|
||||
|
||||
func (d *simpleDecDriver) decLen() int {
|
||||
switch d.bd % 8 {
|
||||
case 0:
|
||||
return 0
|
||||
case 1:
|
||||
return int(d.r.readn1())
|
||||
case 2:
|
||||
return int(bigen.Uint16(d.r.readx(2)))
|
||||
case 3:
|
||||
ui := uint64(bigen.Uint32(d.r.readx(4)))
|
||||
if chkOvf.Uint(ui, intBitsize) {
|
||||
d.d.errorf("overflow integer: %v", ui)
|
||||
return 0
|
||||
}
|
||||
return int(ui)
|
||||
case 4:
|
||||
ui := bigen.Uint64(d.r.readx(8))
|
||||
if chkOvf.Uint(ui, intBitsize) {
|
||||
d.d.errorf("overflow integer: %v", ui)
|
||||
return 0
|
||||
}
|
||||
return int(ui)
|
||||
}
|
||||
d.d.errorf("cannot read length: bd%%8 must be in range 0..4. Got: %d", d.bd%8)
|
||||
return -1
|
||||
}
|
||||
|
||||
func (d *simpleDecDriver) DecodeString() (s string) {
|
||||
return string(d.DecodeBytes(d.d.b[:], true))
|
||||
}
|
||||
|
||||
func (d *simpleDecDriver) DecodeStringAsBytes() (s []byte) {
|
||||
return d.DecodeBytes(d.d.b[:], true)
|
||||
}
|
||||
|
||||
func (d *simpleDecDriver) DecodeBytes(bs []byte, zerocopy bool) (bsOut []byte) {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
if d.bd == simpleVdNil {
|
||||
d.bdRead = false
|
||||
return
|
||||
}
|
||||
// check if an "array" of uint8's (see ContainerType for how to infer if an array)
|
||||
if d.bd >= simpleVdArray && d.bd <= simpleVdMap+4 {
|
||||
if len(bs) == 0 && zerocopy {
|
||||
bs = d.d.b[:]
|
||||
}
|
||||
bsOut, _ = fastpathTV.DecSliceUint8V(bs, true, d.d)
|
||||
return
|
||||
}
|
||||
|
||||
clen := d.decLen()
|
||||
d.bdRead = false
|
||||
if zerocopy {
|
||||
if d.br {
|
||||
return d.r.readx(clen)
|
||||
} else if len(bs) == 0 {
|
||||
bs = d.d.b[:]
|
||||
}
|
||||
}
|
||||
return decByteSlice(d.r, clen, d.d.h.MaxInitLen, bs)
|
||||
}
|
||||
|
||||
func (d *simpleDecDriver) DecodeTime() (t time.Time) {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
if d.bd == simpleVdNil {
|
||||
d.bdRead = false
|
||||
return
|
||||
}
|
||||
if d.bd != simpleVdTime {
|
||||
d.d.errorf("invalid descriptor for time.Time - expect 0x%x, received 0x%x", simpleVdTime, d.bd)
|
||||
return
|
||||
}
|
||||
d.bdRead = false
|
||||
clen := int(d.r.readn1())
|
||||
b := d.r.readx(clen)
|
||||
if err := (&t).UnmarshalBinary(b); err != nil {
|
||||
d.d.errorv(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *simpleDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) {
|
||||
if xtag > 0xff {
|
||||
d.d.errorf("ext: tag must be <= 0xff; got: %v", xtag)
|
||||
return
|
||||
}
|
||||
realxtag1, xbs := d.decodeExtV(ext != nil, uint8(xtag))
|
||||
realxtag = uint64(realxtag1)
|
||||
if ext == nil {
|
||||
re := rv.(*RawExt)
|
||||
re.Tag = realxtag
|
||||
re.Data = detachZeroCopyBytes(d.br, re.Data, xbs)
|
||||
} else {
|
||||
ext.ReadExt(rv, xbs)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (d *simpleDecDriver) decodeExtV(verifyTag bool, tag byte) (xtag byte, xbs []byte) {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
switch d.bd {
|
||||
case simpleVdExt, simpleVdExt + 1, simpleVdExt + 2, simpleVdExt + 3, simpleVdExt + 4:
|
||||
l := d.decLen()
|
||||
xtag = d.r.readn1()
|
||||
if verifyTag && xtag != tag {
|
||||
d.d.errorf("wrong extension tag. Got %b. Expecting: %v", xtag, tag)
|
||||
return
|
||||
}
|
||||
xbs = d.r.readx(l)
|
||||
case simpleVdByteArray, simpleVdByteArray + 1,
|
||||
simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4:
|
||||
xbs = d.DecodeBytes(nil, true)
|
||||
default:
|
||||
d.d.errorf("ext - %s - expecting extensions/bytearray, got: 0x%x", msgBadDesc, d.bd)
|
||||
return
|
||||
}
|
||||
d.bdRead = false
|
||||
return
|
||||
}
|
||||
|
||||
func (d *simpleDecDriver) DecodeNaked() {
|
||||
if !d.bdRead {
|
||||
d.readNextBd()
|
||||
}
|
||||
|
||||
n := d.d.n
|
||||
var decodeFurther bool
|
||||
|
||||
switch d.bd {
|
||||
case simpleVdNil:
|
||||
n.v = valueTypeNil
|
||||
case simpleVdFalse:
|
||||
n.v = valueTypeBool
|
||||
n.b = false
|
||||
case simpleVdTrue:
|
||||
n.v = valueTypeBool
|
||||
n.b = true
|
||||
case simpleVdPosInt, simpleVdPosInt + 1, simpleVdPosInt + 2, simpleVdPosInt + 3:
|
||||
if d.h.SignedInteger {
|
||||
n.v = valueTypeInt
|
||||
n.i = d.DecodeInt64()
|
||||
} else {
|
||||
n.v = valueTypeUint
|
||||
n.u = d.DecodeUint64()
|
||||
}
|
||||
case simpleVdNegInt, simpleVdNegInt + 1, simpleVdNegInt + 2, simpleVdNegInt + 3:
|
||||
n.v = valueTypeInt
|
||||
n.i = d.DecodeInt64()
|
||||
case simpleVdFloat32:
|
||||
n.v = valueTypeFloat
|
||||
n.f = d.DecodeFloat64()
|
||||
case simpleVdFloat64:
|
||||
n.v = valueTypeFloat
|
||||
n.f = d.DecodeFloat64()
|
||||
case simpleVdTime:
|
||||
n.v = valueTypeTime
|
||||
n.t = d.DecodeTime()
|
||||
case simpleVdString, simpleVdString + 1,
|
||||
simpleVdString + 2, simpleVdString + 3, simpleVdString + 4:
|
||||
n.v = valueTypeString
|
||||
n.s = d.DecodeString()
|
||||
case simpleVdByteArray, simpleVdByteArray + 1,
|
||||
simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4:
|
||||
n.v = valueTypeBytes
|
||||
n.l = d.DecodeBytes(nil, false)
|
||||
case simpleVdExt, simpleVdExt + 1, simpleVdExt + 2, simpleVdExt + 3, simpleVdExt + 4:
|
||||
n.v = valueTypeExt
|
||||
l := d.decLen()
|
||||
n.u = uint64(d.r.readn1())
|
||||
n.l = d.r.readx(l)
|
||||
case simpleVdArray, simpleVdArray + 1, simpleVdArray + 2,
|
||||
simpleVdArray + 3, simpleVdArray + 4:
|
||||
n.v = valueTypeArray
|
||||
decodeFurther = true
|
||||
case simpleVdMap, simpleVdMap + 1, simpleVdMap + 2, simpleVdMap + 3, simpleVdMap + 4:
|
||||
n.v = valueTypeMap
|
||||
decodeFurther = true
|
||||
default:
|
||||
d.d.errorf("cannot infer value - %s 0x%x", msgBadDesc, d.bd)
|
||||
}
|
||||
|
||||
if !decodeFurther {
|
||||
d.bdRead = false
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
//------------------------------------
|
||||
|
||||
// SimpleHandle is a Handle for a very simple encoding format.
|
||||
//
|
||||
// simple is a simplistic codec similar to binc, but not as compact.
|
||||
// - Encoding of a value is always preceded by the descriptor byte (bd)
|
||||
// - True, false, nil are encoded fully in 1 byte (the descriptor)
|
||||
// - Integers (intXXX, uintXXX) are encoded in 1, 2, 4 or 8 bytes (plus a descriptor byte).
|
||||
// There are positive (uintXXX and intXXX >= 0) and negative (intXXX < 0) integers.
|
||||
// - Floats are encoded in 4 or 8 bytes (plus a descriptor byte)
|
||||
// - Length of containers (strings, bytes, array, map, extensions)
|
||||
// are encoded in 0, 1, 2, 4 or 8 bytes.
|
||||
// Zero-length containers have no length encoded.
|
||||
// For others, the number of bytes is given by pow(2, bd%3)
|
||||
// - maps are encoded as [bd] [length] [[key][value]]...
|
||||
// - arrays are encoded as [bd] [length] [value]...
|
||||
// - extensions are encoded as [bd] [length] [tag] [byte]...
|
||||
// - strings/bytearrays are encoded as [bd] [length] [byte]...
|
||||
// - time.Time are encoded as [bd] [length] [byte]...
|
||||
//
|
||||
// The full spec will be published soon.
|
||||
type SimpleHandle struct {
|
||||
BasicHandle
|
||||
binaryEncodingType
|
||||
noElemSeparators
|
||||
// EncZeroValuesAsNil says to encode zero values for numbers, bool, string, etc as nil
|
||||
EncZeroValuesAsNil bool
|
||||
|
||||
// _ [1]uint64 // padding
|
||||
}
|
||||
|
||||
// Name returns the name of the handle: simple
|
||||
func (h *SimpleHandle) Name() string { return "simple" }
|
||||
|
||||
// SetBytesExt sets an extension
|
||||
func (h *SimpleHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) {
|
||||
return h.SetExt(rt, tag, &extWrapper{ext, interfaceExtFailer{}})
|
||||
}
|
||||
|
||||
func (h *SimpleHandle) hasElemSeparators() bool { return true } // as it implements Write(Map|Array)XXX
|
||||
|
||||
func (h *SimpleHandle) newEncDriver(e *Encoder) encDriver {
|
||||
return &simpleEncDriver{e: e, w: e.w, h: h}
|
||||
}
|
||||
|
||||
func (h *SimpleHandle) newDecDriver(d *Decoder) decDriver {
|
||||
return &simpleDecDriver{d: d, h: h, r: d.r, br: d.bytes}
|
||||
}
|
||||
|
||||
func (e *simpleEncDriver) reset() {
|
||||
e.c = 0
|
||||
e.w = e.e.w
|
||||
}
|
||||
|
||||
func (d *simpleDecDriver) reset() {
|
||||
d.c = 0
|
||||
d.r, d.br = d.d.r, d.d.bytes
|
||||
d.bd, d.bdRead = 0, false
|
||||
}
|
||||
|
||||
var _ decDriver = (*simpleDecDriver)(nil)
|
||||
var _ encDriver = (*simpleEncDriver)(nil)
|
||||
639
vendor/github.com/ugorji/go/codec/test-cbor-goldens.json
generated
vendored
Normal file
639
vendor/github.com/ugorji/go/codec/test-cbor-goldens.json
generated
vendored
Normal file
|
|
@ -0,0 +1,639 @@
|
|||
[
|
||||
{
|
||||
"cbor": "AA==",
|
||||
"hex": "00",
|
||||
"roundtrip": true,
|
||||
"decoded": 0
|
||||
},
|
||||
{
|
||||
"cbor": "AQ==",
|
||||
"hex": "01",
|
||||
"roundtrip": true,
|
||||
"decoded": 1
|
||||
},
|
||||
{
|
||||
"cbor": "Cg==",
|
||||
"hex": "0a",
|
||||
"roundtrip": true,
|
||||
"decoded": 10
|
||||
},
|
||||
{
|
||||
"cbor": "Fw==",
|
||||
"hex": "17",
|
||||
"roundtrip": true,
|
||||
"decoded": 23
|
||||
},
|
||||
{
|
||||
"cbor": "GBg=",
|
||||
"hex": "1818",
|
||||
"roundtrip": true,
|
||||
"decoded": 24
|
||||
},
|
||||
{
|
||||
"cbor": "GBk=",
|
||||
"hex": "1819",
|
||||
"roundtrip": true,
|
||||
"decoded": 25
|
||||
},
|
||||
{
|
||||
"cbor": "GGQ=",
|
||||
"hex": "1864",
|
||||
"roundtrip": true,
|
||||
"decoded": 100
|
||||
},
|
||||
{
|
||||
"cbor": "GQPo",
|
||||
"hex": "1903e8",
|
||||
"roundtrip": true,
|
||||
"decoded": 1000
|
||||
},
|
||||
{
|
||||
"cbor": "GgAPQkA=",
|
||||
"hex": "1a000f4240",
|
||||
"roundtrip": true,
|
||||
"decoded": 1000000
|
||||
},
|
||||
{
|
||||
"cbor": "GwAAAOjUpRAA",
|
||||
"hex": "1b000000e8d4a51000",
|
||||
"roundtrip": true,
|
||||
"decoded": 1000000000000
|
||||
},
|
||||
{
|
||||
"cbor": "G///////////",
|
||||
"hex": "1bffffffffffffffff",
|
||||
"roundtrip": true,
|
||||
"decoded": 18446744073709551615
|
||||
},
|
||||
{
|
||||
"cbor": "wkkBAAAAAAAAAAA=",
|
||||
"hex": "c249010000000000000000",
|
||||
"roundtrip": true,
|
||||
"decoded": 18446744073709551616
|
||||
},
|
||||
{
|
||||
"cbor": "O///////////",
|
||||
"hex": "3bffffffffffffffff",
|
||||
"roundtrip": true,
|
||||
"decoded": -18446744073709551616,
|
||||
"skip": true
|
||||
},
|
||||
{
|
||||
"cbor": "w0kBAAAAAAAAAAA=",
|
||||
"hex": "c349010000000000000000",
|
||||
"roundtrip": true,
|
||||
"decoded": -18446744073709551617
|
||||
},
|
||||
{
|
||||
"cbor": "IA==",
|
||||
"hex": "20",
|
||||
"roundtrip": true,
|
||||
"decoded": -1
|
||||
},
|
||||
{
|
||||
"cbor": "KQ==",
|
||||
"hex": "29",
|
||||
"roundtrip": true,
|
||||
"decoded": -10
|
||||
},
|
||||
{
|
||||
"cbor": "OGM=",
|
||||
"hex": "3863",
|
||||
"roundtrip": true,
|
||||
"decoded": -100
|
||||
},
|
||||
{
|
||||
"cbor": "OQPn",
|
||||
"hex": "3903e7",
|
||||
"roundtrip": true,
|
||||
"decoded": -1000
|
||||
},
|
||||
{
|
||||
"cbor": "+QAA",
|
||||
"hex": "f90000",
|
||||
"roundtrip": true,
|
||||
"decoded": 0.0
|
||||
},
|
||||
{
|
||||
"cbor": "+YAA",
|
||||
"hex": "f98000",
|
||||
"roundtrip": true,
|
||||
"decoded": -0.0
|
||||
},
|
||||
{
|
||||
"cbor": "+TwA",
|
||||
"hex": "f93c00",
|
||||
"roundtrip": true,
|
||||
"decoded": 1.0
|
||||
},
|
||||
{
|
||||
"cbor": "+z/xmZmZmZma",
|
||||
"hex": "fb3ff199999999999a",
|
||||
"roundtrip": true,
|
||||
"decoded": 1.1
|
||||
},
|
||||
{
|
||||
"cbor": "+T4A",
|
||||
"hex": "f93e00",
|
||||
"roundtrip": true,
|
||||
"decoded": 1.5
|
||||
},
|
||||
{
|
||||
"cbor": "+Xv/",
|
||||
"hex": "f97bff",
|
||||
"roundtrip": true,
|
||||
"decoded": 65504.0
|
||||
},
|
||||
{
|
||||
"cbor": "+kfDUAA=",
|
||||
"hex": "fa47c35000",
|
||||
"roundtrip": true,
|
||||
"decoded": 100000.0
|
||||
},
|
||||
{
|
||||
"cbor": "+n9///8=",
|
||||
"hex": "fa7f7fffff",
|
||||
"roundtrip": true,
|
||||
"decoded": 3.4028234663852886e+38
|
||||
},
|
||||
{
|
||||
"cbor": "+3435DyIAHWc",
|
||||
"hex": "fb7e37e43c8800759c",
|
||||
"roundtrip": true,
|
||||
"decoded": 1.0e+300
|
||||
},
|
||||
{
|
||||
"cbor": "+QAB",
|
||||
"hex": "f90001",
|
||||
"roundtrip": true,
|
||||
"decoded": 5.960464477539063e-08
|
||||
},
|
||||
{
|
||||
"cbor": "+QQA",
|
||||
"hex": "f90400",
|
||||
"roundtrip": true,
|
||||
"decoded": 6.103515625e-05
|
||||
},
|
||||
{
|
||||
"cbor": "+cQA",
|
||||
"hex": "f9c400",
|
||||
"roundtrip": true,
|
||||
"decoded": -4.0
|
||||
},
|
||||
{
|
||||
"cbor": "+8AQZmZmZmZm",
|
||||
"hex": "fbc010666666666666",
|
||||
"roundtrip": true,
|
||||
"decoded": -4.1
|
||||
},
|
||||
{
|
||||
"cbor": "+XwA",
|
||||
"hex": "f97c00",
|
||||
"roundtrip": true,
|
||||
"diagnostic": "Infinity"
|
||||
},
|
||||
{
|
||||
"cbor": "+X4A",
|
||||
"hex": "f97e00",
|
||||
"roundtrip": true,
|
||||
"diagnostic": "NaN"
|
||||
},
|
||||
{
|
||||
"cbor": "+fwA",
|
||||
"hex": "f9fc00",
|
||||
"roundtrip": true,
|
||||
"diagnostic": "-Infinity"
|
||||
},
|
||||
{
|
||||
"cbor": "+n+AAAA=",
|
||||
"hex": "fa7f800000",
|
||||
"roundtrip": false,
|
||||
"diagnostic": "Infinity"
|
||||
},
|
||||
{
|
||||
"cbor": "+n/AAAA=",
|
||||
"hex": "fa7fc00000",
|
||||
"roundtrip": false,
|
||||
"diagnostic": "NaN"
|
||||
},
|
||||
{
|
||||
"cbor": "+v+AAAA=",
|
||||
"hex": "faff800000",
|
||||
"roundtrip": false,
|
||||
"diagnostic": "-Infinity"
|
||||
},
|
||||
{
|
||||
"cbor": "+3/wAAAAAAAA",
|
||||
"hex": "fb7ff0000000000000",
|
||||
"roundtrip": false,
|
||||
"diagnostic": "Infinity"
|
||||
},
|
||||
{
|
||||
"cbor": "+3/4AAAAAAAA",
|
||||
"hex": "fb7ff8000000000000",
|
||||
"roundtrip": false,
|
||||
"diagnostic": "NaN"
|
||||
},
|
||||
{
|
||||
"cbor": "+//wAAAAAAAA",
|
||||
"hex": "fbfff0000000000000",
|
||||
"roundtrip": false,
|
||||
"diagnostic": "-Infinity"
|
||||
},
|
||||
{
|
||||
"cbor": "9A==",
|
||||
"hex": "f4",
|
||||
"roundtrip": true,
|
||||
"decoded": false
|
||||
},
|
||||
{
|
||||
"cbor": "9Q==",
|
||||
"hex": "f5",
|
||||
"roundtrip": true,
|
||||
"decoded": true
|
||||
},
|
||||
{
|
||||
"cbor": "9g==",
|
||||
"hex": "f6",
|
||||
"roundtrip": true,
|
||||
"decoded": null
|
||||
},
|
||||
{
|
||||
"cbor": "9w==",
|
||||
"hex": "f7",
|
||||
"roundtrip": true,
|
||||
"diagnostic": "undefined"
|
||||
},
|
||||
{
|
||||
"cbor": "8A==",
|
||||
"hex": "f0",
|
||||
"roundtrip": true,
|
||||
"diagnostic": "simple(16)"
|
||||
},
|
||||
{
|
||||
"cbor": "+Bg=",
|
||||
"hex": "f818",
|
||||
"roundtrip": true,
|
||||
"diagnostic": "simple(24)"
|
||||
},
|
||||
{
|
||||
"cbor": "+P8=",
|
||||
"hex": "f8ff",
|
||||
"roundtrip": true,
|
||||
"diagnostic": "simple(255)"
|
||||
},
|
||||
{
|
||||
"cbor": "wHQyMDEzLTAzLTIxVDIwOjA0OjAwWg==",
|
||||
"hex": "c074323031332d30332d32315432303a30343a30305a",
|
||||
"roundtrip": true,
|
||||
"diagnostic": "0(\"2013-03-21T20:04:00Z\")"
|
||||
},
|
||||
{
|
||||
"cbor": "wRpRS2ew",
|
||||
"hex": "c11a514b67b0",
|
||||
"roundtrip": true,
|
||||
"diagnostic": "1(1363896240)"
|
||||
},
|
||||
{
|
||||
"cbor": "wftB1FLZ7CAAAA==",
|
||||
"hex": "c1fb41d452d9ec200000",
|
||||
"roundtrip": true,
|
||||
"diagnostic": "1(1363896240.5)"
|
||||
},
|
||||
{
|
||||
"cbor": "10QBAgME",
|
||||
"hex": "d74401020304",
|
||||
"roundtrip": true,
|
||||
"diagnostic": "23(h'01020304')"
|
||||
},
|
||||
{
|
||||
"cbor": "2BhFZElFVEY=",
|
||||
"hex": "d818456449455446",
|
||||
"roundtrip": true,
|
||||
"diagnostic": "24(h'6449455446')"
|
||||
},
|
||||
{
|
||||
"cbor": "2CB2aHR0cDovL3d3dy5leGFtcGxlLmNvbQ==",
|
||||
"hex": "d82076687474703a2f2f7777772e6578616d706c652e636f6d",
|
||||
"roundtrip": true,
|
||||
"diagnostic": "32(\"http://www.example.com\")"
|
||||
},
|
||||
{
|
||||
"cbor": "QA==",
|
||||
"hex": "40",
|
||||
"roundtrip": true,
|
||||
"diagnostic": "h''"
|
||||
},
|
||||
{
|
||||
"cbor": "RAECAwQ=",
|
||||
"hex": "4401020304",
|
||||
"roundtrip": true,
|
||||
"diagnostic": "h'01020304'"
|
||||
},
|
||||
{
|
||||
"cbor": "YA==",
|
||||
"hex": "60",
|
||||
"roundtrip": true,
|
||||
"decoded": ""
|
||||
},
|
||||
{
|
||||
"cbor": "YWE=",
|
||||
"hex": "6161",
|
||||
"roundtrip": true,
|
||||
"decoded": "a"
|
||||
},
|
||||
{
|
||||
"cbor": "ZElFVEY=",
|
||||
"hex": "6449455446",
|
||||
"roundtrip": true,
|
||||
"decoded": "IETF"
|
||||
},
|
||||
{
|
||||
"cbor": "YiJc",
|
||||
"hex": "62225c",
|
||||
"roundtrip": true,
|
||||
"decoded": "\"\\"
|
||||
},
|
||||
{
|
||||
"cbor": "YsO8",
|
||||
"hex": "62c3bc",
|
||||
"roundtrip": true,
|
||||
"decoded": "ü"
|
||||
},
|
||||
{
|
||||
"cbor": "Y+awtA==",
|
||||
"hex": "63e6b0b4",
|
||||
"roundtrip": true,
|
||||
"decoded": "水"
|
||||
},
|
||||
{
|
||||
"cbor": "ZPCQhZE=",
|
||||
"hex": "64f0908591",
|
||||
"roundtrip": true,
|
||||
"decoded": "𐅑"
|
||||
},
|
||||
{
|
||||
"cbor": "gA==",
|
||||
"hex": "80",
|
||||
"roundtrip": true,
|
||||
"decoded": [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"cbor": "gwECAw==",
|
||||
"hex": "83010203",
|
||||
"roundtrip": true,
|
||||
"decoded": [
|
||||
1,
|
||||
2,
|
||||
3
|
||||
]
|
||||
},
|
||||
{
|
||||
"cbor": "gwGCAgOCBAU=",
|
||||
"hex": "8301820203820405",
|
||||
"roundtrip": true,
|
||||
"decoded": [
|
||||
1,
|
||||
[
|
||||
2,
|
||||
3
|
||||
],
|
||||
[
|
||||
4,
|
||||
5
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"cbor": "mBkBAgMEBQYHCAkKCwwNDg8QERITFBUWFxgYGBk=",
|
||||
"hex": "98190102030405060708090a0b0c0d0e0f101112131415161718181819",
|
||||
"roundtrip": true,
|
||||
"decoded": [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
23,
|
||||
24,
|
||||
25
|
||||
]
|
||||
},
|
||||
{
|
||||
"cbor": "oA==",
|
||||
"hex": "a0",
|
||||
"roundtrip": true,
|
||||
"decoded": {
|
||||
}
|
||||
},
|
||||
{
|
||||
"cbor": "ogECAwQ=",
|
||||
"hex": "a201020304",
|
||||
"roundtrip": true,
|
||||
"skip": true,
|
||||
"diagnostic": "{1: 2, 3: 4}"
|
||||
},
|
||||
{
|
||||
"cbor": "omFhAWFiggID",
|
||||
"hex": "a26161016162820203",
|
||||
"roundtrip": true,
|
||||
"decoded": {
|
||||
"a": 1,
|
||||
"b": [
|
||||
2,
|
||||
3
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"cbor": "gmFhoWFiYWM=",
|
||||
"hex": "826161a161626163",
|
||||
"roundtrip": true,
|
||||
"decoded": [
|
||||
"a",
|
||||
{
|
||||
"b": "c"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cbor": "pWFhYUFhYmFCYWNhQ2FkYURhZWFF",
|
||||
"hex": "a56161614161626142616361436164614461656145",
|
||||
"roundtrip": true,
|
||||
"decoded": {
|
||||
"a": "A",
|
||||
"b": "B",
|
||||
"c": "C",
|
||||
"d": "D",
|
||||
"e": "E"
|
||||
}
|
||||
},
|
||||
{
|
||||
"cbor": "X0IBAkMDBAX/",
|
||||
"hex": "5f42010243030405ff",
|
||||
"roundtrip": false,
|
||||
"skip": true,
|
||||
"diagnostic": "(_ h'0102', h'030405')"
|
||||
},
|
||||
{
|
||||
"cbor": "f2VzdHJlYWRtaW5n/w==",
|
||||
"hex": "7f657374726561646d696e67ff",
|
||||
"roundtrip": false,
|
||||
"decoded": "streaming"
|
||||
},
|
||||
{
|
||||
"cbor": "n/8=",
|
||||
"hex": "9fff",
|
||||
"roundtrip": false,
|
||||
"decoded": [
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"cbor": "nwGCAgOfBAX//w==",
|
||||
"hex": "9f018202039f0405ffff",
|
||||
"roundtrip": false,
|
||||
"decoded": [
|
||||
1,
|
||||
[
|
||||
2,
|
||||
3
|
||||
],
|
||||
[
|
||||
4,
|
||||
5
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"cbor": "nwGCAgOCBAX/",
|
||||
"hex": "9f01820203820405ff",
|
||||
"roundtrip": false,
|
||||
"decoded": [
|
||||
1,
|
||||
[
|
||||
2,
|
||||
3
|
||||
],
|
||||
[
|
||||
4,
|
||||
5
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"cbor": "gwGCAgOfBAX/",
|
||||
"hex": "83018202039f0405ff",
|
||||
"roundtrip": false,
|
||||
"decoded": [
|
||||
1,
|
||||
[
|
||||
2,
|
||||
3
|
||||
],
|
||||
[
|
||||
4,
|
||||
5
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"cbor": "gwGfAgP/ggQF",
|
||||
"hex": "83019f0203ff820405",
|
||||
"roundtrip": false,
|
||||
"decoded": [
|
||||
1,
|
||||
[
|
||||
2,
|
||||
3
|
||||
],
|
||||
[
|
||||
4,
|
||||
5
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"cbor": "nwECAwQFBgcICQoLDA0ODxAREhMUFRYXGBgYGf8=",
|
||||
"hex": "9f0102030405060708090a0b0c0d0e0f101112131415161718181819ff",
|
||||
"roundtrip": false,
|
||||
"decoded": [
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
5,
|
||||
6,
|
||||
7,
|
||||
8,
|
||||
9,
|
||||
10,
|
||||
11,
|
||||
12,
|
||||
13,
|
||||
14,
|
||||
15,
|
||||
16,
|
||||
17,
|
||||
18,
|
||||
19,
|
||||
20,
|
||||
21,
|
||||
22,
|
||||
23,
|
||||
24,
|
||||
25
|
||||
]
|
||||
},
|
||||
{
|
||||
"cbor": "v2FhAWFinwID//8=",
|
||||
"hex": "bf61610161629f0203ffff",
|
||||
"roundtrip": false,
|
||||
"decoded": {
|
||||
"a": 1,
|
||||
"b": [
|
||||
2,
|
||||
3
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"cbor": "gmFhv2FiYWP/",
|
||||
"hex": "826161bf61626163ff",
|
||||
"roundtrip": false,
|
||||
"decoded": [
|
||||
"a",
|
||||
{
|
||||
"b": "c"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"cbor": "v2NGdW71Y0FtdCH/",
|
||||
"hex": "bf6346756ef563416d7421ff",
|
||||
"roundtrip": false,
|
||||
"decoded": {
|
||||
"Fun": true,
|
||||
"Amt": -2
|
||||
}
|
||||
}
|
||||
]
|
||||
126
vendor/github.com/ugorji/go/codec/test.py
generated
vendored
Executable file
126
vendor/github.com/ugorji/go/codec/test.py
generated
vendored
Executable file
|
|
@ -0,0 +1,126 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# This will create golden files in a directory passed to it.
|
||||
# A Test calls this internally to create the golden files
|
||||
# So it can process them (so we don't have to checkin the files).
|
||||
|
||||
# Ensure msgpack-python and cbor are installed first, using:
|
||||
# sudo apt-get install python-dev
|
||||
# sudo apt-get install python-pip
|
||||
# pip install --user msgpack-python msgpack-rpc-python cbor
|
||||
|
||||
# Ensure all "string" keys are utf strings (else encoded as bytes)
|
||||
|
||||
import cbor, msgpack, msgpackrpc, sys, os, threading
|
||||
|
||||
def get_test_data_list():
|
||||
# get list with all primitive types, and a combo type
|
||||
l0 = [
|
||||
-8,
|
||||
-1616,
|
||||
-32323232,
|
||||
-6464646464646464,
|
||||
192,
|
||||
1616,
|
||||
32323232,
|
||||
6464646464646464,
|
||||
192,
|
||||
-3232.0,
|
||||
-6464646464.0,
|
||||
3232.0,
|
||||
6464.0,
|
||||
6464646464.0,
|
||||
False,
|
||||
True,
|
||||
u"null",
|
||||
None,
|
||||
u"some&day>some<day",
|
||||
1328176922000002000,
|
||||
u"",
|
||||
-2206187877999998000,
|
||||
u"bytestring",
|
||||
270,
|
||||
u"none",
|
||||
-2013855847999995777,
|
||||
#-6795364578871345152,
|
||||
]
|
||||
l1 = [
|
||||
{ "true": True,
|
||||
"false": False },
|
||||
{ "true": u"True",
|
||||
"false": False,
|
||||
"uint16(1616)": 1616 },
|
||||
{ "list": [1616, 32323232, True, -3232.0, {"TRUE":True, "FALSE":False}, [True, False] ],
|
||||
"int32":32323232, "bool": True,
|
||||
"LONG STRING": u"123456789012345678901234567890123456789012345678901234567890",
|
||||
"SHORT STRING": u"1234567890" },
|
||||
{ True: "true", 138: False, "false": 200 }
|
||||
]
|
||||
|
||||
l = []
|
||||
l.extend(l0)
|
||||
l.append(l0)
|
||||
l.append(1)
|
||||
l.extend(l1)
|
||||
return l
|
||||
|
||||
def build_test_data(destdir):
|
||||
l = get_test_data_list()
|
||||
for i in range(len(l)):
|
||||
# packer = msgpack.Packer()
|
||||
serialized = msgpack.dumps(l[i])
|
||||
f = open(os.path.join(destdir, str(i) + '.msgpack.golden'), 'wb')
|
||||
f.write(serialized)
|
||||
f.close()
|
||||
serialized = cbor.dumps(l[i])
|
||||
f = open(os.path.join(destdir, str(i) + '.cbor.golden'), 'wb')
|
||||
f.write(serialized)
|
||||
f.close()
|
||||
|
||||
def doRpcServer(port, stopTimeSec):
|
||||
class EchoHandler(object):
|
||||
def Echo123(self, msg1, msg2, msg3):
|
||||
return ("1:%s 2:%s 3:%s" % (msg1, msg2, msg3))
|
||||
def EchoStruct(self, msg):
|
||||
return ("%s" % msg)
|
||||
|
||||
addr = msgpackrpc.Address('127.0.0.1', port)
|
||||
server = msgpackrpc.Server(EchoHandler())
|
||||
server.listen(addr)
|
||||
# run thread to stop it after stopTimeSec seconds if > 0
|
||||
if stopTimeSec > 0:
|
||||
def myStopRpcServer():
|
||||
server.stop()
|
||||
t = threading.Timer(stopTimeSec, myStopRpcServer)
|
||||
t.start()
|
||||
server.start()
|
||||
|
||||
def doRpcClientToPythonSvc(port):
|
||||
address = msgpackrpc.Address('127.0.0.1', port)
|
||||
client = msgpackrpc.Client(address, unpack_encoding='utf-8')
|
||||
print client.call("Echo123", "A1", "B2", "C3")
|
||||
print client.call("EchoStruct", {"A" :"Aa", "B":"Bb", "C":"Cc"})
|
||||
|
||||
def doRpcClientToGoSvc(port):
|
||||
# print ">>>> port: ", port, " <<<<<"
|
||||
address = msgpackrpc.Address('127.0.0.1', port)
|
||||
client = msgpackrpc.Client(address, unpack_encoding='utf-8')
|
||||
print client.call("TestRpcInt.Echo123", ["A1", "B2", "C3"])
|
||||
print client.call("TestRpcInt.EchoStruct", {"A" :"Aa", "B":"Bb", "C":"Cc"})
|
||||
|
||||
def doMain(args):
|
||||
if len(args) == 2 and args[0] == "testdata":
|
||||
build_test_data(args[1])
|
||||
elif len(args) == 3 and args[0] == "rpc-server":
|
||||
doRpcServer(int(args[1]), int(args[2]))
|
||||
elif len(args) == 2 and args[0] == "rpc-client-python-service":
|
||||
doRpcClientToPythonSvc(int(args[1]))
|
||||
elif len(args) == 2 and args[0] == "rpc-client-go-service":
|
||||
doRpcClientToGoSvc(int(args[1]))
|
||||
else:
|
||||
print("Usage: test.py " +
|
||||
"[testdata|rpc-server|rpc-client-python-service|rpc-client-go-service] ...")
|
||||
|
||||
if __name__ == "__main__":
|
||||
doMain(sys.argv[1:])
|
||||
|
||||
508
vendor/github.com/ugorji/go/codec/xml.go
generated
vendored
Normal file
508
vendor/github.com/ugorji/go/codec/xml.go
generated
vendored
Normal file
|
|
@ -0,0 +1,508 @@
|
|||
// Copyright (c) 2012-2018 Ugorji Nwoke. All rights reserved.
|
||||
// Use of this source code is governed by a MIT license found in the LICENSE file.
|
||||
|
||||
// +build ignore
|
||||
|
||||
package codec
|
||||
|
||||
import "reflect"
|
||||
|
||||
/*
|
||||
|
||||
A strict Non-validating namespace-aware XML 1.0 parser and (en|de)coder.
|
||||
|
||||
We are attempting this due to perceived issues with encoding/xml:
|
||||
- Complicated. It tried to do too much, and is not as simple to use as json.
|
||||
- Due to over-engineering, reflection is over-used AND performance suffers:
|
||||
java is 6X faster:http://fabsk.eu/blog/category/informatique/dev/golang/
|
||||
even PYTHON performs better: http://outgoing.typepad.com/outgoing/2014/07/exploring-golang.html
|
||||
|
||||
codec framework will offer the following benefits
|
||||
- VASTLY improved performance (when using reflection-mode or codecgen)
|
||||
- simplicity and consistency: with the rest of the supported formats
|
||||
- all other benefits of codec framework (streaming, codegeneration, etc)
|
||||
|
||||
codec is not a drop-in replacement for encoding/xml.
|
||||
It is a replacement, based on the simplicity and performance of codec.
|
||||
Look at it like JAXB for Go.
|
||||
|
||||
Challenges:
|
||||
- Need to output XML preamble, with all namespaces at the right location in the output.
|
||||
- Each "end" block is dynamic, so we need to maintain a context-aware stack
|
||||
- How to decide when to use an attribute VS an element
|
||||
- How to handle chardata, attr, comment EXPLICITLY.
|
||||
- Should it output fragments?
|
||||
e.g. encoding a bool should just output true OR false, which is not well-formed XML.
|
||||
|
||||
Extend the struct tag. See representative example:
|
||||
type X struct {
|
||||
ID uint8 `codec:"http://ugorji.net/x-namespace xid id,omitempty,toarray,attr,cdata"`
|
||||
// format: [namespace-uri ][namespace-prefix ]local-name, ...
|
||||
}
|
||||
|
||||
Based on this, we encode
|
||||
- fields as elements, BUT
|
||||
encode as attributes if struct tag contains ",attr" and is a scalar (bool, number or string)
|
||||
- text as entity-escaped text, BUT encode as CDATA if struct tag contains ",cdata".
|
||||
|
||||
To handle namespaces:
|
||||
- XMLHandle is denoted as being namespace-aware.
|
||||
Consequently, we WILL use the ns:name pair to encode and decode if defined, else use the plain name.
|
||||
- *Encoder and *Decoder know whether the Handle "prefers" namespaces.
|
||||
- add *Encoder.getEncName(*structFieldInfo).
|
||||
No one calls *structFieldInfo.indexForEncName directly anymore
|
||||
- OR better yet: indexForEncName is namespace-aware, and helper.go is all namespace-aware
|
||||
indexForEncName takes a parameter of the form namespace:local-name OR local-name
|
||||
- add *Decoder.getStructFieldInfo(encName string) // encName here is either like abc, or h1:nsabc
|
||||
by being a method on *Decoder, or maybe a method on the Handle itself.
|
||||
No one accesses .encName anymore
|
||||
- let encode.go and decode.go use these (for consistency)
|
||||
- only problem exists for gen.go, where we create a big switch on encName.
|
||||
Now, we also have to add a switch on strings.endsWith(kName, encNsName)
|
||||
- gen.go will need to have many more methods, and then double-on the 2 switch loops like:
|
||||
switch k {
|
||||
case "abc" : x.abc()
|
||||
case "def" : x.def()
|
||||
default {
|
||||
switch {
|
||||
case !nsAware: panic(...)
|
||||
case strings.endsWith(":abc"): x.abc()
|
||||
case strings.endsWith(":def"): x.def()
|
||||
default: panic(...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
The structure below accommodates this:
|
||||
|
||||
type typeInfo struct {
|
||||
sfi []*structFieldInfo // sorted by encName
|
||||
sfins // sorted by namespace
|
||||
sfia // sorted, to have those with attributes at the top. Needed to write XML appropriately.
|
||||
sfip // unsorted
|
||||
}
|
||||
type structFieldInfo struct {
|
||||
encName
|
||||
nsEncName
|
||||
ns string
|
||||
attr bool
|
||||
cdata bool
|
||||
}
|
||||
|
||||
indexForEncName is now an internal helper function that takes a sorted array
|
||||
(one of ti.sfins or ti.sfi). It is only used by *Encoder.getStructFieldInfo(...)
|
||||
|
||||
There will be a separate parser from the builder.
|
||||
The parser will have a method: next() xmlToken method. It has lookahead support,
|
||||
so you can pop multiple tokens, make a determination, and push them back in the order popped.
|
||||
This will be needed to determine whether we are "nakedly" decoding a container or not.
|
||||
The stack will be implemented using a slice and push/pop happens at the [0] element.
|
||||
|
||||
xmlToken has fields:
|
||||
- type uint8: 0 | ElementStart | ElementEnd | AttrKey | AttrVal | Text
|
||||
- value string
|
||||
- ns string
|
||||
|
||||
SEE: http://www.xml.com/pub/a/98/10/guide0.html?page=3#ENTDECL
|
||||
|
||||
The following are skipped when parsing:
|
||||
- External Entities (from external file)
|
||||
- Notation Declaration e.g. <!NOTATION GIF87A SYSTEM "GIF">
|
||||
- Entity Declarations & References
|
||||
- XML Declaration (assume UTF-8)
|
||||
- XML Directive i.e. <! ... >
|
||||
- Other Declarations: Notation, etc.
|
||||
- Comment
|
||||
- Processing Instruction
|
||||
- schema / DTD for validation:
|
||||
We are not a VALIDATING parser. Validation is done elsewhere.
|
||||
However, some parts of the DTD internal subset are used (SEE BELOW).
|
||||
For Attribute List Declarations e.g.
|
||||
<!ATTLIST foo:oldjoke name ID #REQUIRED label CDATA #IMPLIED status ( funny | notfunny ) 'funny' >
|
||||
We considered using the ATTLIST to get "default" value, but not to validate the contents. (VETOED)
|
||||
|
||||
The following XML features are supported
|
||||
- Namespace
|
||||
- Element
|
||||
- Attribute
|
||||
- cdata
|
||||
- Unicode escape
|
||||
|
||||
The following DTD (when as an internal sub-set) features are supported:
|
||||
- Internal Entities e.g.
|
||||
<!ELEMENT burns "ugorji is cool" > AND entities for the set: [<>&"']
|
||||
- Parameter entities e.g.
|
||||
<!ENTITY % personcontent "ugorji is cool"> <!ELEMENT burns (%personcontent;)*>
|
||||
|
||||
At decode time, a structure containing the following is kept
|
||||
- namespace mapping
|
||||
- default attribute values
|
||||
- all internal entities (<>&"' and others written in the document)
|
||||
|
||||
When decode starts, it parses XML namespace declarations and creates a map in the
|
||||
xmlDecDriver. While parsing, that map continuously gets updated.
|
||||
The only problem happens when a namespace declaration happens on the node that it defines.
|
||||
e.g. <hn:name xmlns:hn="http://www.ugorji.net" >
|
||||
To handle this, each Element must be fully parsed at a time,
|
||||
even if it amounts to multiple tokens which are returned one at a time on request.
|
||||
|
||||
xmlns is a special attribute name.
|
||||
- It is used to define namespaces, including the default
|
||||
- It is never returned as an AttrKey or AttrVal.
|
||||
*We may decide later to allow user to use it e.g. you want to parse the xmlns mappings into a field.*
|
||||
|
||||
Number, bool, null, mapKey, etc can all be decoded from any xmlToken.
|
||||
This accommodates map[int]string for example.
|
||||
|
||||
It should be possible to create a schema from the types,
|
||||
or vice versa (generate types from schema with appropriate tags).
|
||||
This is however out-of-scope from this parsing project.
|
||||
|
||||
We should write all namespace information at the first point that it is referenced in the tree,
|
||||
and use the mapping for all child nodes and attributes. This means that state is maintained
|
||||
at a point in the tree. This also means that calls to Decode or MustDecode will reset some state.
|
||||
|
||||
When decoding, it is important to keep track of entity references and default attribute values.
|
||||
It seems these can only be stored in the DTD components. We should honor them when decoding.
|
||||
|
||||
Configuration for XMLHandle will look like this:
|
||||
|
||||
XMLHandle
|
||||
DefaultNS string
|
||||
// Encoding:
|
||||
NS map[string]string // ns URI to key, used for encoding
|
||||
// Decoding: in case ENTITY declared in external schema or dtd, store info needed here
|
||||
Entities map[string]string // map of entity rep to character
|
||||
|
||||
|
||||
During encode, if a namespace mapping is not defined for a namespace found on a struct,
|
||||
then we create a mapping for it using nsN (where N is 1..1000000, and doesn't conflict
|
||||
with any other namespace mapping).
|
||||
|
||||
Note that different fields in a struct can have different namespaces.
|
||||
However, all fields will default to the namespace on the _struct field (if defined).
|
||||
|
||||
An XML document is a name, a map of attributes and a list of children.
|
||||
Consequently, we cannot "DecodeNaked" into a map[string]interface{} (for example).
|
||||
We have to "DecodeNaked" into something that resembles XML data.
|
||||
|
||||
To support DecodeNaked (decode into nil interface{}), we have to define some "supporting" types:
|
||||
type Name struct { // Preferred. Less allocations due to conversions.
|
||||
Local string
|
||||
Space string
|
||||
}
|
||||
type Element struct {
|
||||
Name Name
|
||||
Attrs map[Name]string
|
||||
Children []interface{} // each child is either *Element or string
|
||||
}
|
||||
Only two "supporting" types are exposed for XML: Name and Element.
|
||||
|
||||
// ------------------
|
||||
|
||||
We considered 'type Name string' where Name is like "Space Local" (space-separated).
|
||||
We decided against it, because each creation of a name would lead to
|
||||
double allocation (first convert []byte to string, then concatenate them into a string).
|
||||
The benefit is that it is faster to read Attrs from a map. But given that Element is a value
|
||||
object, we want to eschew methods and have public exposed variables.
|
||||
|
||||
We also considered the following, where xml types were not value objects, and we used
|
||||
intelligent accessor methods to extract information and for performance.
|
||||
*** WE DECIDED AGAINST THIS. ***
|
||||
type Attr struct {
|
||||
Name Name
|
||||
Value string
|
||||
}
|
||||
// Element is a ValueObject: There are no accessor methods.
|
||||
// Make element self-contained.
|
||||
type Element struct {
|
||||
Name Name
|
||||
attrsMap map[string]string // where key is "Space Local"
|
||||
attrs []Attr
|
||||
childrenT []string
|
||||
childrenE []Element
|
||||
childrenI []int // each child is a index into T or E.
|
||||
}
|
||||
func (x *Element) child(i) interface{} // returns string or *Element
|
||||
|
||||
// ------------------
|
||||
|
||||
Per XML spec and our default handling, white space is always treated as
|
||||
insignificant between elements, except in a text node. The xml:space='preserve'
|
||||
attribute is ignored.
|
||||
|
||||
**Note: there is no xml: namespace. The xml: attributes were defined before namespaces.**
|
||||
**So treat them as just "directives" that should be interpreted to mean something**.
|
||||
|
||||
On encoding, we support indenting aka prettifying markup in the same way we support it for json.
|
||||
|
||||
A document or element can only be encoded/decoded from/to a struct. In this mode:
|
||||
- struct name maps to element name (or tag-info from _struct field)
|
||||
- fields are mapped to child elements or attributes
|
||||
|
||||
A map is either encoded as attributes on current element, or as a set of child elements.
|
||||
Maps are encoded as attributes iff their keys and values are primitives (number, bool, string).
|
||||
|
||||
A list is encoded as a set of child elements.
|
||||
|
||||
Primitives (number, bool, string) are encoded as an element, attribute or text
|
||||
depending on the context.
|
||||
|
||||
Extensions must encode themselves as a text string.
|
||||
|
||||
Encoding is tough, specifically when encoding mappings, because we need to encode
|
||||
as either attribute or element. To do this, we need to default to encoding as attributes,
|
||||
and then let Encoder inform the Handle when to start encoding as nodes.
|
||||
i.e. Encoder does something like:
|
||||
|
||||
h.EncodeMapStart()
|
||||
h.Encode(), h.Encode(), ...
|
||||
h.EncodeMapNotAttrSignal() // this is not a bool, because it's a signal
|
||||
h.Encode(), h.Encode(), ...
|
||||
h.EncodeEnd()
|
||||
|
||||
Only XMLHandle understands this, and will set itself to start encoding as elements.
|
||||
|
||||
This support extends to maps. For example, if a struct field is a map, and it has
|
||||
the struct tag signifying it should be attr, then all its fields are encoded as attributes.
|
||||
e.g.
|
||||
|
||||
type X struct {
|
||||
M map[string]int `codec:"m,attr"` // encode keys as attributes named
|
||||
}
|
||||
|
||||
Question:
|
||||
- if encoding a map, what if map keys have spaces in them???
|
||||
Then they cannot be attributes or child elements. Error.
|
||||
|
||||
Options to consider adding later:
|
||||
- For attribute values, normalize by trimming beginning and ending white space,
|
||||
and converting every white space sequence to a single space.
|
||||
- ATTLIST restrictions are enforced.
|
||||
e.g. default value of xml:space, skipping xml:XYZ style attributes, etc.
|
||||
- Consider supporting NON-STRICT mode (e.g. to handle HTML parsing).
|
||||
Some elements e.g. br, hr, etc need not close and should be auto-closed
|
||||
... (see http://www.w3.org/TR/html4/loose.dtd)
|
||||
An expansive set of entities are pre-defined.
|
||||
- Have easy way to create a HTML parser:
|
||||
add a HTML() method to XMLHandle, that will set Strict=false, specify AutoClose,
|
||||
and add HTML Entities to the list.
|
||||
- Support validating element/attribute XMLName before writing it.
|
||||
Keep this behind a flag, which is set to false by default (for performance).
|
||||
type XMLHandle struct {
|
||||
CheckName bool
|
||||
}
|
||||
|
||||
Misc:
|
||||
|
||||
ROADMAP (1 weeks):
|
||||
- build encoder (1 day)
|
||||
- build decoder (based off xmlParser) (1 day)
|
||||
- implement xmlParser (2 days).
|
||||
Look at encoding/xml for inspiration.
|
||||
- integrate and TEST (1 days)
|
||||
- write article and post it (1 day)
|
||||
|
||||
// ---------- MORE NOTES FROM 2017-11-30 ------------
|
||||
|
||||
when parsing
|
||||
- parse the attributes first
|
||||
- then parse the nodes
|
||||
|
||||
basically:
|
||||
- if encoding a field: we use the field name for the wrapper
|
||||
- if encoding a non-field, then just use the element type name
|
||||
|
||||
map[string]string ==> <map><key>abc</key><value>val</value></map>... or
|
||||
<map key="abc">val</map>... OR
|
||||
<key1>val1</key1><key2>val2</key2>... <- PREFERED
|
||||
[]string ==> <string>v1</string><string>v2</string>...
|
||||
string v1 ==> <string>v1</string>
|
||||
bool true ==> <bool>true</bool>
|
||||
float 1.0 ==> <float>1.0</float>
|
||||
...
|
||||
|
||||
F1 map[string]string ==> <F1><key>abc</key><value>val</value></F1>... OR
|
||||
<F1 key="abc">val</F1>... OR
|
||||
<F1><abc>val</abc>...</F1> <- PREFERED
|
||||
F2 []string ==> <F2>v1</F2><F2>v2</F2>...
|
||||
F3 bool ==> <F3>true</F3>
|
||||
...
|
||||
|
||||
- a scalar is encoded as:
|
||||
(value) of type T ==> <T><value/></T>
|
||||
(value) of field F ==> <F><value/></F>
|
||||
- A kv-pair is encoded as:
|
||||
(key,value) ==> <map><key><value/></key></map> OR <map key="value">
|
||||
(key,value) of field F ==> <F><key><value/></key></F> OR <F key="value">
|
||||
- A map or struct is just a list of kv-pairs
|
||||
- A list is encoded as sequences of same node e.g.
|
||||
<F1 key1="value11">
|
||||
<F1 key2="value12">
|
||||
<F2>value21</F2>
|
||||
<F2>value22</F2>
|
||||
- we may have to singularize the field name, when entering into xml,
|
||||
and pluralize them when encoding.
|
||||
- bi-directional encode->decode->encode is not a MUST.
|
||||
even encoding/xml cannot decode correctly what was encoded:
|
||||
|
||||
see https://play.golang.org/p/224V_nyhMS
|
||||
func main() {
|
||||
fmt.Println("Hello, playground")
|
||||
v := []interface{}{"hello", 1, true, nil, time.Now()}
|
||||
s, err := xml.Marshal(v)
|
||||
fmt.Printf("err: %v, \ns: %s\n", err, s)
|
||||
var v2 []interface{}
|
||||
err = xml.Unmarshal(s, &v2)
|
||||
fmt.Printf("err: %v, \nv2: %v\n", err, v2)
|
||||
type T struct {
|
||||
V []interface{}
|
||||
}
|
||||
v3 := T{V: v}
|
||||
s, err = xml.Marshal(v3)
|
||||
fmt.Printf("err: %v, \ns: %s\n", err, s)
|
||||
var v4 T
|
||||
err = xml.Unmarshal(s, &v4)
|
||||
fmt.Printf("err: %v, \nv4: %v\n", err, v4)
|
||||
}
|
||||
Output:
|
||||
err: <nil>,
|
||||
s: <string>hello</string><int>1</int><bool>true</bool><Time>2009-11-10T23:00:00Z</Time>
|
||||
err: <nil>,
|
||||
v2: [<nil>]
|
||||
err: <nil>,
|
||||
s: <T><V>hello</V><V>1</V><V>true</V><V>2009-11-10T23:00:00Z</V></T>
|
||||
err: <nil>,
|
||||
v4: {[<nil> <nil> <nil> <nil>]}
|
||||
-
|
||||
*/
|
||||
|
||||
// ----------- PARSER -------------------
|
||||
|
||||
type xmlTokenType uint8
|
||||
|
||||
const (
|
||||
_ xmlTokenType = iota << 1
|
||||
xmlTokenElemStart
|
||||
xmlTokenElemEnd
|
||||
xmlTokenAttrKey
|
||||
xmlTokenAttrVal
|
||||
xmlTokenText
|
||||
)
|
||||
|
||||
type xmlToken struct {
|
||||
Type xmlTokenType
|
||||
Value string
|
||||
Namespace string // blank for AttrVal and Text
|
||||
}
|
||||
|
||||
type xmlParser struct {
|
||||
r decReader
|
||||
toks []xmlToken // list of tokens.
|
||||
ptr int // ptr into the toks slice
|
||||
done bool // nothing else to parse. r now returns EOF.
|
||||
}
|
||||
|
||||
func (x *xmlParser) next() (t *xmlToken) {
|
||||
// once x.done, or x.ptr == len(x.toks) == 0, then return nil (to signify finish)
|
||||
if !x.done && len(x.toks) == 0 {
|
||||
x.nextTag()
|
||||
}
|
||||
// parses one element at a time (into possible many tokens)
|
||||
if x.ptr < len(x.toks) {
|
||||
t = &(x.toks[x.ptr])
|
||||
x.ptr++
|
||||
if x.ptr == len(x.toks) {
|
||||
x.ptr = 0
|
||||
x.toks = x.toks[:0]
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// nextTag will parses the next element and fill up toks.
|
||||
// It set done flag if/once EOF is reached.
|
||||
func (x *xmlParser) nextTag() {
|
||||
// TODO: implement.
|
||||
}
|
||||
|
||||
// ----------- ENCODER -------------------
|
||||
|
||||
type xmlEncDriver struct {
|
||||
e *Encoder
|
||||
w encWriter
|
||||
h *XMLHandle
|
||||
b [64]byte // scratch
|
||||
bs []byte // scratch
|
||||
// s jsonStack
|
||||
noBuiltInTypes
|
||||
}
|
||||
|
||||
// ----------- DECODER -------------------
|
||||
|
||||
type xmlDecDriver struct {
|
||||
d *Decoder
|
||||
h *XMLHandle
|
||||
r decReader // *bytesDecReader decReader
|
||||
ct valueType // container type. one of unset, array or map.
|
||||
bstr [8]byte // scratch used for string \UXXX parsing
|
||||
b [64]byte // scratch
|
||||
|
||||
// wsSkipped bool // whitespace skipped
|
||||
|
||||
// s jsonStack
|
||||
|
||||
noBuiltInTypes
|
||||
}
|
||||
|
||||
// DecodeNaked will decode into an XMLNode
|
||||
|
||||
// XMLName is a value object representing a namespace-aware NAME
|
||||
type XMLName struct {
|
||||
Local string
|
||||
Space string
|
||||
}
|
||||
|
||||
// XMLNode represents a "union" of the different types of XML Nodes.
|
||||
// Only one of fields (Text or *Element) is set.
|
||||
type XMLNode struct {
|
||||
Element *Element
|
||||
Text string
|
||||
}
|
||||
|
||||
// XMLElement is a value object representing an fully-parsed XML element.
|
||||
type XMLElement struct {
|
||||
Name Name
|
||||
Attrs map[XMLName]string
|
||||
// Children is a list of child nodes, each being a *XMLElement or string
|
||||
Children []XMLNode
|
||||
}
|
||||
|
||||
// ----------- HANDLE -------------------
|
||||
|
||||
type XMLHandle struct {
|
||||
BasicHandle
|
||||
textEncodingType
|
||||
|
||||
DefaultNS string
|
||||
NS map[string]string // ns URI to key, for encoding
|
||||
Entities map[string]string // entity representation to string, for encoding.
|
||||
}
|
||||
|
||||
func (h *XMLHandle) newEncDriver(e *Encoder) encDriver {
|
||||
return &xmlEncDriver{e: e, w: e.w, h: h}
|
||||
}
|
||||
|
||||
func (h *XMLHandle) newDecDriver(d *Decoder) decDriver {
|
||||
// d := xmlDecDriver{r: r.(*bytesDecReader), h: h}
|
||||
hd := xmlDecDriver{d: d, r: d.r, h: h}
|
||||
hd.n.bytes = d.b[:]
|
||||
return &hd
|
||||
}
|
||||
|
||||
func (h *XMLHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) {
|
||||
return h.SetExt(rt, tag, &extWrapper{bytesExtFailer{}, ext})
|
||||
}
|
||||
|
||||
var _ decDriver = (*xmlDecDriver)(nil)
|
||||
var _ encDriver = (*xmlEncDriver)(nil)
|
||||
Loading…
Add table
Add a link
Reference in a new issue