get packer plugin sdk version 0.0.12 (#10612)

This commit is contained in:
Adrien Delorme 2021-02-11 14:14:04 +01:00 committed by GitHub
parent 37769c2b95
commit 915372c73d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
67 changed files with 21360 additions and 46301 deletions

3
go.mod
View File

@ -50,7 +50,7 @@ require (
github.com/hashicorp/go-uuid v1.0.2 github.com/hashicorp/go-uuid v1.0.2
github.com/hashicorp/go-version v1.2.0 github.com/hashicorp/go-version v1.2.0
github.com/hashicorp/hcl/v2 v2.8.0 github.com/hashicorp/hcl/v2 v2.8.0
github.com/hashicorp/packer-plugin-sdk v0.0.11 github.com/hashicorp/packer-plugin-sdk v0.0.12
github.com/hashicorp/vault/api v1.0.4 github.com/hashicorp/vault/api v1.0.4
github.com/hetznercloud/hcloud-go v1.15.1 github.com/hetznercloud/hcloud-go v1.15.1
github.com/hyperonecom/h1-client-go v0.0.0-20191203060043-b46280e4c4a4 github.com/hyperonecom/h1-client-go v0.0.0-20191203060043-b46280e4c4a4
@ -76,7 +76,6 @@ require (
github.com/profitbricks/profitbricks-sdk-go v4.0.2+incompatible github.com/profitbricks/profitbricks-sdk-go v4.0.2+incompatible
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7 github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7
github.com/shirou/gopsutil v2.18.12+incompatible github.com/shirou/gopsutil v2.18.12+incompatible
github.com/smartystreets/goconvey v1.6.4 // indirect
github.com/stretchr/testify v1.6.1 github.com/stretchr/testify v1.6.1
github.com/tencentcloud/tencentcloud-sdk-go v3.0.222+incompatible github.com/tencentcloud/tencentcloud-sdk-go v3.0.222+incompatible
github.com/ucloud/ucloud-sdk-go v0.16.3 github.com/ucloud/ucloud-sdk-go v0.16.3

7
go.sum
View File

@ -393,6 +393,7 @@ github.com/hashicorp/packer v1.6.7-0.20210112155033-1bc89e34714f/go.mod h1:sKsux
github.com/hashicorp/packer v1.6.7-0.20210120105538-140685fb4f8b/go.mod h1:Yaw0q8brThFN2PKMWMRcuhQBuwPVDJRHHioNuMJTS7Q= github.com/hashicorp/packer v1.6.7-0.20210120105538-140685fb4f8b/go.mod h1:Yaw0q8brThFN2PKMWMRcuhQBuwPVDJRHHioNuMJTS7Q=
github.com/hashicorp/packer v1.6.7-0.20210125170305-539638b0f951/go.mod h1:Z3eunaxVQ3XgQ+rW7TEH0T/PRQzCUSyCBUTkm/VL7io= github.com/hashicorp/packer v1.6.7-0.20210125170305-539638b0f951/go.mod h1:Z3eunaxVQ3XgQ+rW7TEH0T/PRQzCUSyCBUTkm/VL7io=
github.com/hashicorp/packer v1.6.7-0.20210126105722-aef4ced967ec/go.mod h1:2+Vo/c/fA+TD9yFc/h9jQMFm4yG+IymQIr0OdJJOPiE= github.com/hashicorp/packer v1.6.7-0.20210126105722-aef4ced967ec/go.mod h1:2+Vo/c/fA+TD9yFc/h9jQMFm4yG+IymQIr0OdJJOPiE=
github.com/hashicorp/packer v1.6.7-0.20210208125835-f616955ebcb6/go.mod h1:7f5ZpTTRG53rQ58BcTADuTnpiBcB3wapuxl4sF2sGMM=
github.com/hashicorp/packer-plugin-sdk v0.0.6 h1:BN2G4APXSMvDURFdnk+6DspwsU83pZeMsbEur7NmGsA= github.com/hashicorp/packer-plugin-sdk v0.0.6 h1:BN2G4APXSMvDURFdnk+6DspwsU83pZeMsbEur7NmGsA=
github.com/hashicorp/packer-plugin-sdk v0.0.6/go.mod h1:Nvh28f+Jmpp2rcaN79bULTouNkGNDRfHckhHKTAXtyU= github.com/hashicorp/packer-plugin-sdk v0.0.6/go.mod h1:Nvh28f+Jmpp2rcaN79bULTouNkGNDRfHckhHKTAXtyU=
github.com/hashicorp/packer-plugin-sdk v0.0.6/go.mod h1:Nvh28f+Jmpp2rcaN79bULTouNkGNDRfHckhHKTAXtyU= github.com/hashicorp/packer-plugin-sdk v0.0.6/go.mod h1:Nvh28f+Jmpp2rcaN79bULTouNkGNDRfHckhHKTAXtyU=
@ -405,6 +406,8 @@ github.com/hashicorp/packer-plugin-sdk v0.0.10-0.20210126105622-8e1648006d93 h1:
github.com/hashicorp/packer-plugin-sdk v0.0.10-0.20210126105622-8e1648006d93/go.mod h1:AtWQLNfpn7cgH2SmZ1PTedwqNOhiPvzcuKfH5sDvIQ0= github.com/hashicorp/packer-plugin-sdk v0.0.10-0.20210126105622-8e1648006d93/go.mod h1:AtWQLNfpn7cgH2SmZ1PTedwqNOhiPvzcuKfH5sDvIQ0=
github.com/hashicorp/packer-plugin-sdk v0.0.11 h1:nUurEGaJtpVDyg94bKC2xOXWf1TqQ+++GovFUnP5REI= github.com/hashicorp/packer-plugin-sdk v0.0.11 h1:nUurEGaJtpVDyg94bKC2xOXWf1TqQ+++GovFUnP5REI=
github.com/hashicorp/packer-plugin-sdk v0.0.11/go.mod h1:GNb0WNs7zibb8vzUZce1As64z2AW0FEMwhe2J7/NW5I= github.com/hashicorp/packer-plugin-sdk v0.0.11/go.mod h1:GNb0WNs7zibb8vzUZce1As64z2AW0FEMwhe2J7/NW5I=
github.com/hashicorp/packer-plugin-sdk v0.0.12 h1:eagxsrborfhc0E8zvDVCiRE9pQkjBw/6jm23jp0D8RU=
github.com/hashicorp/packer-plugin-sdk v0.0.12/go.mod h1:hs82OYeufirGG6KRENMpjBWomnIlte99X6wXAPThJ5I=
github.com/hashicorp/serf v0.8.2 h1:YZ7UKsJv+hKjqGVUUbtE3HNj79Eln2oQ75tniF6iPt0= github.com/hashicorp/serf v0.8.2 h1:YZ7UKsJv+hKjqGVUUbtE3HNj79Eln2oQ75tniF6iPt0=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hashicorp/serf v0.9.2 h1:yJoyfZXo4Pk2p/M/viW+YLibBFiIbKoP79gu7kDAFP0= github.com/hashicorp/serf v0.9.2 h1:yJoyfZXo4Pk2p/M/viW+YLibBFiIbKoP79gu7kDAFP0=
@ -638,6 +641,10 @@ github.com/ufilesdk-dev/ufile-gosdk v0.0.0-20190830075812-b4dbc4ef43a6 h1:FAWNiq
github.com/ufilesdk-dev/ufile-gosdk v0.0.0-20190830075812-b4dbc4ef43a6/go.mod h1:R5FMQxkQ+QK/9Vz+jfnJP4rZIktYrRcWmuAnbOSkROI= github.com/ufilesdk-dev/ufile-gosdk v0.0.0-20190830075812-b4dbc4ef43a6/go.mod h1:R5FMQxkQ+QK/9Vz+jfnJP4rZIktYrRcWmuAnbOSkROI=
github.com/ugorji/go v0.0.0-20151218193438-646ae4a518c1 h1:U6ufy3mLDgg9RYupntOvAF7xCmNNquyKaYaaVHo1Nnk= github.com/ugorji/go v0.0.0-20151218193438-646ae4a518c1 h1:U6ufy3mLDgg9RYupntOvAF7xCmNNquyKaYaaVHo1Nnk=
github.com/ugorji/go v0.0.0-20151218193438-646ae4a518c1/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= github.com/ugorji/go v0.0.0-20151218193438-646ae4a518c1/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ=
github.com/ugorji/go v1.2.4 h1:cTciPbZ/VSOzCLKclmssnfQ/jyoVyOcJ3aoJyUV1Urc=
github.com/ugorji/go v1.2.4/go.mod h1:EuaSCk8iZMdIspsu6HXH7X2UGKw1ezO4wCfGszGmmo4=
github.com/ugorji/go/codec v1.2.4 h1:C5VurWRRCKjuENsbM6GYVw8W++WVW9rSxoACKIvxzz8=
github.com/ugorji/go/codec v1.2.4/go.mod h1:bWBu1+kIRWcF8uMklKaJrR6fTWQOwAlrIzX22pHwryA=
github.com/ulikunitz/xz v0.5.5 h1:pFrO0lVpTBXLpYw+pnLj6TbvHuyjXMfjGeCwSqCVwok= github.com/ulikunitz/xz v0.5.5 h1:pFrO0lVpTBXLpYw+pnLj6TbvHuyjXMfjGeCwSqCVwok=
github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=

View File

@ -44,8 +44,7 @@ func newClientWithMux(mux *muxBroker, streamId uint32) (*Client, error) {
} }
h := &codec.MsgpackHandle{ h := &codec.MsgpackHandle{
RawToString: true, WriteExt: true,
WriteExt: true,
} }
clientCodec := codec.GoRpc.ClientCodec(clientConn, h) clientCodec := codec.GoRpc.ClientCodec(clientConn, h)

View File

@ -153,8 +153,7 @@ func (s *PluginServer) Serve() {
defer stream.Close() defer stream.Close()
h := &codec.MsgpackHandle{ h := &codec.MsgpackHandle{
RawToString: true, WriteExt: true,
WriteExt: true,
} }
rpcCodec := codec.GoRpc.ServerCodec(stream, h) rpcCodec := codec.GoRpc.ServerCodec(stream, h)
s.server.ServeCodec(rpcCodec) s.server.ServeCodec(rpcCodec)

7
vendor/github.com/ugorji/go/codec/0_importpath.go generated vendored Normal file
View File

@ -0,0 +1,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 "github.com/ugorji/go/codec"
// This establishes that this package must be imported as github.com/ugorji/go/codec.
// It makes forking easier, and plays well with pre-module releases of go.

View File

@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2012-2015 Ugorji Nwoke. Copyright (c) 2012-2020 Ugorji Nwoke.
All rights reserved. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy

View File

@ -1,7 +1,7 @@
# Codec # Package Documentation for github.com/ugorji/go/codec
High Performance, Feature-Rich Idiomatic Go codec/encoding library for Package codec provides a High Performance, Feature-Rich Idiomatic Go 1.4+
binc, msgpack, cbor, json. codec/encoding library for binc, msgpack, cbor, json.
Supported Serialization formats are: Supported Serialization formats are:
@ -9,39 +9,34 @@ Supported Serialization formats are:
- binc: http://github.com/ugorji/binc - binc: http://github.com/ugorji/binc
- cbor: http://cbor.io http://tools.ietf.org/html/rfc7049 - cbor: http://cbor.io http://tools.ietf.org/html/rfc7049
- json: http://json.org http://tools.ietf.org/html/rfc7159 - json: http://json.org http://tools.ietf.org/html/rfc7159
- simple: - simple:
To install: This package will carefully use 'package 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 ...'.
go get github.com/ugorji/go/codec This library works with both the standard `gc` and the `gccgo` compilers.
This package understands the `unsafe` tag, to allow using unsafe semantics: For detailed usage information, read the primer at
http://ugorji.net/blog/go-codec-primer .
- When decoding into a struct, you need to read the field name as a string The idiomatic Go support is as seen in other encoding packages in the
so you can find the struct field it is mapped to. standard library (ie json, xml, gob, etc).
Using `unsafe` will bypass the allocation and copying overhead of `[]byte->string` conversion.
To use it, you must pass the `unsafe` tag during install:
```
go install -tags=unsafe github.com/ugorji/go/codec
```
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: Rich Feature Set includes:
- Simple but extremely powerful and feature-rich API - Simple but extremely powerful and feature-rich API
- Support for go 1.4 and above, while selectively using newer APIs for later releases
- Excellent code coverage ( > 90% )
- Very High Performance. - Very High Performance.
Our extensive benchmarks show us outperforming Gob, Json, Bson, etc by 2-4X. Our extensive benchmarks show us outperforming Gob, Json, Bson, etc by 2-4X.
- Multiple conversions: - Careful selected use of 'unsafe' for targeted performance gains.
Package coerces types where appropriate - 100% safe mode supported, where 'unsafe' is not used at all.
e.g. decode an int in the stream into a float, etc. - Lock-free (sans mutex) concurrency for scaling to 100's of cores
- Corner Cases: - In-place updates during decode, with option to zero value in maps and slices prior to decode
- 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 Overflows, nil maps/slices, nil values in streams are handled correctly
- Standard field renaming via tags - Standard field renaming via tags
- Support for omitting empty fields during an encoding - Support for omitting empty fields during an encoding
@ -49,15 +44,21 @@ Rich Feature Set includes:
(struct, slice, map, primitives, pointers, interface{}, etc) (struct, slice, map, primitives, pointers, interface{}, etc)
- Extensions to support efficient encoding/decoding of any named types - Extensions to support efficient encoding/decoding of any named types
- Support encoding.(Binary|Text)(M|Unm)arshaler interfaces - Support encoding.(Binary|Text)(M|Unm)arshaler interfaces
- Support using existence of `IsZero() bool` to determine if a value is a zero value.
Analogous to time.Time.IsZero() bool.
- Decoding without a schema (into a interface{}). - Decoding without a schema (into a interface{}).
Includes Options to configure what specific map or slice type to use Includes Options to configure what specific map or slice type to use
when decoding an encoded list or map into a nil interface{} 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 - 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 - Comprehensive support for anonymous fields
- Fast (no-reflection) encoding/decoding of common maps and slices - Fast (no-reflection) encoding/decoding of common maps and slices
- Code-generation for faster performance. - Code-generation for faster performance, supported in go 1.6+
- Support binary (e.g. messagepack, cbor) and text (e.g. json) formats - Support binary (e.g. messagepack, cbor) and text (e.g. json) formats
- Support indefinite-length formats to enable true streaming - Support indefinite-length formats to enable true streaming
(for formats which support it e.g. json, cbor) (for formats which support it e.g. json, cbor)
- Support canonical encoding, where a value is ALWAYS encoded as same sequence of bytes. - 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. This mostly applies to maps, where iteration order is non-deterministic.
@ -65,42 +66,88 @@ Rich Feature Set includes:
- Never silently skip data when decoding. - Never silently skip data when decoding.
User decides whether to return an error or silently skip data when keys or indexes 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. 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) - Encode/Decode from/to chan types (for iterative streaming support)
- Drop-in replacement for encoding/json. `json:` key in struct tag supported. - Drop-in replacement for encoding/json. `json:` key in struct tag supported.
- Provides a RPC Server and Client Codec for net/rpc communication protocol. - Provides a RPC Server and Client Codec for net/rpc communication protocol.
- Handle unique idiosynchracies of codecs e.g. - Handle unique idiosyncrasies of codecs e.g.
- For messagepack, configure how ambiguities in handling raw bytes are resolved - For messagepack, configure how ambiguities in handling raw bytes are resolved
- For messagepack, provide rpc server/client codec to support - For messagepack, provide rpc server/client codec to support
msgpack-rpc protocol defined at: msgpack-rpc protocol defined at:
https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md
## Extension Support ## Extension Support
Users can register a function to handle the encoding or decoding of Users can register a function to handle the encoding or decoding of their
their custom types. custom types.
There are no restrictions on what the custom type can be. Some examples: There are no restrictions on what the custom type can be. Some examples:
```go
type BisSet []int type BisSet []int
type BitSet64 uint64 type BitSet64 uint64
type UUID string type UUID string
type MyStructWithUnexportedFields struct { a int; b bool; c []int; } type MyStructWithUnexportedFields struct { a int; b bool; c []int; }
type GifImage struct { ... } 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.
There is also seamless support provided for registering an extension (with a
tag) but letting the encoding mechanism default to the standard way.
## 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 there an extension registered for the type?
- is type a codec.Selfer?
- 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 and TextUnmarshaler?
- 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.
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.
## RPC ## RPC
RPC Client and Server Codecs are implemented, so the codecs can be used RPC Client and Server Codecs are implemented, so the codecs can be used with
with the standard net/rpc package. the standard net/rpc package.
## Usage ## Usage
Typical usage model: 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:
```go
// create and configure Handle // create and configure Handle
var ( var (
bh codec.BincHandle bh codec.BincHandle
@ -145,4 +192,92 @@ Typical usage model:
rpcCodec := codec.GoRpc.ClientCodec(conn, h) rpcCodec := codec.GoRpc.ClientCodec(conn, h)
//OR rpcCodec := codec.MsgpackSpecRpc.ClientCodec(conn, h) //OR rpcCodec := codec.MsgpackSpecRpc.ClientCodec(conn, h)
client := rpc.NewClientWithCodec(rpcCodec) 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
```
cd bench
go test -bench . -benchmem -benchtime 1s
```
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.
## Exported Package API
```go
const CborStreamBytes byte = 0x5f ...
const GenVersion = 23
var SelfExt = &extFailWrapper{}
var GoRpc goRpc
var MsgpackSpecRpc msgpackSpecRpc
func GenHelper() (g genHelper)
type BasicHandle struct{ ... }
type BincHandle struct{ ... }
type BytesExt interface{ ... }
type CborHandle struct{ ... }
type DecodeOptions struct{ ... }
type Decoder struct{ ... }
func NewDecoder(r io.Reader, h Handle) *Decoder
func NewDecoderBytes(in []byte, h Handle) *Decoder
func NewDecoderString(s string, h Handle) *Decoder
type EncodeOptions struct{ ... }
type Encoder struct{ ... }
func NewEncoder(w io.Writer, h Handle) *Encoder
func NewEncoderBytes(out *[]byte, h Handle) *Encoder
type Ext interface{ ... }
type Handle interface{ ... }
type InterfaceExt interface{ ... }
type JsonHandle struct{ ... }
type MapBySlice interface{ ... }
type MissingFielder interface{ ... }
type MsgpackHandle struct{ ... }
type MsgpackSpecRpcMultiArgs []interface{}
type RPCOptions struct{ ... }
type Raw []byte
type RawExt struct{ ... }
type Rpc interface{ ... }
type Selfer interface{ ... }
type SimpleHandle struct{ ... }
type TypeInfos struct{ ... }
func NewTypeInfos(tags []string) *TypeInfos
```

File diff suppressed because it is too large Load Diff

350
vendor/github.com/ugorji/go/codec/build.sh generated vendored Normal file
View File

@ -0,0 +1,350 @@
#!/bin/bash
# Run all the different permutations of all the tests and other things
# This helps ensure that nothing gets broken.
_tests() {
local vet="" # TODO: make it off
local gover=$( ${gocmd} version | cut -f 3 -d ' ' )
[[ $( ${gocmd} version ) == *"gccgo"* ]] && zcover=0
case $gover in
go1.[7-9]*|go1.1[0-9]*|go2.*|devel*) true ;;
*) return 1
esac
# note that codecgen requires fastpath, so you cannot do "codecgen notfastpath"
# we test the following permutations wnich all execute different code paths as below.
echo "TestCodecSuite: (fastpath/unsafe), (fastpath/!unsafe), (!fastpath/!unsafe), (codecgen/unsafe)"
local nc=1 # count
local a=( "" "safe" "notfastpath safe" "codecgen" )
local b=()
local c=()
for i in "${a[@]}"
do
local i2=${i:-default}
[[ "$zwait" == "1" ]] && echo ">>>> TAGS: 'alltests $i'; RUN: 'TestCodecSuite'"
[[ "$zcover" == "1" ]] && c=( -coverprofile "${i2// /-}.cov.out" )
true &&
${gocmd} vet -printfuncs "errorf" "$@" &&
${gocmd} test ${zargs[*]} ${ztestargs[*]} -vet "$vet" -tags "alltests $i" -count $nc -run "TestCodecSuite" "${c[@]}" "$@" &
b+=("${i2// /-}.cov.out")
[[ "$zwait" == "1" ]] && wait
# if [[ "$?" != 0 ]]; then return 1; fi
done
if [[ "$zextra" == "1" ]]; then
[[ "$zwait" == "1" ]] && echo ">>>> TAGS: 'notfastpath x'; RUN: 'Test.*X$'"
[[ "$zcover" == "1" ]] && c=( -coverprofile "x.cov.out" )
${gocmd} test ${zargs[*]} ${ztestargs[*]} -vet "$vet" -tags "notfastpath x" -count $nc -run 'Test.*X$' "${c[@]}" &
b+=("x.cov.out")
[[ "$zwait" == "1" ]] && wait
fi
wait
# go tool cover is not supported for gccgo.
[[ "$zcover" == "1" ]] &&
command -v gocovmerge &&
gocovmerge "${b[@]}" > __merge.cov.out &&
${gocmd} tool cover -html=__merge.cov.out
}
# is a generation needed?
_ng() {
local a="$1"
if [[ ! -e "$a" ]]; then echo 1; return; fi
for i in `ls -1 *.go.tmpl gen.go values_test.go`
do
if [[ "$a" -ot "$i" ]]; then echo 1; return; fi
done
}
_prependbt() {
cat > ${2} <<EOF
// +build generated
EOF
cat ${1} >> ${2}
rm -f ${1}
}
# _build generates fast-path.go and gen-helper.go.
_build() {
if ! [[ "${zforce}" || $(_ng "fast-path.generated.go") || $(_ng "gen-helper.generated.go") || $(_ng "gen.generated.go") ]]; then return 0; fi
if [ "${zbak}" ]; then
_zts=`date '+%m%d%Y_%H%M%S'`
_gg=".generated.go"
[ -e "gen-helper${_gg}" ] && mv gen-helper${_gg} gen-helper${_gg}__${_zts}.bak
[ -e "fast-path${_gg}" ] && mv fast-path${_gg} fast-path${_gg}__${_zts}.bak
[ -e "gen${_gg}" ] && mv gen${_gg} gen${_gg}__${_zts}.bak
fi
rm -f gen-helper.generated.go fast-path.generated.go gen.generated.go \
*safe.generated.go *_generated_test.go *.generated_ffjson_expose.go
cat > gen.generated.go <<EOF
// +build codecgen.exec
// Copyright (c) 2012-2020 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 = \`
EOF
cat >> gen.generated.go < gen-dec-map.go.tmpl
cat >> gen.generated.go <<EOF
\`
const genDecListTmpl = \`
EOF
cat >> gen.generated.go < gen-dec-array.go.tmpl
cat >> gen.generated.go <<EOF
\`
const genEncChanTmpl = \`
EOF
cat >> gen.generated.go < gen-enc-chan.go.tmpl
cat >> gen.generated.go <<EOF
\`
EOF
cat > gen-from-tmpl.codec.generated.go <<EOF
package codec
func GenRunTmpl2Go(in, out string) { genRunTmpl2Go(in, out) }
func GenRunSortTmpl2Go(in, out string) { genRunSortTmpl2Go(in, out) }
EOF
# stub xxxRv and xxxRvSlice creation, before you create it
cat > gen-from-tmpl.sort-slice-stubs.generated.go <<EOF
// +build codecgen.sort_slice
package codec
import "reflect"
import "time"
EOF
for i in string bool uint64 int64 float64 bytes time; do
local i2=$i
case $i in
'time' ) i2="time.Time";;
'bytes' ) i2="[]byte";;
esac
cat >> gen-from-tmpl.sort-slice-stubs.generated.go <<EOF
type ${i}Rv struct { v ${i2}; r reflect.Value }
type ${i}RvSlice []${i}Rv
func (${i}RvSlice) Len() int { return 0 }
func (${i}RvSlice) Less(i, j int) bool { return false }
func (${i}RvSlice) Swap(i, j int) {}
EOF
done
sed -e 's+// __DO_NOT_REMOVE__NEEDED_FOR_REPLACING__IMPORT_PATH__FOR_CODEC_BENCH__+import . "github.com/ugorji/go/codec"+' \
shared_test.go > bench/shared_test.go
# explicitly return 0 if this passes, else return 1
local btags="notfastpath safe codecgen.exec"
rm -f sort-slice.generated.go fast-path.generated.go gen-helper.generated.go mammoth_generated_test.go mammoth2_generated_test.go
cat > gen-from-tmpl.sort-slice.generated.go <<EOF
// +build ignore
package main
import "${zpkg}"
func main() {
codec.GenRunSortTmpl2Go("sort-slice.go.tmpl", "sort-slice.generated.go")
}
EOF
${gocmd} run -tags "$btags codecgen.sort_slice" gen-from-tmpl.sort-slice.generated.go || return 1
rm -f gen-from-tmpl.sort-slice.generated.go
cat > gen-from-tmpl.generated.go <<EOF
// +build ignore
package main
import "${zpkg}"
func main() {
codec.GenRunTmpl2Go("fast-path.go.tmpl", "fast-path.generated.go")
codec.GenRunTmpl2Go("gen-helper.go.tmpl", "gen-helper.generated.go")
codec.GenRunTmpl2Go("mammoth-test.go.tmpl", "mammoth_generated_test.go")
codec.GenRunTmpl2Go("mammoth2-test.go.tmpl", "mammoth2_generated_test.go")
}
EOF
${gocmd} run -tags "$btags" gen-from-tmpl.generated.go || return 1
rm -f gen-from-tmpl.generated.go
rm -f gen-from-tmpl.*generated.go
return 0
}
_codegenerators() {
local c5="_generated_test.go"
local c7="$PWD/codecgen"
local c8="$c7/__codecgen"
local c9="codecgen-scratch.go"
if ! [[ $zforce || $(_ng "values_codecgen${c5}") ]]; then return 0; fi
# Note: ensure you run the codecgen for this codebase/directory i.e. ./codecgen/codecgen
true &&
echo "codecgen ... " &&
if [[ $zforce || ! -f "$c8" || "$c7/gen.go" -nt "$c8" ]]; then
echo "rebuilding codecgen ... " && ( cd codecgen && ${gocmd} build -o $c8 ${zargs[*]} . )
fi &&
$c8 -rt 'codecgen' -t 'codecgen generated' -o "values_codecgen${c5}" -d 19780 "$zfin" "$zfin2" &&
cp mammoth2_generated_test.go $c9 &&
$c8 -t 'codecgen,!notfastpath generated,!notfastpath' -o "mammoth2_codecgen${c5}" -d 19781 "mammoth2_generated_test.go" &&
rm -f $c9 &&
echo "generators done!"
}
_prebuild() {
echo "prebuild: zforce: $zforce"
local d="$PWD"
local zfin="test_values.generated.go"
local zfin2="test_values_flex.generated.go"
local zpkg="github.com/ugorji/go/codec"
local returncode=1
# zpkg=${d##*/src/}
# zgobase=${d%%/src/*}
# rm -f *_generated_test.go
rm -f codecgen-*.go &&
_build &&
cp $d/values_test.go $d/$zfin &&
cp $d/values_flex_test.go $d/$zfin2 &&
_codegenerators &&
if [[ "$(type -t _codegenerators_external )" = "function" ]]; then _codegenerators_external ; fi &&
if [[ $zforce ]]; then ${gocmd} install ${zargs[*]} .; fi &&
returncode=0 &&
echo "prebuild done successfully"
rm -f $d/$zfin $d/$zfin2
return $returncode
# unset zfin zfin2 zpkg
}
_make() {
local makeforce=${zforce}
zforce=1
(cd codecgen && ${gocmd} install ${zargs[*]} .) && _prebuild && ${gocmd} install ${zargs[*]} .
zforce=${makeforce}
}
_clean() {
rm -f \
gen-from-tmpl.*generated.go \
codecgen-*.go \
test_values.generated.go test_values_flex.generated.go
}
_release() {
local reply
read -p "Pre-release validation takes a few minutes and MUST be run from within GOPATH/src. Confirm y/n? " -n 1 -r reply
echo
if [[ ! $reply =~ ^[Yy]$ ]]; then return 1; fi
# expects GOROOT, GOROOT_BOOTSTRAP to have been set.
if [[ -z "${GOROOT// }" || -z "${GOROOT_BOOTSTRAP// }" ]]; then return 1; fi
# (cd $GOROOT && git checkout -f master && git pull && git reset --hard)
(cd $GOROOT && git pull)
local f=`pwd`/make.release.out
cat > $f <<EOF
========== `date` ===========
EOF
# # go 1.6 and below kept giving memory errors on Mac OS X during SDK build or go run execution,
# # that is fine, as we only explicitly test the last 3 releases and tip (2 years).
local makeforce=${zforce}
zforce=1
for i in 1.10 1.11 1.12 master
do
echo "*********** $i ***********" >>$f
if [[ "$i" != "master" ]]; then i="release-branch.go$i"; fi
(false ||
(echo "===== BUILDING GO SDK for branch: $i ... =====" &&
cd $GOROOT &&
git checkout -f $i && git reset --hard && git clean -f . &&
cd src && ./make.bash >>$f 2>&1 && sleep 1 ) ) &&
echo "===== GO SDK BUILD DONE =====" &&
_prebuild &&
echo "===== PREBUILD DONE with exit: $? =====" &&
_tests "$@"
if [[ "$?" != 0 ]]; then return 1; fi
done
zforce=${makeforce}
echo "++++++++ RELEASE TEST SUITES ALL PASSED ++++++++"
}
_usage() {
# hidden args:
# -pf [p=prebuild (f=force)]
cat <<EOF
primary usage: $0
-[tesow m n l d] -> [t=tests (e=extra, s=short, o=cover, w=wait), m=make, n=inlining diagnostics, l=mid-stack inlining, d=race detector]
-v -> v=verbose
EOF
if [[ "$(type -t _usage_run)" = "function" ]]; then _usage_run ; fi
}
_main() {
if [[ -z "$1" ]]; then _usage; return 1; fi
local x # determines the main action to run in this build
local zforce # force
local zcover # generate cover profile and show in browser when done
local zwait # run tests in sequence, not parallel ie wait for one to finish before starting another
local zextra # means run extra (python based tests, etc) during testing
local ztestargs=()
local zargs=()
local zverbose=()
local zbenchflags=""
local gocmd=${MYGOCMD:-go}
OPTIND=1
while getopts ":cetmnrgpfvlyzdsowxb:" flag
do
case "x$flag" in
'xo') zcover=1 ;;
'xe') zextra=1 ;;
'xw') zwait=1 ;;
'xf') zforce=1 ;;
'xs') ztestargs+=("-short") ;;
'xv') zverbose+=(1) ;;
'xl') zargs+=("-gcflags"); zargs+=("-l=4") ;;
'xn') zargs+=("-gcflags"); zargs+=("-m=2") ;;
'xd') zargs+=("-race") ;;
'xb') x='b'; zbenchflags=${OPTARG} ;;
x\?) _usage; return 1 ;;
*) x=$flag ;;
esac
done
shift $((OPTIND-1))
# echo ">>>> _main: extra args: $@"
case "x$x" in
'xt') _tests "$@" ;;
'xm') _make "$@" ;;
'xr') _release "$@" ;;
'xg') _go ;;
'xp') _prebuild "$@" ;;
'xc') _clean "$@" ;;
'xx') _analyze_checks "$@" ;;
'xy') _analyze_debug_types "$@" ;;
'xz') _analyze_do_inlining_and_more "$@" ;;
'xb') _bench "$@" ;;
esac
# unset zforce zargs zbenchflags
}
[ "." = `dirname $0` ] && _main "$@"

File diff suppressed because it is too large Load Diff

13
vendor/github.com/ugorji/go/codec/codecgen.go generated vendored Normal file
View File

@ -0,0 +1,13 @@
// +build codecgen generated
package codec
// this file sets the codecgen variable to true
// when the build tag codecgen is set.
//
// some tests depend on knowing whether in the context of codecgen or not.
// For example, some tests should be skipped during codecgen e.g. missing fields tests.
func init() {
codecgen = true
}

454
vendor/github.com/ugorji/go/codec/decimal.go generated vendored Normal file
View File

@ -0,0 +1,454 @@
// Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.
package codec
import (
"strconv"
)
// Per go spec, floats are represented in memory as
// IEEE single or double precision floating point values.
//
// We also looked at the source for stdlib math/modf.go,
// reviewed https://github.com/chewxy/math32
// and read wikipedia documents describing the formats.
//
// It became clear that we could easily look at the bits to determine
// whether any fraction exists.
func parseFloat32(b []byte) (f float32, err error) {
return parseFloat32_custom(b)
}
func parseFloat64(b []byte) (f float64, err error) {
return parseFloat64_custom(b)
}
func parseFloat32_strconv(b []byte) (f float32, err error) {
f64, err := strconv.ParseFloat(stringView(b), 32)
f = float32(f64)
return
}
func parseFloat64_strconv(b []byte) (f float64, err error) {
return strconv.ParseFloat(stringView(b), 64)
}
// ------ parseFloat custom below --------
// JSON really supports decimal numbers in base 10 notation, with exponent support.
//
// We assume the following:
// - a lot of floating point numbers in json files will have defined precision
// (in terms of number of digits after decimal point), etc.
// - these (referenced above) can be written in exact format.
//
// strconv.ParseFloat has some unnecessary overhead which we can do without
// for the common case:
//
// - expensive char-by-char check to see if underscores are in right place
// - testing for and skipping underscores
// - check if the string matches ignorecase +/- inf, +/- infinity, nan
// - support for base 16 (0xFFFF...)
//
// The functions below will try a fast-path for floats which can be decoded
// without any loss of precision, meaning they:
//
// - fits within the significand bits of the 32-bits or 64-bits
// - exponent fits within the exponent value
// - there is no truncation (any extra numbers are all trailing zeros)
//
// To figure out what the values are for maxMantDigits, use this idea below:
//
// 2^23 = 838 8608 (between 10^ 6 and 10^ 7) (significand bits of uint32)
// 2^32 = 42 9496 7296 (between 10^ 9 and 10^10) (full uint32)
// 2^52 = 4503 5996 2737 0496 (between 10^15 and 10^16) (significand bits of uint64)
// 2^64 = 1844 6744 0737 0955 1616 (between 10^19 and 10^20) (full uint64)
//
// Note: we only allow for up to what can comfortably fit into the significand
// ignoring the exponent, and we only try to parse iff significand fits.
const (
fMaxMultiplierForExactPow10_64 = 1e15
fMaxMultiplierForExactPow10_32 = 1e7
fUint64Cutoff = (1<<64-1)/10 + 1
// fUint32Cutoff = (1<<32-1)/10 + 1
fBase = 10
)
const (
thousand = 1000
million = thousand * thousand
billion = thousand * million
trillion = thousand * billion
quadrillion = thousand * trillion
quintillion = thousand * quadrillion
)
// Exact powers of 10.
var uint64pow10 = [...]uint64{
1, 10, 100,
1 * thousand, 10 * thousand, 100 * thousand,
1 * million, 10 * million, 100 * million,
1 * billion, 10 * billion, 100 * billion,
1 * trillion, 10 * trillion, 100 * trillion,
1 * quadrillion, 10 * quadrillion, 100 * quadrillion,
1 * quintillion, 10 * quintillion,
}
var float64pow10 = [...]float64{
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
1e20, 1e21, 1e22,
}
var float32pow10 = [...]float32{
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10,
}
type floatinfo struct {
mantbits uint8
// expbits uint8 // (unused)
// bias int16 // (unused)
is32bit bool
exactPow10 int8 // Exact powers of ten are <= 10^N (32: 10, 64: 22)
exactInts int8 // Exact integers are <= 10^N (for non-float, set to 0)
// maxMantDigits int8 // 10^19 fits in uint64, while 10^9 fits in uint32
mantCutoffIsUint64Cutoff bool
mantCutoff uint64
}
var fi32 = floatinfo{23, true, 10, 7, false, 1<<23 - 1}
var fi64 = floatinfo{52, false, 22, 15, false, 1<<52 - 1}
var fi64u = floatinfo{0, false, 19, 0, true, fUint64Cutoff}
var fi64i = floatinfo{0, false, 19, 0, true, fUint64Cutoff}
func strconvParseErr(b []byte, fn string) error {
return &strconv.NumError{
Func: fn,
Err: strconv.ErrSyntax,
Num: string(b),
}
}
func parseFloat32_reader(r readFloatResult) (f float32, fail bool) {
f = float32(r.mantissa)
if r.exp == 0 {
} else if r.exp < 0 { // int / 10^k
f /= float32pow10[uint8(-r.exp)]
} else { // exp > 0
if r.exp > fi32.exactPow10 {
f *= float32pow10[r.exp-fi32.exactPow10]
if f > fMaxMultiplierForExactPow10_32 { // exponent too large - outside range
fail = true
return // ok = false
}
f *= float32pow10[fi32.exactPow10]
} else {
f *= float32pow10[uint8(r.exp)]
}
}
if r.neg {
f = -f
}
return
}
func parseFloat32_custom(b []byte) (f float32, err error) {
r := readFloat(b, fi32)
if r.bad {
return 0, strconvParseErr(b, "ParseFloat")
}
if r.ok {
f, r.bad = parseFloat32_reader(r)
if !r.bad {
return
}
}
return parseFloat32_strconv(b)
}
func parseFloat64_reader(r readFloatResult) (f float64, fail bool) {
f = float64(r.mantissa)
if r.exp == 0 {
} else if r.exp < 0 { // int / 10^k
f /= float64pow10[-uint8(r.exp)]
} else { // exp > 0
if r.exp > fi64.exactPow10 {
f *= float64pow10[r.exp-fi64.exactPow10]
if f > fMaxMultiplierForExactPow10_64 { // exponent too large - outside range
fail = true
return
}
f *= float64pow10[fi64.exactPow10]
} else {
f *= float64pow10[uint8(r.exp)]
}
}
if r.neg {
f = -f
}
return
}
func parseFloat64_custom(b []byte) (f float64, err error) {
r := readFloat(b, fi64)
if r.bad {
return 0, strconvParseErr(b, "ParseFloat")
}
if r.ok {
f, r.bad = parseFloat64_reader(r)
if !r.bad {
return
}
}
return parseFloat64_strconv(b)
}
func parseUint64_simple(b []byte) (n uint64, ok bool) {
var i int
var n1 uint64
var c uint8
LOOP:
if i < len(b) {
c = b[i]
// unsigned integers don't overflow well on multiplication, so check cutoff here
// e.g. (maxUint64-5)*10 doesn't overflow well ...
// if n >= fUint64Cutoff || !isDigitChar(b[i]) { // if c < '0' || c > '9' {
if n >= fUint64Cutoff || c < '0' || c > '9' {
return
} else if c == '0' {
n *= fBase
} else {
n1 = n
n = n*fBase + uint64(c-'0')
if n < n1 {
return
}
}
i++
goto LOOP
}
ok = true
return
}
func parseUint64_reader(r readFloatResult) (f uint64, fail bool) {
f = r.mantissa
if r.exp == 0 {
} else if r.exp < 0 { // int / 10^k
if f%uint64pow10[uint8(-r.exp)] != 0 {
fail = true
} else {
f /= uint64pow10[uint8(-r.exp)]
}
} else { // exp > 0
f *= uint64pow10[uint8(r.exp)]
}
return
}
func parseInt64_reader(r readFloatResult) (v int64, fail bool) {
if r.exp == 0 {
} else if r.exp < 0 { // int / 10^k
if r.mantissa%uint64pow10[uint8(-r.exp)] != 0 {
// fail = true
return 0, true
}
r.mantissa /= uint64pow10[uint8(-r.exp)]
} else { // exp > 0
r.mantissa *= uint64pow10[uint8(r.exp)]
}
if chkOvf.Uint2Int(r.mantissa, r.neg) {
fail = true
} else if r.neg {
v = -int64(r.mantissa)
} else {
v = int64(r.mantissa)
}
return
}
// parseNumber will return an integer if only composed of [-]?[0-9]+
// Else it will return a float.
func parseNumber(b []byte, z *fauxUnion, preferSignedInt bool) (err error) {
var ok, neg bool
var f uint64
if len(b) == 0 {
return
}
if b[0] == '-' {
neg = true
f, ok = parseUint64_simple(b[1:])
} else {
f, ok = parseUint64_simple(b)
}
if ok {
if neg {
z.v = valueTypeInt
if chkOvf.Uint2Int(f, neg) {
return strconvParseErr(b, "ParseInt")
}
z.i = -int64(f)
} else if preferSignedInt {
z.v = valueTypeInt
if chkOvf.Uint2Int(f, neg) {
return strconvParseErr(b, "ParseInt")
}
z.i = int64(f)
} else {
z.v = valueTypeUint
z.u = f
}
return
}
z.v = valueTypeFloat
z.f, err = parseFloat64_custom(b)
return
}
type readFloatResult struct {
mantissa uint64
exp int8
neg, sawdot, sawexp, trunc, bad bool
ok bool
_ byte // padding
}
func readFloat(s []byte, y floatinfo) (r readFloatResult) {
var i uint // uint, so that we eliminate bounds checking
var slen = uint(len(s))
if slen == 0 {
// read an empty string as the zero value
// r.bad = true
r.ok = true
return
}
if s[0] == '-' {
r.neg = true
i++
}
// we considered punting early if string has length > maxMantDigits, but this doesn't account
// for trailing 0's e.g. 700000000000000000000 can be encoded exactly as it is 7e20
var nd, ndMant, dp int8
var xu uint64
LOOP:
for ; i < slen; i++ {
switch s[i] {
case '.':
if r.sawdot {
r.bad = true
return
}
r.sawdot = true
dp = nd
case 'e', 'E':
r.sawexp = true
break LOOP
case '0':
if nd == 0 {
dp--
continue LOOP
}
nd++
if r.mantissa < y.mantCutoff {
r.mantissa *= fBase
ndMant++
}
case '1', '2', '3', '4', '5', '6', '7', '8', '9':
nd++
if y.mantCutoffIsUint64Cutoff && r.mantissa < fUint64Cutoff {
r.mantissa *= fBase
xu = r.mantissa + uint64(s[i]-'0')
if xu < r.mantissa {
r.trunc = true
return
}
r.mantissa = xu
} else if r.mantissa < y.mantCutoff {
// mantissa = (mantissa << 1) + (mantissa << 3) + uint64(c-'0')
r.mantissa = r.mantissa*fBase + uint64(s[i]-'0')
} else {
r.trunc = true
return
}
ndMant++
default:
r.bad = true
return
}
}
if !r.sawdot {
dp = nd
}
if r.sawexp {
i++
if i < slen {
var eneg bool
if s[i] == '+' {
i++
} else if s[i] == '-' {
i++
eneg = true
}
if i < slen {
// for exact match, exponent is 1 or 2 digits (float64: -22 to 37, float32: -1 to 17).
// exit quick if exponent is more than 2 digits.
if i+2 < slen {
return
}
var e int8
if s[i] < '0' || s[i] > '9' { // !isDigitChar(s[i]) { //
r.bad = true
return
}
e = int8(s[i] - '0')
i++
if i < slen {
if s[i] < '0' || s[i] > '9' { // !isDigitChar(s[i]) { //
r.bad = true
return
}
e = e*fBase + int8(s[i]-'0') // (e << 1) + (e << 3) + int8(s[i]-'0')
i++
}
if eneg {
dp -= e
} else {
dp += e
}
}
}
}
if r.mantissa != 0 {
r.exp = dp - ndMant
// do not set ok=true for cases we cannot handle
if r.exp < -y.exactPow10 ||
r.exp > y.exactInts+y.exactPow10 ||
(y.mantbits != 0 && r.mantissa>>y.mantbits != 0) {
return
}
}
r.ok = true
return
}

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,10 @@
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file. // Use of this source code is governed by a MIT license found in the LICENSE file.
/* /*
High Performance, Feature-Rich Idiomatic Go codec/encoding library for Package codec provides a
binc, msgpack, cbor, json. High Performance, Feature-Rich Idiomatic Go 1.4+ codec/encoding library
for binc, msgpack, cbor, json.
Supported Serialization formats are: Supported Serialization formats are:
@ -11,21 +12,13 @@ Supported Serialization formats are:
- binc: http://github.com/ugorji/binc - binc: http://github.com/ugorji/binc
- cbor: http://cbor.io http://tools.ietf.org/html/rfc7049 - cbor: http://cbor.io http://tools.ietf.org/html/rfc7049
- json: http://json.org http://tools.ietf.org/html/rfc7159 - json: http://json.org http://tools.ietf.org/html/rfc7159
- simple: - simple:
To install: This package will carefully use 'package 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 ...'.
go get github.com/ugorji/go/codec This library works with both the standard `gc` and the `gccgo` compilers.
This package understands the 'unsafe' tag, to allow using unsafe semantics:
- When decoding into a struct, you need to read the field name as a string
so you can find the struct field it is mapped to.
Using `unsafe` will bypass the allocation and copying overhead of []byte->string conversion.
To install using unsafe, pass the 'unsafe' tag:
go get -tags=unsafe github.com/ugorji/go/codec
For detailed usage information, read the primer at http://ugorji.net/blog/go-codec-primer . For detailed usage information, read the primer at http://ugorji.net/blog/go-codec-primer .
@ -35,12 +28,17 @@ the standard library (ie json, xml, gob, etc).
Rich Feature Set includes: Rich Feature Set includes:
- Simple but extremely powerful and feature-rich API - Simple but extremely powerful and feature-rich API
- Support for go 1.4 and above, while selectively using newer APIs for later releases
- Excellent code coverage ( > 90% )
- Very High Performance. - Very High Performance.
Our extensive benchmarks show us outperforming Gob, Json, Bson, etc by 2-4X. Our extensive benchmarks show us outperforming Gob, Json, Bson, etc by 2-4X.
- Multiple conversions: - Careful selected use of 'unsafe' for targeted performance gains.
Package coerces types where appropriate - 100% safe mode supported, where 'unsafe' is not used at all.
e.g. decode an int in the stream into a float, etc. - Lock-free (sans mutex) concurrency for scaling to 100's of cores
- Corner Cases: - In-place updates during decode, with option to zero value in maps and slices prior to decode
- 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 Overflows, nil maps/slices, nil values in streams are handled correctly
- Standard field renaming via tags - Standard field renaming via tags
- Support for omitting empty fields during an encoding - Support for omitting empty fields during an encoding
@ -48,15 +46,21 @@ Rich Feature Set includes:
(struct, slice, map, primitives, pointers, interface{}, etc) (struct, slice, map, primitives, pointers, interface{}, etc)
- Extensions to support efficient encoding/decoding of any named types - Extensions to support efficient encoding/decoding of any named types
- Support encoding.(Binary|Text)(M|Unm)arshaler interfaces - Support encoding.(Binary|Text)(M|Unm)arshaler interfaces
- Support using existence of `IsZero() bool` to determine if a value is a zero value.
Analogous to time.Time.IsZero() bool.
- Decoding without a schema (into a interface{}). - Decoding without a schema (into a interface{}).
Includes Options to configure what specific map or slice type to use Includes Options to configure what specific map or slice type to use
when decoding an encoded list or map into a nil interface{} 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 - 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 - Comprehensive support for anonymous fields
- Fast (no-reflection) encoding/decoding of common maps and slices - Fast (no-reflection) encoding/decoding of common maps and slices
- Code-generation for faster performance. - Code-generation for faster performance, supported in go 1.6+
- Support binary (e.g. messagepack, cbor) and text (e.g. json) formats - Support binary (e.g. messagepack, cbor) and text (e.g. json) formats
- Support indefinite-length formats to enable true streaming - Support indefinite-length formats to enable true streaming
(for formats which support it e.g. json, cbor) (for formats which support it e.g. json, cbor)
- Support canonical encoding, where a value is ALWAYS encoded as same sequence of bytes. - 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. This mostly applies to maps, where iteration order is non-deterministic.
@ -68,12 +72,12 @@ Rich Feature Set includes:
- Encode/Decode from/to chan types (for iterative streaming support) - Encode/Decode from/to chan types (for iterative streaming support)
- Drop-in replacement for encoding/json. `json:` key in struct tag supported. - Drop-in replacement for encoding/json. `json:` key in struct tag supported.
- Provides a RPC Server and Client Codec for net/rpc communication protocol. - Provides a RPC Server and Client Codec for net/rpc communication protocol.
- Handle unique idiosynchracies of codecs e.g. - Handle unique idiosyncrasies of codecs e.g.
- For messagepack, configure how ambiguities in handling raw bytes are resolved - For messagepack, configure how ambiguities in handling raw bytes are resolved
- For messagepack, provide rpc server/client codec to support - For messagepack, provide rpc server/client codec to support
msgpack-rpc protocol defined at: msgpack-rpc protocol defined at:
https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md https://github.com/msgpack-rpc/msgpack-rpc/blob/master/spec.md
Extension Support Extension Support
Users can register a function to handle the encoding or decoding of Users can register a function to handle the encoding or decoding of
@ -92,6 +96,30 @@ 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 would be encoded as a string. However, with extension support, you can
encode any of these however you like. encode any of these however you like.
There is also seamless support provided for registering an extension (with a tag)
but letting the encoding mechanism default to the standard way.
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 there an extension registered for the type?
- is type a codec.Selfer?
- 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 and TextUnmarshaler?
- 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
RPC Client and Server Codecs are implemented, so the codecs can be used RPC Client and Server Codecs are implemented, so the codecs can be used
@ -160,40 +188,41 @@ Sample usage model:
//OR rpcCodec := codec.MsgpackSpecRpc.ClientCodec(conn, h) //OR rpcCodec := codec.MsgpackSpecRpc.ClientCodec(conn, h)
client := rpc.NewClientWithCodec(rpcCodec) 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
cd bench
go test -bench . -benchmem -benchtime 1s
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 package codec
// Benefits of go-codec:
//
// - encoding/json always reads whole file into memory first.
// This makes it unsuitable for parsing very large files.
// - encoding/xml cannot parse into a map[string]interface{}
// I found this out on reading https://github.com/clbanning/mxj
// TODO:
//
// - optimization for codecgen:
// if len of entity is <= 3 words, then support a value receiver for encode.
// - (En|De)coder should store an error when it occurs.
// Until reset, subsequent calls return that error that was stored.
// This means that free panics must go away.
// All errors must be raised through errorf method.
// - Decoding using a chan is good, but incurs concurrency costs.
// This is because there's no fast way to use a channel without it
// having to switch goroutines constantly.
// Callback pattern is still the best. Maybe cnsider supporting something like:
// type X struct {
// Name string
// Ys []Y
// Ys chan <- Y
// Ys func(Y) -> call this function for each entry
// }
// - Consider adding a isZeroer interface { isZero() bool }
// It is used within isEmpty, for omitEmpty support.
// - Consider making Handle used AS-IS within the encoding/decoding session.
// This means that we don't cache Handle information within the (En|De)coder,
// except we really need it at Reset(...)
// - Consider adding math/big support
// - Consider reducing the size of the generated functions:
// Maybe use one loop, and put the conditionals in the loop.
// for ... { if cLen > 0 { if j == cLen { break } } else if dd.CheckBreak() { break } }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,540 +1,554 @@
// +build !notfastpath // +build !notfastpath
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file. // 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.
// DO NOT EDIT.
// THIS FILE IS AUTO-GENERATED from fast-path.go.tmpl
// ************************************************************
package codec package codec
// Fast path functions try to create a fast path encode or decode implementation // Fast path functions try to create a fast path encode or decode implementation
// for common maps and slices. // for common maps and slices.
// //
// We define the functions and register then in this single file // We define the functions and register them in this single file
// so as not to pollute the encode.go and decode.go, and create a dependency in there. // 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. // This file can be omitted without causing a build failure.
// //
// The advantage of fast paths is: // The advantage of fast paths is:
// - Many calls bypass reflection altogether // - Many calls bypass reflection altogether
// //
// Currently support // Currently support
// - slice of all builtin types, // - slice of all builtin types (numeric, bool, string, []byte)
// - map of all builtin types to string or interface value // - maps of builtin types to builtin or interface{} type, EXCEPT FOR
// - symetrical maps of all builtin types (e.g. str-str, uint8-uint8) // keys of type uintptr, int8/16/32, uint16/32, float32/64, bool, interface{}
// AND values of type type int8/16/32, uint16/32
// This should provide adequate "typical" implementations. // This should provide adequate "typical" implementations.
// //
// Note that fast track decode functions must handle values for which an address cannot be obtained. // Note that fast track decode functions must handle values for which an address cannot be obtained.
// For example: // For example:
// m2 := map[string]int{} // m2 := map[string]int{}
// p2 := []interface{}{m2} // p2 := []interface{}{m2}
// // decoding into p2 will bomb if fast track functions do not treat like unaddressable. // // decoding into p2 will bomb if fast track functions do not treat like unaddressable.
// //
{{/*
fastpathEncMapStringUint64R (called by fastpath...switch)
EncMapStringUint64V (called by codecgen)
fastpathEncSliceBoolR: (called by fastpath...switch) (checks f.ti.mbs and calls one of them below)
EncSliceBoolV (also called by codecgen)
EncAsMapSliceBoolV (delegate when mapbyslice=true)
fastpathDecSliceIntfR (called by fastpath...switch) (calls Y or N below depending on if it can be updated)
DecSliceIntfX (called by codecgen) (calls Y below)
DecSliceIntfY (delegate when slice CAN be updated)
DecSliceIntfN (delegate when slice CANNOT be updated e.g. from array or non-addressable slice)
fastpathDecMap...R (called by fastpath...switch) (calls L or X? below)
DecMap...X (called by codecgen)
DecMap...L (delegated to by both above)
*/ -}}
import ( import (
"reflect" "reflect"
"sort" "sort"
) )
const fastpathCheckNilFalse = false // for reflect const fastpathEnabled = true
const fastpathCheckNilTrue = true // for type switch
{{/*
const fastpathMapBySliceErrMsg = "mapBySlice requires even slice length, but got %v"
*/ -}}
type fastpathT struct {} type fastpathT struct {}
var fastpathTV fastpathT var fastpathTV fastpathT
type fastpathE struct { type fastpathE struct {
rtid uintptr {{/* rtid uintptr */ -}}
rt reflect.Type rt reflect.Type
encfn func(*encFnInfo, reflect.Value) encfn func(*Encoder, *codecFnInfo, reflect.Value)
decfn func(*decFnInfo, reflect.Value) decfn func(*Decoder, *codecFnInfo, reflect.Value)
} }
type fastpathA [{{ .FastpathLen }}]fastpathE type fastpathA [{{ .FastpathLen }}]fastpathE
type fastpathARtid [{{ .FastpathLen }}]uintptr
func (x *fastpathA) index(rtid uintptr) int { var fastpathAv fastpathA
var fastpathAvRtid fastpathARtid
type fastpathAslice struct{}
func (fastpathAslice) Len() int { return {{ .FastpathLen }} }
func (fastpathAslice) Less(i, j int) bool {
return fastpathAvRtid[uint(i)] < fastpathAvRtid[uint(j)]
}
func (fastpathAslice) Swap(i, j int) {
fastpathAvRtid[uint(i)], fastpathAvRtid[uint(j)] = fastpathAvRtid[uint(j)], fastpathAvRtid[uint(i)]
fastpathAv[uint(i)], fastpathAv[uint(j)] = fastpathAv[uint(j)], fastpathAv[uint(i)]
}
func fastpathAvIndex(rtid uintptr) int {
// use binary search to grab the index (adapted from sort/search.go) // use binary search to grab the index (adapted from sort/search.go)
h, i, j := 0, 0, {{ .FastpathLen }} // len(x) // Note: we use goto (instead of for loop) so this can be inlined.
for i < j { // h, i, j := 0, 0, {{ .FastpathLen }}
h = i + (j-i)/2 var h, i uint
if x[h].rtid < rtid { var j uint = {{ .FastpathLen }}
LOOP:
if i < j {
h = (i + j) >> 1 // avoid overflow when computing h // h = i + (j-i)/2
if fastpathAvRtid[h] < rtid {
i = h + 1 i = h + 1
} else { } else {
j = h j = h
} }
goto LOOP
} }
if i < {{ .FastpathLen }} && x[i].rtid == rtid { if i < {{ .FastpathLen }} && fastpathAvRtid[i] == rtid {
return i return int(i)
} }
return -1 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() // due to possible initialization loop error, make fastpath in an init()
func init() { func init() {
if !fastpathEnabled { var i uint = 0
return fn := func(v interface{},
} fe func(*Encoder, *codecFnInfo, reflect.Value),
i := 0 fd func(*Decoder, *codecFnInfo, reflect.Value)) {
fn := func(v interface{}, fe func(*encFnInfo, reflect.Value), fd func(*decFnInfo, reflect.Value)) (f fastpathE) {
xrt := reflect.TypeOf(v) xrt := reflect.TypeOf(v)
xptr := reflect.ValueOf(xrt).Pointer() xptr := rt2id(xrt)
fastpathAV[i] = fastpathE{xptr, xrt, fe, fd} fastpathAvRtid[i] = xptr
fastpathAv[i] = fastpathE{xrt, fe, fd}
i++ i++
return
} }
{{/* do not register []byte in fast-path */}}
{{range .Values}}{{if not .Primitive}}{{if not .MapKey -}}
fn([]{{ .Elem }}(nil), (*Encoder).{{ .MethodNamePfx "fastpathEnc" false }}R, (*Decoder).{{ .MethodNamePfx "fastpathDec" false }}R)
{{end}}{{end}}{{end}}
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }} {{range .Values}}{{if not .Primitive}}{{if .MapKey -}}
fn([]{{ .Elem }}(nil), (*encFnInfo).{{ .MethodNamePfx "fastpathEnc" false }}R, (*decFnInfo).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}} fn(map[{{ .MapKey }}]{{ .Elem }}(nil), (*Encoder).{{ .MethodNamePfx "fastpathEnc" false }}R, (*Decoder).{{ .MethodNamePfx "fastpathDec" false }}R)
{{end}}{{end}}{{end}}
{{range .Values}}{{if not .Primitive}}{{if .MapKey }} sort.Sort(fastpathAslice{})
fn(map[{{ .MapKey }}]{{ .Elem }}(nil), (*encFnInfo).{{ .MethodNamePfx "fastpathEnc" false }}R, (*decFnInfo).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}}
sort.Sort(fastpathAslice(fastpathAV[:]))
} }
// -- encode // -- encode
// -- -- fast path type switch // -- -- fast path type switch
func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool {
if !fastpathEnabled {
return false
}
switch v := iv.(type) { switch v := iv.(type) {
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }} {{range .Values}}{{if not .Primitive}}{{if not .MapKey -}}
case []{{ .Elem }}:{{else}}
case map[{{ .MapKey }}]{{ .Elem }}:{{end}}
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, fastpathCheckNilTrue, e){{if not .MapKey }}
case *[]{{ .Elem }}:{{else}}
case *map[{{ .MapKey }}]{{ .Elem }}:{{end}}
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, fastpathCheckNilTrue, e)
{{end}}{{end}}
default:
_ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release)
return false
}
return true
}
func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool {
if !fastpathEnabled {
return false
}
switch v := iv.(type) {
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }}
case []{{ .Elem }}: case []{{ .Elem }}:
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, fastpathCheckNilTrue, e) fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
case *[]{{ .Elem }}: case *[]{{ .Elem }}:
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, fastpathCheckNilTrue, e) if *v == nil {
{{end}}{{end}}{{end}} e.e.EncodeNil()
default: } else {
_ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release) fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e)
return false }
} {{end}}{{end}}{{end -}}
return true
}
func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { {{range .Values}}{{if not .Primitive}}{{if .MapKey -}}
if !fastpathEnabled {
return false
}
switch v := iv.(type) {
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
case map[{{ .MapKey }}]{{ .Elem }}: case map[{{ .MapKey }}]{{ .Elem }}:
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, fastpathCheckNilTrue, e) fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
case *map[{{ .MapKey }}]{{ .Elem }}: case *map[{{ .MapKey }}]{{ .Elem }}:
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, fastpathCheckNilTrue, e) if *v == nil {
{{end}}{{end}}{{end}} e.e.EncodeNil()
} else {
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, e)
}
{{end}}{{end}}{{end -}}
default: default:
_ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release) _ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
return false return false
} }
return true return true
} }
// -- -- fast path functions // -- -- fast path functions
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }} {{range .Values}}{{if not .Primitive}}{{if not .MapKey -}}
func (e *Encoder) {{ .MethodNamePfx "fastpathEnc" false }}R(f *codecFnInfo, rv reflect.Value) {
func (f *encFnInfo) {{ .MethodNamePfx "fastpathEnc" false }}R(rv reflect.Value) { var v []{{ .Elem }}
if f.ti.mbs { if rv.Kind() == reflect.Array {
fastpathTV.{{ .MethodNamePfx "EncAsMap" false }}V(rv.Interface().([]{{ .Elem }}), fastpathCheckNilFalse, f.e) rvGetSlice4Array(rv, &v)
} else { } else {
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv.Interface().([]{{ .Elem }}), fastpathCheckNilFalse, f.e) v = rv2i(rv).([]{{ .Elem }})
}
if f.ti.mbs {
fastpathTV.{{ .MethodNamePfx "EncAsMap" false }}V(v, e)
} else {
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, e)
} }
} }
func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v []{{ .Elem }}, checkNil bool, e *Encoder) { func (fastpathT) {{ .MethodNamePfx "Enc" false }}V(v []{{ .Elem }}, e *Encoder) {
ee := e.e {{/* if v == nil { e.e.EncodeNil(); return } */ -}}
cr := e.cr {{ if eq .Elem "uint8" "byte" -}}
if checkNil && v == nil { e.e.EncodeStringBytesRaw(v)
ee.EncodeNil() {{ else -}}
return e.arrayStart(len(v))
} for j := range v {
ee.EncodeArrayStart(len(v)) e.arrayElem()
for _, v2 := range v { {{ encmd .Elem "v[j]"}}
if cr != nil { cr.sendContainerState(containerArrayElem) } }
{{ encmd .Elem "v2"}} e.arrayEnd()
} {{ end -}}
if cr != nil { cr.sendContainerState(containerArrayEnd) }{{/* ee.EncodeEnd() */}}
} }
func (fastpathT) {{ .MethodNamePfx "EncAsMap" false }}V(v []{{ .Elem }}, e *Encoder) {
func (_ fastpathT) {{ .MethodNamePfx "EncAsMap" false }}V(v []{{ .Elem }}, checkNil bool, e *Encoder) { {{/* if v == nil { e.e.EncodeNil() } else */ -}}
ee := e.e e.haltOnMbsOddLen(len(v))
cr := e.cr {{/*
if checkNil && v == nil { if len(v)&1 != 0 { // similar to &1==1 or %2 == 1
ee.EncodeNil() e.errorf(fastpathMapBySliceErrMsg, len(v))
return
} }
if len(v)%2 == 1 { */ -}}
e.errorf("mapBySlice requires even slice length, but got %v", len(v)) e.mapStart(len(v) >> 1) // e.mapStart(len(v) / 2)
return for j := range v {
} if j&1 == 0 { // if j%2 == 0 {
ee.EncodeMapStart(len(v) / 2) e.mapElemKey()
for j, v2 := range v { } else {
if cr != nil { e.mapElemValue()
if j%2 == 0 {
cr.sendContainerState(containerMapKey)
} else {
cr.sendContainerState(containerMapValue)
}
} }
{{ encmd .Elem "v2"}} {{ encmd .Elem "v[j]"}}
} }
if cr != nil { cr.sendContainerState(containerMapEnd) } e.mapEnd()
} }
{{end}}{{end}}{{end -}}
{{end}}{{end}}{{end}} {{range .Values}}{{if not .Primitive}}{{if .MapKey -}}
func (e *Encoder) {{ .MethodNamePfx "fastpathEnc" false }}R(f *codecFnInfo, rv reflect.Value) {
{{range .Values}}{{if not .Primitive}}{{if .MapKey }} fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv2i(rv).(map[{{ .MapKey }}]{{ .Elem }}), e)
func (f *encFnInfo) {{ .MethodNamePfx "fastpathEnc" false }}R(rv reflect.Value) {
fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv.Interface().(map[{{ .MapKey }}]{{ .Elem }}), fastpathCheckNilFalse, f.e)
} }
func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v map[{{ .MapKey }}]{{ .Elem }}, checkNil bool, e *Encoder) { func (fastpathT) {{ .MethodNamePfx "Enc" false }}V(v map[{{ .MapKey }}]{{ .Elem }}, e *Encoder) {
ee := e.e {{/* if v == nil { e.e.EncodeNil(); return } */ -}}
cr := e.cr e.mapStart(len(v))
if checkNil && v == nil { if e.h.Canonical { {{/* need to figure out .NoCanonical */}}
ee.EncodeNil() {{if eq .MapKey "interface{}"}}{{/* out of band */ -}}
return var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding
}
ee.EncodeMapStart(len(v))
{{if eq .MapKey "string"}}asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0
{{end}}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) e2 := NewEncoderBytes(&mksv, e.hh)
v2 := make([]bytesI, len(v)) v2 := make([]bytesIntf, len(v))
var i, l int var i, l uint {{/* put loop variables outside. seems currently needed for better perf */}}
var vp *bytesI {{/* put loop variables outside. seems currently needed for better perf */}} var vp *bytesIntf
for k2, _ := range v { for k2 := range v {
l = len(mksv) l = uint(len(mksv))
e2.MustEncode(k2) e2.MustEncode(k2)
vp = &v2[i] vp = &v2[i]
vp.v = mksv[l:] vp.v = mksv[l:]
vp.i = k2 vp.i = k2
i++ i++
} }
sort.Sort(bytesISlice(v2)) sort.Sort(bytesIntfSlice(v2))
for j := range v2 { for j := range v2 {
if cr != nil { cr.sendContainerState(containerMapKey) } e.mapElemKey()
e.asis(v2[j].v) e.asis(v2[j].v)
if cr != nil { cr.sendContainerState(containerMapValue) } e.mapElemValue()
e.encode(v[v2[j].i]) e.encode(v[v2[j].i])
} {{else}}{{ $x := sorttype .MapKey true}}v2 := make([]{{ $x }}, len(v)) } {{else}}{{ $x := sorttype .MapKey true}}v2 := make([]{{ $x }}, len(v))
var i int var i uint
for k, _ := range v { for k := range v {
v2[i] = {{ $x }}(k) v2[i] = {{if eq $x .MapKey}}k{{else}}{{ $x }}(k){{end}}
i++ i++
} }
sort.Sort({{ sorttype .MapKey false}}(v2)) sort.Sort({{ sorttype .MapKey false}}(v2))
for _, k2 := range v2 { for _, k2 := range v2 {
if cr != nil { cr.sendContainerState(containerMapKey) } e.mapElemKey()
{{if eq .MapKey "string"}}if asSymbols { {{if eq .MapKey "string"}} e.e.EncodeString(k2) {{else}}{{ $y := printf "%s(k2)" .MapKey }}{{if eq $x .MapKey }}{{ $y = "k2" }}{{end}}{{ encmd .MapKey $y }}{{end}}
ee.EncodeSymbol(k2) e.mapElemValue()
} else { {{ $y := printf "v[%s(k2)]" .MapKey }}{{if eq $x .MapKey }}{{ $y = "v[k2]" }}{{end}}{{ encmd .Elem $y }}
ee.EncodeString(c_UTF8, k2)
}{{else}}{{ $y := printf "%s(k2)" .MapKey }}{{ encmd .MapKey $y }}{{end}}
if cr != nil { cr.sendContainerState(containerMapValue) }
{{ $y := printf "v[%s(k2)]" .MapKey }}{{ encmd .Elem $y }}
} {{end}} } {{end}}
} else { } else {
for k2, v2 := range v { for k2, v2 := range v {
if cr != nil { cr.sendContainerState(containerMapKey) } e.mapElemKey()
{{if eq .MapKey "string"}}if asSymbols { {{if eq .MapKey "string"}} e.e.EncodeString(k2) {{else}}{{ encmd .MapKey "k2"}}{{end}}
ee.EncodeSymbol(k2) e.mapElemValue()
} else {
ee.EncodeString(c_UTF8, k2)
}{{else}}{{ encmd .MapKey "k2"}}{{end}}
if cr != nil { cr.sendContainerState(containerMapValue) }
{{ encmd .Elem "v2"}} {{ encmd .Elem "v2"}}
} }
} }
if cr != nil { cr.sendContainerState(containerMapEnd) }{{/* ee.EncodeEnd() */}} e.mapEnd()
} }
{{end}}{{end}}{{end -}}
{{end}}{{end}}{{end}}
// -- decode // -- decode
// -- -- fast path type switch // -- -- fast path type switch
func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool {
if !fastpathEnabled { var changed bool
var containerLen int
switch v := iv.(type) {
{{range .Values}}{{if not .Primitive}}{{if not .MapKey -}}
case []{{ .Elem }}:
fastpathTV.{{ .MethodNamePfx "Dec" false }}N(v, d)
case *[]{{ .Elem }}:
var v2 []{{ .Elem }}
if v2, changed = fastpathTV.{{ .MethodNamePfx "Dec" false }}Y(*v, d); changed {
*v = v2
}
{{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 }}:
containerLen = d.mapStart(d.d.ReadMapStart())
if containerLen != containerLenNil {
if containerLen != 0 {
fastpathTV.{{ .MethodNamePfx "Dec" false }}L(v, containerLen, d)
}
d.mapEnd()
}
case *map[{{ .MapKey }}]{{ .Elem }}:
{{/*
containerLen = d.mapStart(d.d.ReadMapStart())
if containerLen == 0 {
d.mapEnd()
} else if containerLen == containerLenNil {
*v = nil
} else {
if *v == nil {
*v = make(map[{{ .MapKey }}]{{ .Elem }}, decInferLen(containerLen, d.h.MaxInitLen, {{ .Size }}))
}
fastpathTV.{{ .MethodNamePfx "Dec" false }}L(*v, containerLen, d)
}
// consider delegating fully to X - encoding *map is uncommon, so ok to pay small function call cost
*/ -}}
fastpathTV.{{ .MethodNamePfx "Dec" false }}X(v, d)
{{end}}{{end}}{{end -}}
default:
_ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
return false return false
} }
return true
}
func fastpathDecodeSetZeroTypeSwitch(iv interface{}) bool {
switch v := iv.(type) { switch v := iv.(type) {
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }} {{range .Values}}{{if not .Primitive}}{{if not .MapKey -}}
case []{{ .Elem }}:{{else}} case *[]{{ .Elem }}:
case map[{{ .MapKey }}]{{ .Elem }}:{{end}} *v = nil
fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, fastpathCheckNilFalse, false, d){{if not .MapKey }} {{end}}{{end}}{{end}}
case *[]{{ .Elem }}:{{else}} {{range .Values}}{{if not .Primitive}}{{if .MapKey -}}
case *map[{{ .MapKey }}]{{ .Elem }}:{{end}} case *map[{{ .MapKey }}]{{ .Elem }}:
v2, changed2 := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*v, fastpathCheckNilFalse, true, d) *v = nil
if changed2 { {{end}}{{end}}{{end}}
*v = v2
}
{{end}}{{end}}
default: default:
_ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release) _ = v // workaround https://github.com/golang/go/issues/12927 seen in go1.4
return false return false
} }
return true return true
} }
// -- -- fast path functions // -- -- fast path functions
{{range .Values}}{{if not .Primitive}}{{if not .MapKey }} {{range .Values}}{{if not .Primitive}}{{if not .MapKey -}}
{{/* {{/*
Slices can change if they Slices can change if they
- did not come from an array - did not come from an array
- are addressable (from a ptr) - are addressable (from a ptr)
- are settable (e.g. contained in an interface{}) - are settable (e.g. contained in an interface{})
*/}} */}}
func (f *decFnInfo) {{ .MethodNamePfx "fastpathDec" false }}R(rv reflect.Value) { func (d *Decoder) {{ .MethodNamePfx "fastpathDec" false }}R(f *codecFnInfo, rv reflect.Value) {
array := f.seq == seqTypeArray {{/*
if !array && rv.CanAddr() { {{/* // CanSet => CanAddr + Exported */}} // seqTypeArray=true means that we are not getting a pointer, so no need to check that.
vp := rv.Addr().Interface().(*[]{{ .Elem }}) if f.seq != seqTypeArray && rv.Kind() == reflect.Ptr {
v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, fastpathCheckNilFalse, !array, f.d) */ -}}
if changed { var v []{{ .Elem }}
switch rv.Kind() {
case reflect.Ptr:
vp := rv2i(rv).(*[]{{ .Elem }})
var changed bool
if v, changed = fastpathTV.{{ .MethodNamePfx "Dec" false }}Y(*vp, d); changed {
*vp = v *vp = v
} }
} else { case reflect.Array:
v := rv.Interface().([]{{ .Elem }}) rvGetSlice4Array(rv, &v)
fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, fastpathCheckNilFalse, false, f.d) fastpathTV.{{ .MethodNamePfx "Dec" false }}N(v, d)
default:
fastpathTV.{{ .MethodNamePfx "Dec" false }}N(rv2i(rv).([]{{ .Elem }}), d)
} }
} }
func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *[]{{ .Elem }}, d *Decoder) {
func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *[]{{ .Elem }}, checkNil bool, d *Decoder) { if v, changed := f.{{ .MethodNamePfx "Dec" false }}Y(*vp, d); changed { *vp = v }
v, changed := f.{{ .MethodNamePfx "Dec" false }}V(*vp, checkNil, true, d)
if changed {
*vp = v
}
} }
func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, checkNil bool, canChange bool, d *Decoder) (_ []{{ .Elem }}, changed bool) { func (fastpathT) {{ .MethodNamePfx "Dec" false }}Y(v []{{ .Elem }}, d *Decoder) (v2 []{{ .Elem }}, changed bool) {
dd := d.d {{ if eq .Elem "uint8" "byte" -}}
{{/* // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() */}} switch d.d.ContainerType() {
if checkNil && dd.TryDecodeAsNil() { case valueTypeNil, valueTypeMap:
if v != nil { break
changed = true default:
} v2 = d.decodeBytesInto(v[:len(v):len(v)])
return nil, changed changed = !(len(v2) > 0 && len(v2) == len(v) && &v2[0] == &v[0]) // not same slice
return
} }
{{ end -}}
slh, containerLenS := d.decSliceHelperStart() slh, containerLenS := d.decSliceHelperStart()
if slh.IsNil {
if v == nil { return }
return nil, true
}
if containerLenS == 0 { if containerLenS == 0 {
if canChange { if v == nil { v = []{{ .Elem }}{} } else if len(v) != 0 { v = v[:0] }
if v == nil {
v = []{{ .Elem }}{}
} else if len(v) != 0 {
v = v[:0]
}
changed = true
}
slh.End() slh.End()
return v, changed return v, true
} }
hasLen := containerLenS > 0
if containerLenS > 0 { var xlen int
x2read := containerLenS if hasLen {
var xtrunc bool
if containerLenS > cap(v) { if containerLenS > cap(v) {
if canChange { {{/* xlen = decInferLen(containerLenS, d.h.MaxInitLen, {{ .Size }})
// fast-path is for "basic" immutable types, so no need to copy them over if xlen <= cap(v) {
// s := make([]{{ .Elem }}, decInferLen(containerLenS, d.h.MaxInitLen)) v = v[:uint(xlen)]
// copy(s, v[:cap(v)])
// v = s */}}
var xlen int
xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, {{ .Size }})
if xtrunc {
if xlen <= cap(v) {
v = v[:xlen]
} else {
v = make([]{{ .Elem }}, xlen)
}
} else {
v = make([]{{ .Elem }}, xlen)
}
changed = true
} else { } else {
d.arrayCannotExpand(len(v), containerLenS) v = make([]{{ .Elem }}, uint(xlen))
} }
x2read = len(v) changed = true
} else if containerLenS != len(v) { } else if containerLenS != len(v) {
if canChange { v = v[:containerLenS]
v = v[:containerLenS]
changed = true
}
} {{/* // all checks done. cannot go past len. */}}
j := 0
for ; j < x2read; j++ {
slh.ElemContainerState(j)
{{ if eq .Elem "interface{}" }}d.decode(&v[j]){{ else }}v[j] = {{ decmd .Elem }}{{ end }}
}
if xtrunc { {{/* // means canChange=true, changed=true already. */}}
for ; j < containerLenS; j++ {
v = append(v, {{ zerocmd .Elem }})
slh.ElemContainerState(j)
{{ if eq .Elem "interface{}" }}d.decode(&v[j]){{ else }}v[j] = {{ decmd .Elem }}{{ end }}
}
} else if !canChange {
for ; j < containerLenS; j++ {
slh.ElemContainerState(j)
d.swallow()
}
}
} else {
breakFound := dd.CheckBreak() {{/* check break first, so we can initialize v with a capacity of 4 if necessary */}}
if breakFound {
if canChange {
if v == nil {
v = []{{ .Elem }}{}
} else if len(v) != 0 {
v = v[:0]
}
changed = true
}
slh.End()
return v, changed
}
if cap(v) == 0 {
v = make([]{{ .Elem }}, 1, 4)
changed = true
}
j := 0
for ; !breakFound; j++ {
if j >= len(v) {
if canChange {
v = append(v, {{ zerocmd .Elem }})
changed = true
} else {
d.arrayCannotExpand(len(v), j+1)
}
}
slh.ElemContainerState(j)
if j < len(v) { {{/* // all checks done. cannot go past len. */}}
{{ if eq .Elem "interface{}" }}d.decode(&v[j])
{{ else }}v[j] = {{ decmd .Elem }}{{ end }}
} else {
d.swallow()
}
breakFound = dd.CheckBreak()
}
if canChange && j < len(v) {
v = v[:j]
changed = true changed = true
} }
} }
slh.End() var j int
return v, changed for j = 0; (hasLen && j < containerLenS) || !(hasLen || d.checkBreak()); j++ {
if j == 0 && len(v) == 0 { // means hasLen == false
xlen = decInferLen(containerLenS, d.h.MaxInitLen, {{ .Size }}) {{/* xlen = decDefSliceCap */}}
v = make([]{{ .Elem }}, uint(xlen))
changed = true
}
{{/* // if indefinite, etc, then expand the slice if necessary */ -}}
if j >= len(v) {
v = append(v, {{ zerocmd .Elem }})
changed = true
}
slh.ElemContainerState(j)
{{ if eq .Elem "interface{}" }}d.decode(&v[uint(j)]){{ else }}v[uint(j)] = {{ decmd .Elem false }}{{ end }}
}
if j < len(v) {
v = v[:uint(j)]
changed = true
} else if j == 0 && v == nil {
v = []{{ .Elem }}{}
changed = true
}
slh.End()
return v, changed
} }
func (fastpathT) {{ .MethodNamePfx "Dec" false }}N(v []{{ .Elem }}, d *Decoder) {
{{ if eq .Elem "uint8" "byte" -}}
switch d.d.ContainerType() {
case valueTypeNil, valueTypeMap:
break
default:
v2 := d.decodeBytesInto(v[:len(v):len(v)])
if !(len(v2) > 0 && len(v2) == len(v) && &v2[0] == &v[0]) { // not same slice
copy(v, v2)
}
return
}
{{ end -}}
slh, containerLenS := d.decSliceHelperStart()
if slh.IsNil {
return
}
if containerLenS == 0 {
slh.End()
return
}
hasLen := containerLenS > 0
for j := 0; (hasLen && j < containerLenS) || !(hasLen || d.checkBreak()); j++ {
{{/* // if indefinite, etc, then expand the slice if necessary */ -}}
if j >= len(v) {
slh.arrayCannotExpand(hasLen, len(v), j, containerLenS)
return
}
slh.ElemContainerState(j)
{{ if eq .Elem "interface{}" -}}
d.decode(&v[uint(j)])
{{- else -}}
v[uint(j)] = {{ decmd .Elem false }}
{{- end }}
}
slh.End()
}
{{end}}{{end}}{{end -}}
{{end}}{{end}}{{end}} {{range .Values}}{{if not .Primitive}}{{if .MapKey -}}
{{range .Values}}{{if not .Primitive}}{{if .MapKey }}
{{/* {{/*
Maps can change if they are Maps can change if they are
- addressable (from a ptr) - addressable (from a ptr)
- settable (e.g. contained in an interface{}) - settable (e.g. contained in an interface{})
*/}}
func (f *decFnInfo) {{ .MethodNamePfx "fastpathDec" false }}R(rv reflect.Value) { Also, these methods are called by decodeValue directly, after handling a TryNil.
if rv.CanAddr() { Consequently, there's no need to check for containerLenNil here.
vp := rv.Addr().Interface().(*map[{{ .MapKey }}]{{ .Elem }}) */ -}}
v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, fastpathCheckNilFalse, true, f.d) func (d *Decoder) {{ .MethodNamePfx "fastpathDec" false }}R(f *codecFnInfo, rv reflect.Value) {
if changed { containerLen := d.mapStart(d.d.ReadMapStart())
*vp = v {{/*
if containerLen == containerLenNil {
if rv.Kind() == reflect.Ptr {
*(rv2i(rv).(*map[{{ .MapKey }}]{{ .Elem }})) = nil
} }
return
}
*/ -}}
if rv.Kind() == reflect.Ptr {
vp, _ := rv2i(rv).(*map[{{ .MapKey }}]{{ .Elem }})
if *vp == nil {
*vp = make(map[{{ .MapKey }}]{{ .Elem }}, decInferLen(containerLen, d.h.MaxInitLen, {{ .Size }}))
}
if containerLen != 0 {
fastpathTV.{{ .MethodNamePfx "Dec" false }}L(*vp, containerLen, d)
}
} else if containerLen != 0 {
fastpathTV.{{ .MethodNamePfx "Dec" false }}L(rv2i(rv).(map[{{ .MapKey }}]{{ .Elem }}), containerLen, d)
}
d.mapEnd()
}
func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *map[{{ .MapKey }}]{{ .Elem }}, d *Decoder) {
containerLen := d.mapStart(d.d.ReadMapStart())
if containerLen == containerLenNil {
*vp = nil
} else { } else {
v := rv.Interface().(map[{{ .MapKey }}]{{ .Elem }}) if *vp == nil {
fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, fastpathCheckNilFalse, false, f.d) *vp = make(map[{{ .MapKey }}]{{ .Elem }}, decInferLen(containerLen, d.h.MaxInitLen, {{ .Size }}))
}
if containerLen != 0 {
f.{{ .MethodNamePfx "Dec" false }}L(*vp, containerLen, d)
}
d.mapEnd()
} }
} }
func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *map[{{ .MapKey }}]{{ .Elem }}, checkNil bool, d *Decoder) { func (fastpathT) {{ .MethodNamePfx "Dec" false }}L(v map[{{ .MapKey }}]{{ .Elem }}, containerLen int, d *Decoder) {
v, changed := f.{{ .MethodNamePfx "Dec" false }}V(*vp, checkNil, true, d) {{/* No need to check if containerLen == containerLenNil, as that is checked by R and L above */ -}}
if changed { if v == nil {
*vp = v d.errorf("cannot decode into nil map[{{ .MapKey }}]{{ .Elem }} given stream length: %v", containerLen)
{{/* d.swallowMapContents(containerLen) */ -}}
return
} }
} {{if eq .Elem "interface{}" }}mapGet := v != nil && !d.h.MapValueReset && !d.h.InterfaceReset
func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v map[{{ .MapKey }}]{{ .Elem }}, checkNil bool, canChange bool, {{else if eq .Elem "bytes" "[]byte" }}mapGet := v != nil && !d.h.MapValueReset
d *Decoder) (_ map[{{ .MapKey }}]{{ .Elem }}, changed bool) { {{end -}}
dd := d.d var mk {{ .MapKey }}
cr := d.cr
{{/* // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() */}}
if checkNil && dd.TryDecodeAsNil() {
if v != nil {
changed = true
}
return nil, changed
}
containerLen := dd.ReadMapStart()
if canChange && v == nil {
xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, {{ .Size }})
v = make(map[{{ .MapKey }}]{{ .Elem }}, xlen)
changed = true
}
{{ if eq .Elem "interface{}" }}mapGet := !d.h.MapValueReset && !d.h.InterfaceReset{{end}}
var mk {{ .MapKey }}
var mv {{ .Elem }} var mv {{ .Elem }}
if containerLen > 0 { hasLen := containerLen > 0
for j := 0; j < containerLen; j++ { for j := 0; (hasLen && j < containerLen) || !(hasLen || d.checkBreak()); j++ {
if cr != nil { cr.sendContainerState(containerMapKey) } d.mapElemKey()
{{ if eq .MapKey "interface{}" }}mk = nil {{ if eq .MapKey "interface{}" }}mk = nil
d.decode(&mk) d.decode(&mk)
if bv, bok := mk.([]byte); bok { if bv, bok := mk.([]byte); bok {
mk = d.string(bv) {{/* // maps cannot have []byte as key. switch to string. */}} mk = d.stringZC(bv) {{/* // maps cannot have []byte as key. switch to string. */}}
}{{ else }}mk = {{ decmd .MapKey }}{{ end }} }{{ else }}mk = {{ decmd .MapKey true }}{{ end }}
if cr != nil { cr.sendContainerState(containerMapValue) } d.mapElemValue()
{{ if eq .Elem "interface{}" }}if mapGet { mv = v[mk] } else { mv = nil } {{ if eq .Elem "interface{}" "[]byte" "bytes" -}}
d.decode(&mv){{ else }}mv = {{ decmd .Elem }}{{ end }} if mapGet { mv = v[mk] } else { mv = nil }
if v != nil { {{ end -}}
v[mk] = mv {{ if eq .Elem "interface{}" -}}
} d.decode(&mv)
} {{ else if eq .Elem "[]byte" "bytes" -}}
} else if containerLen < 0 { mv = d.decodeBytesInto(mv)
for j := 0; !dd.CheckBreak(); j++ { {{ else -}}
if cr != nil { cr.sendContainerState(containerMapKey) } mv = {{ decmd .Elem false }}
{{ if eq .MapKey "interface{}" }}mk = nil {{ end -}}
d.decode(&mk) v[mk] = mv
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 cr != nil { cr.sendContainerState(containerMapValue) }
{{ 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
}
}
} }
if cr != nil { cr.sendContainerState(containerMapEnd) }
return v, changed
} }
{{end}}{{end}}{{end}} {{end}}{{end}}{{end}}

View File

@ -1,9 +1,14 @@
// Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.
// +build notfastpath // +build notfastpath
package codec package codec
import "reflect" import "reflect"
const fastpathEnabled = false
// The generated fast-path code is very large, and adds a few seconds to the build time. // 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 // This causes test execution, execution of small tools which use codec, etc
// to take a long time. // to take a long time.
@ -12,21 +17,27 @@ import "reflect"
// This tag disables fastpath during build, allowing for faster build, test execution, // This tag disables fastpath during build, allowing for faster build, test execution,
// short-program runs, etc. // short-program runs, etc.
func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { return false } func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { return false }
func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) 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 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 fastpathT struct{}
type fastpathE struct { type fastpathE struct {
rtid uintptr rtid uintptr
rt reflect.Type rt reflect.Type
encfn func(*encFnInfo, reflect.Value) encfn func(*Encoder, *codecFnInfo, reflect.Value)
decfn func(*decFnInfo, reflect.Value) decfn func(*Decoder, *codecFnInfo, reflect.Value)
} }
type fastpathA [0]fastpathE type fastpathA [0]fastpathE
func (x fastpathA) index(rtid uintptr) int { return -1 } func fastpathAvIndex(rtid uintptr) int { return -1 }
var fastpathAV fastpathA var fastpathAv fastpathA
var fastpathTV fastpathT var fastpathTV fastpathT
// ----
type TestMammoth2Wrapper struct{} // to allow testMammoth work in notfastpath mode

View File

@ -1,104 +1,90 @@
{{var "v"}} := {{if not isArray}}*{{end}}{{ .Varname }} {{var "v"}} := {{if not isArray}}*{{end}}{{ .Varname }}
{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}{{if not isArray}} {{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}
{{if not isArray -}}
var {{var "c"}} bool {{/* // changed */}} var {{var "c"}} bool {{/* // changed */}}
_ = {{var "c"}}{{end}} _ = {{var "c"}}
if {{var "h"}}.IsNil {
if {{var "v"}} != nil {
{{var "v"}} = nil
{{var "c"}} = true
}
} else {{end -}}
if {{var "l"}} == 0 { if {{var "l"}} == 0 {
{{if isSlice }}if {{var "v"}} == nil { {{if isSlice -}}
if {{var "v"}} == nil {
{{var "v"}} = []{{ .Typ }}{} {{var "v"}} = []{{ .Typ }}{}
{{var "c"}} = true {{var "c"}} = true
} else if len({{var "v"}}) != 0 { } else if len({{var "v"}}) != 0 {
{{var "v"}} = {{var "v"}}[:0] {{var "v"}} = {{var "v"}}[:0]
{{var "c"}} = true {{var "c"}} = true
} {{end}} {{if isChan }}if {{var "v"}} == nil { } {{else if isChan }}if {{var "v"}} == nil {
{{var "v"}} = make({{ .CTyp }}, 0) {{var "v"}} = make({{ .CTyp }}, 0)
{{var "c"}} = true {{var "c"}} = true
} {{end}}
} else if {{var "l"}} > 0 {
{{if isChan }}if {{var "v"}} == nil {
{{var "rl"}}, _ = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
{{var "v"}} = make({{ .CTyp }}, {{var "rl"}})
{{var "c"}} = true
} }
for {{var "r"}} := 0; {{var "r"}} < {{var "l"}}; {{var "r"}}++ { {{end -}}
{{var "h"}}.ElemContainerState({{var "r"}}) } else {
var {{var "t"}} {{ .Typ }} {{var "hl"}} := {{var "l"}} > 0
{{ $x := printf "%st%s" .TempVar .Rand }}{{ decLineVar $x }} var {{var "rl"}} int
{{var "v"}} <- {{var "t"}} _ = {{var "rl"}}
} {{if isSlice }} if {{var "hl"}} {
{{ else }} var {{var "rr"}}, {{var "rl"}} int {{/* // num2read, length of slice/array/chan */}}
var {{var "rt"}} bool {{/* truncated */}}
_, _ = {{var "rl"}}, {{var "rt"}}
{{var "rr"}} = {{var "l"}} // len({{var "v"}})
if {{var "l"}} > cap({{var "v"}}) { if {{var "l"}} > cap({{var "v"}}) {
{{if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "l"}}) {{var "rl"}} = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
{{ else }}{{if not .Immutable }} if {{var "rl"}} <= cap({{var "v"}}) {
{{var "rg"}} := len({{var "v"}}) > 0 {{var "v"}} = {{var "v"}}[:{{var "rl"}}]
{{var "v2"}} := {{var "v"}} {{end}}
{{var "rl"}}, {{var "rt"}} = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
if {{var "rt"}} {
if {{var "rl"}} <= cap({{var "v"}}) {
{{var "v"}} = {{var "v"}}[:{{var "rl"}}]
} else {
{{var "v"}} = make([]{{ .Typ }}, {{var "rl"}})
}
} else { } else {
{{var "v"}} = make([]{{ .Typ }}, {{var "rl"}}) {{var "v"}} = make([]{{ .Typ }}, {{var "rl"}})
} }
{{var "c"}} = true {{var "c"}} = true
{{var "rr"}} = len({{var "v"}}) {{if not .Immutable }} } else if {{var "l"}} != len({{var "v"}}) {
if {{var "rg"}} { copy({{var "v"}}, {{var "v2"}}) } {{end}} {{end}}{{/* end not Immutable, isArray */}}
} {{if isSlice }} else if {{var "l"}} != len({{var "v"}}) {
{{var "v"}} = {{var "v"}}[:{{var "l"}}] {{var "v"}} = {{var "v"}}[:{{var "l"}}]
{{var "c"}} = true {{var "c"}} = true
} {{end}} {{/* end isSlice:47 */}}
{{var "j"}} := 0
for ; {{var "j"}} < {{var "rr"}} ; {{var "j"}}++ {
{{var "h"}}.ElemContainerState({{var "j"}})
{{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x }}
} }
{{if isArray }}for ; {{var "j"}} < {{var "l"}} ; {{var "j"}}++ {
{{var "h"}}.ElemContainerState({{var "j"}})
z.DecSwallow()
} }
{{ else }}if {{var "rt"}} { {{end -}}
for ; {{var "j"}} < {{var "l"}} ; {{var "j"}}++ { var {{var "j"}} int
{{var "v"}} = append({{var "v"}}, {{ zero}}) {{/* // var {{var "dn"}} bool */ -}}
{{var "h"}}.ElemContainerState({{var "j"}}) for {{var "j"}} = 0; ({{var "hl"}} && {{var "j"}} < {{var "l"}}) || !({{var "hl"}} || z.DecCheckBreak()); {{var "j"}}++ { // bounds-check-elimination
{{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x }} {{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}} {{/* end isArray:56 */}} {{end -}}
{{end}} {{/* end isChan:16 */}}
} else { {{/* len < 0 */}}
{{var "j"}} := 0
for ; !r.CheckBreak(); {{var "j"}}++ {
{{if isChan }}
{{var "h"}}.ElemContainerState({{var "j"}}) {{var "h"}}.ElemContainerState({{var "j"}})
var {{var "t"}} {{ .Typ }} {{/* {{var "dn"}} = r.TryDecodeAsNil() */}}{{/* commented out, as decLineVar handles this already each time */ -}}
{{ $x := printf "%st%s" .TempVar .Rand }}{{ decLineVar $x }} {{if isChan}}{{ $x := printf "%[1]vvcx%[2]v" .TempVar .Rand }}var {{$x}} {{ .Typ }}
{{var "v"}} <- {{var "t"}} {{ decLineVar $x -}}
{{ else }} {{var "v"}} <- {{ $x }}
{{else}}{{/* // if indefinite, etc, then expand the slice if necessary */ -}}
var {{var "db"}} bool
if {{var "j"}} >= len({{var "v"}}) { if {{var "j"}} >= len({{var "v"}}) {
{{if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "j"}}+1) {{if isSlice }} {{var "v"}} = append({{var "v"}}, {{ zero }})
{{ else }}{{var "v"}} = append({{var "v"}}, {{zero}})// var {{var "z"}} {{ .Typ }} {{var "c"}} = true
{{var "c"}} = true {{end}} {{else}} z.DecArrayCannotExpand(len(v), {{var "j"}}+1); {{var "db"}} = true
{{end -}}
} }
{{var "h"}}.ElemContainerState({{var "j"}}) if {{var "db"}} {
if {{var "j"}} < len({{var "v"}}) {
{{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x }}
} else {
z.DecSwallow() z.DecSwallow()
} else {
{{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x -}}
} }
{{end}} {{end -}}
} }
{{if isSlice }}if {{var "j"}} < len({{var "v"}}) { {{if isSlice}} if {{var "j"}} < len({{var "v"}}) {
{{var "v"}} = {{var "v"}}[:{{var "j"}}] {{var "v"}} = {{var "v"}}[:{{var "j"}}]
{{var "c"}} = true {{var "c"}} = true
} else if {{var "j"}} == 0 && {{var "v"}} == nil { } else if {{var "j"}} == 0 && {{var "v"}} == nil {
{{var "v"}} = []{{ .Typ }}{} {{var "v"}} = make([]{{ .Typ }}, 0)
{{var "c"}} = true {{var "c"}} = true
}{{end}} }
{{end -}}
} }
{{var "h"}}.End() {{var "h"}}.End()
{{if not isArray }}if {{var "c"}} { {{if not isArray }}if {{var "c"}} {
*{{ .Varname }} = {{var "v"}} *{{ .Varname }} = {{var "v"}}
}{{end}} }
{{end -}}

View File

@ -1,58 +1,58 @@
{{var "v"}} := *{{ .Varname }} {{var "v"}} := *{{ .Varname }}
{{var "l"}} := r.ReadMapStart() {{var "l"}} := z.DecReadMapStart()
{{var "bh"}} := z.DecBasicHandle() if {{var "l"}} == codecSelferDecContainerLenNil{{xs}} {
*{{ .Varname }} = nil
} else {
if {{var "v"}} == nil { if {{var "v"}} == nil {
{{var "rl"}}, _ := z.DecInferLen({{var "l"}}, {{var "bh"}}.MaxInitLen, {{ .Size }}) {{var "rl"}} := z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
{{var "v"}} = make(map[{{ .KTyp }}]{{ .Typ }}, {{var "rl"}}) {{var "v"}} = make(map[{{ .KTyp }}]{{ .Typ }}, {{var "rl"}})
*{{ .Varname }} = {{var "v"}} *{{ .Varname }} = {{var "v"}}
} }
var {{var "mk"}} {{ .KTyp }} {{ $mk := var "mk" -}}
var {{ $mk }} {{ .KTyp }}
var {{var "mv"}} {{ .Typ }} var {{var "mv"}} {{ .Typ }}
var {{var "mg"}} {{if decElemKindPtr}}, {{var "ms"}}, {{var "mok"}}{{end}} bool var {{var "mg"}}, {{var "mdn"}} {{if decElemKindPtr}}, {{var "ms"}}, {{var "mok"}}{{end}} bool
if {{var "bh"}}.MapValueReset { if z.DecBasicHandle().MapValueReset {
{{if decElemKindPtr}}{{var "mg"}} = true {{if decElemKindPtr}}{{var "mg"}} = true
{{else if decElemKindIntf}}if !{{var "bh"}}.InterfaceReset { {{var "mg"}} = true } {{else if decElemKindIntf}}if !z.DecBasicHandle().InterfaceReset { {{var "mg"}} = true }
{{else if not decElemKindImmutable}}{{var "mg"}} = true {{else if not decElemKindImmutable}}{{var "mg"}} = true
{{end}} } {{end}} }
if {{var "l"}} > 0 { if {{var "l"}} != 0 {
for {{var "j"}} := 0; {{var "j"}} < {{var "l"}}; {{var "j"}}++ { {{var "hl"}} := {{var "l"}} > 0
z.DecSendContainerState(codecSelfer_containerMapKey{{ .Sfx }}) for {{var "j"}} := 0; ({{var "hl"}} && {{var "j"}} < {{var "l"}}) || !({{var "hl"}} || z.DecCheckBreak()); {{var "j"}}++ {
{{ $x := printf "%vmk%v" .TempVar .Rand }}{{ decLineVarK $x }} z.DecReadMapElemKey()
{{ if eq .KTyp "interface{}" }}{{/* // special case if a byte array. */}}if {{var "bv"}}, {{var "bok"}} := {{var "mk"}}.([]byte); {{var "bok"}} { {{ if eq .KTyp "string" -}}
{{var "mk"}} = string({{var "bv"}}) {{ decLineVarK $mk -}}{{- /* decLineVarKStrZC $mk */ -}}
}{{ end }}{{if decElemKindPtr}} {{ else -}}
{{var "ms"}} = true{{end}} {{ decLineVarK $mk -}}
{{ end -}}
{{ if eq .KTyp "interface{}" }}{{/* // special case if a byte array. */ -}}
if {{var "bv"}}, {{var "bok"}} := {{var "mk"}}.([]byte); {{var "bok"}} {
{{var "mk"}} = z.DecStringZC({{var "bv"}})
}
{{ end -}}
{{if decElemKindPtr -}}
{{var "ms"}} = true
{{end -}}
if {{var "mg"}} { if {{var "mg"}} {
{{if decElemKindPtr}}{{var "mv"}}, {{var "mok"}} = {{var "v"}}[{{var "mk"}}] {{if decElemKindPtr -}}
{{var "mv"}}, {{var "mok"}} = {{var "v"}}[{{ $mk }}]
if {{var "mok"}} { if {{var "mok"}} {
{{var "ms"}} = false {{var "ms"}} = false
} {{else}}{{var "mv"}} = {{var "v"}}[{{var "mk"}}] {{end}} }
{{else -}}
{{var "mv"}} = {{var "v"}}[{{ $mk }}]
{{end -}}
} {{if not decElemKindImmutable}}else { {{var "mv"}} = {{decElemZero}} }{{end}} } {{if not decElemKindImmutable}}else { {{var "mv"}} = {{decElemZero}} }{{end}}
z.DecSendContainerState(codecSelfer_containerMapValue{{ .Sfx }}) z.DecReadMapElemValue()
{{ $x := printf "%vmv%v" .TempVar .Rand }}{{ decLineVar $x }} {{var "mdn"}} = false
if {{if decElemKindPtr}} {{var "ms"}} && {{end}} {{var "v"}} != nil { {{ $x := printf "%vmv%v" .TempVar .Rand }}{{ $y := printf "%vmdn%v" .TempVar .Rand }}{{ decLineVar $x $y -}}
{{var "v"}}[{{var "mk"}}] = {{var "mv"}} if {{var "mdn"}} {
{{var "v"}}[{{ $mk }}] = {{decElemZero}}
} else {{if decElemKindPtr}} if {{var "ms"}} {{end}} {
{{var "v"}}[{{ $mk }}] = {{var "mv"}}
} }
} }
} else if {{var "l"}} < 0 { } // else len==0: leave as-is (do not clear map entries)
for {{var "j"}} := 0; !r.CheckBreak(); {{var "j"}}++ { z.DecReadMapEnd()
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}}
z.DecSendContainerState(codecSelfer_containerMapValue{{ .Sfx }})
{{ $x := printf "%vmv%v" .TempVar .Rand }}{{ decLineVar $x }}
if {{if decElemKindPtr}} {{var "ms"}} && {{end}} {{var "v"}} != nil {
{{var "v"}}[{{var "mk"}}] = {{var "mv"}}
}
} }
} // else len==0: TODO: Should we clear map entries?
z.DecSendContainerState(codecSelfer_containerMapEnd{{ .Sfx }})

27
vendor/github.com/ugorji/go/codec/gen-enc-chan.go.tmpl generated vendored Normal file
View 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}})
}
}

View File

@ -1,12 +1,9 @@
// //+build ignore // comment this out // + build ignore
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file. // 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.
// DO NOT EDIT.
// THIS FILE IS AUTO-GENERATED from gen-helper.go.tmpl
// ************************************************************
package codec package codec
@ -15,38 +12,52 @@ import (
"reflect" "reflect"
) )
// GenVersion is the current version of codecgen.
const GenVersion = 23
// This file is used to generate helper code for codecgen. // 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 // The values here i.e. genHelper(En|De)coder are not to be used directly by
// library users. They WILL change continously and without notice. // 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. // 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) (genHelperEncoder, encDriver) { // Library users: DO NOT USE IT DIRECTLY or INDIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
return genHelperEncoder{e: e}, e.e func GenHelper() (g genHelper) { return }
type genHelper struct{}
func (genHelper) Encoder(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. func (genHelper) Decoder(d *Decoder) (gd genHelperDecoder, dd genHelperDecDriver) {
// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE. gd = genHelperDecoder{d: d}
func GenHelperDecoder(d *Decoder) (genHelperDecoder, decDriver) { dd = genHelperDecDriver{decDriver: d.d}
return genHelperDecoder{d: d}, d.d return
}
type genHelperEncDriver struct {
encDriver
}
type genHelperDecDriver struct {
decDriver
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
type genHelperEncoder struct { type genHelperEncoder struct {
e *Encoder M mustHdl
F fastpathT F fastpathT
e *Encoder
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
type genHelperDecoder struct { type genHelperDecoder struct {
d *Decoder C checkOverflow
F fastpathT F fastpathT
d *Decoder
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
@ -59,69 +70,80 @@ func (f genHelperEncoder) EncBinary() bool {
return f.e.be // f.e.hh.isBinaryEncoding() return f.e.be // f.e.hh.isBinaryEncoding()
} }
// 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)
}
// 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, c_UTF8)
}
// 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, c_UTF8)
}
// 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, c_RAW)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) TimeRtidIfBinc() uintptr {
if _, ok := f.e.hh.(*BincHandle); ok {
return timeTypId
}
return 0
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) IsJSONHandle() bool { func (f genHelperEncoder) IsJSONHandle() bool {
return f.e.js return f.e.js
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) HasExtensions() bool { func (f genHelperEncoder) EncFallback(iv interface{}) {
return len(f.e.h.extHandle) != 0 // f.e.encodeI(iv, false, false)
f.e.encodeValue(reflect.ValueOf(iv), nil)
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncExt(v interface{}) (r bool) { func (f genHelperEncoder) EncTextMarshal(iv encoding.TextMarshaler) {
rt := reflect.TypeOf(v) bs, fnerr := iv.MarshalText()
if rt.Kind() == reflect.Ptr { f.e.marshalUtf8(bs, fnerr)
rt = rt.Elem()
}
rtid := reflect.ValueOf(rt).Pointer()
if xfFn := f.e.h.getExt(rtid); xfFn != nil {
f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
return true
}
return false
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncSendContainerState(c containerState) { func (f genHelperEncoder) EncJSONMarshal(iv jsonMarshaler) {
if f.e.cr != nil { bs, fnerr := iv.MarshalJSON()
f.e.cr.sendContainerState(c) f.e.marshalAsis(bs, fnerr)
}
} }
// 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.marshalRaw(bs, fnerr)
}
// 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*
func (f genHelperEncoder) Extension(v interface{}) (xfn *extTypeTagFn) {
return f.e.h.getExtForI(v)
}
// 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)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) WriteStr(s string) {
f.e.w().writestr(s)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncWriteMapStart(length int) { f.e.mapStart(length) }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncWriteMapEnd() { f.e.mapEnd() }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncWriteArrayStart(length int) { f.e.arrayStart(length) }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncWriteArrayEnd() { f.e.arrayEnd() }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncWriteArrayElem() { f.e.arrayElem() }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncWriteMapElemKey() { f.e.mapElemKey() }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncWriteMapElemValue() { f.e.mapElemValue() }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncEncodeComplex64(v complex64) { f.e.encodeComplex64(v) }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncEncodeComplex128(v complex128) { f.e.encodeComplex128(v) }
// ---------------- DECODER FOLLOWS ----------------- // ---------------- DECODER FOLLOWS -----------------
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
@ -135,19 +157,27 @@ func (f genHelperDecoder) DecBinary() bool {
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecSwallow() { func (f genHelperDecoder) DecSwallow() { f.d.swallow() }
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* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecScratchBuffer() []byte { func (f genHelperDecoder) DecScratchArrayBuffer() *[decScratchByteArrayLen]byte {
return f.d.b[:] return &f.d.b
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecFallback(iv interface{}, chkPtr bool) { func (f genHelperDecoder) DecFallback(iv interface{}, chkPtr bool) {
// println(">>>>>>>>> DecFallback") rv := reflect.ValueOf(iv)
f.d.decodeI(iv, chkPtr, false, false, false) if chkPtr {
if x, _ := isDecodeable(rv); !x {
f.d.haltAsNotDecodeable(rv)
}
}
f.d.decodeValue(rv, nil)
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
@ -167,37 +197,21 @@ func (f genHelperDecoder) DecArrayCannotExpand(sliceLen, streamLen int) {
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecTextUnmarshal(tm encoding.TextUnmarshaler) { func (f genHelperDecoder) DecTextUnmarshal(tm encoding.TextUnmarshaler) {
fnerr := tm.UnmarshalText(f.d.d.DecodeBytes(f.d.b[:], true, true)) halt.onerror(tm.UnmarshalText(f.d.d.DecodeStringAsBytes()))
if fnerr != nil {
panic(fnerr)
}
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecJSONUnmarshal(tm jsonUnmarshaler) { func (f genHelperDecoder) DecJSONUnmarshal(tm jsonUnmarshaler) {
// bs := f.dd.DecodeBytes(f.d.b[:], true, true) f.d.jsonUnmarshalV(tm)
// 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* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecBinaryUnmarshal(bm encoding.BinaryUnmarshaler) { func (f genHelperDecoder) DecBinaryUnmarshal(bm encoding.BinaryUnmarshaler) {
fnerr := bm.UnmarshalBinary(f.d.d.DecodeBytes(nil, false, true)) halt.onerror(bm.UnmarshalBinary(f.d.d.DecodeBytes(nil)))
if fnerr != nil {
panic(fnerr)
}
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) TimeRtidIfBinc() uintptr { func (f genHelperDecoder) DecRaw() []byte { return f.d.rawBytes() }
if _, ok := f.d.hh.(*BincHandle); ok {
return timeTypId
}
return 0
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) IsJSONHandle() bool { func (f genHelperDecoder) IsJSONHandle() bool {
@ -205,29 +219,49 @@ func (f genHelperDecoder) IsJSONHandle() bool {
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) HasExtensions() bool { func (f genHelperDecoder) Extension(v interface{}) (xfn *extTypeTagFn) {
return len(f.d.h.extHandle) != 0 return f.d.h.getExtForI(v)
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecExt(v interface{}) (r bool) { func (f genHelperDecoder) DecExtension(v interface{}, xfFn *extTypeTagFn) {
rt := reflect.TypeOf(v).Elem() f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
rtid := reflect.ValueOf(rt).Pointer()
if xfFn := f.d.h.getExt(rtid); 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* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecInferLen(clen, maxlen, unit int) (rvlen int, truncated bool) { func (f genHelperDecoder) DecInferLen(clen, maxlen, unit int) (rvlen int) {
return decInferLen(clen, maxlen, unit) return decInferLen(clen, maxlen, unit)
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecSendContainerState(c containerState) { func (f genHelperDecoder) DecReadMapStart() int { return f.d.mapStart(f.d.d.ReadMapStart()) }
if f.d.cr != nil {
f.d.cr.sendContainerState(c) // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
} func (f genHelperDecoder) DecReadMapEnd() { f.d.mapEnd() }
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecReadArrayStart() int { return f.d.arrayStart(f.d.d.ReadArrayStart()) }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecReadArrayEnd() { f.d.arrayEnd() }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecReadArrayElem() { f.d.arrayElem() }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecReadMapElemKey() { f.d.mapElemKey() }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecReadMapElemValue() { f.d.mapElemValue() }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecDecodeFloat32() float32 { return f.d.decodeFloat32() }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecCheckBreak() bool { return f.d.checkBreak() }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecStringZC(v []byte) string { return f.d.stringZC(v) }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecodeBytesInto(v []byte) []byte { return f.d.decodeBytesInto(v) }

View File

@ -1,12 +1,9 @@
// //+build ignore // comment this out // + build ignore
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file. // 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.
// DO NOT EDIT.
// THIS FILE IS AUTO-GENERATED from gen-helper.go.tmpl
// ************************************************************
package codec package codec
@ -15,103 +12,127 @@ import (
"reflect" "reflect"
) )
// GenVersion is the current version of codecgen.
const GenVersion = {{ .Version }}
// This file is used to generate helper code for codecgen. // 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 // The values here i.e. genHelper(En|De)coder are not to be used directly by
// library users. They WILL change continously and without notice. // library users. They WILL change continuously and without notice.
//
{{/*
// To help enforce this, we create an unexported type with exported members. // 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). // 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 // 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. // 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. // 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) (genHelperEncoder, encDriver) { // Library users: DO NOT USE IT DIRECTLY or INDIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.
return genHelperEncoder{e:e}, e.e func GenHelper() (g genHelper) { return }
type genHelper struct {}
func (genHelper) Encoder(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. func (genHelper) Decoder(d *Decoder) (gd genHelperDecoder, dd genHelperDecDriver) {
// Library users: DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE. gd = genHelperDecoder{d: d}
func GenHelperDecoder(d *Decoder) (genHelperDecoder, decDriver) { dd = genHelperDecDriver{decDriver: d.d}
return genHelperDecoder{d:d}, d.d return
}
type genHelperEncDriver struct {
encDriver
}
type genHelperDecDriver struct {
decDriver
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
type genHelperEncoder struct { type genHelperEncoder struct {
e *Encoder M mustHdl
F fastpathT F fastpathT
e *Encoder
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
type genHelperDecoder struct { type genHelperDecoder struct {
d *Decoder C checkOverflow
F fastpathT F fastpathT
d *Decoder
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncBasicHandle() *BasicHandle { func (f genHelperEncoder) EncBasicHandle() *BasicHandle {
return f.e.h return f.e.h
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncBinary() bool { func (f genHelperEncoder) EncBinary() bool {
return f.e.be // f.e.hh.isBinaryEncoding() return f.e.be // f.e.hh.isBinaryEncoding()
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // 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)
}
// 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, c_UTF8)
}
// 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, c_UTF8)
}
// 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, c_RAW)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) TimeRtidIfBinc() uintptr {
if _, ok := f.e.hh.(*BincHandle); ok {
return timeTypId
}
return 0
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) IsJSONHandle() bool { func (f genHelperEncoder) IsJSONHandle() bool {
return f.e.js return f.e.js
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) HasExtensions() bool { func (f genHelperEncoder) EncFallback(iv interface{}) {
return len(f.e.h.extHandle) != 0 // f.e.encodeI(iv, false, false)
f.e.encodeValue(reflect.ValueOf(iv), nil)
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncExt(v interface{}) (r bool) { func (f genHelperEncoder) EncTextMarshal(iv encoding.TextMarshaler) {
rt := reflect.TypeOf(v) bs, fnerr := iv.MarshalText()
if rt.Kind() == reflect.Ptr { f.e.marshalUtf8(bs, fnerr)
rt = rt.Elem()
}
rtid := reflect.ValueOf(rt).Pointer()
if xfFn := f.e.h.getExt(rtid); xfFn != nil {
f.e.e.EncodeExt(v, xfFn.tag, xfFn.ext, f.e)
return true
}
return false
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncSendContainerState(c containerState) { func (f genHelperEncoder) EncJSONMarshal(iv jsonMarshaler) {
if f.e.cr != nil { bs, fnerr := iv.MarshalJSON()
f.e.cr.sendContainerState(c) f.e.marshalAsis(bs, fnerr)
}
} }
// 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.marshalRaw(bs, fnerr)
}
// 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*
func (f genHelperEncoder) Extension(v interface{}) (xfn *extTypeTagFn) {
return f.e.h.getExtForI(v)
}
// 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)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) WriteStr(s string) {
f.e.w().writestr(s)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncWriteMapStart(length int) { f.e.mapStart(length) }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncWriteMapEnd() { f.e.mapEnd() }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncWriteArrayStart(length int) { f.e.arrayStart(length) }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncWriteArrayEnd() { f.e.arrayEnd() }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncWriteArrayElem() { f.e.arrayElem() }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncWriteMapElemKey() { f.e.mapElemKey() }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncWriteMapElemValue() { f.e.mapElemValue() }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncEncodeComplex64(v complex64) { f.e.encodeComplex64(v) }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncEncodeComplex128(v complex128) { f.e.encodeComplex128(v) }
// ---------------- DECODER FOLLOWS ----------------- // ---------------- DECODER FOLLOWS -----------------
@ -124,17 +145,26 @@ func (f genHelperDecoder) DecBinary() bool {
return f.d.be // f.d.hh.isBinaryEncoding() return f.d.be // f.d.hh.isBinaryEncoding()
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecSwallow() { func (f genHelperDecoder) DecSwallow() { f.d.swallow() }
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* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecScratchBuffer() []byte { func (f genHelperDecoder) DecScratchArrayBuffer() *[decScratchByteArrayLen]byte {
return f.d.b[:] return &f.d.b
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecFallback(iv interface{}, chkPtr bool) { func (f genHelperDecoder) DecFallback(iv interface{}, chkPtr bool) {
// println(">>>>>>>>> DecFallback") rv := reflect.ValueOf(iv)
f.d.decodeI(iv, chkPtr, false, false, false) if chkPtr {
if x, _ := isDecodeable(rv); !x {
f.d.haltAsNotDecodeable(rv)
}
}
f.d.decodeValue(rv, nil)
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecSliceHelperStart() (decSliceHelper, int) { func (f genHelperDecoder) DecSliceHelperStart() (decSliceHelper, int) {
@ -150,215 +180,62 @@ func (f genHelperDecoder) DecArrayCannotExpand(sliceLen, streamLen int) {
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecTextUnmarshal(tm encoding.TextUnmarshaler) { func (f genHelperDecoder) DecTextUnmarshal(tm encoding.TextUnmarshaler) {
fnerr := tm.UnmarshalText(f.d.d.DecodeBytes(f.d.b[:], true, true)) halt.onerror(tm.UnmarshalText(f.d.d.DecodeStringAsBytes()))
if fnerr != nil {
panic(fnerr)
}
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecJSONUnmarshal(tm jsonUnmarshaler) { func (f genHelperDecoder) DecJSONUnmarshal(tm jsonUnmarshaler) {
// bs := f.dd.DecodeBytes(f.d.b[:], true, true) f.d.jsonUnmarshalV(tm)
// 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* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecBinaryUnmarshal(bm encoding.BinaryUnmarshaler) { func (f genHelperDecoder) DecBinaryUnmarshal(bm encoding.BinaryUnmarshaler) {
fnerr := bm.UnmarshalBinary(f.d.d.DecodeBytes(nil, false, true)) halt.onerror(bm.UnmarshalBinary(f.d.d.DecodeBytes(nil)))
if fnerr != nil {
panic(fnerr)
}
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) TimeRtidIfBinc() uintptr { func (f genHelperDecoder) DecRaw() []byte { return f.d.rawBytes() }
if _, ok := f.d.hh.(*BincHandle); ok {
return timeTypId
}
return 0
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) IsJSONHandle() bool { func (f genHelperDecoder) IsJSONHandle() bool {
return f.d.js return f.d.js
} }
{{/*
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) HasExtensions() bool { func (f genHelperDecoder) I2Rtid(v interface{}) uintptr {
return len(f.d.h.extHandle) != 0 return i2rtid(v)
}
*/ -}}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) Extension(v interface{}) (xfn *extTypeTagFn) {
return f.d.h.getExtForI(v)
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecExt(v interface{}) (r bool) { func (f genHelperDecoder) DecExtension(v interface{}, xfFn *extTypeTagFn) {
rt := reflect.TypeOf(v).Elem() f.d.d.DecodeExt(v, xfFn.tag, xfFn.ext)
rtid := reflect.ValueOf(rt).Pointer()
if xfFn := f.d.h.getExt(rtid); 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* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecInferLen(clen, maxlen, unit int) (rvlen int, truncated bool) { func (f genHelperDecoder) DecInferLen(clen, maxlen, unit int) (rvlen int) {
return decInferLen(clen, maxlen, unit) return decInferLen(clen, maxlen, unit)
} }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecSendContainerState(c containerState) {
if f.d.cr != nil {
f.d.cr.sendContainerState(c)
}
}
{{/*
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncDriver() encDriver { func (f genHelperDecoder) DecReadMapStart() int { return f.d.mapStart(f.d.d.ReadMapStart()) }
return f.e.e
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecDriver() decDriver { func (f genHelperDecoder) DecReadMapEnd() { f.d.mapEnd() }
return f.d.d // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
} func (f genHelperDecoder) DecReadArrayStart() int { return f.d.arrayStart(f.d.d.ReadArrayStart()) }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecReadArrayEnd() { f.d.arrayEnd() }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecReadArrayElem() { f.d.arrayElem() }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecReadMapElemKey() { f.d.mapElemKey() }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecReadMapElemValue() { f.d.mapElemValue() }
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncNil() { func (f genHelperDecoder) DecDecodeFloat32() float32 { return f.d.decodeFloat32() }
f.e.e.EncodeNil()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncBytes(v []byte) { func (f genHelperDecoder) DecCheckBreak() bool { return f.d.checkBreak() }
f.e.e.EncodeStringBytes(c_RAW, v)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncArrayStart(length int) { func (f genHelperDecoder) DecStringZC(v []byte) string { return f.d.stringZC(v) }
f.e.e.EncodeArrayStart(length)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncArrayEnd() { func (f genHelperDecoder) DecodeBytesInto(v []byte) []byte { return f.d.decodeBytesInto(v) }
f.e.e.EncodeArrayEnd()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncArrayEntrySeparator() {
f.e.e.EncodeArrayEntrySeparator()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncMapStart(length int) {
f.e.e.EncodeMapStart(length)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncMapEnd() {
f.e.e.EncodeMapEnd()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncMapEntrySeparator() {
f.e.e.EncodeMapEntrySeparator()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) EncMapKVSeparator() {
f.e.e.EncodeMapKVSeparator()
}
// ---------
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecBytes(v *[]byte) {
*v = f.d.d.DecodeBytes(*v)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecTryNil() bool {
return f.d.d.TryDecodeAsNil()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecContainerIsNil() (b bool) {
return f.d.d.IsContainerType(valueTypeNil)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecContainerIsMap() (b bool) {
return f.d.d.IsContainerType(valueTypeMap)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecContainerIsArray() (b bool) {
return f.d.d.IsContainerType(valueTypeArray)
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecCheckBreak() bool {
return f.d.d.CheckBreak()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecMapStart() int {
return f.d.d.ReadMapStart()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecArrayStart() int {
return f.d.d.ReadArrayStart()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecMapEnd() {
f.d.d.ReadMapEnd()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecArrayEnd() {
f.d.d.ReadArrayEnd()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecArrayEntrySeparator() {
f.d.d.ReadArrayEntrySeparator()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecMapEntrySeparator() {
f.d.d.ReadMapEntrySeparator()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) DecMapKVSeparator() {
f.d.d.ReadMapKVSeparator()
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) ReadStringAsBytes(bs []byte) []byte {
return f.d.d.DecodeStringAsBytes(bs)
}
// -- encode calls (primitives)
{{range .Values}}{{if .Primitive }}{{if ne .Primitive "interface{}" }}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) {{ .MethodNamePfx "Enc" true }}(v {{ .Primitive }}) {
ee := f.e.e
{{ encmd .Primitive "v" }}
}
{{ end }}{{ end }}{{ end }}
// -- decode calls (primitives)
{{range .Values}}{{if .Primitive }}{{if ne .Primitive "interface{}" }}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) {{ .MethodNamePfx "Dec" true }}(vp *{{ .Primitive }}) {
dd := f.d.d
*vp = {{ decmd .Primitive }}
}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperDecoder) {{ .MethodNamePfx "Read" true }}() (v {{ .Primitive }}) {
dd := f.d.d
v = {{ decmd .Primitive }}
return
}
{{ end }}{{ end }}{{ end }}
// -- encode calls (slices/maps)
{{range .Values}}{{if not .Primitive }}{{if .Slice }}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) {{ .MethodNamePfx "Enc" false }}(v []{{ .Elem }}) { {{ else }}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
func (f genHelperEncoder) {{ .MethodNamePfx "Enc" false }}(v map[{{ .MapKey }}]{{ .Elem }}) { {{end}}
f.F.{{ .MethodNamePfx "Enc" false }}V(v, false, f.e)
}
{{ end }}{{ end }}
// -- decode calls (slices/maps)
{{range .Values}}{{if not .Primitive }}
// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE*
{{if .Slice }}func (f genHelperDecoder) {{ .MethodNamePfx "Dec" false }}(vp *[]{{ .Elem }}) {
{{else}}func (f genHelperDecoder) {{ .MethodNamePfx "Dec" false }}(vp *map[{{ .MapKey }}]{{ .Elem }}) { {{end}}
v, changed := f.F.{{ .MethodNamePfx "Dec" false }}V(*vp, false, true, f.d)
if changed {
*vp = v
}
}
{{ end }}{{ end }}
*/}}

View File

@ -1,4 +1,6 @@
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // +build codecgen.exec
// Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file. // Use of this source code is governed by a MIT license found in the LICENSE file.
package codec package codec
@ -7,169 +9,184 @@ package codec
const genDecMapTmpl = ` const genDecMapTmpl = `
{{var "v"}} := *{{ .Varname }} {{var "v"}} := *{{ .Varname }}
{{var "l"}} := r.ReadMapStart() {{var "l"}} := z.DecReadMapStart()
{{var "bh"}} := z.DecBasicHandle() if {{var "l"}} == codecSelferDecContainerLenNil{{xs}} {
*{{ .Varname }} = nil
} else {
if {{var "v"}} == nil { if {{var "v"}} == nil {
{{var "rl"}}, _ := z.DecInferLen({{var "l"}}, {{var "bh"}}.MaxInitLen, {{ .Size }}) {{var "rl"}} := z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
{{var "v"}} = make(map[{{ .KTyp }}]{{ .Typ }}, {{var "rl"}}) {{var "v"}} = make(map[{{ .KTyp }}]{{ .Typ }}, {{var "rl"}})
*{{ .Varname }} = {{var "v"}} *{{ .Varname }} = {{var "v"}}
} }
var {{var "mk"}} {{ .KTyp }} {{ $mk := var "mk" -}}
var {{ $mk }} {{ .KTyp }}
var {{var "mv"}} {{ .Typ }} var {{var "mv"}} {{ .Typ }}
var {{var "mg"}} {{if decElemKindPtr}}, {{var "ms"}}, {{var "mok"}}{{end}} bool var {{var "mg"}}, {{var "mdn"}} {{if decElemKindPtr}}, {{var "ms"}}, {{var "mok"}}{{end}} bool
if {{var "bh"}}.MapValueReset { if z.DecBasicHandle().MapValueReset {
{{if decElemKindPtr}}{{var "mg"}} = true {{if decElemKindPtr}}{{var "mg"}} = true
{{else if decElemKindIntf}}if !{{var "bh"}}.InterfaceReset { {{var "mg"}} = true } {{else if decElemKindIntf}}if !z.DecBasicHandle().InterfaceReset { {{var "mg"}} = true }
{{else if not decElemKindImmutable}}{{var "mg"}} = true {{else if not decElemKindImmutable}}{{var "mg"}} = true
{{end}} } {{end}} }
if {{var "l"}} > 0 { if {{var "l"}} != 0 {
for {{var "j"}} := 0; {{var "j"}} < {{var "l"}}; {{var "j"}}++ { {{var "hl"}} := {{var "l"}} > 0
z.DecSendContainerState(codecSelfer_containerMapKey{{ .Sfx }}) for {{var "j"}} := 0; ({{var "hl"}} && {{var "j"}} < {{var "l"}}) || !({{var "hl"}} || z.DecCheckBreak()); {{var "j"}}++ {
{{ $x := printf "%vmk%v" .TempVar .Rand }}{{ decLineVarK $x }} z.DecReadMapElemKey()
{{ if eq .KTyp "interface{}" }}{{/* // special case if a byte array. */}}if {{var "bv"}}, {{var "bok"}} := {{var "mk"}}.([]byte); {{var "bok"}} { {{ if eq .KTyp "string" -}}
{{var "mk"}} = string({{var "bv"}}) {{ decLineVarK $mk -}}{{- /* decLineVarKStrZC $mk */ -}}
}{{ end }}{{if decElemKindPtr}} {{ else -}}
{{var "ms"}} = true{{end}} {{ decLineVarK $mk -}}
{{ end -}}
{{ if eq .KTyp "interface{}" }}{{/* // special case if a byte array. */ -}}
if {{var "bv"}}, {{var "bok"}} := {{var "mk"}}.([]byte); {{var "bok"}} {
{{var "mk"}} = z.DecStringZC({{var "bv"}})
}
{{ end -}}
{{if decElemKindPtr -}}
{{var "ms"}} = true
{{end -}}
if {{var "mg"}} { if {{var "mg"}} {
{{if decElemKindPtr}}{{var "mv"}}, {{var "mok"}} = {{var "v"}}[{{var "mk"}}] {{if decElemKindPtr -}}
{{var "mv"}}, {{var "mok"}} = {{var "v"}}[{{ $mk }}]
if {{var "mok"}} { if {{var "mok"}} {
{{var "ms"}} = false {{var "ms"}} = false
} {{else}}{{var "mv"}} = {{var "v"}}[{{var "mk"}}] {{end}} }
{{else -}}
{{var "mv"}} = {{var "v"}}[{{ $mk }}]
{{end -}}
} {{if not decElemKindImmutable}}else { {{var "mv"}} = {{decElemZero}} }{{end}} } {{if not decElemKindImmutable}}else { {{var "mv"}} = {{decElemZero}} }{{end}}
z.DecSendContainerState(codecSelfer_containerMapValue{{ .Sfx }}) z.DecReadMapElemValue()
{{ $x := printf "%vmv%v" .TempVar .Rand }}{{ decLineVar $x }} {{var "mdn"}} = false
if {{if decElemKindPtr}} {{var "ms"}} && {{end}} {{var "v"}} != nil { {{ $x := printf "%vmv%v" .TempVar .Rand }}{{ $y := printf "%vmdn%v" .TempVar .Rand }}{{ decLineVar $x $y -}}
{{var "v"}}[{{var "mk"}}] = {{var "mv"}} if {{var "mdn"}} {
{{var "v"}}[{{ $mk }}] = {{decElemZero}}
} else {{if decElemKindPtr}} if {{var "ms"}} {{end}} {
{{var "v"}}[{{ $mk }}] = {{var "mv"}}
} }
} }
} else if {{var "l"}} < 0 { } // else len==0: leave as-is (do not clear map entries)
for {{var "j"}} := 0; !r.CheckBreak(); {{var "j"}}++ { z.DecReadMapEnd()
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}}
z.DecSendContainerState(codecSelfer_containerMapValue{{ .Sfx }})
{{ $x := printf "%vmv%v" .TempVar .Rand }}{{ decLineVar $x }}
if {{if decElemKindPtr}} {{var "ms"}} && {{end}} {{var "v"}} != nil {
{{var "v"}}[{{var "mk"}}] = {{var "mv"}}
}
} }
} // else len==0: TODO: Should we clear map entries?
z.DecSendContainerState(codecSelfer_containerMapEnd{{ .Sfx }})
` `
const genDecListTmpl = ` const genDecListTmpl = `
{{var "v"}} := {{if not isArray}}*{{end}}{{ .Varname }} {{var "v"}} := {{if not isArray}}*{{end}}{{ .Varname }}
{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}{{if not isArray}} {{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}
{{if not isArray -}}
var {{var "c"}} bool {{/* // changed */}} var {{var "c"}} bool {{/* // changed */}}
_ = {{var "c"}}{{end}} _ = {{var "c"}}
if {{var "h"}}.IsNil {
if {{var "v"}} != nil {
{{var "v"}} = nil
{{var "c"}} = true
}
} else {{end -}}
if {{var "l"}} == 0 { if {{var "l"}} == 0 {
{{if isSlice }}if {{var "v"}} == nil { {{if isSlice -}}
if {{var "v"}} == nil {
{{var "v"}} = []{{ .Typ }}{} {{var "v"}} = []{{ .Typ }}{}
{{var "c"}} = true {{var "c"}} = true
} else if len({{var "v"}}) != 0 { } else if len({{var "v"}}) != 0 {
{{var "v"}} = {{var "v"}}[:0] {{var "v"}} = {{var "v"}}[:0]
{{var "c"}} = true {{var "c"}} = true
} {{end}} {{if isChan }}if {{var "v"}} == nil { } {{else if isChan }}if {{var "v"}} == nil {
{{var "v"}} = make({{ .CTyp }}, 0) {{var "v"}} = make({{ .CTyp }}, 0)
{{var "c"}} = true {{var "c"}} = true
} {{end}}
} else if {{var "l"}} > 0 {
{{if isChan }}if {{var "v"}} == nil {
{{var "rl"}}, _ = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
{{var "v"}} = make({{ .CTyp }}, {{var "rl"}})
{{var "c"}} = true
} }
for {{var "r"}} := 0; {{var "r"}} < {{var "l"}}; {{var "r"}}++ { {{end -}}
{{var "h"}}.ElemContainerState({{var "r"}}) } else {
var {{var "t"}} {{ .Typ }} {{var "hl"}} := {{var "l"}} > 0
{{ $x := printf "%st%s" .TempVar .Rand }}{{ decLineVar $x }} var {{var "rl"}} int
{{var "v"}} <- {{var "t"}} _ = {{var "rl"}}
} {{if isSlice }} if {{var "hl"}} {
{{ else }} var {{var "rr"}}, {{var "rl"}} int {{/* // num2read, length of slice/array/chan */}}
var {{var "rt"}} bool {{/* truncated */}}
_, _ = {{var "rl"}}, {{var "rt"}}
{{var "rr"}} = {{var "l"}} // len({{var "v"}})
if {{var "l"}} > cap({{var "v"}}) { if {{var "l"}} > cap({{var "v"}}) {
{{if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "l"}}) {{var "rl"}} = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
{{ else }}{{if not .Immutable }} if {{var "rl"}} <= cap({{var "v"}}) {
{{var "rg"}} := len({{var "v"}}) > 0 {{var "v"}} = {{var "v"}}[:{{var "rl"}}]
{{var "v2"}} := {{var "v"}} {{end}}
{{var "rl"}}, {{var "rt"}} = z.DecInferLen({{var "l"}}, z.DecBasicHandle().MaxInitLen, {{ .Size }})
if {{var "rt"}} {
if {{var "rl"}} <= cap({{var "v"}}) {
{{var "v"}} = {{var "v"}}[:{{var "rl"}}]
} else {
{{var "v"}} = make([]{{ .Typ }}, {{var "rl"}})
}
} else { } else {
{{var "v"}} = make([]{{ .Typ }}, {{var "rl"}}) {{var "v"}} = make([]{{ .Typ }}, {{var "rl"}})
} }
{{var "c"}} = true {{var "c"}} = true
{{var "rr"}} = len({{var "v"}}) {{if not .Immutable }} } else if {{var "l"}} != len({{var "v"}}) {
if {{var "rg"}} { copy({{var "v"}}, {{var "v2"}}) } {{end}} {{end}}{{/* end not Immutable, isArray */}}
} {{if isSlice }} else if {{var "l"}} != len({{var "v"}}) {
{{var "v"}} = {{var "v"}}[:{{var "l"}}] {{var "v"}} = {{var "v"}}[:{{var "l"}}]
{{var "c"}} = true {{var "c"}} = true
} {{end}} {{/* end isSlice:47 */}}
{{var "j"}} := 0
for ; {{var "j"}} < {{var "rr"}} ; {{var "j"}}++ {
{{var "h"}}.ElemContainerState({{var "j"}})
{{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x }}
} }
{{if isArray }}for ; {{var "j"}} < {{var "l"}} ; {{var "j"}}++ {
{{var "h"}}.ElemContainerState({{var "j"}})
z.DecSwallow()
} }
{{ else }}if {{var "rt"}} { {{end -}}
for ; {{var "j"}} < {{var "l"}} ; {{var "j"}}++ { var {{var "j"}} int
{{var "v"}} = append({{var "v"}}, {{ zero}}) {{/* // var {{var "dn"}} bool */ -}}
{{var "h"}}.ElemContainerState({{var "j"}}) for {{var "j"}} = 0; ({{var "hl"}} && {{var "j"}} < {{var "l"}}) || !({{var "hl"}} || z.DecCheckBreak()); {{var "j"}}++ { // bounds-check-elimination
{{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x }} {{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}} {{/* end isArray:56 */}} {{end -}}
{{end}} {{/* end isChan:16 */}}
} else { {{/* len < 0 */}}
{{var "j"}} := 0
for ; !r.CheckBreak(); {{var "j"}}++ {
{{if isChan }}
{{var "h"}}.ElemContainerState({{var "j"}}) {{var "h"}}.ElemContainerState({{var "j"}})
var {{var "t"}} {{ .Typ }} {{/* {{var "dn"}} = r.TryDecodeAsNil() */}}{{/* commented out, as decLineVar handles this already each time */ -}}
{{ $x := printf "%st%s" .TempVar .Rand }}{{ decLineVar $x }} {{if isChan}}{{ $x := printf "%[1]vvcx%[2]v" .TempVar .Rand }}var {{$x}} {{ .Typ }}
{{var "v"}} <- {{var "t"}} {{ decLineVar $x -}}
{{ else }} {{var "v"}} <- {{ $x }}
{{else}}{{/* // if indefinite, etc, then expand the slice if necessary */ -}}
var {{var "db"}} bool
if {{var "j"}} >= len({{var "v"}}) { if {{var "j"}} >= len({{var "v"}}) {
{{if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "j"}}+1) {{if isSlice }} {{var "v"}} = append({{var "v"}}, {{ zero }})
{{ else }}{{var "v"}} = append({{var "v"}}, {{zero}})// var {{var "z"}} {{ .Typ }} {{var "c"}} = true
{{var "c"}} = true {{end}} {{else}} z.DecArrayCannotExpand(len(v), {{var "j"}}+1); {{var "db"}} = true
{{end -}}
} }
{{var "h"}}.ElemContainerState({{var "j"}}) if {{var "db"}} {
if {{var "j"}} < len({{var "v"}}) {
{{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x }}
} else {
z.DecSwallow() z.DecSwallow()
} else {
{{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x -}}
} }
{{end}} {{end -}}
} }
{{if isSlice }}if {{var "j"}} < len({{var "v"}}) { {{if isSlice}} if {{var "j"}} < len({{var "v"}}) {
{{var "v"}} = {{var "v"}}[:{{var "j"}}] {{var "v"}} = {{var "v"}}[:{{var "j"}}]
{{var "c"}} = true {{var "c"}} = true
} else if {{var "j"}} == 0 && {{var "v"}} == nil { } else if {{var "j"}} == 0 && {{var "v"}} == nil {
{{var "v"}} = []{{ .Typ }}{} {{var "v"}} = make([]{{ .Typ }}, 0)
{{var "c"}} = true {{var "c"}} = true
}{{end}} }
{{end -}}
} }
{{var "h"}}.End() {{var "h"}}.End()
{{if not isArray }}if {{var "c"}} { {{if not isArray }}if {{var "c"}} {
*{{ .Varname }} = {{var "v"}} *{{ .Varname }} = {{var "v"}}
}{{end}} }
{{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}})
}
}
`

File diff suppressed because it is too large Load Diff

5
vendor/github.com/ugorji/go/codec/go.mod generated vendored Normal file
View File

@ -0,0 +1,5 @@
module github.com/ugorji/go/codec
go 1.11
require github.com/ugorji/go v1.2.4

View File

@ -0,0 +1,14 @@
// Copyright (c) 2012-2020 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)
}

View File

@ -0,0 +1,19 @@
// Copyright (c) 2012-2020 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 (
"errors"
"reflect"
)
const reflectArrayOfSupported = false
var errNoReflectArrayOf = errors.New("codec: reflect.ArrayOf unsupported by this go version")
func reflectArrayOf(count int, elem reflect.Type) reflect.Type {
panic(errNoReflectArrayOf)
}

View File

@ -0,0 +1,12 @@
// Copyright (c) 2012-2020 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 "time"
func fmtTime(t time.Time, fmt string, b []byte) []byte {
return t.AppendFormat(b, fmt)
}

View File

@ -0,0 +1,15 @@
// Copyright (c) 2012-2020 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 "time"
func fmtTime(t time.Time, fmt string, b []byte) []byte {
s := t.Format(fmt)
b = b[:len(s)]
copy(b, s)
return b
}

View File

@ -0,0 +1,12 @@
// Copyright (c) 2012-2020 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
import "reflect"
func makeMapReflect(t reflect.Type, size int) reflect.Value {
return reflect.MakeMap(t)
}

View File

@ -0,0 +1,13 @@
// Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.
// +build go1.10
// +build safe appengine
package codec
import "reflect"
func makeMapReflect(t reflect.Type, size int) reflect.Value {
return reflect.MakeMapWithSize(t, size)
}

View File

@ -0,0 +1,26 @@
// +build go1.10
// +build !safe
// +build !appengine
// Copyright (c) 2012-2020 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"
"unsafe"
)
func makeMapReflect(typ reflect.Type, size int) (rv reflect.Value) {
t := (*unsafeIntf)(unsafe.Pointer(&typ)).ptr
urv := (*unsafeReflectValue)(unsafe.Pointer(&rv))
urv.typ = t
urv.flag = uintptr(reflect.Map)
urv.ptr = makemap(t, size, nil)
return
}
//go:linkname makemap runtime.makemap
//go:noescape
func makemap(typ unsafe.Pointer, size int, h unsafe.Pointer) unsafe.Pointer

View File

@ -0,0 +1,40 @@
// Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.
// +build go1.12
// +build safe appengine
package codec
import "reflect"
type mapIter struct {
t *reflect.MapIter
m reflect.Value
values bool
}
func (t *mapIter) Next() (r bool) {
return t.t.Next()
}
func (t *mapIter) Key() reflect.Value {
return t.t.Key()
}
func (t *mapIter) Value() (r reflect.Value) {
if t.values {
return t.t.Value()
}
return
}
func (t *mapIter) Done() {}
func mapRange(t *mapIter, m, k, v reflect.Value, values bool) {
*t = mapIter{
m: m,
t: m.MapRange(),
values: values,
}
}

View File

@ -0,0 +1,44 @@
// Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.
// +build go1.7
// +build !go1.12
// +build safe appengine
package codec
import "reflect"
type mapIter struct {
m reflect.Value
keys []reflect.Value
j int
values bool
}
func (t *mapIter) Next() (r bool) {
t.j++
return t.j < len(t.keys)
}
func (t *mapIter) Key() reflect.Value {
return t.keys[t.j]
}
func (t *mapIter) Value() (r reflect.Value) {
if t.values {
return t.m.MapIndex(t.keys[t.j])
}
return
}
func (t *mapIter) Done() {}
func mapRange(t *mapIter, m, k, v reflect.Value, values bool) {
*t = mapIter{
m: m,
keys: m.MapKeys(),
values: values,
j: -1,
}
}

View File

@ -0,0 +1,8 @@
// Copyright (c) 2012-2020 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

View File

@ -0,0 +1,8 @@
// Copyright (c) 2012-2020 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

View File

@ -0,0 +1,21 @@
// Copyright (c) 2012-2020 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
import "errors"
// 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
var errCodecSupportedOnlyFromGo14 = errors.New("codec: go 1.3 and below are not supported")
func init() {
panic(errCodecSupportedOnlyFromGo14)
}

View File

@ -0,0 +1,10 @@
// Copyright (c) 2012-2020 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"

View File

@ -0,0 +1,10 @@
// Copyright (c) 2012-2020 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"

View File

@ -0,0 +1,8 @@
// Copyright (c) 2012-2020 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

View File

@ -0,0 +1,8 @@
// Copyright (c) 2012-2020 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

File diff suppressed because it is too large Load Diff

0
vendor/github.com/ugorji/go/codec/helper.s generated vendored Normal file
View File

View File

@ -1,79 +1,15 @@
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file. // Use of this source code is governed by a MIT license found in the LICENSE file.
package codec package codec
// maxArrayLen is the size of uint, which determines
// the maximum length of any array.
const maxArrayLen = 1<<((32<<(^uint(0)>>63))-1) - 1
// All non-std package dependencies live in this file, // All non-std package dependencies live in this file,
// so porting to different environment is easy (just update functions). // so porting to different environment is easy (just update functions).
import (
"errors"
"fmt"
"math"
"reflect"
)
func panicValToErr(panicVal interface{}, err *error) {
if panicVal == nil {
return
}
// case nil
switch xerr := panicVal.(type) {
case error:
*err = xerr
case string:
*err = errors.New(xerr)
default:
*err = fmt.Errorf("%v", panicVal)
}
return
}
func hIsEmptyValue(v reflect.Value, 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 hIsEmptyValue(v.Elem(), deref, checkStruct)
} else {
return v.IsNil()
}
case reflect.Struct:
if !checkStruct {
return false
}
// return true if all fields are empty. else return false.
// we cannot use equality check, because some fields may be maps/slices/etc
// and consequently the structs are not comparable.
// return v.Interface() == reflect.Zero(v.Type()).Interface()
for i, n := 0, v.NumField(); i < n; i++ {
if !hIsEmptyValue(v.Field(i), deref, checkStruct) {
return false
}
}
return true
}
return false
}
func isEmptyValue(v reflect.Value) bool {
return hIsEmptyValue(v, derefForIsEmptyValue, checkStructForEmptyValue)
}
func pruneSignExt(v []byte, pos bool) (n int) { func pruneSignExt(v []byte, pos bool) (n int) {
if len(v) < 2 { if len(v) < 2 {
} else if pos && v[0] == 0 { } else if pos && v[0] == 0 {
@ -86,157 +22,126 @@ func pruneSignExt(v []byte, pos bool) (n int) {
return return
} }
func implementsIntf(typ, iTyp reflect.Type) (success bool, indir int8) { func halfFloatToFloatBits(h uint16) (f uint32) {
if typ == nil { // retrofitted from:
return // - OGRE (Object-Oriented Graphics Rendering Engine)
} // function: halfToFloatI https://www.ogre3d.org/docs/api/1.9/_ogre_bitwise_8h_source.html
rt := typ
// The type might be a pointer and we need to keep
// dereferencing to the base type until we find an implementation.
for {
if rt.Implements(iTyp) {
return true, indir
}
if p := rt; p.Kind() == reflect.Ptr {
indir++
if indir >= math.MaxInt8 { // insane number of indirections
return false, 0
}
rt = p.Elem()
continue
}
break
}
// No luck yet, but if this is a base type (non-pointer), the pointer might satisfy.
if typ.Kind() != reflect.Ptr {
// Not a pointer, but does the pointer work?
if reflect.PtrTo(typ).Implements(iTyp) {
return true, -1
}
}
return false, 0
}
// validate that this function is correct ... s := uint32(h >> 15)
// culled from OGRE (Object-Oriented Graphics Rendering Engine) m := uint32(h & 0x03ff)
// function: halfToFloatI (http://stderr.org/doc/ogre-doc/api/OgreBitwise_8h-source.html) e := int32((h >> 10) & 0x1f)
func halfFloatToFloatBits(yy uint16) (d uint32) {
y := uint32(yy)
s := (y >> 15) & 0x01
e := (y >> 10) & 0x1f
m := y & 0x03ff
if e == 0 { if e == 0 {
if m == 0 { // plu or minus 0 if m == 0 { // plus or minus 0
return s << 31 return s << 31
} else { // Denormalized number -- renormalize it
for (m & 0x00000400) == 0 {
m <<= 1
e -= 1
}
e += 1
const zz uint32 = 0x0400
m &= ^zz
} }
// Denormalized number -- renormalize it
for (m & 0x0400) == 0 {
m <<= 1
e -= 1
}
e += 1
m &= ^uint32(0x0400)
} else if e == 31 { } else if e == 31 {
if m == 0 { // Inf if m == 0 { // Inf
return (s << 31) | 0x7f800000 return (s << 31) | 0x7f800000
} else { // NaN
return (s << 31) | 0x7f800000 | (m << 13)
} }
return (s << 31) | 0x7f800000 | (m << 13) // NaN
} }
e = e + (127 - 15) e = e + (127 - 15)
m = m << 13 m = m << 13
return (s << 31) | (e << 23) | m return (s << 31) | (uint32(e) << 23) | m
} }
// GrowCap will return a new capacity for a slice, given the following: func floatToHalfFloatBits(i uint32) (h uint16) {
// retrofitted from:
// - OGRE (Object-Oriented Graphics Rendering Engine)
// function: halfToFloatI https://www.ogre3d.org/docs/api/1.9/_ogre_bitwise_8h_source.html
// - http://www.java2s.com/example/java-utility-method/float-to/floattohalf-float-f-fae00.html
s := (i >> 16) & 0x8000
e := int32(((i >> 23) & 0xff) - (127 - 15))
m := i & 0x7fffff
var h32 uint32
if e <= 0 {
if e < -10 { // zero
h32 = s // track -0 vs +0
} else {
m = (m | 0x800000) >> uint32(1-e)
h32 = s | (m >> 13)
}
} else if e == 0xff-(127-15) {
if m == 0 { // Inf
h32 = s | 0x7c00
} else { // NAN
m >>= 13
var me uint32
if m == 0 {
me = 1
}
h32 = s | 0x7c00 | m | me
}
} else {
if e > 30 { // Overflow
h32 = s | 0x7c00
} else {
h32 = s | (uint32(e) << 10) | (m >> 13)
}
}
h = uint16(h32)
return
}
// growCap will return a new capacity for a slice, given the following:
// - oldCap: current capacity // - oldCap: current capacity
// - unit: in-memory size of an element // - unit: in-memory size of an element
// - num: number of elements to add // - num: number of elements to add
func growCap(oldCap, unit, num int) (newCap int) { func growCap(oldCap, unit, num uint) (newCap uint) {
// appendslice logic (if cap < 1024, *2, else *1.25): // appendslice logic (if cap < 1024, *2, else *1.25):
// leads to many copy calls, especially when copying bytes. // leads to many copy calls, especially when copying bytes.
// bytes.Buffer model (2*cap + n): much better for 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 // smarter way is to take the byte-size of the appended element(type) into account
// maintain 3 thresholds: // maintain 1 thresholds:
// t1: if cap <= t1, newcap = 2x // t1: if cap <= t1, newcap = 2x
// t2: if cap <= t2, newcap = 1.75x // else newcap = 1.5x
// t3: if cap <= t3, newcap = 1.5x
// else newcap = 1.25x
// //
// t1, t2, t3 >= 1024 always. // t1 is always >= 1024.
// i.e. if unit size >= 16, then always do 2x or 1.25x (ie t1, t2, t3 are all same) // This means that, if unit size >= 16, then always do 2x or 1.5x (ie t1, t2, t3 are all same)
// //
// With this, appending for bytes increase by: // With this, appending for bytes increase by:
// 100% up to 4K // 100% up to 4K
// 75% up to 8K // 50% beyond that
// 50% up to 16K
// 25% beyond that
// unit can be 0 e.g. for struct{}{}; handle that appropriately // unit can be 0 e.g. for struct{}{}; handle that appropriately
var t1, t2, t3 int // thresholds maxCap := num + (oldCap * 3 / 2)
if unit <= 1 { if unit == 0 || maxCap > maxArrayLen || maxCap < oldCap { // handle wraparound, etc
t1, t2, t3 = 4*1024, 8*1024, 16*1024 return maxArrayLen
} 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 var t1 uint = 1024 // default thresholds for large values
if unit <= 4 {
// x is multiplier here: one of 5, 6, 7 or 8; incr of 25%, 50%, 75% or 100% respectively t1 = 8 * 1024
if oldCap <= t1 { // [0,t1] } else if unit <= 16 {
x = 8 t1 = 2 * 1024
} 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. newCap = 2 + num
if newCap > 64 { if oldCap > 0 {
if x = newCap % 64; x != 0 { if oldCap <= t1 { // [0,t1]
x = newCap / 64 newCap = num + (oldCap * 2)
newCap = 64 * (x + 1) } else { // (t1,infinity]
} newCap = maxCap
} else {
if x = newCap % 16; x != 0 {
x = newCap / 16
newCap = 16 * (x + 1)
} }
} }
// ensure newCap takes multiples of a cache line (size is a multiple of 64)
t1 = newCap * unit
if t2 := t1 % 64; t2 != 0 {
t1 += 64 - t2
newCap = t1 / unit
}
return return
} }
func expandSliceValue(s reflect.Value, num int) reflect.Value {
if num <= 0 {
return s
}
l0 := s.Len()
l1 := l0 + num // new slice length
if l1 < l0 {
panic("ExpandSlice: slice overflow")
}
c0 := s.Cap()
if l1 <= c0 {
return s.Slice(0, l1)
}
st := s.Type()
c1 := growCap(c0, int(st.Elem().Size()), num)
s2 := reflect.MakeSlice(st, l1, c1)
// println("expandslicevalue: cap-old: ", c0, ", cap-new: ", c1, ", len-new: ", l1)
reflect.Copy(s2, s)
return s2
}

View File

@ -1,20 +1,607 @@
//+build !unsafe // +build !go1.9 safe appengine
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file. // Use of this source code is governed by a MIT license found in the LICENSE file.
package codec package codec
// stringView returns a view of the []byte as a string. import (
// In unsafe mode, it doesn't incur allocation and copying caused by conversion. // "hash/adler32"
// In regular safe mode, it is an allocation and copy. "math"
"reflect"
"sync/atomic"
"time"
)
// This file has safe variants of some helper functions.
// MARKER: See helper_unsafe.go for the usage documentation.
const safeMode = true
func stringView(v []byte) string { func stringView(v []byte) string {
return string(v) 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.
func bytesView(v string) []byte { func bytesView(v string) []byte {
return []byte(v) return []byte(v)
} }
func byteSliceSameData(v1 []byte, v2 []byte) bool {
return cap(v1) != 0 && cap(v2) != 0 && &(v1[:1][0]) == &(v2[:1][0])
}
// func copyBytes(dst []byte, src []byte) {
// copy(dst, src)
// }
func isNil(v interface{}) (rv reflect.Value, isnil bool) {
rv = reflect.ValueOf(v)
if isnilBitset.isset(byte(rv.Kind())) {
isnil = rv.IsNil()
}
return
}
// func rvAddr(rv reflect.Value) uintptr {
// return rv.UnsafeAddr()
// }
func eq4i(i0, i1 interface{}) bool {
return i0 == i1
}
func rv4iptr(i interface{}) reflect.Value { return reflect.ValueOf(i) }
func rv4istr(i interface{}) reflect.Value { return reflect.ValueOf(i) }
// func rv4i(i interface{}) reflect.Value { return reflect.ValueOf(i) }
// func rv4iK(i interface{}, kind byte, isref bool) reflect.Value { return reflect.ValueOf(i) }
func rv2i(rv reflect.Value) interface{} {
return rv.Interface()
}
func rvType(rv reflect.Value) reflect.Type {
return rv.Type()
}
func rvIsNil(rv reflect.Value) bool {
return rv.IsNil()
}
func rvSetSliceLen(rv reflect.Value, length int) {
rv.SetLen(length)
}
func rvZeroAddrK(t reflect.Type, k reflect.Kind) reflect.Value {
return reflect.New(t).Elem()
}
func rvZeroAddrTransientK(t reflect.Type, k reflect.Kind) (rv reflect.Value) {
return reflect.New(t).Elem()
}
func rvZeroAddrTransient2K(t reflect.Type, k reflect.Kind) (rv reflect.Value) {
return reflect.New(t).Elem()
}
func rvZeroK(t reflect.Type, k reflect.Kind) reflect.Value {
return reflect.Zero(t)
}
func rvConvert(v reflect.Value, t reflect.Type) (rv reflect.Value) {
// reflect.Value.Convert(...) will make a copy if it is addressable.
// since we need to maintain references for decoding, we must check appropriately.
if v.CanAddr() {
return v.Addr().Convert(reflect.PtrTo(t)).Elem()
}
return v.Convert(t)
}
func rvAddressableReadonly(v reflect.Value) (rv reflect.Value) {
rv = rvZeroAddrK(v.Type(), v.Kind())
rvSetDirect(rv, v)
return
}
func rt2id(rt reflect.Type) uintptr {
return reflect.ValueOf(rt).Pointer()
}
func i2rtid(i interface{}) uintptr {
return reflect.ValueOf(reflect.TypeOf(i)).Pointer()
}
// --------------------------
func isEmptyValue(v reflect.Value, tinfos *TypeInfos, recursive bool) bool {
switch v.Kind() {
case reflect.Invalid:
return true
case reflect.Array, reflect.String:
return v.Len() == 0
case reflect.Map, reflect.Slice, reflect.Chan:
return v.IsNil() || 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.Complex64, reflect.Complex128:
c := v.Complex()
return math.Float64bits(real(c)) == 0 && math.Float64bits(imag(c)) == 0
case reflect.Float32, reflect.Float64:
return v.Float() == 0
case reflect.Func, reflect.UnsafePointer:
return v.IsNil()
case reflect.Interface, reflect.Ptr:
isnil := v.IsNil()
if recursive && !isnil {
return isEmptyValue(v.Elem(), tinfos, recursive)
}
return isnil
case reflect.Struct:
return isEmptyStruct(v, tinfos, recursive)
}
return false
}
// isEmptyStruct is only called from isEmptyValue, and checks if a struct is empty:
// - does it implement IsZero() bool
// - is it comparable, and can i compare directly using ==
// - if checkStruct, then walk through the encodable fields
// and check if they are empty or not.
func isEmptyStruct(v reflect.Value, tinfos *TypeInfos, recursive bool) bool {
// v is a struct kind - no need to check again.
// We only check isZero on a struct kind, to reduce the amount of times
// that we lookup the rtid and typeInfo for each type as we walk the tree.
vt := rvType(v)
rtid := rt2id(vt)
if tinfos == nil {
tinfos = defTypeInfos
}
ti := tinfos.get(rtid, vt)
if ti.rtid == timeTypId {
return rv2i(v).(time.Time).IsZero()
}
if ti.flagIsZeroer {
return rv2i(v).(isZeroer).IsZero()
}
if ti.flagIsZeroerPtr && v.CanAddr() {
return rv2i(v.Addr()).(isZeroer).IsZero()
}
if ti.flagIsCodecEmptyer {
return rv2i(v).(isCodecEmptyer).IsCodecEmpty()
}
if ti.flagIsCodecEmptyerPtr && v.CanAddr() {
return rv2i(v.Addr()).(isCodecEmptyer).IsCodecEmpty()
}
if ti.flagComparable {
return rv2i(v) == rv2i(rvZeroK(vt, reflect.Struct))
}
if !recursive {
return false
}
// We only care about what we can encode/decode,
// so that is what we use to check omitEmpty.
for _, si := range ti.sfiSrc {
sfv := si.path.field(v)
if sfv.IsValid() && !isEmptyValue(sfv, tinfos, recursive) {
return false
}
}
return true
}
// --------------------------
type atomicClsErr struct {
v atomic.Value
}
func (x *atomicClsErr) load() (e clsErr) {
if i := x.v.Load(); i != nil {
e = i.(clsErr)
}
return
}
func (x *atomicClsErr) store(p clsErr) {
x.v.Store(p)
}
// --------------------------
type atomicTypeInfoSlice struct {
v atomic.Value
}
func (x *atomicTypeInfoSlice) load() (e []rtid2ti) {
if i := x.v.Load(); i != nil {
e = i.([]rtid2ti)
}
return
}
func (x *atomicTypeInfoSlice) store(p []rtid2ti) {
x.v.Store(p)
}
// --------------------------
type atomicRtidFnSlice struct {
v atomic.Value
}
func (x *atomicRtidFnSlice) load() (e []codecRtidFn) {
if i := x.v.Load(); i != nil {
e = i.([]codecRtidFn)
}
return
}
func (x *atomicRtidFnSlice) store(p []codecRtidFn) {
x.v.Store(p)
}
// --------------------------
func (n *fauxUnion) ru() reflect.Value {
return reflect.ValueOf(&n.u).Elem()
}
func (n *fauxUnion) ri() reflect.Value {
return reflect.ValueOf(&n.i).Elem()
}
func (n *fauxUnion) rf() reflect.Value {
return reflect.ValueOf(&n.f).Elem()
}
func (n *fauxUnion) rl() reflect.Value {
return reflect.ValueOf(&n.l).Elem()
}
func (n *fauxUnion) rs() reflect.Value {
return reflect.ValueOf(&n.s).Elem()
}
func (n *fauxUnion) rt() reflect.Value {
return reflect.ValueOf(&n.t).Elem()
}
func (n *fauxUnion) rb() reflect.Value {
return reflect.ValueOf(&n.b).Elem()
}
// --------------------------
func rvSetBytes(rv reflect.Value, v []byte) {
rv.SetBytes(v)
}
func rvSetString(rv reflect.Value, v string) {
rv.SetString(v)
}
func rvSetBool(rv reflect.Value, v bool) {
rv.SetBool(v)
}
func rvSetTime(rv reflect.Value, v time.Time) {
rv.Set(reflect.ValueOf(v))
}
func rvSetFloat32(rv reflect.Value, v float32) {
rv.SetFloat(float64(v))
}
func rvSetFloat64(rv reflect.Value, v float64) {
rv.SetFloat(v)
}
func rvSetComplex64(rv reflect.Value, v complex64) {
rv.SetComplex(complex128(v))
}
func rvSetComplex128(rv reflect.Value, v complex128) {
rv.SetComplex(v)
}
func rvSetInt(rv reflect.Value, v int) {
rv.SetInt(int64(v))
}
func rvSetInt8(rv reflect.Value, v int8) {
rv.SetInt(int64(v))
}
func rvSetInt16(rv reflect.Value, v int16) {
rv.SetInt(int64(v))
}
func rvSetInt32(rv reflect.Value, v int32) {
rv.SetInt(int64(v))
}
func rvSetInt64(rv reflect.Value, v int64) {
rv.SetInt(v)
}
func rvSetUint(rv reflect.Value, v uint) {
rv.SetUint(uint64(v))
}
func rvSetUintptr(rv reflect.Value, v uintptr) {
rv.SetUint(uint64(v))
}
func rvSetUint8(rv reflect.Value, v uint8) {
rv.SetUint(uint64(v))
}
func rvSetUint16(rv reflect.Value, v uint16) {
rv.SetUint(uint64(v))
}
func rvSetUint32(rv reflect.Value, v uint32) {
rv.SetUint(uint64(v))
}
func rvSetUint64(rv reflect.Value, v uint64) {
rv.SetUint(v)
}
// ----------------
func rvSetDirect(rv reflect.Value, v reflect.Value) {
rv.Set(v)
}
func rvSetDirectZero(rv reflect.Value) {
rv.Set(reflect.Zero(rv.Type()))
}
func rvSlice(rv reflect.Value, length int) reflect.Value {
return rv.Slice(0, length)
}
func rvMakeSlice(rv reflect.Value, ti *typeInfo, xlen, xcap int) (v reflect.Value, set bool) {
v = reflect.MakeSlice(ti.rt, xlen, xcap)
if rv.Len() > 0 {
reflect.Copy(v, rv)
}
return
}
func rvGrowSlice(rv reflect.Value, ti *typeInfo, xcap, incr int) (v reflect.Value, newcap int, set bool) {
newcap = int(growCap(uint(xcap), uint(ti.elemsize), uint(incr)))
v = reflect.MakeSlice(ti.rt, newcap, newcap)
if rv.Len() > 0 {
reflect.Copy(v, rv)
}
return
}
// ----------------
func rvSliceIndex(rv reflect.Value, i int, ti *typeInfo) reflect.Value {
return rv.Index(i)
}
func rvArrayIndex(rv reflect.Value, i int, ti *typeInfo) reflect.Value {
return rv.Index(i)
}
func rvSliceZeroCap(t reflect.Type) (v reflect.Value) {
return reflect.MakeSlice(t, 0, 0)
}
func rvLenSlice(rv reflect.Value) int {
return rv.Len()
}
func rvCapSlice(rv reflect.Value) int {
return rv.Cap()
}
func rvGetArrayBytes(rv reflect.Value, scratch []byte) (bs []byte) {
l := rv.Len()
if scratch == nil || rv.CanAddr() {
return rv.Slice(0, l).Bytes()
}
if l <= cap(scratch) {
bs = scratch[:l]
} else {
bs = make([]byte, l)
}
reflect.Copy(reflect.ValueOf(bs), rv)
return
}
func rvGetArray4Slice(rv reflect.Value) (v reflect.Value) {
v = rvZeroAddrK(reflectArrayOf(rvLenSlice(rv), rvType(rv).Elem()), reflect.Array)
reflect.Copy(v, rv)
return
}
func rvGetSlice4Array(rv reflect.Value, v interface{}) {
// v is a pointer to a slice to be populated
// rv.Slice fails if address is not addressable, which can occur during encoding.
// Consequently, check if non-addressable, and if so, make new slice and copy into it first.
// MARKER: this *may* cause allocation if non-addressable, unfortunately.
rve := reflect.ValueOf(v).Elem()
l := rv.Len()
if rv.CanAddr() {
rve.Set(rv.Slice(0, l))
} else {
rvs := reflect.MakeSlice(rve.Type(), l, l)
reflect.Copy(rvs, rv)
rve.Set(rvs)
}
// reflect.ValueOf(v).Elem().Set(rv.Slice(0, rv.Len()))
}
func rvCopySlice(dest, src reflect.Value) {
reflect.Copy(dest, src)
}
// ------------
func rvGetBool(rv reflect.Value) bool {
return rv.Bool()
}
func rvGetBytes(rv reflect.Value) []byte {
return rv.Bytes()
}
func rvGetTime(rv reflect.Value) time.Time {
return rv2i(rv).(time.Time)
}
func rvGetString(rv reflect.Value) string {
return rv.String()
}
func rvGetFloat64(rv reflect.Value) float64 {
return rv.Float()
}
func rvGetFloat32(rv reflect.Value) float32 {
return float32(rv.Float())
}
func rvGetComplex64(rv reflect.Value) complex64 {
return complex64(rv.Complex())
}
func rvGetComplex128(rv reflect.Value) complex128 {
return rv.Complex()
}
func rvGetInt(rv reflect.Value) int {
return int(rv.Int())
}
func rvGetInt8(rv reflect.Value) int8 {
return int8(rv.Int())
}
func rvGetInt16(rv reflect.Value) int16 {
return int16(rv.Int())
}
func rvGetInt32(rv reflect.Value) int32 {
return int32(rv.Int())
}
func rvGetInt64(rv reflect.Value) int64 {
return rv.Int()
}
func rvGetUint(rv reflect.Value) uint {
return uint(rv.Uint())
}
func rvGetUint8(rv reflect.Value) uint8 {
return uint8(rv.Uint())
}
func rvGetUint16(rv reflect.Value) uint16 {
return uint16(rv.Uint())
}
func rvGetUint32(rv reflect.Value) uint32 {
return uint32(rv.Uint())
}
func rvGetUint64(rv reflect.Value) uint64 {
return rv.Uint()
}
func rvGetUintptr(rv reflect.Value) uintptr {
return uintptr(rv.Uint())
}
func rvLenMap(rv reflect.Value) int {
return rv.Len()
}
// func rvLenArray(rv reflect.Value) int { return rv.Len() }
// ------------ map range and map indexing ----------
func mapGet(m, k, v reflect.Value, keyFastKind mapKeyFastKind, valIsIndirect, valIsRef bool) (vv reflect.Value) {
return m.MapIndex(k)
}
func mapSet(m, k, v reflect.Value, keyFastKind mapKeyFastKind, valIsIndirect, valIsRef bool) {
m.SetMapIndex(k, v)
}
// func mapDelete(m, k reflect.Value) {
// m.SetMapIndex(k, reflect.Value{})
// }
func mapAddrLoopvarRV(t reflect.Type, k reflect.Kind) (r reflect.Value) {
return // reflect.New(t).Elem()
}
// ---------- ENCODER optimized ---------------
func (e *Encoder) jsondriver() *jsonEncDriver {
return e.e.(*jsonEncDriver)
}
// ---------- DECODER optimized ---------------
func (d *Decoder) checkBreak() bool {
return d.d.CheckBreak()
}
func (d *Decoder) jsondriver() *jsonDecDriver {
return d.d.(*jsonDecDriver)
}
// ---------- structFieldInfo optimized ---------------
func (n *structFieldInfoPathNode) rvField(v reflect.Value) reflect.Value {
return v.Field(int(n.index))
}
// ---------- others ---------------
/*
func hashShortString(b []byte) (h uintptr) {
// MARKER: consider fnv - it may be a better hash than adler
return uintptr(adler32.Checksum(b))
}
// func hashShortString(b []byte) (h uint64) {
// // culled from https://github.com/golang/go/issues/32779#issuecomment-735494578
// // Read the string in two parts using wide-integer loads.
// // The prefix and suffix may overlap, which is fine.
// switch {
// case len(b) > 8:
// h ^= binary.LittleEndian.Uint64(b[:8])
// h *= 0x00000100000001B3 // inspired by FNV-64
// h ^= binary.LittleEndian.Uint64(b[len(b)-8:])
// case len(b) > 4:
// h ^= uint64(binary.LittleEndian.Uint32(b[:4]))
// h *= 0x01000193 // inspired by FNV-32
// h ^= uint64(binary.LittleEndian.Uint32(b[len(b)-4:]))
// default:
// h ^= uint64(binary.LittleEndian.Uint16(b[:2]))
// h *= 0x010f // inspired by hypothetical FNV-16
// h ^= uint64(binary.LittleEndian.Uint16(b[len(b)-2:]))
// }
//
// // Collapse a 64-bit, 32-bit, or 16-bit hash into an 8-bit hash.
// h ^= h >> 32
// h ^= h >> 16
// h ^= h >> 8
//
// // The cache has 8 buckets based on the lower 3-bits of the length.
// h = ((h << 3) | uint64(len(b)&7))
// return
// }
func rtsize(rt reflect.Type) uintptr {
return rt.Size()
}
*/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,25 @@
// +build !safe
// +build !appengine
// +build go1.9
// +build gc
// Copyright (c) 2012-2020 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"
"unsafe"
)
func rvType(rv reflect.Value) reflect.Type {
return rvPtrToType(((*unsafeReflectValue)(unsafe.Pointer(&rv))).typ) // rv.Type()
}
//go:linkname unsafeZeroArr runtime.zeroVal
var unsafeZeroArr [1024]byte
//go:linkname rvPtrToType reflect.toType
//go:noescape
func rvPtrToType(typ unsafe.Pointer) reflect.Type

View File

@ -0,0 +1,17 @@
// +build !safe
// +build !appengine
// +build go1.9
// +build !gc
// Copyright (c) 2012-2020 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"
var unsafeZeroArr [1024]byte
func rvType(rv reflect.Value) reflect.Type {
return rv.Type()
}

File diff suppressed because it is too large Load Diff

184
vendor/github.com/ugorji/go/codec/mammoth-test.go.tmpl generated vendored Normal file
View File

@ -0,0 +1,184 @@
// Copyright (c) 2012-2020 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 }}
{{ .MethodNamePfx "Farr4" false }} [4]{{ .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 }}
var bs{{$i}} []byte
v{{$i}}v1 = v
bs{{$i}} = testMarshalErr(v{{$i}}v1, h, t, "enc-slice-v{{$i}}")
if v == nil {
v{{$i}}v2 = make([]{{ .Elem }}, 2)
testUnmarshalErr(v{{$i}}v2, bs{{$i}}, h, t, "dec-slice-v{{$i}}")
testDeepEqualErr(v{{$i}}v2[0], v{{$i}}v2[1], t, "equal-slice-v{{$i}}") // should not change
testDeepEqualErr(len(v{{$i}}v2), 2, t, "equal-slice-v{{$i}}") // should not change
v{{$i}}v2 = make([]{{ .Elem }}, 2)
testUnmarshalErr(reflect.ValueOf(v{{$i}}v2), bs{{$i}}, h, t, "dec-slice-v{{$i}}-noaddr") // non-addressable value
testDeepEqualErr(v{{$i}}v2[0], v{{$i}}v2[1], t, "equal-slice-v{{$i}}-noaddr") // should not change
testDeepEqualErr(len(v{{$i}}v2), 2, t, "equal-slice-v{{$i}}") // should not change
} 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}}")
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")
}
testReleaseBytes(bs{{$i}})
// ...
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
testUnmarshalErr(&v{{$i}}va, bs{{$i}}, h, t, "dec-array-v{{$i}}-p-1")
if v{{$i}}v1 == nil && v{{$i}}v2 == nil { v{{$i}}v2 = []{{ .Elem }}{} } // so we can compare to zero len slice below
testDeepEqualErr(v{{$i}}va[:len(v{{$i}}v2)], v{{$i}}v2, t, "equal-array-v{{$i}}-p-1")
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")
}
testReleaseBytes(bs{{$i}})
// ...
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)
if v != nil {
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")
testReleaseBytes(bs{{$i}})
}
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")
testReleaseBytes(bs{{$i}})
}
{{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 }}
var bs{{$i}} []byte
v{{$i}}v1 = v
bs{{$i}} = testMarshalErr(v{{$i}}v1, h, t, "enc-map-v{{$i}}")
if v != nil {
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")
testReleaseBytes(bs{{$i}})
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")
testReleaseBytes(bs{{$i}})
// ...
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)
if v != nil {
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")
testReleaseBytes(bs{{$i}})
}
}
{{end}}{{end}}{{end}}
}
func doTestMammothMapsAndSlices(t *testing.T, h Handle) {
doTestMammothSlices(t, h)
doTestMammothMaps(t, h)
}

View File

@ -0,0 +1,99 @@
// +build !notfastpath
// Copyright (c) 2012-2020 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)
bigenstd.PutUint64(data, uint64(x))
return
}
func (x *testMammoth2Binary) UnmarshalBinary(data []byte) (err error) {
*x = testMammoth2Binary(bigenstd.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
Tcomplex128 complex128
Tcomplex64 complex64
Tbytes []uint8
Tpbytes *[]uint8
}

File diff suppressed because it is too large Load Diff

View File

@ -1,213 +0,0 @@
// 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
import (
"math/rand"
"time"
)
// NoopHandle returns a no-op handle. It basically does nothing.
// It is only useful for benchmarking, as it gives an idea of the
// overhead from the codec framework.
//
// LIBRARY USERS: *** DO NOT USE ***
func NoopHandle(slen int) *noopHandle {
h := noopHandle{}
h.rand = rand.New(rand.NewSource(time.Now().UnixNano()))
h.B = make([][]byte, slen)
h.S = make([]string, slen)
for i := 0; i < len(h.S); i++ {
b := make([]byte, i+1)
for j := 0; j < len(b); j++ {
b[j] = 'a' + byte(i)
}
h.B[i] = b
h.S[i] = string(b)
}
return &h
}
// noopHandle does nothing.
// It is used to simulate the overhead of the codec framework.
type noopHandle struct {
BasicHandle
binaryEncodingType
noopDrv // noopDrv is unexported here, so we can get a copy of it when needed.
}
type noopDrv struct {
d *Decoder
e *Encoder
i int
S []string
B [][]byte
mks []bool // stack. if map (true), else if array (false)
mk bool // top of stack. what container are we on? map or array?
ct valueType // last response for IsContainerType.
cb int // counter for ContainerType
rand *rand.Rand
}
func (h *noopDrv) r(v int) int { return h.rand.Intn(v) }
func (h *noopDrv) m(v int) int { h.i++; return h.i % v }
func (h *noopDrv) newEncDriver(e *Encoder) encDriver { h.e = e; return h }
func (h *noopDrv) newDecDriver(d *Decoder) decDriver { h.d = d; return h }
func (h *noopDrv) reset() {}
func (h *noopDrv) uncacheRead() {}
// --- encDriver
// stack functions (for map and array)
func (h *noopDrv) start(b bool) {
// println("start", len(h.mks)+1)
h.mks = append(h.mks, b)
h.mk = b
}
func (h *noopDrv) end() {
// println("end: ", len(h.mks)-1)
h.mks = h.mks[:len(h.mks)-1]
if len(h.mks) > 0 {
h.mk = h.mks[len(h.mks)-1]
} else {
h.mk = false
}
}
func (h *noopDrv) EncodeBuiltin(rt uintptr, v interface{}) {}
func (h *noopDrv) EncodeNil() {}
func (h *noopDrv) EncodeInt(i int64) {}
func (h *noopDrv) EncodeUint(i uint64) {}
func (h *noopDrv) EncodeBool(b bool) {}
func (h *noopDrv) EncodeFloat32(f float32) {}
func (h *noopDrv) EncodeFloat64(f float64) {}
func (h *noopDrv) EncodeRawExt(re *RawExt, e *Encoder) {}
func (h *noopDrv) EncodeArrayStart(length int) { h.start(true) }
func (h *noopDrv) EncodeMapStart(length int) { h.start(false) }
func (h *noopDrv) EncodeEnd() { h.end() }
func (h *noopDrv) EncodeString(c charEncoding, v string) {}
func (h *noopDrv) EncodeSymbol(v string) {}
func (h *noopDrv) EncodeStringBytes(c charEncoding, v []byte) {}
func (h *noopDrv) EncodeExt(rv interface{}, xtag uint64, ext Ext, e *Encoder) {}
// ---- decDriver
func (h *noopDrv) initReadNext() {}
func (h *noopDrv) CheckBreak() bool { return false }
func (h *noopDrv) IsBuiltinType(rt uintptr) bool { return false }
func (h *noopDrv) DecodeBuiltin(rt uintptr, v interface{}) {}
func (h *noopDrv) DecodeInt(bitsize uint8) (i int64) { return int64(h.m(15)) }
func (h *noopDrv) DecodeUint(bitsize uint8) (ui uint64) { return uint64(h.m(35)) }
func (h *noopDrv) DecodeFloat(chkOverflow32 bool) (f float64) { return float64(h.m(95)) }
func (h *noopDrv) DecodeBool() (b bool) { return h.m(2) == 0 }
func (h *noopDrv) DecodeString() (s string) { return h.S[h.m(8)] }
// func (h *noopDrv) DecodeStringAsBytes(bs []byte) []byte { return h.DecodeBytes(bs) }
func (h *noopDrv) DecodeBytes(bs []byte, isstring, zerocopy bool) []byte { return h.B[h.m(len(h.B))] }
func (h *noopDrv) ReadEnd() { h.end() }
// toggle map/slice
func (h *noopDrv) ReadMapStart() int { h.start(true); return h.m(10) }
func (h *noopDrv) ReadArrayStart() int { h.start(false); return h.m(10) }
func (h *noopDrv) ContainerType() (vt valueType) {
// return h.m(2) == 0
// handle kStruct, which will bomb is it calls this and doesn't get back a map or array.
// consequently, if the return value is not map or array, reset it to one of them based on h.m(7) % 2
// for kstruct: at least one out of every 2 times, return one of valueTypeMap or Array (else kstruct bombs)
// however, every 10th time it is called, we just return something else.
var vals = [...]valueType{valueTypeArray, valueTypeMap}
// ------------ TAKE ------------
// if h.cb%2 == 0 {
// if h.ct == valueTypeMap || h.ct == valueTypeArray {
// } else {
// h.ct = vals[h.m(2)]
// }
// } else if h.cb%5 == 0 {
// h.ct = valueType(h.m(8))
// } else {
// h.ct = vals[h.m(2)]
// }
// ------------ TAKE ------------
// if h.cb%16 == 0 {
// h.ct = valueType(h.cb % 8)
// } else {
// h.ct = vals[h.cb%2]
// }
h.ct = vals[h.cb%2]
h.cb++
return h.ct
// if h.ct == valueTypeNil || h.ct == valueTypeString || h.ct == valueTypeBytes {
// return h.ct
// }
// return valueTypeUnset
// TODO: may need to tweak this so it works.
// if h.ct == valueTypeMap && vt == valueTypeArray || h.ct == valueTypeArray && vt == valueTypeMap {
// h.cb = !h.cb
// h.ct = vt
// return h.cb
// }
// // go in a loop and check it.
// h.ct = vt
// h.cb = h.m(7) == 0
// return h.cb
}
func (h *noopDrv) TryDecodeAsNil() bool {
if h.mk {
return false
} else {
return h.m(8) == 0
}
}
func (h *noopDrv) DecodeExt(rv interface{}, xtag uint64, ext Ext) uint64 {
return 0
}
func (h *noopDrv) DecodeNaked() {
// use h.r (random) not h.m() because h.m() could cause the same value to be given.
var sk int
if h.mk {
// if mapkey, do not support values of nil OR bytes, array, map or rawext
sk = h.r(7) + 1
} else {
sk = h.r(12)
}
n := &h.d.n
switch sk {
case 0:
n.v = valueTypeNil
case 1:
n.v, n.b = valueTypeBool, false
case 2:
n.v, n.b = valueTypeBool, true
case 3:
n.v, n.i = valueTypeInt, h.DecodeInt(64)
case 4:
n.v, n.u = valueTypeUint, h.DecodeUint(64)
case 5:
n.v, n.f = valueTypeFloat, h.DecodeFloat(true)
case 6:
n.v, n.f = valueTypeFloat, h.DecodeFloat(false)
case 7:
n.v, n.s = valueTypeString, h.DecodeString()
case 8:
n.v, n.l = valueTypeBytes, h.B[h.m(len(h.B))]
case 9:
n.v = valueTypeArray
case 10:
n.v = valueTypeMap
default:
n.v = valueTypeExt
n.u = h.DecodeUint(64)
n.l = h.B[h.m(len(h.B))]
}
h.ct = n.v
return
}

View File

@ -1,3 +0,0 @@
package codec
//go:generate bash prebuild.sh

View File

@ -1,199 +0,0 @@
#!/bin/bash
# _needgen is a helper function to tell if we need to generate files for msgp, codecgen.
_needgen() {
local a="$1"
zneedgen=0
if [[ ! -e "$a" ]]
then
zneedgen=1
echo 1
return 0
fi
for i in `ls -1 *.go.tmpl gen.go values_test.go`
do
if [[ "$a" -ot "$i" ]]
then
zneedgen=1
echo 1
return 0
fi
done
echo 0
}
# _build generates fast-path.go and gen-helper.go.
#
# It is needed because there is some dependency between the generated code
# and the other classes. Consequently, we have to totally remove the
# generated files and put stubs in place, before calling "go run" again
# to recreate them.
_build() {
if ! [[ "${zforce}" == "1" ||
"1" == $( _needgen "fast-path.generated.go" ) ||
"1" == $( _needgen "gen-helper.generated.go" ) ||
"1" == $( _needgen "gen.generated.go" ) ||
1 == 0 ]]
then
return 0
fi
# echo "Running prebuild"
if [ "${zbak}" == "1" ]
then
# echo "Backing up old generated files"
_zts=`date '+%m%d%Y_%H%M%S'`
_gg=".generated.go"
[ -e "gen-helper${_gg}" ] && mv gen-helper${_gg} gen-helper${_gg}__${_zts}.bak
[ -e "fast-path${_gg}" ] && mv fast-path${_gg} fast-path${_gg}__${_zts}.bak
# [ -e "safe${_gg}" ] && mv safe${_gg} safe${_gg}__${_zts}.bak
# [ -e "unsafe${_gg}" ] && mv unsafe${_gg} unsafe${_gg}__${_zts}.bak
else
rm -f fast-path.generated.go gen.generated.go gen-helper.generated.go \
*safe.generated.go *_generated_test.go *.generated_ffjson_expose.go
fi
cat > gen.generated.go <<EOF
// 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 = \`
EOF
cat >> gen.generated.go < gen-dec-map.go.tmpl
cat >> gen.generated.go <<EOF
\`
const genDecListTmpl = \`
EOF
cat >> gen.generated.go < gen-dec-array.go.tmpl
cat >> gen.generated.go <<EOF
\`
EOF
cat > gen-from-tmpl.codec.generated.go <<EOF
package codec
import "io"
func GenInternalGoFile(r io.Reader, w io.Writer, safe bool) error {
return genInternalGoFile(r, w, safe)
}
EOF
cat > gen-from-tmpl.generated.go <<EOF
//+build ignore
package main
//import "flag"
import "ugorji.net/codec"
import "os"
func run(fnameIn, fnameOut string, safe bool) {
fin, err := os.Open(fnameIn)
if err != nil { panic(err) }
defer fin.Close()
fout, err := os.Create(fnameOut)
if err != nil { panic(err) }
defer fout.Close()
err = codec.GenInternalGoFile(fin, fout, safe)
if err != nil { panic(err) }
}
func main() {
// do not make safe/unsafe variants.
// Instead, depend on escape analysis, and place string creation and usage appropriately.
// run("unsafe.go.tmpl", "safe.generated.go", true)
// run("unsafe.go.tmpl", "unsafe.generated.go", false)
run("fast-path.go.tmpl", "fast-path.generated.go", false)
run("gen-helper.go.tmpl", "gen-helper.generated.go", false)
}
EOF
go run -tags=notfastpath gen-from-tmpl.generated.go && \
rm -f gen-from-tmpl.*generated.go
}
_codegenerators() {
if [[ $zforce == "1" ||
"1" == $( _needgen "values_codecgen${zsfx}" ) ||
"1" == $( _needgen "values_msgp${zsfx}" ) ||
"1" == $( _needgen "values_ffjson${zsfx}" ) ||
1 == 0 ]]
then
# codecgen creates some temporary files in the directory (main, pkg).
# Consequently, we should start msgp and ffjson first, and also put a small time latency before
# starting codecgen.
# Without this, ffjson chokes on one of the temporary files from codecgen.
if [[ $zexternal == "1" ]]
then
echo "ffjson ... " && \
ffjson -w values_ffjson${zsfx} $zfin &
zzzIdFF=$!
echo "msgp ... " && \
msgp -tests=false -o=values_msgp${zsfx} -file=$zfin &
zzzIdMsgp=$!
sleep 1 # give ffjson and msgp some buffer time. see note above.
fi
echo "codecgen - !unsafe ... " && \
codecgen -rt codecgen -t 'x,codecgen,!unsafe' -o values_codecgen${zsfx} -d 19780 $zfin &
zzzIdC=$!
echo "codecgen - unsafe ... " && \
codecgen -u -rt codecgen -t 'x,codecgen,unsafe' -o values_codecgen_unsafe${zsfx} -d 19781 $zfin &
zzzIdCU=$!
wait $zzzIdC $zzzIdCU $zzzIdMsgp $zzzIdFF && \
# remove (M|Unm)arshalJSON implementations, so they don't conflict with encoding/json bench \
if [[ $zexternal == "1" ]]
then
sed -i 's+ MarshalJSON(+ _MarshalJSON(+g' values_ffjson${zsfx} && \
sed -i 's+ UnmarshalJSON(+ _UnmarshalJSON(+g' values_ffjson${zsfx}
fi && \
echo "generators done!" && \
true
fi
}
# _init reads the arguments and sets up the flags
_init() {
OPTIND=1
while getopts "fbx" flag
do
case "x$flag" in
'xf') zforce=1;;
'xb') zbak=1;;
'xx') zexternal=1;;
*) echo "prebuild.sh accepts [-fbx] only"; return 1;;
esac
done
shift $((OPTIND-1))
OPTIND=1
}
# main script.
# First ensure that this is being run from the basedir (i.e. dirname of script is .)
if [ "." = `dirname $0` ]
then
zmydir=`pwd`
zfin="test_values.generated.go"
zsfx="_generated_test.go"
# rm -f *_generated_test.go
rm -f codecgen-*.go && \
_init "$@" && \
_build && \
cp $zmydir/values_test.go $zmydir/$zfin && \
_codegenerators && \
echo prebuild done successfully
rm -f $zmydir/$zfin
else
echo "Script must be run from the directory it resides in"
fi

814
vendor/github.com/ugorji/go/codec/reader.go generated vendored Normal file
View File

@ -0,0 +1,814 @@
// Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.
package codec
import "io"
// decReader abstracts the reading source, allowing implementations that can
// read from an io.Reader or directly off a byte slice with zero-copying.
type decReader interface {
// readx will use the implementation scratch buffer if possible i.e. n < len(scratchbuf), OR
// just return a view of the []byte being decoded from.
readx(n uint) []byte
readb([]byte)
readn1() byte
readn2() [2]byte
readn3() [3]byte
readn4() [4]byte
readn8() [8]byte
// readn1eof() (v uint8, eof bool)
// // read up to 8 bytes at a time
// readn(num uint8) (v [8]byte)
numread() uint // number of bytes read
// readNumber(includeLastByteRead bool) []byte
// skip any whitespace characters, and return the first non-matching byte
skipWhitespace() (token byte)
// jsonReadNum will include last read byte in first element of slice,
// and continue numeric characters until it sees a non-numeric char
// or EOF. If it sees a non-numeric character, it will unread that.
jsonReadNum() []byte
// jsonReadAsisChars will read json plain characters (anything but " or \)
// and return a slice terminated by a non-json asis character.
jsonReadAsisChars() []byte
// skip will skip any byte that matches, and return the first non-matching byte
// skip(accept *bitset256) (token byte)
// readTo will read any byte that matches, stopping once no-longer matching.
// readTo(accept *bitset256) (out []byte)
// readUntil will read, only stopping once it matches the 'stop' byte (which it excludes).
readUntil(stop byte) (out []byte)
}
// ------------------------------------------------
type unreadByteStatus uint8
// unreadByteStatus goes from
// undefined (when initialized) -- (read) --> canUnread -- (unread) --> canRead ...
const (
unreadByteUndefined unreadByteStatus = iota
unreadByteCanRead
unreadByteCanUnread
)
// --------------------
type ioDecReaderCommon struct {
r io.Reader // the reader passed in
n uint // num read
l byte // last byte
ls unreadByteStatus // last byte status
b [6]byte // tiny buffer for reading single bytes
blist *bytesFreelist
bufr []byte // buffer for readTo/readUntil
}
func (z *ioDecReaderCommon) reset(r io.Reader, blist *bytesFreelist) {
z.blist = blist
z.r = r
z.ls = unreadByteUndefined
z.l, z.n = 0, 0
z.bufr = z.blist.check(z.bufr, 256)
}
func (z *ioDecReaderCommon) numread() uint {
return z.n
}
// ------------------------------------------
// ioDecReader is a decReader that reads off an io.Reader.
//
// It also has a fallback implementation of ByteScanner if needed.
type ioDecReader struct {
ioDecReaderCommon
br io.ByteScanner
x [64 + 48]byte // for: get struct field name, swallow valueTypeBytes, etc
}
func (z *ioDecReader) reset(r io.Reader, blist *bytesFreelist) {
z.ioDecReaderCommon.reset(r, blist)
z.br, _ = r.(io.ByteScanner)
}
func (z *ioDecReader) Read(p []byte) (n int, err error) {
if len(p) == 0 {
return
}
var firstByte bool
if z.ls == unreadByteCanRead {
z.ls = unreadByteCanUnread
p[0] = z.l
if len(p) == 1 {
n = 1
return
}
firstByte = true
p = p[1:]
}
n, err = z.r.Read(p)
if n > 0 {
if err == io.EOF && n == len(p) {
err = nil // read was successful, so postpone EOF (till next time)
}
z.l = p[n-1]
z.ls = unreadByteCanUnread
}
if firstByte {
n++
}
return
}
func (z *ioDecReader) ReadByte() (c byte, err error) {
if z.br != nil {
c, err = z.br.ReadByte()
if err == nil {
z.l = c
z.ls = unreadByteCanUnread
}
return
}
n, err := z.Read(z.b[:1])
if n == 1 {
c = z.b[0]
if err == io.EOF {
err = nil // read was successful, so postpone EOF (till next time)
}
}
return
}
func (z *ioDecReader) UnreadByte() (err error) {
if z.br != nil {
err = z.br.UnreadByte()
if err == nil {
z.ls = unreadByteCanRead
}
return
}
switch z.ls {
case unreadByteCanUnread:
z.ls = unreadByteCanRead
case unreadByteCanRead:
err = errDecUnreadByteLastByteNotRead
case unreadByteUndefined:
err = errDecUnreadByteNothingToRead
default:
err = errDecUnreadByteUnknown
}
return
}
func (z *ioDecReader) readn2() (bs [2]byte) {
z.readb(bs[:])
return
}
func (z *ioDecReader) readn3() (bs [3]byte) {
z.readb(bs[:])
return
}
func (z *ioDecReader) readn4() (bs [4]byte) {
z.readb(bs[:])
return
}
func (z *ioDecReader) readn8() (bs [8]byte) {
z.readb(bs[:])
return
}
func (z *ioDecReader) readx(n uint) (bs []byte) {
if n == 0 {
return
}
if n < uint(len(z.x)) {
bs = z.x[:n]
} else {
bs = make([]byte, n)
}
_, err := readFull(z.r, bs)
halt.onerror(err)
z.n += uint(len(bs))
return
}
func (z *ioDecReader) readb(bs []byte) {
if len(bs) == 0 {
return
}
_, err := readFull(z.r, bs)
halt.onerror(err)
z.n += uint(len(bs))
}
func (z *ioDecReader) readn1() (b uint8) {
b, err := z.ReadByte()
halt.onerror(err)
z.n++
return
}
func (z *ioDecReader) readn1eof() (b uint8, eof bool) {
b, err := z.ReadByte()
if err == nil {
z.n++
} else if err == io.EOF {
eof = true
} else {
halt.onerror(err)
}
return
}
func (z *ioDecReader) jsonReadNum() (bs []byte) {
z.unreadn1()
z.bufr = z.bufr[:0]
LOOP:
i, eof := z.readn1eof()
if eof {
return z.bufr
}
if isNumberChar(i) {
z.bufr = append(z.bufr, i)
goto LOOP
}
z.unreadn1()
return z.bufr
}
func (z *ioDecReader) jsonReadAsisChars() (bs []byte) {
z.bufr = z.bufr[:0]
LOOP:
i := z.readn1()
z.bufr = append(z.bufr, i)
if i == '"' || i == '\\' {
return z.bufr
}
goto LOOP
}
func (z *ioDecReader) skipWhitespace() (token byte) {
LOOP:
token = z.readn1()
if isWhitespaceChar(token) {
goto LOOP
}
return
}
func (z *ioDecReader) readUntil(stop byte) []byte {
z.bufr = z.bufr[:0]
LOOP:
token := z.readn1()
z.bufr = append(z.bufr, token)
if token == stop {
return z.bufr[:len(z.bufr)-1]
}
goto LOOP
}
func (z *ioDecReader) unreadn1() {
err := z.UnreadByte()
halt.onerror(err)
z.n--
}
// ------------------------------------
type bufioDecReader struct {
ioDecReaderCommon
c uint // cursor
buf []byte
}
func (z *bufioDecReader) reset(r io.Reader, bufsize int, blist *bytesFreelist) {
z.ioDecReaderCommon.reset(r, blist)
z.c = 0
if cap(z.buf) < bufsize {
z.buf = blist.get(bufsize)
} else {
z.buf = z.buf[:0]
}
}
func (z *bufioDecReader) readb(p []byte) {
var n = uint(copy(p, z.buf[z.c:]))
z.n += n
z.c += n
if len(p) != int(n) {
z.readbFill(p, n, true, false)
}
}
func readbFillHandleErr(err error, must, eof bool) (isEOF bool) {
if err == io.EOF {
isEOF = true
}
if must && !(eof && isEOF) {
halt.onerror(err)
}
return
}
func (z *bufioDecReader) readbFill(p0 []byte, n uint, must, eof bool) (isEOF bool, err error) {
// at this point, there's nothing in z.buf to read (z.buf is fully consumed)
var p []byte
if p0 != nil {
p = p0[n:]
}
var n2 uint
if len(p) > cap(z.buf) {
n2, err = readFull(z.r, p)
if err != nil {
isEOF = readbFillHandleErr(err, must, eof)
return
}
n += n2
z.n += n2
// always keep last byte in z.buf
z.buf = z.buf[:1]
z.buf[0] = p[len(p)-1]
z.c = 1
return
}
// z.c is now 0, and len(p) <= cap(z.buf)
var n1 int
LOOP:
// for len(p) > 0 && z.err == nil {
z.buf = z.buf[0:cap(z.buf)]
n1, err = z.r.Read(z.buf)
n2 = uint(n1)
if n2 == 0 && err != nil {
isEOF = readbFillHandleErr(err, must, eof)
return
}
err = nil
z.buf = z.buf[:n2]
z.c = 0
if len(p) > 0 {
n2 = uint(copy(p, z.buf))
z.c = n2
n += n2
z.n += n2
p = p[n2:]
if len(p) > 0 {
goto LOOP
}
if z.c == 0 {
z.buf = z.buf[:1]
z.buf[0] = p[len(p)-1]
z.c = 1
}
}
return
}
func (z *bufioDecReader) readn1() (b byte) {
if z.c >= uint(len(z.buf)) {
z.readbFill(nil, 0, true, false)
}
b = z.buf[z.c]
z.c++
z.n++
return
}
func (z *bufioDecReader) readn1eof() (b byte, eof bool) {
if z.c >= uint(len(z.buf)) {
eof, _ = z.readbFill(nil, 0, true, true)
if eof {
return
}
}
b = z.buf[z.c]
z.c++
z.n++
return
}
func (z *bufioDecReader) unreadn1() {
if z.c == 0 {
halt.onerror(errDecUnreadByteNothingToRead)
}
z.c--
z.n--
}
func (z *bufioDecReader) readn2() (bs [2]byte) {
z.readb(bs[:])
return
}
func (z *bufioDecReader) readn3() (bs [3]byte) {
z.readb(bs[:])
return
}
func (z *bufioDecReader) readn4() (bs [4]byte) {
z.readb(bs[:])
return
}
func (z *bufioDecReader) readn8() (bs [8]byte) {
z.readb(bs[:])
return
}
func (z *bufioDecReader) readx(n uint) (bs []byte) {
if n == 0 {
// return
} else if z.c+n <= uint(len(z.buf)) {
bs = z.buf[z.c : z.c+n]
z.n += n
z.c += n
} else {
bs = make([]byte, n)
// n no longer used - can reuse
n = uint(copy(bs, z.buf[z.c:]))
z.n += n
z.c += n
z.readbFill(bs, n, true, false)
}
return
}
func (z *bufioDecReader) jsonReadNum() (bs []byte) {
z.unreadn1()
z.bufr = z.bufr[:0]
LOOP:
i, eof := z.readn1eof()
if eof {
return z.bufr
}
if isNumberChar(i) {
z.bufr = append(z.bufr, i)
goto LOOP
}
z.unreadn1()
return z.bufr
}
func (z *bufioDecReader) jsonReadAsisChars() (bs []byte) {
z.bufr = z.bufr[:0]
LOOP:
i := z.readn1()
z.bufr = append(z.bufr, i)
if i == '"' || i == '\\' {
return z.bufr
}
goto LOOP
}
func (z *bufioDecReader) skipWhitespace() (token byte) {
i := z.c
LOOP:
if i < uint(len(z.buf)) {
// inline z.skipLoopFn(i) and refactor, so cost is within inline budget
token = z.buf[i]
i++
if isWhitespaceChar(token) {
goto LOOP
}
z.n += i - 2 - z.c
z.c = i
return
}
return z.skipFillWhitespace()
}
func (z *bufioDecReader) skipFillWhitespace() (token byte) {
z.n += uint(len(z.buf)) - z.c
var i, n2 int
var err error
for {
z.c = 0
z.buf = z.buf[0:cap(z.buf)]
n2, err = z.r.Read(z.buf)
if n2 == 0 {
halt.onerror(err)
}
z.buf = z.buf[:n2]
for i, token = range z.buf {
if !isWhitespaceChar(token) {
z.n += (uint(i) - z.c) - 1
z.loopFn(uint(i + 1))
return
}
}
z.n += uint(n2)
}
}
func (z *bufioDecReader) loopFn(i uint) {
z.c = i
}
func (z *bufioDecReader) readUntil(stop byte) (out []byte) {
i := z.c
LOOP:
if i < uint(len(z.buf)) {
if z.buf[i] == stop {
z.n += (i - z.c) - 1
i++
out = z.buf[z.c:i]
z.c = i
goto FINISH
}
i++
goto LOOP
}
out = z.readUntilFill(stop)
FINISH:
return out[:len(out)-1]
}
func (z *bufioDecReader) readUntilFill(stop byte) []byte {
z.bufr = z.bufr[:0]
z.n += uint(len(z.buf)) - z.c
z.bufr = append(z.bufr, z.buf[z.c:]...)
for {
z.c = 0
z.buf = z.buf[0:cap(z.buf)]
n1, err := z.r.Read(z.buf)
if n1 == 0 {
halt.onerror(err)
}
n2 := uint(n1)
z.buf = z.buf[:n2]
for i, token := range z.buf {
if token == stop {
z.n += (uint(i) - z.c) - 1
z.bufr = append(z.bufr, z.buf[z.c:i+1]...)
z.loopFn(uint(i + 1))
return z.bufr
}
}
z.bufr = append(z.bufr, z.buf...)
z.n += n2
}
}
// ------------------------------------
// bytesDecReader is a decReader that reads off a byte slice with zero copying
//
// Note: we do not try to convert index'ing out of bounds to an io.EOF.
// instead, we let it bubble up to the exported Encode/Decode method
// and recover it as an io.EOF.
//
// see panicValToErr(...) function in helper.go.
type bytesDecReader struct {
b []byte // data
c uint // cursor
}
func (z *bytesDecReader) reset(in []byte) {
z.b = in[:len(in):len(in)] // reslicing must not go past capacity
z.c = 0
}
func (z *bytesDecReader) numread() uint {
return z.c
}
// Note: slicing from a non-constant start position is more expensive,
// as more computation is required to decipher the pointer start position.
// However, we do it only once, and it's better than reslicing both z.b and return value.
func (z *bytesDecReader) readx(n uint) (bs []byte) {
x := z.c + n
bs = z.b[z.c:x]
z.c = x
return
}
func (z *bytesDecReader) readb(bs []byte) {
copy(bs, z.readx(uint(len(bs))))
}
func (z *bytesDecReader) readn1() (v uint8) {
v = z.b[z.c]
z.c++
return
}
// func (z *bytesDecReader) readn(num uint8) (bs [8]byte) {
// x := z.c + uint(num)
// copy(bs[:], z.b[z.c:x]) // slice z.b completely, so we get bounds error if past
// z.c = x
// return
// }
func (z *bytesDecReader) readn2() (bs [2]byte) {
x := z.c + 2
copy(bs[:], z.b[z.c:x]) // slice z.b completely, so we get bounds error if past
z.c = x
return
}
func (z *bytesDecReader) readn3() (bs [3]byte) {
x := z.c + 3
copy(bs[:], z.b[z.c:x]) // slice z.b completely, so we get bounds error if past
z.c = x
return
}
func (z *bytesDecReader) readn4() (bs [4]byte) {
x := z.c + 4
copy(bs[:], z.b[z.c:x]) // slice z.b completely, so we get bounds error if past
z.c = x
return
}
func (z *bytesDecReader) readn8() (bs [8]byte) {
x := z.c + 8
copy(bs[:], z.b[z.c:x]) // slice z.b completely, so we get bounds error if past
z.c = x
return
}
func (z *bytesDecReader) jsonReadNum() (out []byte) {
z.c--
i := z.c
LOOP:
if i < uint(len(z.b)) && isNumberChar(z.b[i]) {
i++
goto LOOP
}
out = z.b[z.c:i]
z.c = i
return
}
func (z *bytesDecReader) jsonReadAsisChars() (out []byte) {
i := z.c
LOOP:
token := z.b[i]
i++
if token == '"' || token == '\\' {
out = z.b[z.c:i]
z.c = i
return // z.b[c:i]
}
goto LOOP
}
func (z *bytesDecReader) skipWhitespace() (token byte) {
i := z.c
LOOP:
if isWhitespaceChar(z.b[i]) {
i++
goto LOOP
}
z.c = i + 1
return z.b[i]
}
// func (z *bytesDecReader) skipWhitespace() (token byte) {
// LOOP:
// token = z.b[z.c]
// z.c++
// if isWhitespaceChar(token) {
// goto LOOP
// }
// return
// }
func (z *bytesDecReader) readUntil(stop byte) (out []byte) {
i := z.c
LOOP:
if z.b[i] == stop {
i++
out = z.b[z.c : i-1]
z.c = i
return
}
i++
goto LOOP
}
// --------------
type decRd struct {
mtr bool // is maptype a known type?
str bool // is slicetype a known type?
be bool // is binary encoding
js bool // is json handle
jsms bool // is json handle, and MapKeyAsString
cbor bool // is cbor handle
bytes bool // is bytes reader
bufio bool // is this a bufioDecReader?
rb bytesDecReader
ri *ioDecReader
bi *bufioDecReader
decReader
}
// From out benchmarking, we see the following in terms of performance:
//
// - interface calls
// - branch that can inline what it calls
//
// the if/else-if/else block is expensive to inline.
// Each node of this construct costs a lot and dominates the budget.
// Best to only do an if fast-path else block (so fast-path is inlined).
// This is irrespective of inlineExtraCallCost set in $GOROOT/src/cmd/compile/internal/gc/inl.go
//
// In decRd methods below, we delegate all IO functions into their own methods.
// This allows for the inlining of the common path when z.bytes=true.
// Go 1.12+ supports inlining methods with up to 1 inlined function (or 2 if no other constructs).
//
// However, up through Go 1.13, decRd's readXXX, skip and unreadXXX methods are not inlined.
// Consequently, there is no benefit to do the xxxIO methods for decRd at this time.
// Instead, we have a if/else-if/else block so that IO calls do not have to jump through
// a second unnecessary function call.
//
// If golang inlining gets better and bytesDecReader methods can be inlined,
// then we can revert to using these 2 functions so the bytesDecReader
// methods are inlined and the IO paths call out to a function.
//
// decRd is designed to embed a decReader, and then re-implement some of the decReader
// methods using a conditional branch. We only override the ones that have a bytes version
// that is small enough to be inlined. We use ./run.sh -z to check.
// Right now, only numread and readn1 can be inlined.
func (z *decRd) numread() uint {
if z.bytes {
return z.rb.numread()
} else if z.bufio {
return z.bi.numread()
} else {
return z.ri.numread()
}
}
func (z *decRd) readn1() (v uint8) {
if z.bytes {
// MARKER: manually inline, else this function is not inlined.
// Keep in sync with bytesDecReader.readn1
// return z.rb.readn1()
v = z.rb.b[z.rb.c]
z.rb.c++
} else {
v = z.readn1IO()
}
return
}
func (z *decRd) readn1IO() uint8 {
if z.bufio {
return z.bi.readn1()
}
return z.ri.readn1()
}
type devNullReader struct{}
func (devNullReader) Read(p []byte) (int, error) { return 0, io.EOF }
func (devNullReader) Close() error { return nil }
func readFull(r io.Reader, bs []byte) (n uint, err error) {
var nn int
for n < uint(len(bs)) && err == nil {
nn, err = r.Read(bs[n:])
if nn > 0 {
if err == io.EOF {
// leave EOF for next time
err = nil
}
n += uint(nn)
}
}
// do not do this below - it serves no purpose
// if n != len(bs) && err == io.EOF { err = io.ErrUnexpectedEOF }
return
}
var _ decReader = (*decRd)(nil)

38
vendor/github.com/ugorji/go/codec/register_ext.go generated vendored Normal file
View File

@ -0,0 +1,38 @@
// Copyright (c) 2012-2020 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"
// This file exists, so that the files for specific formats do not all import reflect.
// This just helps us ensure that reflect package is isolated to a few files.
// SetInterfaceExt sets an extension
func (h *JsonHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) {
return h.SetExt(rt, tag, makeExt(ext))
}
// SetInterfaceExt sets an extension
func (h *CborHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) {
return h.SetExt(rt, tag, makeExt(ext))
}
// SetBytesExt sets an extension
func (h *MsgpackHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) {
return h.SetExt(rt, tag, makeExt(ext))
}
// SetBytesExt sets an extension
func (h *SimpleHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) {
return h.SetExt(rt, tag, makeExt(ext))
}
// SetBytesExt sets an extension
func (h *BincHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) {
return h.SetExt(rt, tag, makeExt(ext))
}
// func (h *XMLHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) {
// return h.SetExt(rt, tag, &interfaceExtWrapper{InterfaceExt: ext})
// }

View File

@ -1,22 +1,20 @@
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file. // Use of this source code is governed by a MIT license found in the LICENSE file.
package codec package codec
import ( import (
"bufio" "bufio"
"errors"
"io" "io"
"net/rpc" "net/rpc"
"sync"
) )
// rpcEncodeTerminator allows a handler specify a []byte terminator to send after each Encode. var (
// errRpcJsonNeedsTermWhitespace = errors.New("rpc - requires JsonHandle with TermWhitespace=true")
// Some codecs like json need to put a space after each encoded value, to serve as a errRpcIsClosed = errors.New("rpc - connection has been closed")
// delimiter for things like numbers (else json codec will continue reading till EOF). errRpcNoConn = errors.New("rpc - no connection")
type rpcEncodeTerminator interface { )
rpcEncodeTerminate() []byte
}
// Rpc provides a rpc Server or Client Codec for rpc communication. // Rpc provides a rpc Server or Client Codec for rpc communication.
type Rpc interface { type Rpc interface {
@ -24,104 +22,124 @@ type Rpc interface {
ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec
} }
// RpcCodecBuffered allows access to the underlying bufio.Reader/Writer // RPCOptions holds options specific to rpc functionality
// used by the rpc connection. It accomodates use-cases where the connection type RPCOptions struct {
// should be used by rpc and non-rpc functions, e.g. streaming a file after // RPCNoBuffer configures whether we attempt to buffer reads and writes during RPC calls.
// sending an rpc response. //
type RpcCodecBuffered interface { // Set RPCNoBuffer=true to turn buffering off.
BufferedReader() *bufio.Reader // Buffering can still be done if buffered connections are passed in, or
BufferedWriter() *bufio.Writer // buffering is configured on the handle.
RPCNoBuffer bool
} }
// -------------------------------------
// rpcCodec defines the struct members and common methods. // rpcCodec defines the struct members and common methods.
type rpcCodec struct { type rpcCodec struct {
rwc io.ReadWriteCloser c io.Closer
r io.Reader
w io.Writer
f ioFlusher
dec *Decoder dec *Decoder
enc *Encoder enc *Encoder
bw *bufio.Writer
br *bufio.Reader
mu sync.Mutex
h Handle h Handle
cls bool cls atomicClsErr
clsmu sync.RWMutex
} }
func newRPCCodec(conn io.ReadWriteCloser, h Handle) rpcCodec { func newRPCCodec(conn io.ReadWriteCloser, h Handle) rpcCodec {
bw := bufio.NewWriter(conn) return newRPCCodec2(conn, conn, conn, h)
br := bufio.NewReader(conn) }
func newRPCCodec2(r io.Reader, w io.Writer, c io.Closer, h Handle) rpcCodec {
// defensive: ensure that jsonH has TermWhitespace turned on.
jsonH, ok := h.(*JsonHandle)
if ok && !jsonH.TermWhitespace {
halt.onerror(errRpcJsonNeedsTermWhitespace)
}
var f ioFlusher
bh := h.getBasicHandle()
if !bh.RPCNoBuffer {
f, ok = w.(ioFlusher)
if bh.WriterBufferSize <= 0 {
if !ok {
bw := bufio.NewWriter(w)
f, w = bw, bw
}
}
if bh.ReaderBufferSize <= 0 {
if _, ok = w.(ioBuffered); !ok {
r = bufio.NewReader(r)
}
}
}
return rpcCodec{ return rpcCodec{
rwc: conn, c: c,
bw: bw, w: w,
br: br, r: r,
enc: NewEncoder(bw, h), f: f,
dec: NewDecoder(br, h),
h: h, h: h,
enc: NewEncoder(w, h),
dec: NewDecoder(r, h),
} }
} }
func (c *rpcCodec) BufferedReader() *bufio.Reader { func (c *rpcCodec) write(obj1, obj2 interface{}, writeObj2 bool) (err error) {
return c.br err = c.ready()
} if err == nil {
err = c.enc.Encode(obj1)
func (c *rpcCodec) BufferedWriter() *bufio.Writer { if err == nil && writeObj2 {
return c.bw err = c.enc.Encode(obj2)
}
func (c *rpcCodec) write(obj1, obj2 interface{}, writeObj2, doFlush bool) (err error) {
if c.isClosed() {
return io.EOF
}
if err = c.enc.Encode(obj1); err != nil {
return
}
t, tOk := c.h.(rpcEncodeTerminator)
if tOk {
c.bw.Write(t.rpcEncodeTerminate())
}
if writeObj2 {
if err = c.enc.Encode(obj2); err != nil {
return
} }
if tOk { if c.f != nil {
c.bw.Write(t.rpcEncodeTerminate()) flushErr := c.f.Flush()
if err == nil {
// ignore flush error if prior error occurred during Encode
err = flushErr
}
} }
} }
if doFlush {
return c.bw.Flush()
}
return return
} }
func (c *rpcCodec) read(obj interface{}) (err error) { func (c *rpcCodec) read(obj interface{}) (err error) {
if c.isClosed() { err = c.ready()
return io.EOF if err == nil {
//If nil is passed in, we should read and discard
if obj == nil {
// return c.dec.Decode(&obj)
err = c.dec.swallowErr()
} else {
err = c.dec.Decode(obj)
}
} }
//If nil is passed in, we should still attempt to read content to nowhere. return
if obj == nil {
var obj2 interface{}
return c.dec.Decode(&obj2)
}
return c.dec.Decode(obj)
} }
func (c *rpcCodec) isClosed() bool { func (c *rpcCodec) Close() (err error) {
c.clsmu.RLock() if c.c != nil {
x := c.cls cls := c.cls.load()
c.clsmu.RUnlock() if !cls.closed {
return x cls.err = c.c.Close()
cls.closed = true
c.cls.store(cls)
}
err = cls.err
}
return
} }
func (c *rpcCodec) Close() error { func (c *rpcCodec) ready() (err error) {
if c.isClosed() { if c.c == nil {
return io.EOF err = errRpcNoConn
} else {
cls := c.cls.load()
if cls.closed {
if err = cls.err; err == nil {
err = errRpcIsClosed
}
}
} }
c.clsmu.Lock() return
c.cls = true
c.clsmu.Unlock()
return c.rwc.Close()
} }
func (c *rpcCodec) ReadResponseBody(body interface{}) error { func (c *rpcCodec) ReadResponseBody(body interface{}) error {
@ -135,16 +153,11 @@ type goRpcCodec struct {
} }
func (c *goRpcCodec) WriteRequest(r *rpc.Request, body interface{}) error { func (c *goRpcCodec) WriteRequest(r *rpc.Request, body interface{}) error {
// Must protect for concurrent access as per API return c.write(r, body, true)
c.mu.Lock()
defer c.mu.Unlock()
return c.write(r, body, true, true)
} }
func (c *goRpcCodec) WriteResponse(r *rpc.Response, body interface{}) error { func (c *goRpcCodec) WriteResponse(r *rpc.Response, body interface{}) error {
c.mu.Lock() return c.write(r, body, true)
defer c.mu.Unlock()
return c.write(r, body, true, true)
} }
func (c *goRpcCodec) ReadResponseHeader(r *rpc.Response) error { func (c *goRpcCodec) ReadResponseHeader(r *rpc.Response) error {
@ -166,7 +179,36 @@ func (c *goRpcCodec) ReadRequestBody(body interface{}) error {
type goRpc struct{} type goRpc struct{}
// GoRpc implements Rpc using the communication protocol defined in net/rpc package. // GoRpc implements Rpc using the communication protocol defined in net/rpc package.
// Its methods (ServerCodec and ClientCodec) return values that implement RpcCodecBuffered. //
// 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 var GoRpc goRpc
func (x goRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec { func (x goRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec {
@ -176,5 +218,3 @@ func (x goRpc) ServerCodec(conn io.ReadWriteCloser, h Handle) rpc.ServerCodec {
func (x goRpc) ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec { func (x goRpc) ClientCodec(conn io.ReadWriteCloser, h Handle) rpc.ClientCodec {
return &goRpcCodec{newRPCCodec(conn, h)} return &goRpcCodec{newRPCCodec(conn, h)}
} }
var _ RpcCodecBuffered = (*rpcCodec)(nil) // ensure *rpcCodec implements RpcCodecBuffered

View File

@ -1,11 +1,11 @@
// Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file. // Use of this source code is governed by a MIT license found in the LICENSE file.
package codec package codec
import ( import (
"math" "math"
"reflect" "time"
) )
const ( const (
@ -20,6 +20,8 @@ const (
simpleVdPosInt = 8 simpleVdPosInt = 8
simpleVdNegInt = 12 simpleVdNegInt = 12
simpleVdTime = 24
// containers: each lasts for 4 (ie n, n+1, n+2, ... n+7) // containers: each lasts for 4 (ie n, n+1, n+2, ... n+7)
simpleVdString = 216 simpleVdString = 216
simpleVdByteArray = 224 simpleVdByteArray = 224
@ -28,35 +30,77 @@ const (
simpleVdExt = 248 simpleVdExt = 248
) )
var simpledescNames = map[byte]string{
simpleVdNil: "null",
simpleVdFalse: "false",
simpleVdTrue: "true",
simpleVdFloat32: "float32",
simpleVdFloat64: "float64",
simpleVdPosInt: "+int",
simpleVdNegInt: "-int",
simpleVdTime: "time",
simpleVdString: "string",
simpleVdByteArray: "binary",
simpleVdArray: "array",
simpleVdMap: "map",
simpleVdExt: "ext",
}
func simpledesc(bd byte) (s string) {
s = simpledescNames[bd]
if s == "" {
s = "unknown"
}
return
}
type simpleEncDriver struct { type simpleEncDriver struct {
noBuiltInTypes noBuiltInTypes
encNoSeparator encDriverNoopContainerWriter
e *Encoder
h *SimpleHandle h *SimpleHandle
w encWriter // b [8]byte
b [8]byte e Encoder
}
func (e *simpleEncDriver) encoder() *Encoder {
return &e.e
} }
func (e *simpleEncDriver) EncodeNil() { func (e *simpleEncDriver) EncodeNil() {
e.w.writen1(simpleVdNil) e.e.encWr.writen1(simpleVdNil)
} }
func (e *simpleEncDriver) EncodeBool(b bool) { func (e *simpleEncDriver) EncodeBool(b bool) {
if e.h.EncZeroValuesAsNil && e.e.c != containerMapKey && !b {
e.EncodeNil()
return
}
if b { if b {
e.w.writen1(simpleVdTrue) e.e.encWr.writen1(simpleVdTrue)
} else { } else {
e.w.writen1(simpleVdFalse) e.e.encWr.writen1(simpleVdFalse)
} }
} }
func (e *simpleEncDriver) EncodeFloat32(f float32) { func (e *simpleEncDriver) EncodeFloat32(f float32) {
e.w.writen1(simpleVdFloat32) if e.h.EncZeroValuesAsNil && e.e.c != containerMapKey && f == 0.0 {
bigenHelper{e.b[:4], e.w}.writeUint32(math.Float32bits(f)) e.EncodeNil()
return
}
e.e.encWr.writen1(simpleVdFloat32)
bigen.writeUint32(e.e.w(), math.Float32bits(f))
} }
func (e *simpleEncDriver) EncodeFloat64(f float64) { func (e *simpleEncDriver) EncodeFloat64(f float64) {
e.w.writen1(simpleVdFloat64) if e.h.EncZeroValuesAsNil && e.e.c != containerMapKey && f == 0.0 {
bigenHelper{e.b[:8], e.w}.writeUint64(math.Float64bits(f)) e.EncodeNil()
return
}
e.e.encWr.writen1(simpleVdFloat64)
bigen.writeUint64(e.e.w(), math.Float64bits(f))
} }
func (e *simpleEncDriver) EncodeInt(v int64) { func (e *simpleEncDriver) EncodeInt(v int64) {
@ -72,162 +116,206 @@ func (e *simpleEncDriver) EncodeUint(v uint64) {
} }
func (e *simpleEncDriver) encUint(v uint64, bd uint8) { func (e *simpleEncDriver) encUint(v uint64, bd uint8) {
if e.h.EncZeroValuesAsNil && e.e.c != containerMapKey && v == 0 {
e.EncodeNil()
return
}
if v <= math.MaxUint8 { if v <= math.MaxUint8 {
e.w.writen2(bd, uint8(v)) e.e.encWr.writen2(bd, uint8(v))
} else if v <= math.MaxUint16 { } else if v <= math.MaxUint16 {
e.w.writen1(bd + 1) e.e.encWr.writen1(bd + 1)
bigenHelper{e.b[:2], e.w}.writeUint16(uint16(v)) bigen.writeUint16(e.e.w(), uint16(v))
} else if v <= math.MaxUint32 { } else if v <= math.MaxUint32 {
e.w.writen1(bd + 2) e.e.encWr.writen1(bd + 2)
bigenHelper{e.b[:4], e.w}.writeUint32(uint32(v)) bigen.writeUint32(e.e.w(), uint32(v))
} else { // if v <= math.MaxUint64 { } else { // if v <= math.MaxUint64 {
e.w.writen1(bd + 3) e.e.encWr.writen1(bd + 3)
bigenHelper{e.b[:8], e.w}.writeUint64(v) bigen.writeUint64(e.e.w(), v)
} }
} }
func (e *simpleEncDriver) encLen(bd byte, length int) { func (e *simpleEncDriver) encLen(bd byte, length int) {
if length == 0 { if length == 0 {
e.w.writen1(bd) e.e.encWr.writen1(bd)
} else if length <= math.MaxUint8 { } else if length <= math.MaxUint8 {
e.w.writen1(bd + 1) e.e.encWr.writen1(bd + 1)
e.w.writen1(uint8(length)) e.e.encWr.writen1(uint8(length))
} else if length <= math.MaxUint16 { } else if length <= math.MaxUint16 {
e.w.writen1(bd + 2) e.e.encWr.writen1(bd + 2)
bigenHelper{e.b[:2], e.w}.writeUint16(uint16(length)) bigen.writeUint16(e.e.w(), uint16(length))
} else if int64(length) <= math.MaxUint32 { } else if int64(length) <= math.MaxUint32 {
e.w.writen1(bd + 3) e.e.encWr.writen1(bd + 3)
bigenHelper{e.b[:4], e.w}.writeUint32(uint32(length)) bigen.writeUint32(e.e.w(), uint32(length))
} else { } else {
e.w.writen1(bd + 4) e.e.encWr.writen1(bd + 4)
bigenHelper{e.b[:8], e.w}.writeUint64(uint64(length)) bigen.writeUint64(e.e.w(), uint64(length))
} }
} }
func (e *simpleEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, _ *Encoder) { func (e *simpleEncDriver) EncodeExt(v interface{}, xtag uint64, ext Ext) {
bs := ext.WriteExt(rv) var bs0, bs []byte
if ext == SelfExt {
bs0 = e.e.blist.get(1024)
bs = bs0
e.e.sideEncode(v, &bs)
} else {
bs = ext.WriteExt(v)
}
if bs == nil { if bs == nil {
e.EncodeNil() e.EncodeNil()
return goto END
} }
e.encodeExtPreamble(uint8(xtag), len(bs)) e.encodeExtPreamble(uint8(xtag), len(bs))
e.w.writeb(bs) e.e.encWr.writeb(bs)
END:
if ext == SelfExt {
e.e.blist.put(bs)
if !byteSliceSameData(bs0, bs) {
e.e.blist.put(bs0)
}
}
} }
func (e *simpleEncDriver) EncodeRawExt(re *RawExt, _ *Encoder) { func (e *simpleEncDriver) EncodeRawExt(re *RawExt) {
e.encodeExtPreamble(uint8(re.Tag), len(re.Data)) e.encodeExtPreamble(uint8(re.Tag), len(re.Data))
e.w.writeb(re.Data) e.e.encWr.writeb(re.Data)
} }
func (e *simpleEncDriver) encodeExtPreamble(xtag byte, length int) { func (e *simpleEncDriver) encodeExtPreamble(xtag byte, length int) {
e.encLen(simpleVdExt, length) e.encLen(simpleVdExt, length)
e.w.writen1(xtag) e.e.encWr.writen1(xtag)
} }
func (e *simpleEncDriver) EncodeArrayStart(length int) { func (e *simpleEncDriver) WriteArrayStart(length int) {
e.encLen(simpleVdArray, length) e.encLen(simpleVdArray, length)
} }
func (e *simpleEncDriver) EncodeMapStart(length int) { func (e *simpleEncDriver) WriteMapStart(length int) {
e.encLen(simpleVdMap, length) e.encLen(simpleVdMap, length)
} }
func (e *simpleEncDriver) EncodeString(c charEncoding, v string) { func (e *simpleEncDriver) EncodeString(v string) {
e.encLen(simpleVdString, len(v)) if e.h.EncZeroValuesAsNil && e.e.c != containerMapKey && v == "" {
e.w.writestr(v) e.EncodeNil()
return
}
if e.h.StringToRaw {
e.encLen(simpleVdByteArray, len(v))
} else {
e.encLen(simpleVdString, len(v))
}
e.e.encWr.writestr(v)
} }
func (e *simpleEncDriver) EncodeSymbol(v string) { func (e *simpleEncDriver) EncodeStringBytesRaw(v []byte) {
e.EncodeString(c_UTF8, v) // if e.h.EncZeroValuesAsNil && e.c != containerMapKey && v == nil {
} if v == nil {
e.EncodeNil()
func (e *simpleEncDriver) EncodeStringBytes(c charEncoding, v []byte) { return
}
e.encLen(simpleVdByteArray, len(v)) e.encLen(simpleVdByteArray, len(v))
e.w.writeb(v) e.e.encWr.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()
e.e.onerror(err)
e.e.encWr.writen2(simpleVdTime, uint8(len(v)))
e.e.encWr.writeb(v)
} }
//------------------------------------ //------------------------------------
type simpleDecDriver struct { type simpleDecDriver struct {
d *Decoder
h *SimpleHandle h *SimpleHandle
r decReader
bdRead bool bdRead bool
bd byte bd byte
br bool // bytes reader _ bool
noBuiltInTypes noBuiltInTypes
noStreamingCodec decDriverNoopContainerReader
decNoSeparator d Decoder
b [scratchByteArrayLen]byte }
func (d *simpleDecDriver) decoder() *Decoder {
return &d.d
} }
func (d *simpleDecDriver) readNextBd() { func (d *simpleDecDriver) readNextBd() {
d.bd = d.r.readn1() d.bd = d.d.decRd.readn1()
d.bdRead = true d.bdRead = true
} }
func (d *simpleDecDriver) ContainerType() (vt valueType) { func (d *simpleDecDriver) advanceNil() (null bool) {
if d.bd == simpleVdNil {
return valueTypeNil
} else if d.bd == simpleVdByteArray || d.bd == simpleVdByteArray+1 ||
d.bd == simpleVdByteArray+2 || d.bd == simpleVdByteArray+3 || d.bd == simpleVdByteArray+4 {
return valueTypeBytes
} else if d.bd == simpleVdString || d.bd == simpleVdString+1 ||
d.bd == simpleVdString+2 || d.bd == simpleVdString+3 || d.bd == simpleVdString+4 {
return valueTypeString
} else if d.bd == simpleVdArray || d.bd == simpleVdArray+1 ||
d.bd == simpleVdArray+2 || d.bd == simpleVdArray+3 || d.bd == simpleVdArray+4 {
return valueTypeArray
} else if d.bd == simpleVdMap || d.bd == simpleVdMap+1 ||
d.bd == simpleVdMap+2 || d.bd == simpleVdMap+3 || d.bd == simpleVdMap+4 {
return valueTypeMap
} else {
// d.d.errorf("isContainerType: unsupported parameter: %v", vt)
}
return valueTypeUnset
}
func (d *simpleDecDriver) TryDecodeAsNil() bool {
if !d.bdRead { if !d.bdRead {
d.readNextBd() d.readNextBd()
} }
if d.bd == simpleVdNil { if d.bd == simpleVdNil {
d.bdRead = false d.bdRead = false
return true return true // null = true
} }
return false return
} }
func (d *simpleDecDriver) decCheckInteger() (ui uint64, neg bool) { func (d *simpleDecDriver) ContainerType() (vt valueType) {
if !d.bdRead { if !d.bdRead {
d.readNextBd() d.readNextBd()
} }
switch d.bd {
case simpleVdNil:
d.bdRead = false
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
}
return valueTypeUnset
}
func (d *simpleDecDriver) TryNil() bool {
return d.advanceNil()
}
func (d *simpleDecDriver) decCheckInteger() (ui uint64, neg bool) {
switch d.bd { switch d.bd {
case simpleVdPosInt: case simpleVdPosInt:
ui = uint64(d.r.readn1()) ui = uint64(d.d.decRd.readn1())
case simpleVdPosInt + 1: case simpleVdPosInt + 1:
ui = uint64(bigen.Uint16(d.r.readx(2))) ui = uint64(bigen.Uint16(d.d.decRd.readn2()))
case simpleVdPosInt + 2: case simpleVdPosInt + 2:
ui = uint64(bigen.Uint32(d.r.readx(4))) ui = uint64(bigen.Uint32(d.d.decRd.readn4()))
case simpleVdPosInt + 3: case simpleVdPosInt + 3:
ui = uint64(bigen.Uint64(d.r.readx(8))) ui = uint64(bigen.Uint64(d.d.decRd.readn8()))
case simpleVdNegInt: case simpleVdNegInt:
ui = uint64(d.r.readn1()) ui = uint64(d.d.decRd.readn1())
neg = true neg = true
case simpleVdNegInt + 1: case simpleVdNegInt + 1:
ui = uint64(bigen.Uint16(d.r.readx(2))) ui = uint64(bigen.Uint16(d.d.decRd.readn2()))
neg = true neg = true
case simpleVdNegInt + 2: case simpleVdNegInt + 2:
ui = uint64(bigen.Uint32(d.r.readx(4))) ui = uint64(bigen.Uint32(d.d.decRd.readn4()))
neg = true neg = true
case simpleVdNegInt + 3: case simpleVdNegInt + 3:
ui = uint64(bigen.Uint64(d.r.readx(8))) ui = uint64(bigen.Uint64(d.d.decRd.readn8()))
neg = true neg = true
default: default:
d.d.errorf("decIntAny: Integer only valid from pos/neg integer1..8. Invalid descriptor: %v", d.bd) 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. // DO NOT do this check below, because callers may only want the unsigned value:
//
// if ui > math.MaxInt64 { // if ui > math.MaxInt64 {
// d.d.errorf("decIntAny: Integer out of range for signed int64: %v", ui) // d.d.errorf("decIntAny: Integer out of range for signed int64: %v", ui)
// return // return
@ -235,174 +323,197 @@ func (d *simpleDecDriver) decCheckInteger() (ui uint64, neg bool) {
return return
} }
func (d *simpleDecDriver) DecodeInt(bitsize uint8) (i int64) { func (d *simpleDecDriver) DecodeInt64() (i int64) {
ui, neg := d.decCheckInteger() if d.advanceNil() {
i, overflow := chkOvf.SignedInt(ui)
if overflow {
d.d.errorf("simple: overflow converting %v to signed integer", ui)
return return
} }
ui, neg := d.decCheckInteger()
i = chkOvf.SignedIntV(ui)
if neg { if neg {
i = -i i = -i
} }
if chkOvf.Int(i, bitsize) {
d.d.errorf("simple: overflow integer: %v", i)
return
}
d.bdRead = false d.bdRead = false
return return
} }
func (d *simpleDecDriver) DecodeUint(bitsize uint8) (ui uint64) { func (d *simpleDecDriver) DecodeUint64() (ui uint64) {
if d.advanceNil() {
return
}
ui, neg := d.decCheckInteger() ui, neg := d.decCheckInteger()
if neg { if neg {
d.d.errorf("Assigning negative signed value to unsigned type") d.d.errorf("assigning negative signed value to unsigned type")
return
}
if chkOvf.Uint(ui, bitsize) {
d.d.errorf("simple: overflow integer: %v", ui)
return
} }
d.bdRead = false d.bdRead = false
return return
} }
func (d *simpleDecDriver) DecodeFloat(chkOverflow32 bool) (f float64) { func (d *simpleDecDriver) DecodeFloat64() (f float64) {
if !d.bdRead { if d.advanceNil() {
d.readNextBd() return
} }
if d.bd == simpleVdFloat32 { if d.bd == simpleVdFloat32 {
f = float64(math.Float32frombits(bigen.Uint32(d.r.readx(4)))) f = float64(math.Float32frombits(bigen.Uint32(d.d.decRd.readn4())))
} else if d.bd == simpleVdFloat64 { } else if d.bd == simpleVdFloat64 {
f = math.Float64frombits(bigen.Uint64(d.r.readx(8))) f = math.Float64frombits(bigen.Uint64(d.d.decRd.readn8()))
} else { } else {
if d.bd >= simpleVdPosInt && d.bd <= simpleVdNegInt+3 { if d.bd >= simpleVdPosInt && d.bd <= simpleVdNegInt+3 {
f = float64(d.DecodeInt(64)) f = float64(d.DecodeInt64())
} else { } else {
d.d.errorf("Float only valid from float32/64: Invalid descriptor: %v", d.bd) d.d.errorf("float only valid from float32/64: Invalid descriptor: %v", d.bd)
return
} }
} }
if chkOverflow32 && chkOvf.Float32(f) {
d.d.errorf("msgpack: float32 overflow: %v", f)
return
}
d.bdRead = false d.bdRead = false
return return
} }
// bool can be decoded from bool only (single byte). // bool can be decoded from bool only (single byte).
func (d *simpleDecDriver) DecodeBool() (b bool) { func (d *simpleDecDriver) DecodeBool() (b bool) {
if !d.bdRead { if d.advanceNil() {
d.readNextBd()
}
if d.bd == simpleVdTrue {
b = true
} else if d.bd == simpleVdFalse {
} else {
d.d.errorf("Invalid single-byte value for bool: %s: %x", msgBadDesc, d.bd)
return return
} }
if d.bd == simpleVdFalse {
} else if d.bd == simpleVdTrue {
b = true
} else {
d.d.errorf("cannot decode bool - %s: %x", msgBadDesc, d.bd)
}
d.bdRead = false d.bdRead = false
return return
} }
func (d *simpleDecDriver) ReadMapStart() (length int) { func (d *simpleDecDriver) ReadMapStart() (length int) {
if d.advanceNil() {
return containerLenNil
}
d.bdRead = false d.bdRead = false
return d.decLen() return d.decLen()
} }
func (d *simpleDecDriver) ReadArrayStart() (length int) { func (d *simpleDecDriver) ReadArrayStart() (length int) {
if d.advanceNil() {
return containerLenNil
}
d.bdRead = false d.bdRead = false
return d.decLen() return d.decLen()
} }
func (d *simpleDecDriver) uint2Len(ui uint64) int {
if chkOvf.Uint(ui, intBitsize) {
d.d.errorf("overflow integer: %v", ui)
}
return int(ui)
}
func (d *simpleDecDriver) decLen() int { func (d *simpleDecDriver) decLen() int {
switch d.bd % 8 { switch d.bd & 7 { // d.bd % 8 {
case 0: case 0:
return 0 return 0
case 1: case 1:
return int(d.r.readn1()) return int(d.d.decRd.readn1())
case 2: case 2:
return int(bigen.Uint16(d.r.readx(2))) return int(bigen.Uint16(d.d.decRd.readn2()))
case 3: case 3:
ui := uint64(bigen.Uint32(d.r.readx(4))) return d.uint2Len(uint64(bigen.Uint32(d.d.decRd.readn4())))
if chkOvf.Uint(ui, intBitsize) {
d.d.errorf("simple: overflow integer: %v", ui)
return 0
}
return int(ui)
case 4: case 4:
ui := bigen.Uint64(d.r.readx(8)) return d.uint2Len(bigen.Uint64(d.d.decRd.readn8()))
if chkOvf.Uint(ui, intBitsize) {
d.d.errorf("simple: overflow integer: %v", ui)
return 0
}
return int(ui)
} }
d.d.errorf("decLen: Cannot read length: bd%8 must be in range 0..4. Got: %d", d.bd%8) d.d.errorf("cannot read length: bd%%8 must be in range 0..4. Got: %d", d.bd%8)
return -1 return -1
} }
func (d *simpleDecDriver) DecodeString() (s string) { func (d *simpleDecDriver) DecodeStringAsBytes() (s []byte) {
return string(d.DecodeBytes(d.b[:], true, true)) return d.DecodeBytes(nil)
} }
func (d *simpleDecDriver) DecodeBytes(bs []byte, isstring, zerocopy bool) (bsOut []byte) { func (d *simpleDecDriver) DecodeBytes(bs []byte) (bsOut []byte) {
if !d.bdRead { d.d.decByteState = decByteStateNone
d.readNextBd() if d.advanceNil() {
}
if d.bd == simpleVdNil {
d.bdRead = false
return 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 bs == nil {
d.d.decByteState = decByteStateReuseBuf
bs = d.d.b[:]
}
slen := d.ReadArrayStart()
var changed bool
if bs, changed = usableByteSlice(bs, slen); changed {
d.d.decByteState = decByteStateNone
}
for i := 0; i < len(bs); i++ {
bs[i] = uint8(chkOvf.UintV(d.DecodeUint64(), 8))
}
return bs
}
clen := d.decLen() clen := d.decLen()
d.bdRead = false d.bdRead = false
if zerocopy { if d.d.zerocopy() {
if d.br { d.d.decByteState = decByteStateZerocopy
return d.r.readx(clen) return d.d.decRd.rb.readx(uint(clen))
} else if len(bs) == 0 {
bs = d.b[:]
}
} }
return decByteSlice(d.r, clen, bs) if bs == nil {
d.d.decByteState = decByteStateReuseBuf
bs = d.d.b[:]
}
return decByteSlice(d.d.r(), clen, d.d.h.MaxInitLen, bs)
} }
func (d *simpleDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxtag uint64) { func (d *simpleDecDriver) DecodeTime() (t time.Time) {
if xtag > 0xff { if d.advanceNil() {
d.d.errorf("decodeExt: tag must be <= 0xff; got: %v", xtag)
return return
} }
realxtag1, xbs := d.decodeExtV(ext != nil, uint8(xtag)) if d.bd != simpleVdTime {
realxtag = uint64(realxtag1) d.d.errorf("invalid descriptor for time.Time - expect 0x%x, received 0x%x", simpleVdTime, d.bd)
if ext == nil {
re := rv.(*RawExt)
re.Tag = realxtag
re.Data = detachZeroCopyBytes(d.br, re.Data, xbs)
} else {
ext.ReadExt(rv, xbs)
} }
d.bdRead = false
clen := uint(d.d.decRd.readn1())
b := d.d.decRd.readx(clen)
d.d.onerror((&t).UnmarshalBinary(b))
return return
} }
func (d *simpleDecDriver) decodeExtV(verifyTag bool, tag byte) (xtag byte, xbs []byte) { func (d *simpleDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) {
if !d.bdRead { if xtag > 0xff {
d.readNextBd() d.d.errorf("ext: tag must be <= 0xff; got: %v", xtag)
} }
if d.advanceNil() {
return
}
xbs, realxtag1, zerocopy := d.decodeExtV(ext != nil, uint8(xtag))
realxtag := uint64(realxtag1)
if ext == nil {
re := rv.(*RawExt)
re.Tag = realxtag
re.setData(xbs, zerocopy)
} else if ext == SelfExt {
d.d.sideDecode(rv, xbs)
} else {
ext.ReadExt(rv, xbs)
}
}
func (d *simpleDecDriver) decodeExtV(verifyTag bool, tag byte) (xbs []byte, xtag byte, zerocopy bool) {
switch d.bd { switch d.bd {
case simpleVdExt, simpleVdExt + 1, simpleVdExt + 2, simpleVdExt + 3, simpleVdExt + 4: case simpleVdExt, simpleVdExt + 1, simpleVdExt + 2, simpleVdExt + 3, simpleVdExt + 4:
l := d.decLen() l := d.decLen()
xtag = d.r.readn1() xtag = d.d.decRd.readn1()
if verifyTag && xtag != tag { if verifyTag && xtag != tag {
d.d.errorf("Wrong extension tag. Got %b. Expecting: %v", xtag, tag) d.d.errorf("wrong extension tag. Got %b. Expecting: %v", xtag, tag)
return
} }
xbs = d.r.readx(l) if d.d.bytes {
case simpleVdByteArray, simpleVdByteArray + 1, simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4: xbs = d.d.decRd.rb.readx(uint(l))
xbs = d.DecodeBytes(nil, false, true) zerocopy = true
} else {
xbs = decByteSlice(d.d.r(), l, d.d.h.MaxInitLen, d.d.b[:])
}
case simpleVdByteArray, simpleVdByteArray + 1,
simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4:
xbs = d.DecodeBytes(nil)
default: default:
d.d.errorf("Invalid d.bd for extensions (Expecting extensions or byte array). Got: 0x%x", d.bd) d.d.errorf("ext - %s - expecting extensions/bytearray, got: 0x%x", msgBadDesc, d.bd)
return
} }
d.bdRead = false d.bdRead = false
return return
@ -413,7 +524,7 @@ func (d *simpleDecDriver) DecodeNaked() {
d.readNextBd() d.readNextBd()
} }
n := &d.d.n n := d.d.naked()
var decodeFurther bool var decodeFurther bool
switch d.bd { switch d.bd {
@ -428,44 +539,154 @@ func (d *simpleDecDriver) DecodeNaked() {
case simpleVdPosInt, simpleVdPosInt + 1, simpleVdPosInt + 2, simpleVdPosInt + 3: case simpleVdPosInt, simpleVdPosInt + 1, simpleVdPosInt + 2, simpleVdPosInt + 3:
if d.h.SignedInteger { if d.h.SignedInteger {
n.v = valueTypeInt n.v = valueTypeInt
n.i = d.DecodeInt(64) n.i = d.DecodeInt64()
} else { } else {
n.v = valueTypeUint n.v = valueTypeUint
n.u = d.DecodeUint(64) n.u = d.DecodeUint64()
} }
case simpleVdNegInt, simpleVdNegInt + 1, simpleVdNegInt + 2, simpleVdNegInt + 3: case simpleVdNegInt, simpleVdNegInt + 1, simpleVdNegInt + 2, simpleVdNegInt + 3:
n.v = valueTypeInt n.v = valueTypeInt
n.i = d.DecodeInt(64) n.i = d.DecodeInt64()
case simpleVdFloat32: case simpleVdFloat32:
n.v = valueTypeFloat n.v = valueTypeFloat
n.f = d.DecodeFloat(true) n.f = d.DecodeFloat64()
case simpleVdFloat64: case simpleVdFloat64:
n.v = valueTypeFloat n.v = valueTypeFloat
n.f = d.DecodeFloat(false) n.f = d.DecodeFloat64()
case simpleVdString, simpleVdString + 1, simpleVdString + 2, simpleVdString + 3, simpleVdString + 4: case simpleVdTime:
n.v = valueTypeTime
n.t = d.DecodeTime()
case simpleVdString, simpleVdString + 1,
simpleVdString + 2, simpleVdString + 3, simpleVdString + 4:
n.v = valueTypeString n.v = valueTypeString
n.s = d.DecodeString() n.s = d.d.stringZC(d.DecodeStringAsBytes())
case simpleVdByteArray, simpleVdByteArray + 1, simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4: case simpleVdByteArray, simpleVdByteArray + 1,
n.v = valueTypeBytes simpleVdByteArray + 2, simpleVdByteArray + 3, simpleVdByteArray + 4:
n.l = d.DecodeBytes(nil, false, false) d.d.fauxUnionReadRawBytes(false)
case simpleVdExt, simpleVdExt + 1, simpleVdExt + 2, simpleVdExt + 3, simpleVdExt + 4: case simpleVdExt, simpleVdExt + 1, simpleVdExt + 2, simpleVdExt + 3, simpleVdExt + 4:
n.v = valueTypeExt n.v = valueTypeExt
l := d.decLen() l := d.decLen()
n.u = uint64(d.r.readn1()) n.u = uint64(d.d.decRd.readn1())
n.l = d.r.readx(l) if d.d.bytes {
case simpleVdArray, simpleVdArray + 1, simpleVdArray + 2, simpleVdArray + 3, simpleVdArray + 4: n.l = d.d.decRd.rb.readx(uint(l))
} else {
n.l = decByteSlice(d.d.r(), l, d.d.h.MaxInitLen, d.d.b[:])
}
case simpleVdArray, simpleVdArray + 1, simpleVdArray + 2,
simpleVdArray + 3, simpleVdArray + 4:
n.v = valueTypeArray n.v = valueTypeArray
decodeFurther = true decodeFurther = true
case simpleVdMap, simpleVdMap + 1, simpleVdMap + 2, simpleVdMap + 3, simpleVdMap + 4: case simpleVdMap, simpleVdMap + 1, simpleVdMap + 2, simpleVdMap + 3, simpleVdMap + 4:
n.v = valueTypeMap n.v = valueTypeMap
decodeFurther = true decodeFurther = true
default: default:
d.d.errorf("decodeNaked: Unrecognized d.bd: 0x%x", d.bd) d.d.errorf("cannot infer value - %s 0x%x", msgBadDesc, d.bd)
} }
if !decodeFurther { if !decodeFurther {
d.bdRead = false d.bdRead = false
} }
}
func (d *simpleDecDriver) nextValueBytes(v0 []byte) (v []byte) {
if !d.bdRead {
d.readNextBd()
}
v = v0
var h = decNextValueBytesHelper{d: &d.d}
var cursor = d.d.rb.c - 1
h.append1(&v, d.bd)
v = d.nextValueBytesBdReadR(v)
d.bdRead = false
h.bytesRdV(&v, cursor)
return
}
func (d *simpleDecDriver) nextValueBytesR(v0 []byte) (v []byte) {
d.readNextBd()
v = v0
var h = decNextValueBytesHelper{d: &d.d}
h.append1(&v, d.bd)
return d.nextValueBytesBdReadR(v)
}
func (d *simpleDecDriver) nextValueBytesBdReadR(v0 []byte) (v []byte) {
v = v0
var h = decNextValueBytesHelper{d: &d.d}
c := d.bd
var length uint
switch c {
case simpleVdNil, simpleVdFalse, simpleVdTrue, simpleVdString, simpleVdByteArray:
// pass
case simpleVdPosInt, simpleVdNegInt:
h.append1(&v, d.d.decRd.readn1())
case simpleVdPosInt + 1, simpleVdNegInt + 1:
h.appendN(&v, d.d.decRd.readx(2)...)
case simpleVdPosInt + 2, simpleVdNegInt + 2, simpleVdFloat32:
h.appendN(&v, d.d.decRd.readx(4)...)
case simpleVdPosInt + 3, simpleVdNegInt + 3, simpleVdFloat64:
h.appendN(&v, d.d.decRd.readx(8)...)
case simpleVdTime:
c = d.d.decRd.readn1()
h.append1(&v, c)
h.appendN(&v, d.d.decRd.readx(uint(c))...)
default:
switch c & 7 { // c % 8 {
case 0:
length = 0
case 1:
b := d.d.decRd.readn1()
length = uint(b)
h.append1(&v, b)
case 2:
x := d.d.decRd.readn2()
length = uint(bigen.Uint16(x))
h.appendN(&v, x[:]...)
case 3:
x := d.d.decRd.readn4()
length = uint(bigen.Uint32(x))
h.appendN(&v, x[:]...)
case 4:
x := d.d.decRd.readn8()
length = uint(bigen.Uint64(x))
h.appendN(&v, x[:]...)
}
bExt := c >= simpleVdExt && c <= simpleVdExt+7
bStr := c >= simpleVdString && c <= simpleVdString+7
bByteArray := c >= simpleVdByteArray && c <= simpleVdByteArray+7
bArray := c >= simpleVdArray && c <= simpleVdArray+7
bMap := c >= simpleVdMap && c <= simpleVdMap+7
if !(bExt || bStr || bByteArray || bArray || bMap) {
d.d.errorf("cannot infer value - %s 0x%x", msgBadDesc, c)
}
if bExt {
h.append1(&v, d.d.decRd.readn1()) // tag
}
if length == 0 {
break
}
if bArray {
for i := uint(0); i < length; i++ {
v = d.nextValueBytesR(v)
}
} else if bMap {
for i := uint(0); i < length; i++ {
v = d.nextValueBytesR(v)
v = d.nextValueBytesR(v)
}
} else {
h.appendN(&v, d.d.decRd.readx(length)...)
}
}
return return
} }
@ -474,12 +695,12 @@ func (d *simpleDecDriver) DecodeNaked() {
// SimpleHandle is a Handle for a very simple encoding format. // SimpleHandle is a Handle for a very simple encoding format.
// //
// simple is a simplistic codec similar to binc, but not as compact. // simple is a simplistic codec similar to binc, but not as compact.
// - Encoding of a value is always preceeded by the descriptor byte (bd) // - Encoding of a value is always preceded by the descriptor byte (bd)
// - True, false, nil are encoded fully in 1 byte (the descriptor) // - 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). // - 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. // There are positive (uintXXX and intXXX >= 0) and negative (intXXX < 0) integers.
// - Floats are encoded in 4 or 8 bytes (plus a descriptor byte) // - Floats are encoded in 4 or 8 bytes (plus a descriptor byte)
// - Lenght of containers (strings, bytes, array, map, extensions) // - Length of containers (strings, bytes, array, map, extensions)
// are encoded in 0, 1, 2, 4 or 8 bytes. // are encoded in 0, 1, 2, 4 or 8 bytes.
// Zero-length containers have no length encoded. // Zero-length containers have no length encoded.
// For others, the number of bytes is given by pow(2, bd%3) // For others, the number of bytes is given by pow(2, bd%3)
@ -487,31 +708,41 @@ func (d *simpleDecDriver) DecodeNaked() {
// - arrays are encoded as [bd] [length] [value]... // - arrays are encoded as [bd] [length] [value]...
// - extensions are encoded as [bd] [length] [tag] [byte]... // - extensions are encoded as [bd] [length] [tag] [byte]...
// - strings/bytearrays are encoded as [bd] [length] [byte]... // - strings/bytearrays are encoded as [bd] [length] [byte]...
// - time.Time are encoded as [bd] [length] [byte]...
// //
// The full spec will be published soon. // The full spec will be published soon.
type SimpleHandle struct { type SimpleHandle struct {
BasicHandle
binaryEncodingType binaryEncodingType
BasicHandle
// EncZeroValuesAsNil says to encode zero values for numbers, bool, string, etc as nil
EncZeroValuesAsNil bool
} }
func (h *SimpleHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) { // Name returns the name of the handle: simple
return h.SetExt(rt, tag, &setExtWrapper{b: ext}) func (h *SimpleHandle) Name() string { return "simple" }
func (h *SimpleHandle) desc(bd byte) string { return simpledesc(bd) }
func (h *SimpleHandle) newEncDriver() encDriver {
var e = &simpleEncDriver{h: h}
e.e.e = e
e.e.init(h)
e.reset()
return e
} }
func (h *SimpleHandle) newEncDriver(e *Encoder) encDriver { func (h *SimpleHandle) newDecDriver() decDriver {
return &simpleEncDriver{e: e, w: e.w, h: h} d := &simpleDecDriver{h: h}
} d.d.d = d
d.d.init(h)
func (h *SimpleHandle) newDecDriver(d *Decoder) decDriver { d.reset()
return &simpleDecDriver{d: d, r: d.r, h: h, br: d.bytes} return d
} }
func (e *simpleEncDriver) reset() { func (e *simpleEncDriver) reset() {
e.w = e.e.w
} }
func (d *simpleDecDriver) reset() { func (d *simpleDecDriver) reset() {
d.r = d.d.r
d.bd, d.bdRead = 0, false d.bd, d.bdRead = 0, false
} }

View File

@ -0,0 +1,146 @@
// Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.
// Code generated from sort-slice.go.tmpl - DO NOT EDIT.
package codec
import "time"
import "reflect"
import "bytes"
type stringSlice []string
func (p stringSlice) Len() int { return len(p) }
func (p stringSlice) Swap(i, j int) { p[uint(i)], p[uint(j)] = p[uint(j)], p[uint(i)] }
func (p stringSlice) Less(i, j int) bool {
return p[uint(i)] < p[uint(j)]
}
type uint8Slice []uint8
func (p uint8Slice) Len() int { return len(p) }
func (p uint8Slice) Swap(i, j int) { p[uint(i)], p[uint(j)] = p[uint(j)], p[uint(i)] }
func (p uint8Slice) Less(i, j int) bool {
return p[uint(i)] < p[uint(j)]
}
type uint64Slice []uint64
func (p uint64Slice) Len() int { return len(p) }
func (p uint64Slice) Swap(i, j int) { p[uint(i)], p[uint(j)] = p[uint(j)], p[uint(i)] }
func (p uint64Slice) Less(i, j int) bool {
return p[uint(i)] < p[uint(j)]
}
type intSlice []int
func (p intSlice) Len() int { return len(p) }
func (p intSlice) Swap(i, j int) { p[uint(i)], p[uint(j)] = p[uint(j)], p[uint(i)] }
func (p intSlice) Less(i, j int) bool {
return p[uint(i)] < p[uint(j)]
}
type int32Slice []int32
func (p int32Slice) Len() int { return len(p) }
func (p int32Slice) Swap(i, j int) { p[uint(i)], p[uint(j)] = p[uint(j)], p[uint(i)] }
func (p int32Slice) Less(i, j int) bool {
return p[uint(i)] < p[uint(j)]
}
type stringRv struct {
v string
r reflect.Value
}
type stringRvSlice []stringRv
func (p stringRvSlice) Len() int { return len(p) }
func (p stringRvSlice) Swap(i, j int) { p[uint(i)], p[uint(j)] = p[uint(j)], p[uint(i)] }
func (p stringRvSlice) Less(i, j int) bool {
return p[uint(i)].v < p[uint(j)].v
}
type float64Rv struct {
v float64
r reflect.Value
}
type float64RvSlice []float64Rv
func (p float64RvSlice) Len() int { return len(p) }
func (p float64RvSlice) Swap(i, j int) { p[uint(i)], p[uint(j)] = p[uint(j)], p[uint(i)] }
func (p float64RvSlice) Less(i, j int) bool {
return p[uint(i)].v < p[uint(j)].v || isNaN64(p[uint(i)].v) && !isNaN64(p[uint(j)].v)
}
type uint64Rv struct {
v uint64
r reflect.Value
}
type uint64RvSlice []uint64Rv
func (p uint64RvSlice) Len() int { return len(p) }
func (p uint64RvSlice) Swap(i, j int) { p[uint(i)], p[uint(j)] = p[uint(j)], p[uint(i)] }
func (p uint64RvSlice) Less(i, j int) bool {
return p[uint(i)].v < p[uint(j)].v
}
type int64Rv struct {
v int64
r reflect.Value
}
type int64RvSlice []int64Rv
func (p int64RvSlice) Len() int { return len(p) }
func (p int64RvSlice) Swap(i, j int) { p[uint(i)], p[uint(j)] = p[uint(j)], p[uint(i)] }
func (p int64RvSlice) Less(i, j int) bool {
return p[uint(i)].v < p[uint(j)].v
}
type boolRv struct {
v bool
r reflect.Value
}
type boolRvSlice []boolRv
func (p boolRvSlice) Len() int { return len(p) }
func (p boolRvSlice) Swap(i, j int) { p[uint(i)], p[uint(j)] = p[uint(j)], p[uint(i)] }
func (p boolRvSlice) Less(i, j int) bool {
return !p[uint(i)].v && p[uint(j)].v
}
type timeRv struct {
v time.Time
r reflect.Value
}
type timeRvSlice []timeRv
func (p timeRvSlice) Len() int { return len(p) }
func (p timeRvSlice) Swap(i, j int) { p[uint(i)], p[uint(j)] = p[uint(j)], p[uint(i)] }
func (p timeRvSlice) Less(i, j int) bool {
return p[uint(i)].v.Before(p[uint(j)].v)
}
type bytesRv struct {
v []byte
r reflect.Value
}
type bytesRvSlice []bytesRv
func (p bytesRvSlice) Len() int { return len(p) }
func (p bytesRvSlice) Swap(i, j int) { p[uint(i)], p[uint(j)] = p[uint(j)], p[uint(i)] }
func (p bytesRvSlice) Less(i, j int) bool {
return bytes.Compare(p[uint(i)].v, p[uint(j)].v) == -1
}
type bytesIntf struct {
v []byte
i interface{}
}
type bytesIntfSlice []bytesIntf
func (p bytesIntfSlice) Len() int { return len(p) }
func (p bytesIntfSlice) Swap(i, j int) { p[uint(i)], p[uint(j)] = p[uint(j)], p[uint(i)] }
func (p bytesIntfSlice) Less(i, j int) bool {
return bytes.Compare(p[uint(i)].v, p[uint(j)].v) == -1
}

66
vendor/github.com/ugorji/go/codec/sort-slice.go.tmpl generated vendored Normal file
View File

@ -0,0 +1,66 @@
// Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.
// Code generated from sort-slice.go.tmpl - DO NOT EDIT.
{{/*
xxxSlice
xxxIntf
xxxIntfSlice
xxxRv
xxxRvSlice
I'm now going to create them for
- sortables
- sortablesplus
With the parameters passed in sortables or sortablesplus,
'time, 'bytes' are special, and correspond to time.Time and []byte respectively.
*/}}
package codec
import "time"
import "reflect"
import "bytes"
{{/* func init() { _ = time.Unix } */}}
{{define "T"}}
func (p {{ .Type }}) Len() int { return len(p) }
func (p {{ .Type }}) Swap(i, j int) { p[uint(i)], p[uint(j)] = p[uint(j)], p[uint(i)] }
func (p {{ .Type }}) Less(i, j int) bool {
{{ if eq .Kind "bool" }} return !p[uint(i)]{{.V}} && p[uint(j)]{{.V}}
{{ else if eq .Kind "float32" }} return p[uint(i)]{{.V}} < p[uint(j)]{{.V}} || isNaN32(p[uint(i)]{{.V}}) && !isNaN32(p[uint(j)]{{.V}})
{{ else if eq .Kind "float64" }} return p[uint(i)]{{.V}} < p[uint(j)]{{.V}} || isNaN64(p[uint(i)]{{.V}}) && !isNaN64(p[uint(j)]{{.V}})
{{ else if eq .Kind "time" }} return p[uint(i)]{{.V}}.Before(p[uint(j)]{{.V}})
{{ else if eq .Kind "bytes" }} return bytes.Compare(p[uint(i)]{{.V}}, p[uint(j)]{{.V}}) == -1
{{ else }} return p[uint(i)]{{.V}} < p[uint(j)]{{.V}}
{{ end -}}
}
{{end}}
{{range $i, $v := sortables }}{{ $t := tshort $v }}
type {{ $v }}Slice []{{ $t }}
{{template "T" args "Kind" $v "Type" (print $v "Slice") "V" ""}}
{{end}}
{{range $i, $v := sortablesplus }}{{ $t := tshort $v }}
type {{ $v }}Rv struct {
v {{ $t }}
r reflect.Value
}
type {{ $v }}RvSlice []{{ $v }}Rv
{{template "T" args "Kind" $v "Type" (print $v "RvSlice") "V" ".v"}}
{{if eq $v "bytes" -}}
type {{ $v }}Intf struct {
v {{ $t }}
i interface{}
}
type {{ $v }}IntfSlice []{{ $v }}Intf
{{template "T" args "Kind" $v "Type" (print $v "IntfSlice") "V" ".v"}}
{{end}}
{{end}}

View File

@ -5,14 +5,17 @@
# So it can process them (so we don't have to checkin the files). # So it can process them (so we don't have to checkin the files).
# Ensure msgpack-python and cbor are installed first, using: # Ensure msgpack-python and cbor are installed first, using:
# sudo apt-get install python-dev # sudo apt install python-dev (may not be necessary)
# sudo apt-get install python-pip # sudo apt install python-pip # or python3-pip
# pip install --user msgpack-python msgpack-rpc-python cbor # pip install --user msgpack-python msgpack-rpc-python cbor
# Ensure all "string" keys are utf strings (else encoded as bytes) # Ensure all "string" keys are utf strings (else encoded as bytes)
from __future__ import print_function
import cbor, msgpack, msgpackrpc, sys, os, threading import cbor, msgpack, msgpackrpc, sys, os, threading
mylocaladdr="127.0.0.1" # localhost.localdomain localhost 127.0.0.1
def get_test_data_list(): def get_test_data_list():
# get list with all primitive types, and a combo type # get list with all primitive types, and a combo type
l0 = [ l0 = [
@ -30,11 +33,13 @@ def get_test_data_list():
3232.0, 3232.0,
6464.0, 6464.0,
6464646464.0, 6464646464.0,
160.0,
1616.0,
False, False,
True, True,
u"null", u"null",
None, None,
u"someday", u"some&day>some<day",
1328176922000002000, 1328176922000002000,
u"", u"",
-2206187877999998000, -2206187877999998000,
@ -69,22 +74,20 @@ def build_test_data(destdir):
for i in range(len(l)): for i in range(len(l)):
# packer = msgpack.Packer() # packer = msgpack.Packer()
serialized = msgpack.dumps(l[i]) serialized = msgpack.dumps(l[i])
f = open(os.path.join(destdir, str(i) + '.msgpack.golden'), 'wb') with open(os.path.join(destdir, str(i) + '.msgpack.golden'), 'wb') as f:
f.write(serialized) f.write(serialized)
f.close()
serialized = cbor.dumps(l[i]) serialized = cbor.dumps(l[i])
f = open(os.path.join(destdir, str(i) + '.cbor.golden'), 'wb') with open(os.path.join(destdir, str(i) + '.cbor.golden'), 'wb') as f:
f.write(serialized) f.write(serialized)
f.close()
def doRpcServer(port, stopTimeSec): def doRpcServer(port, stopTimeSec):
class EchoHandler(object): class EchoHandler(object):
def Echo123(self, msg1, msg2, msg3): def Echo123(self, msg1, msg2, msg3):
return ("1:%s 2:%s 3:%s" % (msg1, msg2, msg3)) return ("1:%s 2:%s 3:%s" % (msg1.decode("utf-8"), msg2.decode("utf-8"), msg3.decode("utf-8")))
def EchoStruct(self, msg): def EchoStruct(self, msg):
return ("%s" % msg) return ("%s" % msg)
addr = msgpackrpc.Address('localhost', port) addr = msgpackrpc.Address(mylocaladdr, port)
server = msgpackrpc.Server(EchoHandler()) server = msgpackrpc.Server(EchoHandler())
server.listen(addr) server.listen(addr)
# run thread to stop it after stopTimeSec seconds if > 0 # run thread to stop it after stopTimeSec seconds if > 0
@ -96,17 +99,27 @@ def doRpcServer(port, stopTimeSec):
server.start() server.start()
def doRpcClientToPythonSvc(port): def doRpcClientToPythonSvc(port):
address = msgpackrpc.Address('localhost', port) address = msgpackrpc.Address(mylocaladdr, port)
client = msgpackrpc.Client(address, unpack_encoding='utf-8') client = msgpackrpc.Client(address, unpack_encoding='utf-8')
print client.call("Echo123", "A1", "B2", "C3") print(client.call("Echo123", "A1", "B2", "C3"))
print client.call("EchoStruct", {"A" :"Aa", "B":"Bb", "C":"Cc"}) print(client.call("EchoStruct", {"A" :"Aa", "B":"Bb", "C":"Cc"}))
# def doCheckSocket(port):
# print(">>>> port: ", port, " <<<<<")
# sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# result = sock.connect_ex(('127.0.0.1', port))
# if result == 0:
# print("\t>>>> Port is open")
# else:
# print("\t>>>> Port is not open")
# sock.close()
def doRpcClientToGoSvc(port): def doRpcClientToGoSvc(port):
# print ">>>> port: ", port, " <<<<<" # doCheckSocket(port)
address = msgpackrpc.Address('localhost', port) address = msgpackrpc.Address(mylocaladdr, port)
client = msgpackrpc.Client(address, unpack_encoding='utf-8') client = msgpackrpc.Client(address, unpack_encoding='utf-8')
print client.call("TestRpcInt.Echo123", ["A1", "B2", "C3"]) print(client.call("TestRpcInt.Echo123", ["A1", "B2", "C3"]))
print client.call("TestRpcInt.EchoStruct", {"A" :"Aa", "B":"Bb", "C":"Cc"}) print(client.call("TestRpcInt.EchoStruct", {"A" :"Aa", "B":"Bb", "C":"Cc"}))
def doMain(args): def doMain(args):
if len(args) == 2 and args[0] == "testdata": if len(args) == 2 and args[0] == "testdata":
@ -123,4 +136,3 @@ def doMain(args):
if __name__ == "__main__": if __name__ == "__main__":
doMain(sys.argv[1:]) doMain(sys.argv[1:])

View File

@ -1,80 +0,0 @@
#!/bin/bash
# Run all the different permutations of all the tests.
# This helps ensure that nothing gets broken.
_run() {
# 1. VARIATIONS: regular (t), canonical (c), IO R/W (i),
# binc-nosymbols (n), struct2array (s), intern string (e),
# json-indent (d), circular (l)
# 2. MODE: reflection (r), external (x), codecgen (g), unsafe (u), notfastpath (f)
# 3. OPTIONS: verbose (v), reset (z), must (m),
#
# Use combinations of mode to get exactly what you want,
# and then pass the variations you need.
ztags=""
zargs=""
local OPTIND
OPTIND=1
while getopts "_xurtcinsvgzmefdl" flag
do
case "x$flag" in
'xr') ;;
'xf') ztags="$ztags notfastpath" ;;
'xg') ztags="$ztags codecgen" ;;
'xx') ztags="$ztags x" ;;
'xu') ztags="$ztags unsafe" ;;
'xv') zargs="$zargs -tv" ;;
'xz') zargs="$zargs -tr" ;;
'xm') zargs="$zargs -tm" ;;
'xl') zargs="$zargs -tl" ;;
*) ;;
esac
done
# shift $((OPTIND-1))
printf '............. TAGS: %s .............\n' "$ztags"
# echo ">>>>>>> TAGS: $ztags"
OPTIND=1
while getopts "_xurtcinsvgzmefdl" flag
do
case "x$flag" in
'xt') printf ">>>>>>> REGULAR : "; go test "-tags=$ztags" $zargs ; sleep 2 ;;
'xc') printf ">>>>>>> CANONICAL : "; go test "-tags=$ztags" $zargs -tc; sleep 2 ;;
'xi') printf ">>>>>>> I/O : "; go test "-tags=$ztags" $zargs -ti; sleep 2 ;;
'xn') printf ">>>>>>> NO_SYMBOLS : "; go test "-tags=$ztags" -run=Binc $zargs -tn; sleep 2 ;;
'xs') printf ">>>>>>> TO_ARRAY : "; go test "-tags=$ztags" $zargs -ts; sleep 2 ;;
'xe') printf ">>>>>>> INTERN : "; go test "-tags=$ztags" $zargs -te; sleep 2 ;;
'xd') printf ">>>>>>> INDENT : ";
go test "-tags=$ztags" -run=JsonCodecsTable -td=-1 $zargs;
go test "-tags=$ztags" -run=JsonCodecsTable -td=8 $zargs;
sleep 2 ;;
*) ;;
esac
done
shift $((OPTIND-1))
OPTIND=1
}
# echo ">>>>>>> RUNNING VARIATIONS OF TESTS"
if [[ "x$@" = "x" ]]; then
# All: r, x, g, gu
_run "-_tcinsed_ml" # regular
_run "-_tcinsed_ml_z" # regular with reset
_run "-_tcinsed_ml_f" # regular with no fastpath (notfastpath)
_run "-x_tcinsed_ml" # external
_run "-gx_tcinsed_ml" # codecgen: requires external
_run "-gxu_tcinsed_ml" # codecgen + unsafe
elif [[ "x$@" = "x-Z" ]]; then
# Regular
_run "-_tcinsed_ml" # regular
_run "-_tcinsed_ml_z" # regular with reset
elif [[ "x$@" = "x-F" ]]; then
# regular with notfastpath
_run "-_tcinsed_ml_f" # regular
_run "-_tcinsed_ml_zf" # regular with reset
else
_run "$@"
fi

View File

@ -1,233 +0,0 @@
// 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
import (
"fmt"
"reflect"
"time"
)
var (
timeDigits = [...]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
timeExtEncFn = func(rv reflect.Value) (bs []byte, err error) {
defer panicToErr(&err)
bs = timeExt{}.WriteExt(rv.Interface())
return
}
timeExtDecFn = func(rv reflect.Value, bs []byte) (err error) {
defer panicToErr(&err)
timeExt{}.ReadExt(rv.Interface(), bs)
return
}
)
type timeExt struct{}
func (x timeExt) WriteExt(v interface{}) (bs []byte) {
switch v2 := v.(type) {
case time.Time:
bs = encodeTime(v2)
case *time.Time:
bs = encodeTime(*v2)
default:
panic(fmt.Errorf("unsupported format for time conversion: expecting time.Time; got %T", v2))
}
return
}
func (x timeExt) ReadExt(v interface{}, bs []byte) {
tt, err := decodeTime(bs)
if err != nil {
panic(err)
}
*(v.(*time.Time)) = tt
}
func (x timeExt) ConvertExt(v interface{}) interface{} {
return x.WriteExt(v)
}
func (x timeExt) UpdateExt(v interface{}, src interface{}) {
x.ReadExt(v, src.([]byte))
}
// EncodeTime encodes a time.Time as a []byte, including
// information on the instant in time and UTC offset.
//
// Format Description
//
// A timestamp is composed of 3 components:
//
// - secs: signed integer representing seconds since unix epoch
// - nsces: unsigned integer representing fractional seconds as a
// nanosecond offset within secs, in the range 0 <= nsecs < 1e9
// - tz: signed integer representing timezone offset in minutes east of UTC,
// and a dst (daylight savings time) flag
//
// When encoding a timestamp, the first byte is the descriptor, which
// defines which components are encoded and how many bytes are used to
// encode secs and nsecs components. *If secs/nsecs is 0 or tz is UTC, it
// is not encoded in the byte array explicitly*.
//
// Descriptor 8 bits are of the form `A B C DDD EE`:
// A: Is secs component encoded? 1 = true
// B: Is nsecs component encoded? 1 = true
// C: Is tz component encoded? 1 = true
// DDD: Number of extra bytes for secs (range 0-7).
// If A = 1, secs encoded in DDD+1 bytes.
// If A = 0, secs is not encoded, and is assumed to be 0.
// If A = 1, then we need at least 1 byte to encode secs.
// DDD says the number of extra bytes beyond that 1.
// E.g. if DDD=0, then secs is represented in 1 byte.
// if DDD=2, then secs is represented in 3 bytes.
// EE: Number of extra bytes for nsecs (range 0-3).
// If B = 1, nsecs encoded in EE+1 bytes (similar to secs/DDD above)
//
// Following the descriptor bytes, subsequent bytes are:
//
// secs component encoded in `DDD + 1` bytes (if A == 1)
// nsecs component encoded in `EE + 1` bytes (if B == 1)
// tz component encoded in 2 bytes (if C == 1)
//
// secs and nsecs components are integers encoded in a BigEndian
// 2-complement encoding format.
//
// tz component is encoded as 2 bytes (16 bits). Most significant bit 15 to
// Least significant bit 0 are described below:
//
// Timezone offset has a range of -12:00 to +14:00 (ie -720 to +840 minutes).
// Bit 15 = have\_dst: set to 1 if we set the dst flag.
// Bit 14 = dst\_on: set to 1 if dst is in effect at the time, or 0 if not.
// Bits 13..0 = timezone offset in minutes. It is a signed integer in Big Endian format.
//
func encodeTime(t time.Time) []byte {
//t := rv.Interface().(time.Time)
tsecs, tnsecs := t.Unix(), t.Nanosecond()
var (
bd byte
btmp [8]byte
bs [16]byte
i int = 1
)
l := t.Location()
if l == time.UTC {
l = nil
}
if tsecs != 0 {
bd = bd | 0x80
bigen.PutUint64(btmp[:], uint64(tsecs))
f := pruneSignExt(btmp[:], tsecs >= 0)
bd = bd | (byte(7-f) << 2)
copy(bs[i:], btmp[f:])
i = i + (8 - f)
}
if tnsecs != 0 {
bd = bd | 0x40
bigen.PutUint32(btmp[:4], uint32(tnsecs))
f := pruneSignExt(btmp[:4], true)
bd = bd | byte(3-f)
copy(bs[i:], btmp[f:4])
i = i + (4 - f)
}
if l != nil {
bd = bd | 0x20
// Note that Go Libs do not give access to dst flag.
_, zoneOffset := t.Zone()
//zoneName, zoneOffset := t.Zone()
zoneOffset /= 60
z := uint16(zoneOffset)
bigen.PutUint16(btmp[:2], z)
// clear dst flags
bs[i] = btmp[0] & 0x3f
bs[i+1] = btmp[1]
i = i + 2
}
bs[0] = bd
return bs[0:i]
}
// DecodeTime decodes a []byte into a time.Time.
func decodeTime(bs []byte) (tt time.Time, err error) {
bd := bs[0]
var (
tsec int64
tnsec uint32
tz uint16
i byte = 1
i2 byte
n byte
)
if bd&(1<<7) != 0 {
var btmp [8]byte
n = ((bd >> 2) & 0x7) + 1
i2 = i + n
copy(btmp[8-n:], bs[i:i2])
//if first bit of bs[i] is set, then fill btmp[0..8-n] with 0xff (ie sign extend it)
if bs[i]&(1<<7) != 0 {
copy(btmp[0:8-n], bsAll0xff)
//for j,k := byte(0), 8-n; j < k; j++ { btmp[j] = 0xff }
}
i = i2
tsec = int64(bigen.Uint64(btmp[:]))
}
if bd&(1<<6) != 0 {
var btmp [4]byte
n = (bd & 0x3) + 1
i2 = i + n
copy(btmp[4-n:], bs[i:i2])
i = i2
tnsec = bigen.Uint32(btmp[:])
}
if bd&(1<<5) == 0 {
tt = time.Unix(tsec, int64(tnsec)).UTC()
return
}
// In stdlib time.Parse, when a date is parsed without a zone name, it uses "" as zone name.
// However, we need name here, so it can be shown when time is printed.
// Zone name is in form: UTC-08:00.
// Note that Go Libs do not give access to dst flag, so we ignore dst bits
i2 = i + 2
tz = bigen.Uint16(bs[i:i2])
i = i2
// sign extend sign bit into top 2 MSB (which were dst bits):
if tz&(1<<13) == 0 { // positive
tz = tz & 0x3fff //clear 2 MSBs: dst bits
} else { // negative
tz = tz | 0xc000 //set 2 MSBs: dst bits
//tzname[3] = '-' (TODO: verify. this works here)
}
tzint := int16(tz)
if tzint == 0 {
tt = time.Unix(tsec, int64(tnsec)).UTC()
} else {
// For Go Time, do not use a descriptive timezone.
// It's unnecessary, and makes it harder to do a reflect.DeepEqual.
// The Offset already tells what the offset should be, if not on UTC and unknown zone name.
// var zoneName = timeLocUTCName(tzint)
tt = time.Unix(tsec, int64(tnsec)).In(time.FixedZone("", int(tzint)*60))
}
return
}
func timeLocUTCName(tzint int16) string {
if tzint == 0 {
return "UTC"
}
var tzname = []byte("UTC+00:00")
//tzname := fmt.Sprintf("UTC%s%02d:%02d", tzsign, tz/60, tz%60) //perf issue using Sprintf. inline below.
//tzhr, tzmin := tz/60, tz%60 //faster if u convert to int first
var tzhr, tzmin int16
if tzint < 0 {
tzname[3] = '-' // (TODO: verify. this works here)
tzhr, tzmin = -tzint/60, (-tzint)%60
} else {
tzhr, tzmin = tzint/60, tzint%60
}
tzname[4] = timeDigits[tzhr/10]
tzname[5] = timeDigits[tzhr%10]
tzname[7] = timeDigits[tzmin/10]
tzname[8] = timeDigits[tzmin%10]
return string(tzname)
//return time.FixedZone(string(tzname), int(tzint)*60)
}

287
vendor/github.com/ugorji/go/codec/writer.go generated vendored Normal file
View File

@ -0,0 +1,287 @@
// Copyright (c) 2012-2020 Ugorji Nwoke. All rights reserved.
// Use of this source code is governed by a MIT license found in the LICENSE file.
package codec
import "io"
// encWriter abstracts writing to a byte array or to an io.Writer.
type encWriter interface {
writeb([]byte)
writestr(string)
writeqstr(string) // write string wrapped in quotes ie "..."
writen1(byte)
// add convenience functions for writing 2,4
writen2(byte, byte)
writen4([4]byte)
writen8([8]byte)
end()
}
// ---------------------------------------------
type bufioEncWriter struct {
w io.Writer
buf []byte
n int
b [16]byte // scratch buffer and padding (cache-aligned)
}
func (z *bufioEncWriter) reset(w io.Writer, bufsize int, blist *bytesFreelist) {
z.w = w
z.n = 0
if bufsize <= 0 {
bufsize = defEncByteBufSize
}
// bufsize must be >= 8, to accomodate writen methods (where n <= 8)
if bufsize <= 8 {
bufsize = 8
}
if cap(z.buf) < bufsize {
if len(z.buf) > 0 && &z.buf[0] != &z.b[0] {
blist.put(z.buf)
}
if len(z.b) > bufsize {
z.buf = z.b[:]
} else {
z.buf = blist.get(bufsize)
}
}
z.buf = z.buf[:cap(z.buf)]
}
func (z *bufioEncWriter) flushErr() (err error) {
n, err := z.w.Write(z.buf[:z.n])
z.n -= n
if z.n > 0 {
if err == nil {
err = io.ErrShortWrite
}
if n > 0 {
copy(z.buf, z.buf[n:z.n+n])
}
}
return err
}
func (z *bufioEncWriter) flush() {
halt.onerror(z.flushErr())
}
func (z *bufioEncWriter) writeb(s []byte) {
LOOP:
a := len(z.buf) - z.n
if len(s) > a {
z.n += copy(z.buf[z.n:], s[:a])
s = s[a:]
z.flush()
goto LOOP
}
z.n += copy(z.buf[z.n:], s)
}
func (z *bufioEncWriter) writestr(s string) {
// z.writeb(bytesView(s)) // inlined below
LOOP:
a := len(z.buf) - z.n
if len(s) > a {
z.n += copy(z.buf[z.n:], s[:a])
s = s[a:]
z.flush()
goto LOOP
}
z.n += copy(z.buf[z.n:], s)
}
func (z *bufioEncWriter) writeqstr(s string) {
// z.writen1('"')
// z.writestr(s)
// z.writen1('"')
if z.n+len(s)+2 > len(z.buf) {
z.flush()
}
z.buf[z.n] = '"'
z.n++
LOOP:
a := len(z.buf) - z.n
if len(s)+1 > a {
z.n += copy(z.buf[z.n:], s[:a])
s = s[a:]
z.flush()
goto LOOP
}
z.n += copy(z.buf[z.n:], s)
z.buf[z.n] = '"'
z.n++
}
func (z *bufioEncWriter) writen1(b1 byte) {
if 1 > len(z.buf)-z.n {
z.flush()
}
z.buf[z.n] = b1
z.n++
}
func (z *bufioEncWriter) writen2(b1, b2 byte) {
if 2 > len(z.buf)-z.n {
z.flush()
}
z.buf[z.n+1] = b2
z.buf[z.n] = b1
z.n += 2
}
func (z *bufioEncWriter) writen4(b [4]byte) {
if 4 > len(z.buf)-z.n {
z.flush()
}
copy(z.buf[z.n:], b[:])
z.n += 4
}
func (z *bufioEncWriter) writen8(b [8]byte) {
if 8 > len(z.buf)-z.n {
z.flush()
}
copy(z.buf[z.n:], b[:])
z.n += 8
}
func (z *bufioEncWriter) endErr() (err error) {
if z.n > 0 {
err = z.flushErr()
}
return
}
// ---------------------------------------------
// bytesEncAppender implements encWriter and can write to an byte slice.
type bytesEncAppender struct {
b []byte
out *[]byte
}
func (z *bytesEncAppender) writeb(s []byte) {
z.b = append(z.b, s...)
}
func (z *bytesEncAppender) writestr(s string) {
z.b = append(z.b, s...)
}
func (z *bytesEncAppender) writeqstr(s string) {
z.b = append(append(append(z.b, '"'), s...), '"')
// z.b = append(z.b, '"')
// z.b = append(z.b, s...)
// z.b = append(z.b, '"')
}
func (z *bytesEncAppender) writen1(b1 byte) {
z.b = append(z.b, b1)
}
func (z *bytesEncAppender) writen2(b1, b2 byte) {
z.b = append(z.b, b1, b2)
}
func (z *bytesEncAppender) writen4(b [4]byte) {
z.b = append(z.b, b[:]...)
}
func (z *bytesEncAppender) writen8(b [8]byte) {
z.b = append(z.b, b[:]...)
}
func (z *bytesEncAppender) endErr() error {
*(z.out) = z.b
return nil
}
func (z *bytesEncAppender) reset(in []byte, out *[]byte) {
z.b = in[:0]
z.out = out
}
// --------------------------------------------------
type encWr struct {
bytes bool // encoding to []byte
js bool // is json encoder?
be bool // is binary encoder?
c containerState
calls uint16
seq uint16 // sequencer (e.g. used by binc for symbols, etc)
wb bytesEncAppender
wf *bufioEncWriter
}
// MARKER: manually inline bytesEncAppender.writenx/writeqstr methods,
// as calling them causes encWr.writenx/writeqstr methods to not be inlined (cost > 80).
//
// i.e. e.g. instead of writing z.wb.writen2(b1, b2), use z.wb.b = append(z.wb.b, b1, b2)
func (z *encWr) writeb(s []byte) {
if z.bytes {
z.wb.writeb(s)
} else {
z.wf.writeb(s)
}
}
func (z *encWr) writeqstr(s string) {
if z.bytes {
// MARKER: z.wb.writeqstr(s)
z.wb.b = append(append(append(z.wb.b, '"'), s...), '"')
} else {
z.wf.writeqstr(s)
}
}
func (z *encWr) writestr(s string) {
if z.bytes {
z.wb.writestr(s)
} else {
z.wf.writestr(s)
}
}
func (z *encWr) writen1(b1 byte) {
if z.bytes {
z.wb.writen1(b1)
} else {
z.wf.writen1(b1)
}
}
func (z *encWr) writen2(b1, b2 byte) {
if z.bytes {
// MARKER: z.wb.writen2(b1, b2)
z.wb.b = append(z.wb.b, b1, b2)
} else {
z.wf.writen2(b1, b2)
}
}
func (z *encWr) writen4(b [4]byte) {
if z.bytes {
z.wb.writen4(b)
} else {
z.wf.writen4(b)
}
}
func (z *encWr) writen8(b [8]byte) {
if z.bytes {
z.wb.writen8(b)
} else {
z.wf.writen8(b)
}
}
func (z *encWr) endErr() error {
if z.bytes {
return z.wb.endErr()
}
return z.wf.endErr()
}
func (z *encWr) end() {
halt.onerror(z.endErr())
}
var _ encWriter = (*encWr)(nil)

4
vendor/modules.txt vendored
View File

@ -360,7 +360,7 @@ github.com/hashicorp/hcl/v2/hclparse
github.com/hashicorp/hcl/v2/hclsyntax github.com/hashicorp/hcl/v2/hclsyntax
github.com/hashicorp/hcl/v2/hclwrite github.com/hashicorp/hcl/v2/hclwrite
github.com/hashicorp/hcl/v2/json github.com/hashicorp/hcl/v2/json
# github.com/hashicorp/packer-plugin-sdk v0.0.11 # github.com/hashicorp/packer-plugin-sdk v0.0.12
github.com/hashicorp/packer-plugin-sdk/acctest github.com/hashicorp/packer-plugin-sdk/acctest
github.com/hashicorp/packer-plugin-sdk/acctest/provisioneracc github.com/hashicorp/packer-plugin-sdk/acctest/provisioneracc
github.com/hashicorp/packer-plugin-sdk/acctest/testutils github.com/hashicorp/packer-plugin-sdk/acctest/testutils
@ -585,7 +585,7 @@ github.com/ucloud/ucloud-sdk-go/ucloud/response
github.com/ucloud/ucloud-sdk-go/ucloud/version github.com/ucloud/ucloud-sdk-go/ucloud/version
# github.com/ufilesdk-dev/ufile-gosdk v0.0.0-20190830075812-b4dbc4ef43a6 # github.com/ufilesdk-dev/ufile-gosdk v0.0.0-20190830075812-b4dbc4ef43a6
github.com/ufilesdk-dev/ufile-gosdk github.com/ufilesdk-dev/ufile-gosdk
# github.com/ugorji/go v0.0.0-20151218193438-646ae4a518c1 # github.com/ugorji/go/codec v1.2.4
github.com/ugorji/go/codec github.com/ugorji/go/codec
# github.com/ulikunitz/xz v0.5.5 # github.com/ulikunitz/xz v0.5.5
github.com/ulikunitz/xz github.com/ulikunitz/xz