From cbe0782446f00d68c0a806f1613c703647986e86 Mon Sep 17 00:00:00 2001 From: Simone Gotti Date: Mon, 25 Jan 2016 17:06:00 +0100 Subject: [PATCH] stolon: support consul as a store. This patch uses docker/libkv and swarm/leadership to also handle consul as a stolon's store. In future also zookeeper should be supported (needs testing). Incompatible changes: --etcd-endpoints option has been removed --store-backend and --store-endpoints options has been added. --- Godeps/Godeps.json | 50 +- .../github.com/coreos/etcd/client/README.md | 20 +- .../coreos/etcd/client/auth_role.go | 12 +- .../coreos/etcd/client/auth_user.go | 22 +- .../github.com/coreos/etcd/client/client.go | 72 +- .../coreos/etcd/client/keys.generated.go | 1101 +- .../src/github.com/coreos/etcd/client/keys.go | 2 +- .../github.com/coreos/etcd/client/members.go | 32 + .../coreos/etcd/pkg/pathutil/path.go | 2 + .../github.com/coreos/etcd/pkg/types/doc.go | 17 + .../coreos/etcd/pkg/types/urlsmap.go | 34 +- .../github.com/coreos/fleet/pkg/lease/etcd.go | 205 - .../coreos/fleet/pkg/lease/interface.go | 72 - .../src/github.com/docker/libkv/.travis.yml | 34 + .../src/github.com/docker/libkv/LICENSE.code | 191 + .../src/github.com/docker/libkv/LICENSE.docs | 425 + .../src/github.com/docker/libkv/MAINTAINERS | 46 + .../src/github.com/docker/libkv/README.md | 106 + .../docker/libkv/docs/compatibility.md | 82 + .../github.com/docker/libkv/docs/examples.md | 157 + .../src/github.com/docker/libkv/libkv.go | 40 + .../github.com/docker/libkv/script/.validate | 33 + .../github.com/docker/libkv/script/coverage | 21 + .../docker/libkv/script/travis_consul.sh | 18 + .../docker/libkv/script/travis_etcd.sh | 11 + .../docker/libkv/script/travis_zk.sh | 12 + .../docker/libkv/script/validate-gofmt | 30 + .../docker/libkv/store/boltdb/boltdb.go | 471 + .../docker/libkv/store/consul/consul.go | 495 + .../docker/libkv/store/etcd/etcd.go | 597 + .../github.com/docker/libkv/store/helpers.go | 47 + .../docker/libkv/store/mock/mock.go | 113 + .../github.com/docker/libkv/store/store.go | 130 + .../docker/libkv/store/zookeeper/zookeeper.go | 429 + .../docker/libkv/testutils/utils.go | 622 + .../docker/swarm/leadership/README.md | 110 + .../docker/swarm/leadership/candidate.go | 136 + .../docker/swarm/leadership/follower.go | 74 + .../github.com/hashicorp/consul/api/README.md | 43 + .../github.com/hashicorp/consul/api/acl.go | 140 + .../github.com/hashicorp/consul/api/agent.go | 337 + .../github.com/hashicorp/consul/api/api.go | 475 + .../hashicorp/consul/api/catalog.go | 182 + .../hashicorp/consul/api/coordinate.go | 66 + .../github.com/hashicorp/consul/api/event.go | 104 + .../github.com/hashicorp/consul/api/health.go | 136 + .../src/github.com/hashicorp/consul/api/kv.go | 240 + .../github.com/hashicorp/consul/api/lock.go | 380 + .../hashicorp/consul/api/prepared_query.go | 173 + .../github.com/hashicorp/consul/api/raw.go | 24 + .../hashicorp/consul/api/semaphore.go | 512 + .../hashicorp/consul/api/session.go | 217 + .../github.com/hashicorp/consul/api/status.go | 43 + .../github.com/hashicorp/go-cleanhttp/LICENSE | 363 + .../hashicorp/go-cleanhttp/README.md | 30 + .../hashicorp/go-cleanhttp/cleanhttp.go | 40 + .../hashicorp/serf/coordinate/README.md | 1 + .../hashicorp/serf/coordinate/client.go | 180 + .../hashicorp/serf/coordinate/config.go | 70 + .../hashicorp/serf/coordinate/coordinate.go | 183 + .../hashicorp/serf/coordinate/phantom.go | 187 + .../hashicorp/serf/coordinate/test_util.go | 27 + .../src/github.com/lib/pq/.travis.yml | 22 +- .../src/github.com/lib/pq/README.md | 8 + .../_workspace/src/github.com/lib/pq/buf.go | 30 +- .../_workspace/src/github.com/lib/pq/conn.go | 703 +- .../_workspace/src/github.com/lib/pq/copy.go | 56 +- .../_workspace/src/github.com/lib/pq/doc.go | 3 +- .../src/github.com/lib/pq/encode.go | 185 +- .../_workspace/src/github.com/lib/pq/error.go | 13 + .../github.com/lib/pq/listen_example/doc.go | 4 +- .../src/github.com/lib/pq/notify.go | 59 +- .../src/github.com/lib/pq/oid/gen.go | 2 +- .../_workspace/src/github.com/lib/pq/url.go | 2 +- .../src/github.com/lib/pq/user_posix.go | 19 +- .../src/github.com/lib/pq/user_windows.go | 2 +- .../src/github.com/satori/go.uuid/.travis.yml | 4 + .../src/github.com/satori/go.uuid/LICENSE | 2 +- .../src/github.com/satori/go.uuid/README.md | 4 +- .../src/github.com/satori/go.uuid/uuid.go | 218 +- .../src/github.com/ugorji/go/codec/0doc.go | 51 +- .../src/github.com/ugorji/go/codec/binc.go | 155 +- .../src/github.com/ugorji/go/codec/cbor.go | 133 +- .../ugorji/go/codec/codecgen/gen.go | 40 +- .../src/github.com/ugorji/go/codec/decode.go | 1379 +- .../src/github.com/ugorji/go/codec/encode.go | 1017 +- .../ugorji/go/codec/fast-path.generated.go | 25020 +++++++++++----- .../ugorji/go/codec/fast-path.go.tmpl | 320 +- .../ugorji/go/codec/fast-path.not.go | 32 + .../ugorji/go/codec/gen-dec-array.go.tmpl | 142 +- .../ugorji/go/codec/gen-dec-map.go.tmpl | 60 +- .../ugorji/go/codec/gen-helper.generated.go | 131 + .../ugorji/go/codec/gen-helper.go.tmpl | 116 +- .../ugorji/go/codec/gen.generated.go | 202 +- .../src/github.com/ugorji/go/codec/gen.go | 873 +- .../src/github.com/ugorji/go/codec/helper.go | 605 +- .../ugorji/go/codec/helper_internal.go | 91 + .../ugorji/go/codec/helper_unsafe.go | 6 + .../src/github.com/ugorji/go/codec/json.go | 725 +- .../src/github.com/ugorji/go/codec/msgpack.go | 168 +- .../src/github.com/ugorji/go/codec/noop.go | 153 +- .../github.com/ugorji/go/codec/prebuild.sh | 74 +- .../src/github.com/ugorji/go/codec/simple.go | 116 +- .../src/github.com/ugorji/go/codec/test.py | 23 +- .../src/github.com/ugorji/go/codec/tests.sh | 80 + .../src/github.com/ugorji/go/codec/time.go | 42 +- .../src/golang.org/x/net/context/context.go | 69 +- .../x/net/context/ctxhttp/cancelreq.go | 19 + .../x/net/context/ctxhttp/cancelreq_go14.go | 23 + .../x/net/context/ctxhttp/ctxhttp.go | 123 + README.md | 6 +- cmd/keeper/keeper.go | 25 +- cmd/proxy/proxy.go | 35 +- cmd/sentinel/handlers.go | 11 +- cmd/sentinel/sentinel.go | 201 +- cmd/stolonctl/config_get.go | 12 +- cmd/stolonctl/config_patch.go | 11 +- cmd/stolonctl/config_replace.go | 19 +- cmd/stolonctl/listclusters.go | 35 +- cmd/stolonctl/status.go | 16 +- cmd/stolonctl/stolonctl.go | 17 +- common/common.go | 11 +- doc/architecture.png | Bin 80811 -> 88169 bytes doc/architecture.svg | 141 +- doc/architecture_small.png | Bin 36265 -> 39625 bytes doc/simplecluster.md | 2 +- doc/stolonctl.md | 7 +- examples/kubernetes/README.md | 2 +- examples/kubernetes/stolon-keeper.yaml | 6 +- examples/kubernetes/stolon-proxy.yaml | 6 +- examples/kubernetes/stolon-sentinel.yaml | 6 +- pkg/cluster/clusterview.go | 3 +- pkg/cluster/config.go | 2 +- pkg/etcd/etcd.go | 283 - pkg/etcd/utils.go | 37 - pkg/store/store.go | 311 + scripts/semaphore.sh | 15 +- test | 37 +- tests/integration/config_test.go | 43 +- tests/integration/ha_test.go | 40 +- tests/integration/init_test.go | 58 +- tests/integration/proxy_test.go | 78 +- tests/integration/utils.go | 205 +- 143 files changed, 34122 insertions(+), 11107 deletions(-) create mode 100644 Godeps/_workspace/src/github.com/coreos/etcd/pkg/types/doc.go delete mode 100644 Godeps/_workspace/src/github.com/coreos/fleet/pkg/lease/etcd.go delete mode 100644 Godeps/_workspace/src/github.com/coreos/fleet/pkg/lease/interface.go create mode 100644 Godeps/_workspace/src/github.com/docker/libkv/.travis.yml create mode 100644 Godeps/_workspace/src/github.com/docker/libkv/LICENSE.code create mode 100644 Godeps/_workspace/src/github.com/docker/libkv/LICENSE.docs create mode 100644 Godeps/_workspace/src/github.com/docker/libkv/MAINTAINERS create mode 100644 Godeps/_workspace/src/github.com/docker/libkv/README.md create mode 100644 Godeps/_workspace/src/github.com/docker/libkv/docs/compatibility.md create mode 100644 Godeps/_workspace/src/github.com/docker/libkv/docs/examples.md create mode 100644 Godeps/_workspace/src/github.com/docker/libkv/libkv.go create mode 100644 Godeps/_workspace/src/github.com/docker/libkv/script/.validate create mode 100644 Godeps/_workspace/src/github.com/docker/libkv/script/coverage create mode 100644 Godeps/_workspace/src/github.com/docker/libkv/script/travis_consul.sh create mode 100644 Godeps/_workspace/src/github.com/docker/libkv/script/travis_etcd.sh create mode 100644 Godeps/_workspace/src/github.com/docker/libkv/script/travis_zk.sh create mode 100644 Godeps/_workspace/src/github.com/docker/libkv/script/validate-gofmt create mode 100644 Godeps/_workspace/src/github.com/docker/libkv/store/boltdb/boltdb.go create mode 100644 Godeps/_workspace/src/github.com/docker/libkv/store/consul/consul.go create mode 100644 Godeps/_workspace/src/github.com/docker/libkv/store/etcd/etcd.go create mode 100644 Godeps/_workspace/src/github.com/docker/libkv/store/helpers.go create mode 100644 Godeps/_workspace/src/github.com/docker/libkv/store/mock/mock.go create mode 100644 Godeps/_workspace/src/github.com/docker/libkv/store/store.go create mode 100644 Godeps/_workspace/src/github.com/docker/libkv/store/zookeeper/zookeeper.go create mode 100644 Godeps/_workspace/src/github.com/docker/libkv/testutils/utils.go create mode 100644 Godeps/_workspace/src/github.com/docker/swarm/leadership/README.md create mode 100644 Godeps/_workspace/src/github.com/docker/swarm/leadership/candidate.go create mode 100644 Godeps/_workspace/src/github.com/docker/swarm/leadership/follower.go create mode 100644 Godeps/_workspace/src/github.com/hashicorp/consul/api/README.md create mode 100644 Godeps/_workspace/src/github.com/hashicorp/consul/api/acl.go create mode 100644 Godeps/_workspace/src/github.com/hashicorp/consul/api/agent.go create mode 100644 Godeps/_workspace/src/github.com/hashicorp/consul/api/api.go create mode 100644 Godeps/_workspace/src/github.com/hashicorp/consul/api/catalog.go create mode 100644 Godeps/_workspace/src/github.com/hashicorp/consul/api/coordinate.go create mode 100644 Godeps/_workspace/src/github.com/hashicorp/consul/api/event.go create mode 100644 Godeps/_workspace/src/github.com/hashicorp/consul/api/health.go create mode 100644 Godeps/_workspace/src/github.com/hashicorp/consul/api/kv.go create mode 100644 Godeps/_workspace/src/github.com/hashicorp/consul/api/lock.go create mode 100644 Godeps/_workspace/src/github.com/hashicorp/consul/api/prepared_query.go create mode 100644 Godeps/_workspace/src/github.com/hashicorp/consul/api/raw.go create mode 100644 Godeps/_workspace/src/github.com/hashicorp/consul/api/semaphore.go create mode 100644 Godeps/_workspace/src/github.com/hashicorp/consul/api/session.go create mode 100644 Godeps/_workspace/src/github.com/hashicorp/consul/api/status.go create mode 100644 Godeps/_workspace/src/github.com/hashicorp/go-cleanhttp/LICENSE create mode 100644 Godeps/_workspace/src/github.com/hashicorp/go-cleanhttp/README.md create mode 100644 Godeps/_workspace/src/github.com/hashicorp/go-cleanhttp/cleanhttp.go create mode 100644 Godeps/_workspace/src/github.com/hashicorp/serf/coordinate/README.md create mode 100644 Godeps/_workspace/src/github.com/hashicorp/serf/coordinate/client.go create mode 100644 Godeps/_workspace/src/github.com/hashicorp/serf/coordinate/config.go create mode 100644 Godeps/_workspace/src/github.com/hashicorp/serf/coordinate/coordinate.go create mode 100644 Godeps/_workspace/src/github.com/hashicorp/serf/coordinate/phantom.go create mode 100644 Godeps/_workspace/src/github.com/hashicorp/serf/coordinate/test_util.go create mode 100644 Godeps/_workspace/src/github.com/ugorji/go/codec/fast-path.not.go create mode 100644 Godeps/_workspace/src/github.com/ugorji/go/codec/tests.sh create mode 100644 Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq.go create mode 100644 Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq_go14.go create mode 100644 Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/ctxhttp.go delete mode 100644 pkg/etcd/etcd.go delete mode 100644 pkg/etcd/utils.go create mode 100644 pkg/store/store.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index cd2d79f..9952951 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -7,23 +7,18 @@ "Deps": [ { "ImportPath": "github.com/coreos/etcd/client", - "Comment": "v2.2.0-80-g06180be", - "Rev": "06180be154083d0c15378e4703def03afac21bdc" + "Comment": "v2.3.0-alpha.0-430-g374b14e", + "Rev": "374b14e47189c249c069c9b3376cf5c36f286fa6" }, { "ImportPath": "github.com/coreos/etcd/pkg/pathutil", - "Comment": "v2.2.0-80-g06180be", - "Rev": "06180be154083d0c15378e4703def03afac21bdc" + "Comment": "v2.3.0-alpha.0-430-g374b14e", + "Rev": "374b14e47189c249c069c9b3376cf5c36f286fa6" }, { "ImportPath": "github.com/coreos/etcd/pkg/types", - "Comment": "v2.2.0-80-g06180be", - "Rev": "06180be154083d0c15378e4703def03afac21bdc" - }, - { - "ImportPath": "github.com/coreos/fleet/pkg/lease", - "Comment": "v0.10.1-99-g187dd79", - "Rev": "187dd799b8a53647064c53dc3df0e8e67b881da8" + "Comment": "v2.3.0-alpha.0-430-g374b14e", + "Rev": "374b14e47189c249c069c9b3376cf5c36f286fa6" }, { "ImportPath": "github.com/coreos/go-systemd/journal", @@ -43,6 +38,16 @@ "ImportPath": "github.com/davecgh/go-spew/spew", "Rev": "1aaf839fb07e099361e445273993ccd9adc21b07" }, + { + "ImportPath": "github.com/docker/libkv", + "Comment": "v0.1.0-10-ga7db351", + "Rev": "a7db3510533ae4be25daaf61c49c90b1ea3b339c" + }, + { + "ImportPath": "github.com/docker/swarm/leadership", + "Comment": "v1.1.0-rc2-10-gcc4eea8", + "Rev": "cc4eea83da48a83d3f6f757b3858c7dde3f5e666" + }, { "ImportPath": "github.com/gorilla/context", "Rev": "1c83b3eabd45b6d76072b66b746c20815fb2872d" @@ -51,6 +56,20 @@ "ImportPath": "github.com/gorilla/mux", "Rev": "ad4d7a5882b961e07e2626045eb995c022ac6664" }, + { + "ImportPath": "github.com/hashicorp/consul/api", + "Comment": "v0.6.3-21-g35adb39", + "Rev": "35adb391a27cf90fea06d3b676103bc5be3c144c" + }, + { + "ImportPath": "github.com/hashicorp/go-cleanhttp", + "Rev": "ce617e79981a8fff618bb643d155133a8f38db96" + }, + { + "ImportPath": "github.com/hashicorp/serf/coordinate", + "Comment": "v0.7.0-10-g64d10e9", + "Rev": "64d10e9428bd70dbcd831ad087573b66731c014b" + }, { "ImportPath": "github.com/inconshreveable/mousetrap", "Rev": "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75" @@ -70,11 +89,12 @@ }, { "ImportPath": "github.com/lib/pq", - "Rev": "7175accbed18058468c07811f76440d6e8d7cf19" + "Comment": "go1.0-cutoff-63-g11fc39a", + "Rev": "11fc39a580a008f1f39bb3d11d984fb34ed778d9" }, { "ImportPath": "github.com/satori/go.uuid", - "Rev": "46e1db27972f44c7722f23195ba6a8d2c2f3a0a3" + "Rev": "d41af8bb6a7704f00bc3b7cba9355ae6a5a80048" }, { "ImportPath": "github.com/sgotti/gexpect", @@ -94,11 +114,11 @@ }, { "ImportPath": "github.com/ugorji/go/codec", - "Rev": "5abd4e96a45c386928ed2ca2a7ef63e2533e18ec" + "Rev": "646ae4a518c1c3be0739df898118d9bccf993858" }, { "ImportPath": "golang.org/x/net/context", - "Rev": "1dfe7915deaf3f80b962c163b918868d8a6d8974" + "Rev": "5df5483e0518a11a6ef1e894c70236eb3f639557" }, { "ImportPath": "k8s.io/kubernetes/pkg/util/strategicpatch", diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/client/README.md b/Godeps/_workspace/src/github.com/coreos/etcd/client/README.md index 672b8c1..e9e4be4 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/client/README.md +++ b/Godeps/_workspace/src/github.com/coreos/etcd/client/README.md @@ -35,9 +35,25 @@ func main() { log.Fatal(err) } kapi := client.NewKeysAPI(c) - resp, err := kapi.Set(context.Background(), "foo", "bar", nil) + // set "/foo" key with "bar" value + log.Print("Setting '/foo' key with 'bar' value") + resp, err := kapi.Set(context.Background(), "/foo", "bar", nil) if err != nil { log.Fatal(err) + } else { + // print common key info + log.Printf("Set is done. Metadata is %q\n", resp) + } + // get "/foo" key's value + log.Print("Getting '/foo' key value") + resp, err = kapi.Get(context.Background(), "/foo", nil) + if err != nil { + log.Fatal(err) + } else { + // print common key info + log.Printf("Get is done. Metadata is %q\n", resp) + // print value + log.Printf("%q key has %q value\n", resp.Node.Key, resp.Node.Value) } } ``` @@ -61,7 +77,7 @@ If the response gets from the cluster is invalid, a plain string error will be r Here is the example code to handle client errors: ```go -cfg := client.Config{Endpoints: []string{"http://etcd1:2379,http://etcd2:2379,http://etcd3:2379"}} +cfg := client.Config{Endpoints: []string{"http://etcd1:2379","http://etcd2:2379","http://etcd3:2379"}} c, err := client.New(cfg) if err != nil { log.Fatal(err) diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/client/auth_role.go b/Godeps/_workspace/src/github.com/coreos/etcd/client/auth_role.go index 5c4cdfe..7718470 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/client/auth_role.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/client/auth_role.go @@ -115,14 +115,13 @@ func (r *httpAuthRoleAPI) ListRoles(ctx context.Context) ([]string, error) { if err != nil { return nil, err } - if err := assertStatusCode(resp.StatusCode, http.StatusOK); err != nil { + if err = assertStatusCode(resp.StatusCode, http.StatusOK); err != nil { return nil, err } var userList struct { Roles []string `json:"roles"` } - err = json.Unmarshal(body, &userList) - if err != nil { + if err = json.Unmarshal(body, &userList); err != nil { return nil, err } return userList.Roles, nil @@ -218,17 +217,16 @@ func (r *httpAuthRoleAPI) modRole(ctx context.Context, req *authRoleAPIAction) ( if err != nil { return nil, err } - if err := assertStatusCode(resp.StatusCode, http.StatusOK); err != nil { + if err = assertStatusCode(resp.StatusCode, http.StatusOK); err != nil { var sec authError - err := json.Unmarshal(body, &sec) + err = json.Unmarshal(body, &sec) if err != nil { return nil, err } return nil, sec } var role Role - err = json.Unmarshal(body, &role) - if err != nil { + if err = json.Unmarshal(body, &role); err != nil { return nil, err } return &role, nil diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/client/auth_user.go b/Godeps/_workspace/src/github.com/coreos/etcd/client/auth_user.go index 2c27699..490dd4b 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/client/auth_user.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/client/auth_user.go @@ -78,9 +78,9 @@ func (s *httpAuthAPI) enableDisable(ctx context.Context, req httpAction) error { if err != nil { return err } - if err := assertStatusCode(resp.StatusCode, http.StatusOK, http.StatusCreated); err != nil { + if err = assertStatusCode(resp.StatusCode, http.StatusOK, http.StatusCreated); err != nil { var sec authError - err := json.Unmarshal(body, &sec) + err = json.Unmarshal(body, &sec) if err != nil { return err } @@ -179,9 +179,9 @@ func (u *httpAuthUserAPI) ListUsers(ctx context.Context) ([]string, error) { if err != nil { return nil, err } - if err := assertStatusCode(resp.StatusCode, http.StatusOK); err != nil { + if err = assertStatusCode(resp.StatusCode, http.StatusOK); err != nil { var sec authError - err := json.Unmarshal(body, &sec) + err = json.Unmarshal(body, &sec) if err != nil { return nil, err } @@ -190,8 +190,7 @@ func (u *httpAuthUserAPI) ListUsers(ctx context.Context) ([]string, error) { var userList struct { Users []string `json:"users"` } - err = json.Unmarshal(body, &userList) - if err != nil { + if err = json.Unmarshal(body, &userList); err != nil { return nil, err } return userList.Users, nil @@ -221,9 +220,9 @@ func (u *httpAuthUserAPI) addRemoveUser(ctx context.Context, req *authUserAPIAct if err != nil { return err } - if err := assertStatusCode(resp.StatusCode, http.StatusOK, http.StatusCreated); err != nil { + if err = assertStatusCode(resp.StatusCode, http.StatusOK, http.StatusCreated); err != nil { var sec authError - err := json.Unmarshal(body, &sec) + err = json.Unmarshal(body, &sec) if err != nil { return err } @@ -280,17 +279,16 @@ func (u *httpAuthUserAPI) modUser(ctx context.Context, req *authUserAPIAction) ( if err != nil { return nil, err } - if err := assertStatusCode(resp.StatusCode, http.StatusOK); err != nil { + if err = assertStatusCode(resp.StatusCode, http.StatusOK); err != nil { var sec authError - err := json.Unmarshal(body, &sec) + err = json.Unmarshal(body, &sec) if err != nil { return nil, err } return nil, sec } var user User - err = json.Unmarshal(body, &user) - if err != nil { + if err = json.Unmarshal(body, &user); err != nil { return nil, err } return &user, nil diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/client/client.go b/Godeps/_workspace/src/github.com/coreos/etcd/client/client.go index 2af7f28..e87dac6 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/client/client.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/client/client.go @@ -34,6 +34,7 @@ var ( ErrNoEndpoints = errors.New("client: no endpoints available") ErrTooManyRedirects = errors.New("client: too many redirects") ErrClusterUnavailable = errors.New("client: etcd cluster is unavailable or misconfigured") + ErrNoLeaderEndpoint = errors.New("client: no leader endpoint available") errTooManyRedirectChecks = errors.New("client: too many redirect checks") ) @@ -48,6 +49,19 @@ var DefaultTransport CancelableTransport = &http.Transport{ TLSHandshakeTimeout: 10 * time.Second, } +type EndpointSelectionMode int + +const ( + // EndpointSelectionRandom is to pick an endpoint in a random manner. + EndpointSelectionRandom EndpointSelectionMode = iota + + // EndpointSelectionPrioritizeLeader is to prioritize leader for reducing needless + // forward between follower and leader. + // + // This mode should be used with Client.AutoSync(). + EndpointSelectionPrioritizeLeader +) + type Config struct { // Endpoints defines a set of URLs (schemes, hosts and ports only) // that can be used to communicate with a logical etcd cluster. For @@ -104,6 +118,9 @@ type Config struct { // // A HeaderTimeoutPerRequest of zero means no timeout. HeaderTimeoutPerRequest time.Duration + + // SelectionMode specifies a way of selecting destination endpoint. + SelectionMode EndpointSelectionMode } func (cfg *Config) transport() CancelableTransport { @@ -162,6 +179,11 @@ type Client interface { // this may differ from the initial Endpoints provided in the Config. Endpoints() []string + // SetEndpoints sets the set of API endpoints used by Client to resolve + // HTTP requests. If the given endpoints are not valid, an error will be + // returned + SetEndpoints(eps []string) error + httpClient } @@ -169,6 +191,7 @@ func New(cfg Config) (Client, error) { c := &httpClusterClient{ clientFactory: newHTTPClientFactory(cfg.transport(), cfg.checkRedirect(), cfg.HeaderTimeoutPerRequest), rand: rand.New(rand.NewSource(int64(time.Now().Nanosecond()))), + selectionMode: cfg.SelectionMode, } if cfg.Username != "" { c.credentials = &credentials{ @@ -176,7 +199,7 @@ func New(cfg Config) (Client, error) { password: cfg.Password, } } - if err := c.reset(cfg.Endpoints); err != nil { + if err := c.SetEndpoints(cfg.Endpoints); err != nil { return nil, err } return c, nil @@ -216,10 +239,21 @@ type httpClusterClient struct { pinned int credentials *credentials sync.RWMutex - rand *rand.Rand + rand *rand.Rand + selectionMode EndpointSelectionMode } -func (c *httpClusterClient) reset(eps []string) error { +func (c *httpClusterClient) getLeaderEndpoint() (string, error) { + mAPI := NewMembersAPI(c) + leader, err := mAPI.Leader(context.Background()) + if err != nil { + return "", err + } + + return leader.ClientURLs[0], nil // TODO: how to handle multiple client URLs? +} + +func (c *httpClusterClient) SetEndpoints(eps []string) error { if len(eps) == 0 { return ErrNoEndpoints } @@ -233,9 +267,28 @@ func (c *httpClusterClient) reset(eps []string) error { neps[i] = *u } - c.endpoints = shuffleEndpoints(c.rand, neps) - // TODO: pin old endpoint if possible, and rebalance when new endpoint appears - c.pinned = 0 + switch c.selectionMode { + case EndpointSelectionRandom: + c.endpoints = shuffleEndpoints(c.rand, neps) + c.pinned = 0 + case EndpointSelectionPrioritizeLeader: + c.endpoints = neps + lep, err := c.getLeaderEndpoint() + if err != nil { + return ErrNoLeaderEndpoint + } + + for i := range c.endpoints { + if c.endpoints[i].String() == lep { + c.pinned = i + break + } + } + // If endpoints doesn't have the lu, just keep c.pinned = 0. + // Forwarding between follower and leader would be required but it works. + default: + return errors.New(fmt.Sprintf("invalid endpoint selection mode: %d", c.selectionMode)) + } return nil } @@ -341,7 +394,7 @@ func (c *httpClusterClient) Sync(ctx context.Context) error { return nil } - return c.reset(eps) + return c.SetEndpoints(eps) } func (c *httpClusterClient) AutoSync(ctx context.Context, interval time.Duration) error { @@ -378,9 +431,12 @@ func (c *simpleHTTPClient) Do(ctx context.Context, act httpAction) (*http.Respon return nil, nil, err } - hctx, hcancel := context.WithCancel(ctx) + var hctx context.Context + var hcancel context.CancelFunc if c.headerTimeout > 0 { hctx, hcancel = context.WithTimeout(ctx, c.headerTimeout) + } else { + hctx, hcancel = context.WithCancel(ctx) } defer hcancel() diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/client/keys.generated.go b/Godeps/_workspace/src/github.com/coreos/etcd/client/keys.generated.go index 06cee19..74a304c 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/client/keys.generated.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/client/keys.generated.go @@ -11,14 +11,22 @@ import ( codec1978 "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/ugorji/go/codec" "reflect" "runtime" - "time" + time "time" ) const ( - codecSelferC_UTF81819 = 1 - codecSelferC_RAW1819 = 0 - codecSelverValueTypeArray1819 = 10 - codecSelverValueTypeMap1819 = 9 + // ----- content types ---- + codecSelferC_UTF81819 = 1 + codecSelferC_RAW1819 = 0 + // ----- value types used ---- + codecSelferValueTypeArray1819 = 10 + codecSelferValueTypeMap1819 = 9 + // ----- containerStateValues ---- + codecSelfer_containerMapKey1819 = 2 + codecSelfer_containerMapValue1819 = 3 + codecSelfer_containerMapEnd1819 = 4 + codecSelfer_containerArrayElem1819 = 6 + codecSelfer_containerArrayEnd1819 = 7 ) var ( @@ -29,10 +37,10 @@ var ( type codecSelfer1819 struct{} func init() { - if codec1978.GenVersion != 2 { + if codec1978.GenVersion != 5 { _, file, _, _ := runtime.Caller(0) err := fmt.Errorf("codecgen version mismatch: current: %v, need %v. Re-generate file: %v", - 2, codec1978.GenVersion, file) + 5, codec1978.GenVersion, file) panic(err) } if false { // reference the types, but skip this branch at build/run time @@ -48,88 +56,86 @@ func (x *Response) CodecEncodeSelf(e *codec1978.Encoder) { if x == nil { r.EncodeNil() } else { - yysep1 := !z.EncBinary() - yy2arr1 := z.EncBasicHandle().StructToArray - var yyfirst1 bool - var yyq1 [3]bool - _, _, _, _ = yysep1, yyfirst1, yyq1, yy2arr1 - const yyr1 bool = false - if yyr1 || yy2arr1 { - r.EncodeArrayStart(3) + yym1 := z.EncBinary() + _ = yym1 + if false { + } else if z.HasExtensions() && z.EncExt(x) { } else { - var yynn1 int = 3 - for _, b := range yyq1 { - if b { - yynn1++ + yysep2 := !z.EncBinary() + yy2arr2 := z.EncBasicHandle().StructToArray + var yyq2 [3]bool + _, _, _ = yysep2, yyq2, yy2arr2 + const yyr2 bool = false + var yynn2 int + if yyr2 || yy2arr2 { + r.EncodeArrayStart(3) + } else { + yynn2 = 3 + for _, b := range yyq2 { + if b { + yynn2++ + } + } + r.EncodeMapStart(yynn2) + yynn2 = 0 + } + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1819) + yym4 := z.EncBinary() + _ = yym4 + if false { + } else { + r.EncodeString(codecSelferC_UTF81819, string(x.Action)) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1819) + r.EncodeString(codecSelferC_UTF81819, string("action")) + z.EncSendContainerState(codecSelfer_containerMapValue1819) + yym5 := z.EncBinary() + _ = yym5 + if false { + } else { + r.EncodeString(codecSelferC_UTF81819, string(x.Action)) } } - r.EncodeMapStart(yynn1) - } - if yyr1 || yy2arr1 { - r.EncodeString(codecSelferC_UTF81819, string(x.Action)) - } else { - yyfirst1 = true - r.EncodeString(codecSelferC_UTF81819, string("action")) - if yysep1 { - r.EncodeMapKVSeparator() - } - r.EncodeString(codecSelferC_UTF81819, string(x.Action)) - } - if yyr1 || yy2arr1 { - if yysep1 { - r.EncodeArrayEntrySeparator() - } - if x.Node == nil { - r.EncodeNil() + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1819) + if x.Node == nil { + r.EncodeNil() + } else { + x.Node.CodecEncodeSelf(e) + } } else { - x.Node.CodecEncodeSelf(e) + z.EncSendContainerState(codecSelfer_containerMapKey1819) + r.EncodeString(codecSelferC_UTF81819, string("node")) + z.EncSendContainerState(codecSelfer_containerMapValue1819) + if x.Node == nil { + r.EncodeNil() + } else { + x.Node.CodecEncodeSelf(e) + } } - } else { - if yyfirst1 { - r.EncodeMapEntrySeparator() + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayElem1819) + if x.PrevNode == nil { + r.EncodeNil() + } else { + x.PrevNode.CodecEncodeSelf(e) + } } else { - yyfirst1 = true + z.EncSendContainerState(codecSelfer_containerMapKey1819) + r.EncodeString(codecSelferC_UTF81819, string("prevNode")) + z.EncSendContainerState(codecSelfer_containerMapValue1819) + if x.PrevNode == nil { + r.EncodeNil() + } else { + x.PrevNode.CodecEncodeSelf(e) + } } - r.EncodeString(codecSelferC_UTF81819, string("node")) - if yysep1 { - r.EncodeMapKVSeparator() - } - if x.Node == nil { - r.EncodeNil() + if yyr2 || yy2arr2 { + z.EncSendContainerState(codecSelfer_containerArrayEnd1819) } else { - x.Node.CodecEncodeSelf(e) - } - } - if yyr1 || yy2arr1 { - if yysep1 { - r.EncodeArrayEntrySeparator() - } - if x.PrevNode == nil { - r.EncodeNil() - } else { - x.PrevNode.CodecEncodeSelf(e) - } - } else { - if yyfirst1 { - r.EncodeMapEntrySeparator() - } else { - yyfirst1 = true - } - r.EncodeString(codecSelferC_UTF81819, string("prevNode")) - if yysep1 { - r.EncodeMapKVSeparator() - } - if x.PrevNode == nil { - r.EncodeNil() - } else { - x.PrevNode.CodecEncodeSelf(e) - } - } - if yysep1 { - if yyr1 || yy2arr1 { - r.EncodeArrayEnd() - } else { - r.EncodeMapEnd() + z.EncSendContainerState(codecSelfer_containerMapEnd1819) } } } @@ -139,22 +145,29 @@ func (x *Response) CodecDecodeSelf(d *codec1978.Decoder) { var h codecSelfer1819 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - if r.IsContainerType(codecSelverValueTypeMap1819) { - yyl5 := r.ReadMapStart() - if yyl5 == 0 { - r.ReadMapEnd() - } else { - x.codecDecodeSelfFromMap(yyl5, d) - } - } else if r.IsContainerType(codecSelverValueTypeArray1819) { - yyl5 := r.ReadArrayStart() - if yyl5 == 0 { - r.ReadArrayEnd() - } else { - x.codecDecodeSelfFromArray(yyl5, d) - } + yym8 := z.DecBinary() + _ = yym8 + if false { + } else if z.HasExtensions() && z.DecExt(x) { } else { - panic(codecSelferOnlyMapOrArrayEncodeToStructErr1819) + yyct9 := r.ContainerType() + if yyct9 == codecSelferValueTypeMap1819 { + yyl9 := r.ReadMapStart() + if yyl9 == 0 { + z.DecSendContainerState(codecSelfer_containerMapEnd1819) + } else { + x.codecDecodeSelfFromMap(yyl9, d) + } + } else if yyct9 == codecSelferValueTypeArray1819 { + yyl9 := r.ReadArrayStart() + if yyl9 == 0 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) + } else { + x.codecDecodeSelfFromArray(yyl9, d) + } + } else { + panic(codecSelferOnlyMapOrArrayEncodeToStructErr1819) + } } } @@ -162,28 +175,24 @@ func (x *Response) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { var h codecSelfer1819 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yys6Slc = z.DecScratchBuffer() // default slice to decode into - _ = yys6Slc - var yyhl6 bool = l >= 0 - for yyj6 := 0; ; yyj6++ { - if yyhl6 { - if yyj6 >= l { + var yys10Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys10Slc + var yyhl10 bool = l >= 0 + for yyj10 := 0; ; yyj10++ { + if yyhl10 { + if yyj10 >= l { break } } else { if r.CheckBreak() { break } - if yyj6 > 0 { - r.ReadMapEntrySeparator() - } } - yys6Slc = r.DecodeBytes(yys6Slc, true, true) - yys6 := string(yys6Slc) - if !yyhl6 { - r.ReadMapKVSeparator() - } - switch yys6 { + z.DecSendContainerState(codecSelfer_containerMapKey1819) + yys10Slc = r.DecodeBytes(yys10Slc, true, true) + yys10 := string(yys10Slc) + z.DecSendContainerState(codecSelfer_containerMapValue1819) + switch yys10 { case "action": if r.TryDecodeAsNil() { x.Action = "" @@ -213,47 +222,46 @@ func (x *Response) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { x.PrevNode.CodecDecodeSelf(d) } default: - z.DecStructFieldNotFound(-1, yys6) - } // end switch yys6 - } // end for yyj6 - if !yyhl6 { - r.ReadMapEnd() - } + z.DecStructFieldNotFound(-1, yys10) + } // end switch yys10 + } // end for yyj10 + z.DecSendContainerState(codecSelfer_containerMapEnd1819) } func (x *Response) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { var h codecSelfer1819 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj10 int - var yyb10 bool - var yyhl10 bool = l >= 0 - yyj10++ - if yyhl10 { - yyb10 = yyj10 > l + var yyj14 int + var yyb14 bool + var yyhl14 bool = l >= 0 + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l } else { - yyb10 = r.CheckBreak() + yyb14 = r.CheckBreak() } - if yyb10 { - r.ReadArrayEnd() + if yyb14 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } + z.DecSendContainerState(codecSelfer_containerArrayElem1819) if r.TryDecodeAsNil() { x.Action = "" } else { x.Action = string(r.DecodeString()) } - yyj10++ - if yyhl10 { - yyb10 = yyj10 > l + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l } else { - yyb10 = r.CheckBreak() + yyb14 = r.CheckBreak() } - if yyb10 { - r.ReadArrayEnd() + if yyb14 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } - r.ReadArrayEntrySeparator() + z.DecSendContainerState(codecSelfer_containerArrayElem1819) if r.TryDecodeAsNil() { if x.Node != nil { x.Node = nil @@ -264,17 +272,17 @@ func (x *Response) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { } x.Node.CodecDecodeSelf(d) } - yyj10++ - if yyhl10 { - yyb10 = yyj10 > l + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l } else { - yyb10 = r.CheckBreak() + yyb14 = r.CheckBreak() } - if yyb10 { - r.ReadArrayEnd() + if yyb14 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } - r.ReadArrayEntrySeparator() + z.DecSendContainerState(codecSelfer_containerArrayElem1819) if r.TryDecodeAsNil() { if x.PrevNode != nil { x.PrevNode = nil @@ -286,21 +294,19 @@ func (x *Response) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { x.PrevNode.CodecDecodeSelf(d) } for { - yyj10++ - if yyhl10 { - yyb10 = yyj10 > l + yyj14++ + if yyhl14 { + yyb14 = yyj14 > l } else { - yyb10 = r.CheckBreak() + yyb14 = r.CheckBreak() } - if yyb10 { + if yyb14 { break } - if yyj10 > 1 { - r.ReadArrayEntrySeparator() - } - z.DecStructFieldNotFound(yyj10-1, "") + z.DecSendContainerState(codecSelfer_containerArrayElem1819) + z.DecStructFieldNotFound(yyj14-1, "") } - r.ReadArrayEnd() + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) } func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) { @@ -310,194 +316,226 @@ func (x *Node) CodecEncodeSelf(e *codec1978.Encoder) { if x == nil { r.EncodeNil() } else { - yysep14 := !z.EncBinary() - yy2arr14 := z.EncBasicHandle().StructToArray - var yyfirst14 bool - var yyq14 [8]bool - _, _, _, _ = yysep14, yyfirst14, yyq14, yy2arr14 - const yyr14 bool = false - yyq14[1] = x.Dir != false - yyq14[6] = x.Expiration != nil - yyq14[7] = x.TTL != 0 - if yyr14 || yy2arr14 { - r.EncodeArrayStart(8) + yym18 := z.EncBinary() + _ = yym18 + if false { + } else if z.HasExtensions() && z.EncExt(x) { } else { - var yynn14 int = 5 - for _, b := range yyq14 { - if b { - yynn14++ - } - } - r.EncodeMapStart(yynn14) - } - if yyr14 || yy2arr14 { - r.EncodeString(codecSelferC_UTF81819, string(x.Key)) - } else { - yyfirst14 = true - r.EncodeString(codecSelferC_UTF81819, string("key")) - if yysep14 { - r.EncodeMapKVSeparator() - } - r.EncodeString(codecSelferC_UTF81819, string(x.Key)) - } - if yyr14 || yy2arr14 { - if yysep14 { - r.EncodeArrayEntrySeparator() - } - if yyq14[1] { - r.EncodeBool(bool(x.Dir)) + yysep19 := !z.EncBinary() + yy2arr19 := z.EncBasicHandle().StructToArray + var yyq19 [8]bool + _, _, _ = yysep19, yyq19, yy2arr19 + const yyr19 bool = false + yyq19[1] = x.Dir != false + yyq19[6] = x.Expiration != nil + yyq19[7] = x.TTL != 0 + var yynn19 int + if yyr19 || yy2arr19 { + r.EncodeArrayStart(8) } else { - r.EncodeBool(false) + yynn19 = 5 + for _, b := range yyq19 { + if b { + yynn19++ + } + } + r.EncodeMapStart(yynn19) + yynn19 = 0 } - } else { - if yyq14[1] { - if yyfirst14 { - r.EncodeMapEntrySeparator() + if yyr19 || yy2arr19 { + z.EncSendContainerState(codecSelfer_containerArrayElem1819) + yym21 := z.EncBinary() + _ = yym21 + if false { } else { - yyfirst14 = true + r.EncodeString(codecSelferC_UTF81819, string(x.Key)) } - r.EncodeString(codecSelferC_UTF81819, string("dir")) - if yysep14 { - r.EncodeMapKVSeparator() + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1819) + r.EncodeString(codecSelferC_UTF81819, string("key")) + z.EncSendContainerState(codecSelfer_containerMapValue1819) + yym22 := z.EncBinary() + _ = yym22 + if false { + } else { + r.EncodeString(codecSelferC_UTF81819, string(x.Key)) } - r.EncodeBool(bool(x.Dir)) } - } - if yyr14 || yy2arr14 { - if yysep14 { - r.EncodeArrayEntrySeparator() - } - r.EncodeString(codecSelferC_UTF81819, string(x.Value)) - } else { - if yyfirst14 { - r.EncodeMapEntrySeparator() + if yyr19 || yy2arr19 { + z.EncSendContainerState(codecSelfer_containerArrayElem1819) + if yyq19[1] { + yym24 := z.EncBinary() + _ = yym24 + if false { + } else { + r.EncodeBool(bool(x.Dir)) + } + } else { + r.EncodeBool(false) + } } else { - yyfirst14 = true + if yyq19[1] { + z.EncSendContainerState(codecSelfer_containerMapKey1819) + r.EncodeString(codecSelferC_UTF81819, string("dir")) + z.EncSendContainerState(codecSelfer_containerMapValue1819) + yym25 := z.EncBinary() + _ = yym25 + if false { + } else { + r.EncodeBool(bool(x.Dir)) + } + } } - r.EncodeString(codecSelferC_UTF81819, string("value")) - if yysep14 { - r.EncodeMapKVSeparator() - } - r.EncodeString(codecSelferC_UTF81819, string(x.Value)) - } - if yyr14 || yy2arr14 { - if yysep14 { - r.EncodeArrayEntrySeparator() - } - if x.Nodes == nil { - r.EncodeNil() + if yyr19 || yy2arr19 { + z.EncSendContainerState(codecSelfer_containerArrayElem1819) + yym27 := z.EncBinary() + _ = yym27 + if false { + } else { + r.EncodeString(codecSelferC_UTF81819, string(x.Value)) + } } else { - x.Nodes.CodecEncodeSelf(e) + z.EncSendContainerState(codecSelfer_containerMapKey1819) + r.EncodeString(codecSelferC_UTF81819, string("value")) + z.EncSendContainerState(codecSelfer_containerMapValue1819) + yym28 := z.EncBinary() + _ = yym28 + if false { + } else { + r.EncodeString(codecSelferC_UTF81819, string(x.Value)) + } } - } else { - if yyfirst14 { - r.EncodeMapEntrySeparator() - } else { - yyfirst14 = true - } - r.EncodeString(codecSelferC_UTF81819, string("nodes")) - if yysep14 { - r.EncodeMapKVSeparator() - } - if x.Nodes == nil { - r.EncodeNil() - } else { - x.Nodes.CodecEncodeSelf(e) - } - } - if yyr14 || yy2arr14 { - if yysep14 { - r.EncodeArrayEntrySeparator() - } - r.EncodeUint(uint64(x.CreatedIndex)) - } else { - if yyfirst14 { - r.EncodeMapEntrySeparator() - } else { - yyfirst14 = true - } - r.EncodeString(codecSelferC_UTF81819, string("createdIndex")) - if yysep14 { - r.EncodeMapKVSeparator() - } - r.EncodeUint(uint64(x.CreatedIndex)) - } - if yyr14 || yy2arr14 { - if yysep14 { - r.EncodeArrayEntrySeparator() - } - r.EncodeUint(uint64(x.ModifiedIndex)) - } else { - if yyfirst14 { - r.EncodeMapEntrySeparator() - } else { - yyfirst14 = true - } - r.EncodeString(codecSelferC_UTF81819, string("modifiedIndex")) - if yysep14 { - r.EncodeMapKVSeparator() - } - r.EncodeUint(uint64(x.ModifiedIndex)) - } - if yyr14 || yy2arr14 { - if yysep14 { - r.EncodeArrayEntrySeparator() - } - if yyq14[6] { - if x.Expiration == nil { + if yyr19 || yy2arr19 { + z.EncSendContainerState(codecSelfer_containerArrayElem1819) + if x.Nodes == nil { r.EncodeNil() } else { - z.EncFallback(x.Expiration) + x.Nodes.CodecEncodeSelf(e) } } else { - r.EncodeNil() - } - } else { - if yyq14[6] { - if yyfirst14 { - r.EncodeMapEntrySeparator() - } else { - yyfirst14 = true - } - r.EncodeString(codecSelferC_UTF81819, string("expiration")) - if yysep14 { - r.EncodeMapKVSeparator() - } - if x.Expiration == nil { + z.EncSendContainerState(codecSelfer_containerMapKey1819) + r.EncodeString(codecSelferC_UTF81819, string("nodes")) + z.EncSendContainerState(codecSelfer_containerMapValue1819) + if x.Nodes == nil { r.EncodeNil() } else { - z.EncFallback(x.Expiration) + x.Nodes.CodecEncodeSelf(e) } } - } - if yyr14 || yy2arr14 { - if yysep14 { - r.EncodeArrayEntrySeparator() - } - if yyq14[7] { - r.EncodeInt(int64(x.TTL)) - } else { - r.EncodeInt(0) - } - } else { - if yyq14[7] { - if yyfirst14 { - r.EncodeMapEntrySeparator() + if yyr19 || yy2arr19 { + z.EncSendContainerState(codecSelfer_containerArrayElem1819) + yym31 := z.EncBinary() + _ = yym31 + if false { } else { - yyfirst14 = true + r.EncodeUint(uint64(x.CreatedIndex)) } - r.EncodeString(codecSelferC_UTF81819, string("ttl")) - if yysep14 { - r.EncodeMapKVSeparator() - } - r.EncodeInt(int64(x.TTL)) - } - } - if yysep14 { - if yyr14 || yy2arr14 { - r.EncodeArrayEnd() } else { - r.EncodeMapEnd() + z.EncSendContainerState(codecSelfer_containerMapKey1819) + r.EncodeString(codecSelferC_UTF81819, string("createdIndex")) + z.EncSendContainerState(codecSelfer_containerMapValue1819) + yym32 := z.EncBinary() + _ = yym32 + if false { + } else { + r.EncodeUint(uint64(x.CreatedIndex)) + } + } + if yyr19 || yy2arr19 { + z.EncSendContainerState(codecSelfer_containerArrayElem1819) + yym34 := z.EncBinary() + _ = yym34 + if false { + } else { + r.EncodeUint(uint64(x.ModifiedIndex)) + } + } else { + z.EncSendContainerState(codecSelfer_containerMapKey1819) + r.EncodeString(codecSelferC_UTF81819, string("modifiedIndex")) + z.EncSendContainerState(codecSelfer_containerMapValue1819) + yym35 := z.EncBinary() + _ = yym35 + if false { + } else { + r.EncodeUint(uint64(x.ModifiedIndex)) + } + } + if yyr19 || yy2arr19 { + z.EncSendContainerState(codecSelfer_containerArrayElem1819) + if yyq19[6] { + if x.Expiration == nil { + r.EncodeNil() + } else { + yym37 := z.EncBinary() + _ = yym37 + if false { + } else if yym38 := z.TimeRtidIfBinc(); yym38 != 0 { + r.EncodeBuiltin(yym38, x.Expiration) + } else if z.HasExtensions() && z.EncExt(x.Expiration) { + } else if yym37 { + z.EncBinaryMarshal(x.Expiration) + } else if !yym37 && z.IsJSONHandle() { + z.EncJSONMarshal(x.Expiration) + } else { + z.EncFallback(x.Expiration) + } + } + } else { + r.EncodeNil() + } + } else { + if yyq19[6] { + z.EncSendContainerState(codecSelfer_containerMapKey1819) + r.EncodeString(codecSelferC_UTF81819, string("expiration")) + z.EncSendContainerState(codecSelfer_containerMapValue1819) + if x.Expiration == nil { + r.EncodeNil() + } else { + yym39 := z.EncBinary() + _ = yym39 + if false { + } else if yym40 := z.TimeRtidIfBinc(); yym40 != 0 { + r.EncodeBuiltin(yym40, x.Expiration) + } else if z.HasExtensions() && z.EncExt(x.Expiration) { + } else if yym39 { + z.EncBinaryMarshal(x.Expiration) + } else if !yym39 && z.IsJSONHandle() { + z.EncJSONMarshal(x.Expiration) + } else { + z.EncFallback(x.Expiration) + } + } + } + } + if yyr19 || yy2arr19 { + z.EncSendContainerState(codecSelfer_containerArrayElem1819) + if yyq19[7] { + yym42 := z.EncBinary() + _ = yym42 + if false { + } else { + r.EncodeInt(int64(x.TTL)) + } + } else { + r.EncodeInt(0) + } + } else { + if yyq19[7] { + z.EncSendContainerState(codecSelfer_containerMapKey1819) + r.EncodeString(codecSelferC_UTF81819, string("ttl")) + z.EncSendContainerState(codecSelfer_containerMapValue1819) + yym43 := z.EncBinary() + _ = yym43 + if false { + } else { + r.EncodeInt(int64(x.TTL)) + } + } + } + if yyr19 || yy2arr19 { + z.EncSendContainerState(codecSelfer_containerArrayEnd1819) + } else { + z.EncSendContainerState(codecSelfer_containerMapEnd1819) } } } @@ -507,22 +545,29 @@ func (x *Node) CodecDecodeSelf(d *codec1978.Decoder) { var h codecSelfer1819 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - if r.IsContainerType(codecSelverValueTypeMap1819) { - yyl23 := r.ReadMapStart() - if yyl23 == 0 { - r.ReadMapEnd() - } else { - x.codecDecodeSelfFromMap(yyl23, d) - } - } else if r.IsContainerType(codecSelverValueTypeArray1819) { - yyl23 := r.ReadArrayStart() - if yyl23 == 0 { - r.ReadArrayEnd() - } else { - x.codecDecodeSelfFromArray(yyl23, d) - } + yym44 := z.DecBinary() + _ = yym44 + if false { + } else if z.HasExtensions() && z.DecExt(x) { } else { - panic(codecSelferOnlyMapOrArrayEncodeToStructErr1819) + yyct45 := r.ContainerType() + if yyct45 == codecSelferValueTypeMap1819 { + yyl45 := r.ReadMapStart() + if yyl45 == 0 { + z.DecSendContainerState(codecSelfer_containerMapEnd1819) + } else { + x.codecDecodeSelfFromMap(yyl45, d) + } + } else if yyct45 == codecSelferValueTypeArray1819 { + yyl45 := r.ReadArrayStart() + if yyl45 == 0 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) + } else { + x.codecDecodeSelfFromArray(yyl45, d) + } + } else { + panic(codecSelferOnlyMapOrArrayEncodeToStructErr1819) + } } } @@ -530,28 +575,24 @@ func (x *Node) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { var h codecSelfer1819 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yys24Slc = z.DecScratchBuffer() // default slice to decode into - _ = yys24Slc - var yyhl24 bool = l >= 0 - for yyj24 := 0; ; yyj24++ { - if yyhl24 { - if yyj24 >= l { + var yys46Slc = z.DecScratchBuffer() // default slice to decode into + _ = yys46Slc + var yyhl46 bool = l >= 0 + for yyj46 := 0; ; yyj46++ { + if yyhl46 { + if yyj46 >= l { break } } else { if r.CheckBreak() { break } - if yyj24 > 0 { - r.ReadMapEntrySeparator() - } } - yys24Slc = r.DecodeBytes(yys24Slc, true, true) - yys24 := string(yys24Slc) - if !yyhl24 { - r.ReadMapKVSeparator() - } - switch yys24 { + z.DecSendContainerState(codecSelfer_containerMapKey1819) + yys46Slc = r.DecodeBytes(yys46Slc, true, true) + yys46 := string(yys46Slc) + z.DecSendContainerState(codecSelfer_containerMapValue1819) + switch yys46 { case "key": if r.TryDecodeAsNil() { x.Key = "" @@ -574,8 +615,8 @@ func (x *Node) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { if r.TryDecodeAsNil() { x.Nodes = nil } else { - yyv28 := &x.Nodes - yyv28.CodecDecodeSelf(d) + yyv50 := &x.Nodes + yyv50.CodecDecodeSelf(d) } case "createdIndex": if r.TryDecodeAsNil() { @@ -598,7 +639,19 @@ func (x *Node) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { if x.Expiration == nil { x.Expiration = new(time.Time) } - z.DecFallback(x.Expiration, false) + yym54 := z.DecBinary() + _ = yym54 + if false { + } else if yym55 := z.TimeRtidIfBinc(); yym55 != 0 { + r.DecodeBuiltin(yym55, x.Expiration) + } else if z.HasExtensions() && z.DecExt(x.Expiration) { + } else if yym54 { + z.DecBinaryUnmarshal(x.Expiration) + } else if !yym54 && z.IsJSONHandle() { + z.DecJSONUnmarshal(x.Expiration) + } else { + z.DecFallback(x.Expiration, false) + } } case "ttl": if r.TryDecodeAsNil() { @@ -607,128 +660,127 @@ func (x *Node) codecDecodeSelfFromMap(l int, d *codec1978.Decoder) { x.TTL = int64(r.DecodeInt(64)) } default: - z.DecStructFieldNotFound(-1, yys24) - } // end switch yys24 - } // end for yyj24 - if !yyhl24 { - r.ReadMapEnd() - } + z.DecStructFieldNotFound(-1, yys46) + } // end switch yys46 + } // end for yyj46 + z.DecSendContainerState(codecSelfer_containerMapEnd1819) } func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { var h codecSelfer1819 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - var yyj33 int - var yyb33 bool - var yyhl33 bool = l >= 0 - yyj33++ - if yyhl33 { - yyb33 = yyj33 > l + var yyj57 int + var yyb57 bool + var yyhl57 bool = l >= 0 + yyj57++ + if yyhl57 { + yyb57 = yyj57 > l } else { - yyb33 = r.CheckBreak() + yyb57 = r.CheckBreak() } - if yyb33 { - r.ReadArrayEnd() + if yyb57 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } + z.DecSendContainerState(codecSelfer_containerArrayElem1819) if r.TryDecodeAsNil() { x.Key = "" } else { x.Key = string(r.DecodeString()) } - yyj33++ - if yyhl33 { - yyb33 = yyj33 > l + yyj57++ + if yyhl57 { + yyb57 = yyj57 > l } else { - yyb33 = r.CheckBreak() + yyb57 = r.CheckBreak() } - if yyb33 { - r.ReadArrayEnd() + if yyb57 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } - r.ReadArrayEntrySeparator() + z.DecSendContainerState(codecSelfer_containerArrayElem1819) if r.TryDecodeAsNil() { x.Dir = false } else { x.Dir = bool(r.DecodeBool()) } - yyj33++ - if yyhl33 { - yyb33 = yyj33 > l + yyj57++ + if yyhl57 { + yyb57 = yyj57 > l } else { - yyb33 = r.CheckBreak() + yyb57 = r.CheckBreak() } - if yyb33 { - r.ReadArrayEnd() + if yyb57 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } - r.ReadArrayEntrySeparator() + z.DecSendContainerState(codecSelfer_containerArrayElem1819) if r.TryDecodeAsNil() { x.Value = "" } else { x.Value = string(r.DecodeString()) } - yyj33++ - if yyhl33 { - yyb33 = yyj33 > l + yyj57++ + if yyhl57 { + yyb57 = yyj57 > l } else { - yyb33 = r.CheckBreak() + yyb57 = r.CheckBreak() } - if yyb33 { - r.ReadArrayEnd() + if yyb57 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } - r.ReadArrayEntrySeparator() + z.DecSendContainerState(codecSelfer_containerArrayElem1819) if r.TryDecodeAsNil() { x.Nodes = nil } else { - yyv37 := &x.Nodes - yyv37.CodecDecodeSelf(d) + yyv61 := &x.Nodes + yyv61.CodecDecodeSelf(d) } - yyj33++ - if yyhl33 { - yyb33 = yyj33 > l + yyj57++ + if yyhl57 { + yyb57 = yyj57 > l } else { - yyb33 = r.CheckBreak() + yyb57 = r.CheckBreak() } - if yyb33 { - r.ReadArrayEnd() + if yyb57 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } - r.ReadArrayEntrySeparator() + z.DecSendContainerState(codecSelfer_containerArrayElem1819) if r.TryDecodeAsNil() { x.CreatedIndex = 0 } else { x.CreatedIndex = uint64(r.DecodeUint(64)) } - yyj33++ - if yyhl33 { - yyb33 = yyj33 > l + yyj57++ + if yyhl57 { + yyb57 = yyj57 > l } else { - yyb33 = r.CheckBreak() + yyb57 = r.CheckBreak() } - if yyb33 { - r.ReadArrayEnd() + if yyb57 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } - r.ReadArrayEntrySeparator() + z.DecSendContainerState(codecSelfer_containerArrayElem1819) if r.TryDecodeAsNil() { x.ModifiedIndex = 0 } else { x.ModifiedIndex = uint64(r.DecodeUint(64)) } - yyj33++ - if yyhl33 { - yyb33 = yyj33 > l + yyj57++ + if yyhl57 { + yyb57 = yyj57 > l } else { - yyb33 = r.CheckBreak() + yyb57 = r.CheckBreak() } - if yyb33 { - r.ReadArrayEnd() + if yyb57 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } - r.ReadArrayEntrySeparator() + z.DecSendContainerState(codecSelfer_containerArrayElem1819) if r.TryDecodeAsNil() { if x.Expiration != nil { x.Expiration = nil @@ -737,40 +789,50 @@ func (x *Node) codecDecodeSelfFromArray(l int, d *codec1978.Decoder) { if x.Expiration == nil { x.Expiration = new(time.Time) } - z.DecFallback(x.Expiration, false) + yym65 := z.DecBinary() + _ = yym65 + if false { + } else if yym66 := z.TimeRtidIfBinc(); yym66 != 0 { + r.DecodeBuiltin(yym66, x.Expiration) + } else if z.HasExtensions() && z.DecExt(x.Expiration) { + } else if yym65 { + z.DecBinaryUnmarshal(x.Expiration) + } else if !yym65 && z.IsJSONHandle() { + z.DecJSONUnmarshal(x.Expiration) + } else { + z.DecFallback(x.Expiration, false) + } } - yyj33++ - if yyhl33 { - yyb33 = yyj33 > l + yyj57++ + if yyhl57 { + yyb57 = yyj57 > l } else { - yyb33 = r.CheckBreak() + yyb57 = r.CheckBreak() } - if yyb33 { - r.ReadArrayEnd() + if yyb57 { + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) return } - r.ReadArrayEntrySeparator() + z.DecSendContainerState(codecSelfer_containerArrayElem1819) if r.TryDecodeAsNil() { x.TTL = 0 } else { x.TTL = int64(r.DecodeInt(64)) } for { - yyj33++ - if yyhl33 { - yyb33 = yyj33 > l + yyj57++ + if yyhl57 { + yyb57 = yyj57 > l } else { - yyb33 = r.CheckBreak() + yyb57 = r.CheckBreak() } - if yyb33 { + if yyb57 { break } - if yyj33 > 1 { - r.ReadArrayEntrySeparator() - } - z.DecStructFieldNotFound(yyj33-1, "") + z.DecSendContainerState(codecSelfer_containerArrayElem1819) + z.DecStructFieldNotFound(yyj57-1, "") } - r.ReadArrayEnd() + z.DecSendContainerState(codecSelfer_containerArrayEnd1819) } func (x Nodes) CodecEncodeSelf(e *codec1978.Encoder) { @@ -780,7 +842,13 @@ func (x Nodes) CodecEncodeSelf(e *codec1978.Encoder) { if x == nil { r.EncodeNil() } else { - h.encNodes((Nodes)(x), e) + yym68 := z.EncBinary() + _ = yym68 + if false { + } else if z.HasExtensions() && z.EncExt(x) { + } else { + h.encNodes((Nodes)(x), e) + } } } @@ -788,7 +856,13 @@ func (x *Nodes) CodecDecodeSelf(d *codec1978.Decoder) { var h codecSelfer1819 z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - h.decNodes((*Nodes)(x), d) + yym69 := z.DecBinary() + _ = yym69 + if false { + } else if z.HasExtensions() && z.DecExt(x) { + } else { + h.decNodes((*Nodes)(x), d) + } } func (x codecSelfer1819) encNodes(v Nodes, e *codec1978.Encoder) { @@ -796,28 +870,15 @@ func (x codecSelfer1819) encNodes(v Nodes, e *codec1978.Encoder) { z, r := codec1978.GenHelperEncoder(e) _, _, _ = h, z, r r.EncodeArrayStart(len(v)) - yys42 := !z.EncBinary() - if yys42 { - for yyi42, yyv42 := range v { - if yyi42 > 0 { - r.EncodeArrayEntrySeparator() - } - if yyv42 == nil { - r.EncodeNil() - } else { - yyv42.CodecEncodeSelf(e) - } - } - r.EncodeArrayEnd() - } else { - for _, yyv42 := range v { - if yyv42 == nil { - r.EncodeNil() - } else { - yyv42.CodecEncodeSelf(e) - } + for _, yyv70 := range v { + z.EncSendContainerState(codecSelfer_containerArrayElem1819) + if yyv70 == nil { + r.EncodeNil() + } else { + yyv70.CodecEncodeSelf(e) } } + z.EncSendContainerState(codecSelfer_containerArrayEnd1819) } func (x codecSelfer1819) decNodes(v *Nodes, d *codec1978.Decoder) { @@ -825,74 +886,98 @@ func (x codecSelfer1819) decNodes(v *Nodes, d *codec1978.Decoder) { z, r := codec1978.GenHelperDecoder(d) _, _, _ = h, z, r - yyv43 := *v - yyh43, yyl43 := z.DecSliceHelperStart() - - var yyc43 bool - _ = yyc43 - - if yyv43 == nil { - if yyl43 <= 0 { - yyv43 = make(Nodes, 0) - } else { - yyv43 = make(Nodes, yyl43) + yyv71 := *v + yyh71, yyl71 := z.DecSliceHelperStart() + var yyc71 bool + if yyl71 == 0 { + if yyv71 == nil { + yyv71 = []*Node{} + yyc71 = true + } else if len(yyv71) != 0 { + yyv71 = yyv71[:0] + yyc71 = true } - yyc43 = true - } + } else if yyl71 > 0 { + var yyrr71, yyrl71 int + var yyrt71 bool + if yyl71 > cap(yyv71) { - if yyl43 == 0 { - if len(yyv43) != 0 { - yyv43 = yyv43[:0] - yyc43 = true - } - } else if yyl43 > 0 { - - yyn43 := yyl43 - if yyl43 > cap(yyv43) { - yyv43 = make([]*Node, yyl43, yyl43) - yyc43 = true - - } else if yyl43 != len(yyv43) { - yyv43 = yyv43[:yyl43] - yyc43 = true - } - yyj43 := 0 - for ; yyj43 < yyn43; yyj43++ { - if r.TryDecodeAsNil() { - if yyv43[yyj43] != nil { - *yyv43[yyj43] = Node{} + yyrg71 := len(yyv71) > 0 + yyv271 := yyv71 + yyrl71, yyrt71 = z.DecInferLen(yyl71, z.DecBasicHandle().MaxInitLen, 8) + if yyrt71 { + if yyrl71 <= cap(yyv71) { + yyv71 = yyv71[:yyrl71] + } else { + yyv71 = make([]*Node, yyrl71) } } else { - if yyv43[yyj43] == nil { - yyv43[yyj43] = new(Node) + yyv71 = make([]*Node, yyrl71) + } + yyc71 = true + yyrr71 = len(yyv71) + if yyrg71 { + copy(yyv71, yyv271) + } + } else if yyl71 != len(yyv71) { + yyv71 = yyv71[:yyl71] + yyc71 = true + } + yyj71 := 0 + for ; yyj71 < yyrr71; yyj71++ { + yyh71.ElemContainerState(yyj71) + if r.TryDecodeAsNil() { + if yyv71[yyj71] != nil { + *yyv71[yyj71] = Node{} } - yyw44 := yyv43[yyj43] - yyw44.CodecDecodeSelf(d) + } else { + if yyv71[yyj71] == nil { + yyv71[yyj71] = new(Node) + } + yyw72 := yyv71[yyj71] + yyw72.CodecDecodeSelf(d) } } + if yyrt71 { + for ; yyj71 < yyl71; yyj71++ { + yyv71 = append(yyv71, nil) + yyh71.ElemContainerState(yyj71) + if r.TryDecodeAsNil() { + if yyv71[yyj71] != nil { + *yyv71[yyj71] = Node{} + } + } else { + if yyv71[yyj71] == nil { + yyv71[yyj71] = new(Node) + } + yyw73 := yyv71[yyj71] + yyw73.CodecDecodeSelf(d) + } + + } + } } else { - for yyj43 := 0; !r.CheckBreak(); yyj43++ { - if yyj43 >= len(yyv43) { - yyv43 = append(yyv43, nil) // var yyz43 *Node - yyc43 = true - } - if yyj43 > 0 { - yyh43.Sep(yyj43) - } + yyj71 := 0 + for ; !r.CheckBreak(); yyj71++ { - if yyj43 < len(yyv43) { + if yyj71 >= len(yyv71) { + yyv71 = append(yyv71, nil) // var yyz71 *Node + yyc71 = true + } + yyh71.ElemContainerState(yyj71) + if yyj71 < len(yyv71) { if r.TryDecodeAsNil() { - if yyv43[yyj43] != nil { - *yyv43[yyj43] = Node{} + if yyv71[yyj71] != nil { + *yyv71[yyj71] = Node{} } } else { - if yyv43[yyj43] == nil { - yyv43[yyj43] = new(Node) + if yyv71[yyj71] == nil { + yyv71[yyj71] = new(Node) } - yyw45 := yyv43[yyj43] - yyw45.CodecDecodeSelf(d) + yyw74 := yyv71[yyj71] + yyw74.CodecDecodeSelf(d) } } else { @@ -900,10 +985,16 @@ func (x codecSelfer1819) decNodes(v *Nodes, d *codec1978.Decoder) { } } - yyh43.End() + if yyj71 < len(yyv71) { + yyv71 = yyv71[:yyj71] + yyc71 = true + } else if yyj71 == 0 && yyv71 == nil { + yyv71 = []*Node{} + yyc71 = true + } } - if yyc43 { - *v = yyv43 + yyh71.End() + if yyc71 { + *v = yyv71 } - } diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/client/keys.go b/Godeps/_workspace/src/github.com/coreos/etcd/client/keys.go index c26bc7b..2a42390 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/client/keys.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/client/keys.go @@ -14,7 +14,7 @@ package client -//go:generate codecgen -r "Node|Response|Nodes" -o keys.generated.go keys.go +//go:generate codecgen -d 1819 -r "Node|Response|Nodes" -o keys.generated.go keys.go import ( "encoding/json" diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/client/members.go b/Godeps/_workspace/src/github.com/coreos/etcd/client/members.go index 576e2bc..e8297d2 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/client/members.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/client/members.go @@ -29,6 +29,7 @@ import ( var ( defaultV2MembersPrefix = "/v2/members" + defaultLeaderSuffix = "/leader" ) type Member struct { @@ -105,6 +106,9 @@ type MembersAPI interface { // Update instructs etcd to update an existing Member in the cluster. Update(ctx context.Context, mID string, peerURLs []string) error + + // Leader gets current leader of the cluster + Leader(ctx context.Context) (*Member, error) } type httpMembersAPI struct { @@ -199,6 +203,25 @@ func (m *httpMembersAPI) Remove(ctx context.Context, memberID string) error { return assertStatusCode(resp.StatusCode, http.StatusNoContent, http.StatusGone) } +func (m *httpMembersAPI) Leader(ctx context.Context) (*Member, error) { + req := &membersAPIActionLeader{} + resp, body, err := m.client.Do(ctx, req) + if err != nil { + return nil, err + } + + if err := assertStatusCode(resp.StatusCode, http.StatusOK); err != nil { + return nil, err + } + + var leader Member + if err := json.Unmarshal(body, &leader); err != nil { + return nil, err + } + + return &leader, nil +} + type membersAPIActionList struct{} func (l *membersAPIActionList) HTTPRequest(ep url.URL) *http.Request { @@ -255,6 +278,15 @@ func assertStatusCode(got int, want ...int) (err error) { return fmt.Errorf("unexpected status code %d", got) } +type membersAPIActionLeader struct{} + +func (l *membersAPIActionLeader) HTTPRequest(ep url.URL) *http.Request { + u := v2MembersURL(ep) + u.Path = path.Join(u.Path, defaultLeaderSuffix) + req, _ := http.NewRequest("GET", u.String(), nil) + return req +} + // v2MembersURL add the necessary path to the provided endpoint // to route requests to the default v2 members API. func v2MembersURL(ep url.URL) *url.URL { diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/pathutil/path.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/pathutil/path.go index 82fd1db..f26254b 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/pathutil/path.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/pathutil/path.go @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// Package pathutil implements utility functions for handling slash-separated +// paths. package pathutil import "path" diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/types/doc.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/types/doc.go new file mode 100644 index 0000000..04b4c38 --- /dev/null +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/types/doc.go @@ -0,0 +1,17 @@ +// Copyright 2015 CoreOS, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package types declares various data types and implements type-checking +// functions. +package types diff --git a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/types/urlsmap.go b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/types/urlsmap.go index a2aa7fe..f7d5c1c 100644 --- a/Godeps/_workspace/src/github.com/coreos/etcd/pkg/types/urlsmap.go +++ b/Godeps/_workspace/src/github.com/coreos/etcd/pkg/types/urlsmap.go @@ -16,7 +16,6 @@ package types import ( "fmt" - "net/url" "sort" "strings" ) @@ -27,15 +26,10 @@ type URLsMap map[string]URLs // which consists of discovery-formatted names-to-URLs, like: // mach0=http://1.1.1.1:2380,mach0=http://2.2.2.2::2380,mach1=http://3.3.3.3:2380,mach2=http://4.4.4.4:2380 func NewURLsMap(s string) (URLsMap, error) { + m := parse(s) + cl := URLsMap{} - v, err := url.ParseQuery(strings.Replace(s, ",", "&", -1)) - if err != nil { - return nil, err - } - for name, urls := range v { - if len(urls) == 0 || urls[0] == "" { - return nil, fmt.Errorf("empty URL given for %q", name) - } + for name, urls := range m { us, err := NewURLs(urls) if err != nil { return nil, err @@ -73,3 +67,25 @@ func (c URLsMap) URLs() []string { func (c URLsMap) Len() int { return len(c) } + +// parse parses the given string and returns a map listing the values specified for each key. +func parse(s string) map[string][]string { + m := make(map[string][]string) + for s != "" { + key := s + if i := strings.IndexAny(key, ","); i >= 0 { + key, s = key[:i], key[i+1:] + } else { + s = "" + } + if key == "" { + continue + } + value := "" + if i := strings.Index(key, "="); i >= 0 { + key, value = key[:i], key[i+1:] + } + m[key] = append(m[key], value) + } + return m +} diff --git a/Godeps/_workspace/src/github.com/coreos/fleet/pkg/lease/etcd.go b/Godeps/_workspace/src/github.com/coreos/fleet/pkg/lease/etcd.go deleted file mode 100644 index cd4db0d..0000000 --- a/Godeps/_workspace/src/github.com/coreos/fleet/pkg/lease/etcd.go +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright 2014 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package lease - -import ( - "encoding/json" - "path" - "time" - - etcd "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/coreos/etcd/client" - "github.com/sorintlab/stolon/Godeps/_workspace/src/golang.org/x/net/context" -) - -const ( - leasePrefix = "lease" -) - -type etcdLeaseMetadata struct { - MachineID string - Version int -} - -// etcdLease implements the Lease interface -type etcdLease struct { - mgr *etcdLeaseManager - key string - meta etcdLeaseMetadata - idx uint64 - ttl time.Duration -} - -func (l *etcdLease) Release() error { - opts := &etcd.DeleteOptions{ - PrevIndex: l.idx, - } - _, err := l.mgr.kAPI.Delete(l.mgr.ctx(), l.key, opts) - return err -} - -func (l *etcdLease) Renew(period time.Duration) error { - val, err := serializeLeaseMetadata(l.meta.MachineID, l.meta.Version) - opts := &etcd.SetOptions{ - PrevIndex: l.idx, - TTL: period, - } - resp, err := l.mgr.kAPI.Set(l.mgr.ctx(), l.key, val, opts) - if err != nil { - return err - } - - renewed := l.mgr.leaseFromResponse(resp) - *l = *renewed - - return nil -} - -func (l *etcdLease) MachineID() string { - return l.meta.MachineID -} - -func (l *etcdLease) Version() int { - return l.meta.Version -} - -func (l *etcdLease) Index() uint64 { - return l.idx -} - -func (l *etcdLease) TimeRemaining() time.Duration { - return l.ttl -} - -func serializeLeaseMetadata(machID string, ver int) (string, error) { - meta := etcdLeaseMetadata{ - MachineID: machID, - Version: ver, - } - - b, err := json.Marshal(meta) - if err != nil { - return "", err - } - - return string(b), nil -} - -type etcdLeaseManager struct { - kAPI etcd.KeysAPI - keyPrefix string - reqTimeout time.Duration -} - -func NewEtcdLeaseManager(kAPI etcd.KeysAPI, keyPrefix string, reqTimeout time.Duration) *etcdLeaseManager { - return &etcdLeaseManager{kAPI: kAPI, keyPrefix: keyPrefix, reqTimeout: reqTimeout} -} - -func (r *etcdLeaseManager) ctx() context.Context { - ctx, _ := context.WithTimeout(context.Background(), r.reqTimeout) - return ctx -} - -func (r *etcdLeaseManager) leasePath(name string) string { - return path.Join(r.keyPrefix, leasePrefix, name) -} - -func (r *etcdLeaseManager) GetLease(name string) (Lease, error) { - key := r.leasePath(name) - resp, err := r.kAPI.Get(r.ctx(), key, nil) - if err != nil { - if isEtcdError(err, etcd.ErrorCodeKeyNotFound) { - err = nil - } - return nil, err - } - - l := r.leaseFromResponse(resp) - return l, nil -} - -func (r *etcdLeaseManager) StealLease(name, machID string, ver int, period time.Duration, idx uint64) (Lease, error) { - val, err := serializeLeaseMetadata(machID, ver) - if err != nil { - return nil, err - } - - key := r.leasePath(name) - opts := &etcd.SetOptions{ - PrevIndex: idx, - TTL: period, - } - resp, err := r.kAPI.Set(r.ctx(), key, val, opts) - if err != nil { - if isEtcdError(err, etcd.ErrorCodeNodeExist) { - err = nil - } - return nil, err - } - - l := r.leaseFromResponse(resp) - return l, nil -} - -func (r *etcdLeaseManager) AcquireLease(name string, machID string, ver int, period time.Duration) (Lease, error) { - val, err := serializeLeaseMetadata(machID, ver) - if err != nil { - return nil, err - } - - key := r.leasePath(name) - opts := &etcd.SetOptions{ - TTL: period, - PrevExist: etcd.PrevNoExist, - } - - resp, err := r.kAPI.Set(r.ctx(), key, val, opts) - if err != nil { - if isEtcdError(err, etcd.ErrorCodeNodeExist) { - err = nil - } - return nil, err - } - - l := r.leaseFromResponse(resp) - return l, nil -} - -func (r *etcdLeaseManager) leaseFromResponse(res *etcd.Response) *etcdLease { - l := &etcdLease{ - mgr: r, - key: res.Node.Key, - idx: res.Node.ModifiedIndex, - ttl: res.Node.TTLDuration(), - } - - err := json.Unmarshal([]byte(res.Node.Value), &l.meta) - - // fall back to using the entire value as the MachineID for - // backwards-compatibility with engines that are not aware - // of this versioning mechanism - if err != nil { - l.meta = etcdLeaseMetadata{ - MachineID: res.Node.Value, - Version: 0, - } - } - - return l -} - -func isEtcdError(err error, code int) bool { - eerr, ok := err.(etcd.Error) - return ok && eerr.Code == code -} diff --git a/Godeps/_workspace/src/github.com/coreos/fleet/pkg/lease/interface.go b/Godeps/_workspace/src/github.com/coreos/fleet/pkg/lease/interface.go deleted file mode 100644 index 3b87ca0..0000000 --- a/Godeps/_workspace/src/github.com/coreos/fleet/pkg/lease/interface.go +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2014 CoreOS, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package lease - -import "time" - -// Lease proxies to an auto-expiring lease stored in a LeaseRegistry. -// The creator of a Lease must repeatedly call Renew to keep their lease -// from expiring. -type Lease interface { - // Renew attempts to extend the Lease TTL to the provided duration. - // The operation will succeed only if the Lease has not changed in - // the LeaseRegistry since it was last renewed or first acquired. - // An error is returned if the Lease has already expired, or if the - // operation fails for any other reason. - Renew(time.Duration) error - - // Release relinquishes the ownership of a Lease back to the Registry. - // After calling Release, the Lease object should be discarded. An - // error is returned if the Lease has already expired, or if the - // operation fails for any other reason. - Release() error - - // MachineID returns the ID of the Machine that holds this Lease. This - // value must be considered a cached value as it is not guaranteed to - // be correct. - MachineID() string - - // Version returns the current version at which the lessee is operating. - // This value has the same correctness guarantees as MachineID. - // It is up to the caller to determine what this Version means. - Version() int - - // Index exposes the relative time at which the Lease was created or - // renewed. For example, this could be implemented as the ModifiedIndex - // field of a node in etcd. - Index() uint64 - - // TimeRemaining represents the amount of time left on the Lease when - // it was fetched from the LeaseRegistry. - TimeRemaining() time.Duration -} - -type Manager interface { - // GetLease fetches a Lease only if it exists. If it does not - // exist, a nil Lease will be returned. Any other failures - // result in non-nil error and nil Lease objects. - GetLease(name string) (Lease, error) - - // AcquireLease acquires a named lease only if the lease is not - // currently held. If a Lease cannot be acquired, a nil Lease - // object is returned. An error is returned only if there is a - // failure communicating with the Registry. - AcquireLease(name, machID string, ver int, period time.Duration) (Lease, error) - - // StealLease attempts to replace the lessee of the Lease identified - // by the provided name and index with a new lessee. This function - // will fail if the named Lease has progressed past the given index. - StealLease(name, machID string, ver int, period time.Duration, idx uint64) (Lease, error) -} diff --git a/Godeps/_workspace/src/github.com/docker/libkv/.travis.yml b/Godeps/_workspace/src/github.com/docker/libkv/.travis.yml new file mode 100644 index 0000000..1105118 --- /dev/null +++ b/Godeps/_workspace/src/github.com/docker/libkv/.travis.yml @@ -0,0 +1,34 @@ +language: go + +go: + - 1.3 +# - 1.4 +# see https://github.com/moovweb/gvm/pull/116 for why Go 1.4 is currently disabled + +# let us have speedy Docker-based Travis workers +sudo: false + +before_install: + # Symlink below is needed for Travis CI to work correctly on personal forks of libkv + - ln -s $HOME/gopath/src/github.com/${TRAVIS_REPO_SLUG///libkv/} $HOME/gopath/src/github.com/docker + - go get golang.org/x/tools/cmd/vet + - go get golang.org/x/tools/cmd/cover + - go get github.com/mattn/goveralls + - go get github.com/golang/lint/golint + - go get github.com/GeertJohan/fgt + +before_script: + - script/travis_consul.sh 0.6.0 + - script/travis_etcd.sh 2.2.0 + - script/travis_zk.sh 3.5.1-alpha + +script: + - ./consul agent -server -bootstrap -advertise=127.0.0.1 -data-dir /tmp/consul -config-file=./config.json 1>/dev/null & + - ./etcd/etcd --listen-client-urls 'http://0.0.0.0:4001' --advertise-client-urls 'http://127.0.0.1:4001' >/dev/null 2>&1 & + - ./zk/bin/zkServer.sh start ./zk/conf/zoo.cfg 1> /dev/null + - script/validate-gofmt + - go vet ./... + - fgt golint ./... + - go test -v -race ./... + - script/coverage + - goveralls -service=travis-ci -coverprofile=goverage.report diff --git a/Godeps/_workspace/src/github.com/docker/libkv/LICENSE.code b/Godeps/_workspace/src/github.com/docker/libkv/LICENSE.code new file mode 100644 index 0000000..34c4ea7 --- /dev/null +++ b/Godeps/_workspace/src/github.com/docker/libkv/LICENSE.code @@ -0,0 +1,191 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2014-2016 Docker, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Godeps/_workspace/src/github.com/docker/libkv/LICENSE.docs b/Godeps/_workspace/src/github.com/docker/libkv/LICENSE.docs new file mode 100644 index 0000000..e26cd4f --- /dev/null +++ b/Godeps/_workspace/src/github.com/docker/libkv/LICENSE.docs @@ -0,0 +1,425 @@ +Attribution-ShareAlike 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More_considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution-ShareAlike 4.0 International Public +License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution-ShareAlike 4.0 International Public License ("Public +License"). To the extent this Public License may be interpreted as a +contract, You are granted the Licensed Rights in consideration of Your +acceptance of these terms and conditions, and the Licensor grants You +such rights in consideration of benefits the Licensor receives from +making the Licensed Material available under these terms and +conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. BY-SA Compatible License means a license listed at + creativecommons.org/compatiblelicenses, approved by Creative + Commons as essentially the equivalent of this Public License. + + d. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + e. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + f. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + g. License Elements means the license attributes listed in the name + of a Creative Commons Public License. The License Elements of this + Public License are Attribution and ShareAlike. + + h. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + i. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + j. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + k. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + l. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + m. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. Additional offer from the Licensor -- Adapted Material. + Every recipient of Adapted Material from You + automatically receives an offer from the Licensor to + exercise the Licensed Rights in the Adapted Material + under the conditions of the Adapter's License You apply. + + c. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + b. ShareAlike. + + In addition to the conditions in Section 3(a), if You Share + Adapted Material You produce, the following conditions also apply. + + 1. The Adapter's License You apply must be a Creative Commons + license with the same License Elements, this version or + later, or a BY-SA Compatible License. + + 2. You must include the text of, or the URI or hyperlink to, the + Adapter's License You apply. You may satisfy this condition + in any reasonable manner based on the medium, means, and + context in which You Share Adapted Material. + + 3. You may not offer or impose any additional or different terms + or conditions on, or apply any Effective Technological + Measures to, Adapted Material that restrict exercise of the + rights granted under the Adapter's License You apply. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material, + + including for purposes of Section 3(b); and + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public licenses. +Notwithstanding, Creative Commons may elect to apply one of its public +licenses to material it publishes and in those instances will be +considered the "Licensor." Except for the limited purpose of indicating +that material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the public +licenses. + +Creative Commons may be contacted at creativecommons.org. diff --git a/Godeps/_workspace/src/github.com/docker/libkv/MAINTAINERS b/Godeps/_workspace/src/github.com/docker/libkv/MAINTAINERS new file mode 100644 index 0000000..4dd59c7 --- /dev/null +++ b/Godeps/_workspace/src/github.com/docker/libkv/MAINTAINERS @@ -0,0 +1,46 @@ +# Libkv maintainers file +# +# This file describes who runs the docker/libkv project and how. +# This is a living document - if you see something out of date or missing, speak up! +# +# It is structured to be consumable by both humans and programs. +# To extract its contents programmatically, use any TOML-compliant parser. +# +# This file is compiled into the MAINTAINERS file in docker/opensource. +# +[Org] + [Org."Core maintainers"] + people = [ + "abronan", + "aluzzardi", + "sanimej", + "vieux", + ] + +[people] + +# A reference list of all people associated with the project. +# All other sections should refer to people by their canonical key +# in the people section. + + # ADD YOURSELF HERE IN ALPHABETICAL ORDER + + [people.abronan] + Name = "Alexandre Beslic" + Email = "abronan@docker.com" + GitHub = "abronan" + + [people.aluzzardi] + Name = "Andrea Luzzardi" + Email = "al@docker.com" + GitHub = "aluzzardi" + + [people.sanimej] + Name = "Santhosh Manohar" + Email = "santhosh@docker.com" + GitHub = "sanimej" + + [people.vieux] + Name = "Victor Vieux" + Email = "vieux@docker.com" + GitHub = "vieux" diff --git a/Godeps/_workspace/src/github.com/docker/libkv/README.md b/Godeps/_workspace/src/github.com/docker/libkv/README.md new file mode 100644 index 0000000..788c7bd --- /dev/null +++ b/Godeps/_workspace/src/github.com/docker/libkv/README.md @@ -0,0 +1,106 @@ +# libkv + +[![GoDoc](https://godoc.org/github.com/docker/libkv?status.png)](https://godoc.org/github.com/docker/libkv) +[![Build Status](https://travis-ci.org/docker/libkv.svg?branch=master)](https://travis-ci.org/docker/libkv) +[![Coverage Status](https://coveralls.io/repos/docker/libkv/badge.svg)](https://coveralls.io/r/docker/libkv) + +`libkv` provides a `Go` native library to store metadata. + +The goal of `libkv` is to abstract common store operations for multiple distributed and/or local Key/Value store backends. + +For example, you can use it to store your metadata or for service discovery to register machines and endpoints inside your cluster. + +You can also easily implement a generic *Leader Election* on top of it (see the [swarm/leadership](https://github.com/docker/swarm/tree/master/leadership) package). + +As of now, `libkv` offers support for `Consul`, `Etcd`, `Zookeeper` (**Distributed** store) and `BoltDB` (**Local** store). + +## Usage + +`libkv` is meant to be used as an abstraction layer over existing distributed Key/Value stores. It is especially useful if you plan to support `consul`, `etcd` and `zookeeper` using the same codebase. + +It is ideal if you plan for something written in Go that should support: + +- A simple metadata storage, distributed or local +- A lightweight discovery service for your nodes +- A distributed lock mechanism + +You can find examples of usage for `libkv` under in `docs/examples.go`. Optionally you can also take a look at the `docker/swarm` or `docker/libnetwork` repositories which are using `docker/libkv` for all the use cases listed above. + +## Supported versions + +`libkv` supports: +- Consul versions >= `0.5.1` because it uses Sessions with `Delete` behavior for the use of `TTLs` (mimics zookeeper's Ephemeral node support), If you don't plan to use `TTLs`: you can use Consul version `0.4.0+`. +- Etcd versions >= `2.0` because it uses the new `coreos/etcd/client`, this might change in the future as the support for `APIv3` comes along and adds mor capabilities. +- Zookeeper versions >= `3.4.5`. Although this might work with previous version but this remains untested as of now. +- Boltdb, which shouldn't be subject to any version dependencies. + +## Interface + +A **storage backend** in `libkv` should implement (fully or partially) this interface: + +```go +type Store interface { + Put(key string, value []byte, options *WriteOptions) error + Get(key string) (*KVPair, error) + Delete(key string) error + Exists(key string) (bool, error) + Watch(key string, stopCh <-chan struct{}) (<-chan *KVPair, error) + WatchTree(directory string, stopCh <-chan struct{}) (<-chan []*KVPair, error) + NewLock(key string, options *LockOptions) (Locker, error) + List(directory string) ([]*KVPair, error) + DeleteTree(directory string) error + AtomicPut(key string, value []byte, previous *KVPair, options *WriteOptions) (bool, *KVPair, error) + AtomicDelete(key string, previous *KVPair) (bool, error) + Close() +} +``` + +## Compatibility matrix + +Backend drivers in `libkv` are generally divided between **local drivers** and **distributed drivers**. Distributed backends offer enhanced capabilities like `Watches` and/or distributed `Locks`. + +Local drivers are usually used in complement to the distributed drivers to store informations that only needs to be available locally. + +| Calls | Consul | Etcd | Zookeeper | BoltDB | +|-----------------------|:----------:|:------:|:-----------:|:--------:| +| Put | X | X | X | X | +| Get | X | X | X | X | +| Delete | X | X | X | X | +| Exists | X | X | X | X | +| Watch | X | X | X | | +| WatchTree | X | X | X | | +| NewLock (Lock/Unlock) | X | X | X | | +| List | X | X | X | X | +| DeleteTree | X | X | X | X | +| AtomicPut | X | X | X | X | +| Close | X | X | X | X | + +## Limitations + +Distributed Key/Value stores often have different concepts for managing and formatting keys and their associated values. Even though `libkv` tries to abstract those stores aiming for some consistency, in some cases it can't be applied easily. + +Please refer to the `docs/compatibility.md` to see what are the special cases for cross-backend compatibility. + +Other than those special cases, you should expect the same experience for basic operations like `Get`/`Put`, etc. + +Calls like `WatchTree` may return different events (or number of events) depending on the backend (for now, `Etcd` and `Consul` will likely return more events than `Zookeeper` that you should triage properly). Although you should be able to use it successfully to watch on events in an interchangeable way (see the **swarm/leadership** or **swarm/discovery** packages in **docker/swarm**). + +## TLS + +Only `Consul` and `etcd` have support for TLS and you should build and provide your own `config.TLS` object to feed the client. Support is planned for `zookeeper`. + +##Roadmap + +- Make the API nicer to use (using `options`) +- Provide more options (`consistency` for example) +- Improve performance (remove extras `Get`/`List` operations) +- Better key formatting +- New backends? + +##Contributing + +Want to hack on libkv? [Docker's contributions guidelines](https://github.com/docker/docker/blob/master/CONTRIBUTING.md) apply. + +##Copyright and license + +Copyright © 2014-2016 Docker, Inc. All rights reserved, except as follows. Code is released under the Apache 2.0 license. The README.md file, and files in the "docs" folder are licensed under the Creative Commons Attribution 4.0 International License under the terms and conditions set forth in the file "LICENSE.docs". You may obtain a duplicate copy of the same license, titled CC-BY-SA-4.0, at http://creativecommons.org/licenses/by/4.0/. diff --git a/Godeps/_workspace/src/github.com/docker/libkv/docs/compatibility.md b/Godeps/_workspace/src/github.com/docker/libkv/docs/compatibility.md new file mode 100644 index 0000000..c4f27e9 --- /dev/null +++ b/Godeps/_workspace/src/github.com/docker/libkv/docs/compatibility.md @@ -0,0 +1,82 @@ +#Cross-Backend Compatibility + +The value of `libkv` is not to duplicate the code for programs that should support multiple distributed K/V stores like the classic `Consul`/`etcd`/`zookeeper` trio. + +This document provides with general guidelines for users willing to support those backends with the same code using `libkv`. + +Please note that most of those workarounds are going to disappear in the future with `etcd` APIv3. + +##Etcd directory/key distinction + +`etcd` with APIv2 makes the distinction between keys and directories. The result with `libkv` is that when using the etcd driver: + +- You cannot store values on directories +- You cannot invoke `WatchTree` (watching on child values), on a regular key + +This is fundamentaly different than `Consul` and `zookeeper` which are more permissive and allow the same set of operations on keys and directories (called a Node for zookeeper). + +Apiv3 is in the work for `etcd`, which removes this key/directory distinction, but until then you should follow these workarounds to make your `libkv` code work across backends. + +###Put + +`etcd` cannot put values on directories, so this puts a major restriction compared to `Consul` and `zookeeper`. + +If you want to support all those three backends, you should make sure to only put data on **leaves**. + +For example: + +```go +_ := kv.Put("path/to/key/bis", []byte("foo"), nil) +_ := kv.Put("path/to/key", []byte("bar"), nil) +``` + +Will work on `Consul` and `zookeeper` but fail for `etcd`. This is because the first `Put` in the case of `etcd` will recursively create the directory hierarchy and `path/to/key` is now considered as a directory. Thus, values should always be stored on leaves if the support for the three backends is planned. + +###WatchTree + +When initializing the `WatchTree`, the natural way to do so is through the following code: + +```go +key := "path/to/key" +if !kv.Exists(key) { + err := kv.Put(key, []byte("data"), nil) +} +events, err := kv.WatchTree(key, nil) +``` + +The code above will not work across backends and etcd will fail on the `WatchTree` call. What happens exactly: + +- `Consul` will create a regular `key` because it has no distinction between directories and keys. This is not an issue as we can invoke `WatchTree` on regular keys. +- `zookeeper` is going to create a `node` that can either be a directory or a key during the lifetime of a program but it does not matter as a directory can hold values and be watchable like a regular key. +- `etcd` is going to create a regular `key`. We cannot invoke `WatchTree` on regular keys using etcd. + +To be cross-compatible between those three backends for `WatchTree`, we need to enforce a parameter that is only interpreted with `etcd` and which tells the client to create a `directory` instead of a key. + +```go +key := "path/to/key" +if !kv.Exists(key) { + // We enforce IsDir = true to make sure etcd creates a directory + err := kv.Put(key, []byte("data"), &store.WriteOptions{IsDir:true}) +} +events, err := kv.WatchTree(key, nil) +``` + +The code above will work for the three backends but make sure to not try to store any value at that path as the call to `Put` will fail for `etcd` (you can only put at `path/to/key/foo`, `path/to/key/bar` for example). + +##Etcd distributed locking + +There is `Lock` mechanisms baked in the `coreos/etcd/client` for now. Instead, `libkv` has its own implementation of a `Lock` on top of `etcd`. + +The general workflow for the `Lock` is as follows: + +- Call Lock concurrently on a `key` between threads/programs +- Only one will create that key, others are going to fail because the key has already been created +- The thread locking the key can get the right index to set the value of the key using Compare And Swap and effectively Lock and hold the key +- Other threads are given a wrong index to fail the Compare and Swap and block until the key has been released by the thread holding the Lock +- Lock seekers are setting up a Watch listening on that key and events happening on the key +- When the thread/program stops holding the lock, it deletes the key triggering a `delete` event that will notify all the other threads. In case the program crashes, the key has a TTL attached that will send an `expire` event when this TTL expires. +- Once everyone is notified, back to the first step. First come, first served with the Lock. + +The whole Lock process is highly dependent on the `delete`/`expire` events of `etcd`. So don't expect the key to be still there once the Lock is released. + +For example if the whole logic is to `Lock` a key and expect the value to still be there after it has been unlocked, it is not going to be cross-backend compatible with `Consul` and `zookeeper`. On the other end the `etcd` Lock can still be used to do Leader Election for example and still be cross-compatible with other backends. \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/docker/libkv/docs/examples.md b/Godeps/_workspace/src/github.com/docker/libkv/docs/examples.md new file mode 100644 index 0000000..09752db --- /dev/null +++ b/Godeps/_workspace/src/github.com/docker/libkv/docs/examples.md @@ -0,0 +1,157 @@ +#Examples + +This document contains useful example of usage for `libkv`. It might not be complete but provides with general informations on how to use the client. + +##Create a store and use Put/Get/Delete + +```go +package main + +import ( + "fmt" + "time" + "log" + + "github.com/docker/libkv" + "github.com/docker/libkv/store" + "github.com/docker/libkv/store/consul" +) + +func init() { + // Register consul store to libkv + consul.Register() + + // We can register as many backends that are supported by libkv + etcd.Register() + zookeeper.Register() + boltdb.Register() +} + +func main() { + client := "localhost:8500" + + // Initialize a new store with consul + kv, err := libkv.NewStore( + store.CONSUL, // or "consul" + []string{client}, + &store.Config{ + ConnectionTimeout: 10*time.Second, + }, + ) + if err != nil { + log.Fatal("Cannot create store consul") + } + + key := "foo" + err = kv.Put(key, []byte("bar"), nil) + if err != nil { + fmt.Errorf("Error trying to put value at key: %v", key) + } + + pair, err := kv.Get(key) + if err != nil { + fmt.Errorf("Error trying accessing value at key: %v", key) + } + + err = kv.Delete(key) + if err != nil { + fmt.Errorf("Error trying to delete key %v", key) + } + + log.Info("value: ", string(pair.Value)) +} +``` + +##List keys + +```go +// List will list all the keys under `key` if it contains a set of child keys/values +entries, err := kv.List(key) +for _, pair := range entries { + fmt.Printf("key=%v - value=%v", pair.Key, string(pair.Value)) +} + +``` + +##Watching for events on a single key (Watch) + +You can use watches to watch modifications on a key. First you need to check if the key exists. If this is not the case, we need to create it using the `Put` function. + +```go +// Checking on the key before watching +if !kv.Exists(key) { + err := kv.Put(key, []byte("bar"), nil) + if err != nil { + fmt.Errorf("Something went wrong when initializing key %v", key) + } +} + +stopCh := make(<-chan struct{}) +events, err := kv.Watch(key, stopCh) + +select { + case pair := <-events: + // Do something with events + fmt.Printf("value changed on key %v: new value=%v", key, pair.Value) +} + +``` + +##Watching for events happening on child keys (WatchTree) + +You can use watches to watch modifications on a key. First you need to check if the key exists. If this is not the case, we need to create it using the `Put` function. There is a special step here though if you want your code to work across backends. Because `etcd` is a special case and it makes the distinction between directories and keys, we need to make sure that the created key is considered as a directory by enforcing `IsDir` at `true`. + +```go +// Checking on the key before watching +if !kv.Exists(key) { + // Don't forget IsDir:true if the code is used cross-backend + err := kv.Put(key, []byte("bar"), &store.WriteOptions{IsDir:true}) + if err != nil { + fmt.Errorf("Something went wrong when initializing key %v", key) + } +} + +stopCh := make(<-chan struct{}) +events, err := kv.WatchTree(key, stopCh) + +select { + case pairs := <-events: + // Do something with events + for _, pair := range pairs { + fmt.Printf("value changed on key %v: new value=%v", key, pair.Value) + } +} + +``` + +## Distributed Locking, using Lock/Unlock + +```go +key := "lockKey" +value := []byte("bar") + +// Initialize a distributed lock. TTL is optional, it is here to make sure that +// the lock is released after the program that is holding the lock ends or crashes +lock, err := kv.NewLock(key, &store.LockOptions{Value: value, TTL: 2 * time.Second}) +if err != nil { + fmt.Errorf("something went wrong when trying to initialize the Lock") +} + +// Try to lock the key, the call to Lock() is blocking +_, err := lock.Lock(nil) +if err != nil { + fmt.Errorf("something went wrong when trying to lock key %v", key) +} + +// Get should work because we are holding the key +pair, err := kv.Get(key) +if err != nil { + fmt.Errorf("key %v has value %v", key, pair.Value) +} + +// Unlock the key +err = lock.Unlock() +if err != nil { + fmt.Errorf("something went wrong when trying to unlock key %v", key) +} +``` \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/docker/libkv/libkv.go b/Godeps/_workspace/src/github.com/docker/libkv/libkv.go new file mode 100644 index 0000000..c305272 --- /dev/null +++ b/Godeps/_workspace/src/github.com/docker/libkv/libkv.go @@ -0,0 +1,40 @@ +package libkv + +import ( + "fmt" + "sort" + "strings" + + "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/docker/libkv/store" +) + +// Initialize creates a new Store object, initializing the client +type Initialize func(addrs []string, options *store.Config) (store.Store, error) + +var ( + // Backend initializers + initializers = make(map[store.Backend]Initialize) + + supportedBackend = func() string { + keys := make([]string, 0, len(initializers)) + for k := range initializers { + keys = append(keys, string(k)) + } + sort.Strings(keys) + return strings.Join(keys, ", ") + }() +) + +// NewStore creates a an instance of store +func NewStore(backend store.Backend, addrs []string, options *store.Config) (store.Store, error) { + if init, exists := initializers[backend]; exists { + return init(addrs, options) + } + + return nil, fmt.Errorf("%s %s", store.ErrBackendNotSupported.Error(), supportedBackend) +} + +// AddStore adds a new store backend to libkv +func AddStore(store store.Backend, init Initialize) { + initializers[store] = init +} diff --git a/Godeps/_workspace/src/github.com/docker/libkv/script/.validate b/Godeps/_workspace/src/github.com/docker/libkv/script/.validate new file mode 100644 index 0000000..3767f42 --- /dev/null +++ b/Godeps/_workspace/src/github.com/docker/libkv/script/.validate @@ -0,0 +1,33 @@ +#!/bin/bash + +if [ -z "$VALIDATE_UPSTREAM" ]; then + # this is kind of an expensive check, so let's not do this twice if we + # are running more than one validate bundlescript + + VALIDATE_REPO='https://github.com/docker/libkv.git' + VALIDATE_BRANCH='master' + + if [ "$TRAVIS" = 'true' -a "$TRAVIS_PULL_REQUEST" != 'false' ]; then + VALIDATE_REPO="https://github.com/${TRAVIS_REPO_SLUG}.git" + VALIDATE_BRANCH="${TRAVIS_BRANCH}" + fi + + VALIDATE_HEAD="$(git rev-parse --verify HEAD)" + + git fetch -q "$VALIDATE_REPO" "refs/heads/$VALIDATE_BRANCH" + VALIDATE_UPSTREAM="$(git rev-parse --verify FETCH_HEAD)" + + VALIDATE_COMMIT_LOG="$VALIDATE_UPSTREAM..$VALIDATE_HEAD" + VALIDATE_COMMIT_DIFF="$VALIDATE_UPSTREAM...$VALIDATE_HEAD" + + validate_diff() { + if [ "$VALIDATE_UPSTREAM" != "$VALIDATE_HEAD" ]; then + git diff "$VALIDATE_COMMIT_DIFF" "$@" + fi + } + validate_log() { + if [ "$VALIDATE_UPSTREAM" != "$VALIDATE_HEAD" ]; then + git log "$VALIDATE_COMMIT_LOG" "$@" + fi + } +fi diff --git a/Godeps/_workspace/src/github.com/docker/libkv/script/coverage b/Godeps/_workspace/src/github.com/docker/libkv/script/coverage new file mode 100644 index 0000000..a7a13f4 --- /dev/null +++ b/Godeps/_workspace/src/github.com/docker/libkv/script/coverage @@ -0,0 +1,21 @@ +#!/bin/bash + +MODE="mode: count" +ROOT=${TRAVIS_BUILD_DIR:-.}/../../.. + +# Grab the list of packages. +# Exclude the API and CLI from coverage as it will be covered by integration tests. +PACKAGES=`go list ./...` + +# Create the empty coverage file. +echo $MODE > goverage.report + +# Run coverage on every package. +for package in $PACKAGES; do + output="$ROOT/$package/coverage.out" + + go test -test.short -covermode=count -coverprofile=$output $package + if [ -f "$output" ] ; then + cat "$output" | grep -v "$MODE" >> goverage.report + fi +done diff --git a/Godeps/_workspace/src/github.com/docker/libkv/script/travis_consul.sh b/Godeps/_workspace/src/github.com/docker/libkv/script/travis_consul.sh new file mode 100644 index 0000000..7b63d6b --- /dev/null +++ b/Godeps/_workspace/src/github.com/docker/libkv/script/travis_consul.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +if [ $# -gt 0 ] ; then + CONSUL_VERSION="$1" +else + CONSUL_VERSION="0.5.2" +fi + +# install consul +wget "https://releases.hashicorp.com/consul/${CONSUL_VERSION}/consul_${CONSUL_VERSION}_linux_amd64.zip" +unzip "consul_${CONSUL_VERSION}_linux_amd64.zip" + +# make config for minimum ttl +touch config.json +echo "{\"session_ttl_min\": \"1s\"}" >> config.json + +# check +./consul --version diff --git a/Godeps/_workspace/src/github.com/docker/libkv/script/travis_etcd.sh b/Godeps/_workspace/src/github.com/docker/libkv/script/travis_etcd.sh new file mode 100644 index 0000000..bee8567 --- /dev/null +++ b/Godeps/_workspace/src/github.com/docker/libkv/script/travis_etcd.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +if [ $# -gt 0 ] ; then + ETCD_VERSION="$1" +else + ETCD_VERSION="2.2.0" +fi + +curl -L https://github.com/coreos/etcd/releases/download/v$ETCD_VERSION/etcd-v$ETCD_VERSION-linux-amd64.tar.gz -o etcd-v$ETCD_VERSION-linux-amd64.tar.gz +tar xzvf etcd-v$ETCD_VERSION-linux-amd64.tar.gz +mv etcd-v$ETCD_VERSION-linux-amd64 etcd diff --git a/Godeps/_workspace/src/github.com/docker/libkv/script/travis_zk.sh b/Godeps/_workspace/src/github.com/docker/libkv/script/travis_zk.sh new file mode 100644 index 0000000..4485d23 --- /dev/null +++ b/Godeps/_workspace/src/github.com/docker/libkv/script/travis_zk.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +if [ $# -gt 0 ] ; then + ZK_VERSION="$1" +else + ZK_VERSION="3.4.7" +fi + +wget "http://apache.arvixe.com/zookeeper/zookeeper-${ZK_VERSION}/zookeeper-${ZK_VERSION}.tar.gz" +tar -xvf "zookeeper-${ZK_VERSION}.tar.gz" +mv zookeeper-$ZK_VERSION zk +mv ./zk/conf/zoo_sample.cfg ./zk/conf/zoo.cfg diff --git a/Godeps/_workspace/src/github.com/docker/libkv/script/validate-gofmt b/Godeps/_workspace/src/github.com/docker/libkv/script/validate-gofmt new file mode 100644 index 0000000..c565976 --- /dev/null +++ b/Godeps/_workspace/src/github.com/docker/libkv/script/validate-gofmt @@ -0,0 +1,30 @@ +#!/bin/bash + +source "$(dirname "$BASH_SOURCE")/.validate" + +IFS=$'\n' +files=( $(validate_diff --diff-filter=ACMR --name-only -- '*.go' | grep -v '^Godeps/' || true) ) +unset IFS + +badFiles=() +for f in "${files[@]}"; do + # we use "git show" here to validate that what's committed is formatted + if [ "$(git show "$VALIDATE_HEAD:$f" | gofmt -s -l)" ]; then + badFiles+=( "$f" ) + fi +done + +if [ ${#badFiles[@]} -eq 0 ]; then + echo 'Congratulations! All Go source files are properly formatted.' +else + { + echo "These files are not properly gofmt'd:" + for f in "${badFiles[@]}"; do + echo " - $f" + done + echo + echo 'Please reformat the above files using "gofmt -s -w" and commit the result.' + echo + } >&2 + false +fi diff --git a/Godeps/_workspace/src/github.com/docker/libkv/store/boltdb/boltdb.go b/Godeps/_workspace/src/github.com/docker/libkv/store/boltdb/boltdb.go new file mode 100644 index 0000000..fd15217 --- /dev/null +++ b/Godeps/_workspace/src/github.com/docker/libkv/store/boltdb/boltdb.go @@ -0,0 +1,471 @@ +package boltdb + +import ( + "bytes" + "encoding/binary" + "errors" + "os" + "path/filepath" + "sync" + "sync/atomic" + "time" + + "github.com/boltdb/bolt" + "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/docker/libkv" + "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/docker/libkv/store" +) + +var ( + // ErrMultipleEndpointsUnsupported is thrown when multiple endpoints specified for + // BoltDB. Endpoint has to be a local file path + ErrMultipleEndpointsUnsupported = errors.New("boltdb supports one endpoint and should be a file path") + // ErrBoltBucketNotFound is thrown when specified BoltBD bucket doesn't exist in the DB + ErrBoltBucketNotFound = errors.New("boltdb bucket doesn't exist") + // ErrBoltBucketOptionMissing is thrown when boltBcuket config option is missing + ErrBoltBucketOptionMissing = errors.New("boltBucket config option missing") +) + +const ( + filePerm os.FileMode = 0644 +) + +//BoltDB type implements the Store interface +type BoltDB struct { + client *bolt.DB + boltBucket []byte + dbIndex uint64 + path string + timeout time.Duration + // By default libkv opens and closes the bolt DB connection for every + // get/put operation. This allows multiple apps to use a Bolt DB at the + // same time. + // PersistConnection flag provides an option to override ths behavior. + // ie: open the connection in New and use it till Close is called. + PersistConnection bool + sync.Mutex +} + +const ( + libkvmetadatalen = 8 + transientTimeout = time.Duration(10) * time.Second +) + +// Register registers boltdb to libkv +func Register() { + libkv.AddStore(store.BOLTDB, New) +} + +// New opens a new BoltDB connection to the specified path and bucket +func New(endpoints []string, options *store.Config) (store.Store, error) { + var ( + db *bolt.DB + err error + boltOptions *bolt.Options + ) + + if len(endpoints) > 1 { + return nil, ErrMultipleEndpointsUnsupported + } + + if (options == nil) || (len(options.Bucket) == 0) { + return nil, ErrBoltBucketOptionMissing + } + + dir, _ := filepath.Split(endpoints[0]) + if err = os.MkdirAll(dir, 0750); err != nil { + return nil, err + } + + if options.PersistConnection { + boltOptions = &bolt.Options{Timeout: options.ConnectionTimeout} + db, err = bolt.Open(endpoints[0], filePerm, boltOptions) + if err != nil { + return nil, err + } + } + + b := &BoltDB{ + client: db, + path: endpoints[0], + boltBucket: []byte(options.Bucket), + timeout: transientTimeout, + PersistConnection: options.PersistConnection, + } + + return b, nil +} + +func (b *BoltDB) reset() { + b.path = "" + b.boltBucket = []byte{} +} + +func (b *BoltDB) getDBhandle() (*bolt.DB, error) { + var ( + db *bolt.DB + err error + ) + if !b.PersistConnection { + boltOptions := &bolt.Options{Timeout: b.timeout} + if db, err = bolt.Open(b.path, filePerm, boltOptions); err != nil { + return nil, err + } + b.client = db + } + + return b.client, nil +} + +func (b *BoltDB) releaseDBhandle() { + if !b.PersistConnection { + b.client.Close() + } +} + +// Get the value at "key". BoltDB doesn't provide an inbuilt last modified index with every kv pair. Its implemented by +// by a atomic counter maintained by the libkv and appened to the value passed by the client. +func (b *BoltDB) Get(key string) (*store.KVPair, error) { + var ( + val []byte + db *bolt.DB + err error + ) + b.Lock() + defer b.Unlock() + + if db, err = b.getDBhandle(); err != nil { + return nil, err + } + defer b.releaseDBhandle() + + err = db.View(func(tx *bolt.Tx) error { + bucket := tx.Bucket(b.boltBucket) + if bucket == nil { + return ErrBoltBucketNotFound + } + + v := bucket.Get([]byte(key)) + val = make([]byte, len(v)) + copy(val, v) + + return nil + }) + + if len(val) == 0 { + return nil, store.ErrKeyNotFound + } + if err != nil { + return nil, err + } + + dbIndex := binary.LittleEndian.Uint64(val[:libkvmetadatalen]) + val = val[libkvmetadatalen:] + + return &store.KVPair{Key: key, Value: val, LastIndex: (dbIndex)}, nil +} + +//Put the key, value pair. index number metadata is prepended to the value +func (b *BoltDB) Put(key string, value []byte, opts *store.WriteOptions) error { + var ( + dbIndex uint64 + db *bolt.DB + err error + ) + b.Lock() + defer b.Unlock() + + dbval := make([]byte, libkvmetadatalen) + + if db, err = b.getDBhandle(); err != nil { + return err + } + defer b.releaseDBhandle() + + err = db.Update(func(tx *bolt.Tx) error { + bucket, err := tx.CreateBucketIfNotExists(b.boltBucket) + if err != nil { + return err + } + + dbIndex = atomic.AddUint64(&b.dbIndex, 1) + binary.LittleEndian.PutUint64(dbval, dbIndex) + dbval = append(dbval, value...) + + err = bucket.Put([]byte(key), dbval) + if err != nil { + return err + } + return nil + }) + return err +} + +//Delete the value for the given key. +func (b *BoltDB) Delete(key string) error { + var ( + db *bolt.DB + err error + ) + b.Lock() + defer b.Unlock() + + if db, err = b.getDBhandle(); err != nil { + return err + } + defer b.releaseDBhandle() + + err = db.Update(func(tx *bolt.Tx) error { + bucket := tx.Bucket(b.boltBucket) + if bucket == nil { + return ErrBoltBucketNotFound + } + err := bucket.Delete([]byte(key)) + return err + }) + return err +} + +// Exists checks if the key exists inside the store +func (b *BoltDB) Exists(key string) (bool, error) { + var ( + val []byte + db *bolt.DB + err error + ) + b.Lock() + defer b.Unlock() + + if db, err = b.getDBhandle(); err != nil { + return false, err + } + defer b.releaseDBhandle() + + err = db.View(func(tx *bolt.Tx) error { + bucket := tx.Bucket(b.boltBucket) + if bucket == nil { + return ErrBoltBucketNotFound + } + + val = bucket.Get([]byte(key)) + + return nil + }) + + if len(val) == 0 { + return false, err + } + return true, err +} + +// List returns the range of keys starting with the passed in prefix +func (b *BoltDB) List(keyPrefix string) ([]*store.KVPair, error) { + var ( + db *bolt.DB + err error + ) + b.Lock() + defer b.Unlock() + + kv := []*store.KVPair{} + + if db, err = b.getDBhandle(); err != nil { + return nil, err + } + defer b.releaseDBhandle() + + err = db.View(func(tx *bolt.Tx) error { + bucket := tx.Bucket(b.boltBucket) + if bucket == nil { + return ErrBoltBucketNotFound + } + + cursor := bucket.Cursor() + prefix := []byte(keyPrefix) + + for key, v := cursor.Seek(prefix); bytes.HasPrefix(key, prefix); key, v = cursor.Next() { + + dbIndex := binary.LittleEndian.Uint64(v[:libkvmetadatalen]) + v = v[libkvmetadatalen:] + val := make([]byte, len(v)) + copy(val, v) + + kv = append(kv, &store.KVPair{ + Key: string(key), + Value: val, + LastIndex: dbIndex, + }) + } + return nil + }) + if len(kv) == 0 { + return nil, store.ErrKeyNotFound + } + return kv, err +} + +// AtomicDelete deletes a value at "key" if the key +// has not been modified in the meantime, throws an +// error if this is the case +func (b *BoltDB) AtomicDelete(key string, previous *store.KVPair) (bool, error) { + var ( + val []byte + db *bolt.DB + err error + ) + b.Lock() + defer b.Unlock() + + if previous == nil { + return false, store.ErrPreviousNotSpecified + } + if db, err = b.getDBhandle(); err != nil { + return false, err + } + defer b.releaseDBhandle() + + err = db.Update(func(tx *bolt.Tx) error { + bucket := tx.Bucket(b.boltBucket) + if bucket == nil { + return ErrBoltBucketNotFound + } + + val = bucket.Get([]byte(key)) + if val == nil { + return store.ErrKeyNotFound + } + dbIndex := binary.LittleEndian.Uint64(val[:libkvmetadatalen]) + if dbIndex != previous.LastIndex { + return store.ErrKeyModified + } + err := bucket.Delete([]byte(key)) + return err + }) + if err != nil { + return false, err + } + return true, err +} + +// AtomicPut puts a value at "key" if the key has not been +// modified since the last Put, throws an error if this is the case +func (b *BoltDB) AtomicPut(key string, value []byte, previous *store.KVPair, options *store.WriteOptions) (bool, *store.KVPair, error) { + var ( + val []byte + dbIndex uint64 + db *bolt.DB + err error + ) + b.Lock() + defer b.Unlock() + + dbval := make([]byte, libkvmetadatalen) + + if db, err = b.getDBhandle(); err != nil { + return false, nil, err + } + defer b.releaseDBhandle() + + err = db.Update(func(tx *bolt.Tx) error { + var err error + bucket := tx.Bucket(b.boltBucket) + if bucket == nil { + if previous != nil { + return ErrBoltBucketNotFound + } + bucket, err = tx.CreateBucket(b.boltBucket) + if err != nil { + return err + } + } + // AtomicPut is equivalent to Put if previous is nil and the Ky + // doesn't exist in the DB. + val = bucket.Get([]byte(key)) + if previous == nil && len(val) != 0 { + return store.ErrKeyExists + } + if previous != nil { + if len(val) == 0 { + return store.ErrKeyNotFound + } + dbIndex = binary.LittleEndian.Uint64(val[:libkvmetadatalen]) + if dbIndex != previous.LastIndex { + return store.ErrKeyModified + } + } + dbIndex = atomic.AddUint64(&b.dbIndex, 1) + binary.LittleEndian.PutUint64(dbval, b.dbIndex) + dbval = append(dbval, value...) + return (bucket.Put([]byte(key), dbval)) + }) + if err != nil { + return false, nil, err + } + + updated := &store.KVPair{ + Key: key, + Value: value, + LastIndex: dbIndex, + } + + return true, updated, nil +} + +// Close the db connection to the BoltDB +func (b *BoltDB) Close() { + b.Lock() + defer b.Unlock() + + if !b.PersistConnection { + b.reset() + } else { + b.client.Close() + } + return +} + +// DeleteTree deletes a range of keys with a given prefix +func (b *BoltDB) DeleteTree(keyPrefix string) error { + var ( + db *bolt.DB + err error + ) + b.Lock() + defer b.Unlock() + + if db, err = b.getDBhandle(); err != nil { + return err + } + defer b.releaseDBhandle() + + err = db.Update(func(tx *bolt.Tx) error { + bucket := tx.Bucket(b.boltBucket) + if bucket == nil { + return ErrBoltBucketNotFound + } + + cursor := bucket.Cursor() + prefix := []byte(keyPrefix) + + for key, _ := cursor.Seek(prefix); bytes.HasPrefix(key, prefix); key, _ = cursor.Next() { + _ = bucket.Delete([]byte(key)) + } + return nil + }) + + return err +} + +// NewLock has to implemented at the library level since its not supported by BoltDB +func (b *BoltDB) NewLock(key string, options *store.LockOptions) (store.Locker, error) { + return nil, store.ErrCallNotSupported +} + +// Watch has to implemented at the library level since its not supported by BoltDB +func (b *BoltDB) Watch(key string, stopCh <-chan struct{}) (<-chan *store.KVPair, error) { + return nil, store.ErrCallNotSupported +} + +// WatchTree has to implemented at the library level since its not supported by BoltDB +func (b *BoltDB) WatchTree(directory string, stopCh <-chan struct{}) (<-chan []*store.KVPair, error) { + return nil, store.ErrCallNotSupported +} diff --git a/Godeps/_workspace/src/github.com/docker/libkv/store/consul/consul.go b/Godeps/_workspace/src/github.com/docker/libkv/store/consul/consul.go new file mode 100644 index 0000000..5fd77dc --- /dev/null +++ b/Godeps/_workspace/src/github.com/docker/libkv/store/consul/consul.go @@ -0,0 +1,495 @@ +package consul + +import ( + "crypto/tls" + "errors" + "net/http" + "strings" + "sync" + "time" + + "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/docker/libkv" + "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/docker/libkv/store" + api "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/hashicorp/consul/api" +) + +const ( + // DefaultWatchWaitTime is how long we block for at a + // time to check if the watched key has changed. This + // affects the minimum time it takes to cancel a watch. + DefaultWatchWaitTime = 15 * time.Second + + // RenewSessionRetryMax is the number of time we should try + // to renew the session before giving up and throwing an error + RenewSessionRetryMax = 5 +) + +var ( + // ErrMultipleEndpointsUnsupported is thrown when there are + // multiple endpoints specified for Consul + ErrMultipleEndpointsUnsupported = errors.New("consul does not support multiple endpoints") + + // ErrSessionRenew is thrown when the session can't be + // renewed because the Consul version does not support sessions + ErrSessionRenew = errors.New("cannot set or renew session for ttl, unable to operate on sessions") +) + +// Consul is the receiver type for the +// Store interface +type Consul struct { + sync.Mutex + config *api.Config + client *api.Client +} + +type consulLock struct { + lock *api.Lock + renewCh chan struct{} +} + +// Register registers consul to libkv +func Register() { + libkv.AddStore(store.CONSUL, New) +} + +// New creates a new Consul client given a list +// of endpoints and optional tls config +func New(endpoints []string, options *store.Config) (store.Store, error) { + if len(endpoints) > 1 { + return nil, ErrMultipleEndpointsUnsupported + } + + s := &Consul{} + + // Create Consul client + config := api.DefaultConfig() + s.config = config + config.HttpClient = http.DefaultClient + config.Address = endpoints[0] + config.Scheme = "http" + + // Set options + if options != nil { + if options.TLS != nil { + s.setTLS(options.TLS) + } + if options.ConnectionTimeout != 0 { + s.setTimeout(options.ConnectionTimeout) + } + } + + // Creates a new client + client, err := api.NewClient(config) + if err != nil { + return nil, err + } + s.client = client + + return s, nil +} + +// SetTLS sets Consul TLS options +func (s *Consul) setTLS(tls *tls.Config) { + s.config.HttpClient.Transport = &http.Transport{ + TLSClientConfig: tls, + } + s.config.Scheme = "https" +} + +// SetTimeout sets the timeout for connecting to Consul +func (s *Consul) setTimeout(time time.Duration) { + s.config.WaitTime = time +} + +// Normalize the key for usage in Consul +func (s *Consul) normalize(key string) string { + key = store.Normalize(key) + return strings.TrimPrefix(key, "/") +} + +func (s *Consul) renewSession(pair *api.KVPair, ttl time.Duration) error { + // Check if there is any previous session with an active TTL + session, err := s.getActiveSession(pair.Key) + if err != nil { + return err + } + + if session == "" { + entry := &api.SessionEntry{ + Behavior: api.SessionBehaviorDelete, // Delete the key when the session expires + TTL: (ttl / 2).String(), // Consul multiplies the TTL by 2x + LockDelay: 1 * time.Millisecond, // Virtually disable lock delay + } + + // Create the key session + session, _, err = s.client.Session().Create(entry, nil) + if err != nil { + return err + } + + lockOpts := &api.LockOptions{ + Key: pair.Key, + Session: session, + } + + // Lock and ignore if lock is held + // It's just a placeholder for the + // ephemeral behavior + lock, _ := s.client.LockOpts(lockOpts) + if lock != nil { + lock.Lock(nil) + } + } + + _, _, err = s.client.Session().Renew(session, nil) + return err +} + +// getActiveSession checks if the key already has +// a session attached +func (s *Consul) getActiveSession(key string) (string, error) { + pair, _, err := s.client.KV().Get(key, nil) + if err != nil { + return "", err + } + if pair != nil && pair.Session != "" { + return pair.Session, nil + } + return "", nil +} + +// Get the value at "key", returns the last modified index +// to use in conjunction to CAS calls +func (s *Consul) Get(key string) (*store.KVPair, error) { + options := &api.QueryOptions{ + AllowStale: false, + RequireConsistent: true, + } + + pair, meta, err := s.client.KV().Get(s.normalize(key), options) + if err != nil { + return nil, err + } + + // If pair is nil then the key does not exist + if pair == nil { + return nil, store.ErrKeyNotFound + } + + return &store.KVPair{Key: pair.Key, Value: pair.Value, LastIndex: meta.LastIndex}, nil +} + +// Put a value at "key" +func (s *Consul) Put(key string, value []byte, opts *store.WriteOptions) error { + key = s.normalize(key) + + p := &api.KVPair{ + Key: key, + Value: value, + Flags: api.LockFlagValue, + } + + if opts != nil && opts.TTL > 0 { + // Create or renew a session holding a TTL. Operations on sessions + // are not deterministic: creating or renewing a session can fail + for retry := 1; retry <= RenewSessionRetryMax; retry++ { + err := s.renewSession(p, opts.TTL) + if err == nil { + break + } + if retry == RenewSessionRetryMax { + return ErrSessionRenew + } + } + } + + _, err := s.client.KV().Put(p, nil) + return err +} + +// Delete a value at "key" +func (s *Consul) Delete(key string) error { + if _, err := s.Get(key); err != nil { + return err + } + _, err := s.client.KV().Delete(s.normalize(key), nil) + return err +} + +// Exists checks that the key exists inside the store +func (s *Consul) Exists(key string) (bool, error) { + _, err := s.Get(key) + if err != nil { + if err == store.ErrKeyNotFound { + return false, nil + } + return false, err + } + return true, nil +} + +// List child nodes of a given directory +func (s *Consul) List(directory string) ([]*store.KVPair, error) { + pairs, _, err := s.client.KV().List(s.normalize(directory), nil) + if err != nil { + return nil, err + } + if len(pairs) == 0 { + return nil, store.ErrKeyNotFound + } + + kv := []*store.KVPair{} + + for _, pair := range pairs { + if pair.Key == directory { + continue + } + kv = append(kv, &store.KVPair{ + Key: pair.Key, + Value: pair.Value, + LastIndex: pair.ModifyIndex, + }) + } + + return kv, nil +} + +// DeleteTree deletes a range of keys under a given directory +func (s *Consul) DeleteTree(directory string) error { + if _, err := s.List(directory); err != nil { + return err + } + _, err := s.client.KV().DeleteTree(s.normalize(directory), nil) + return err +} + +// Watch for changes on a "key" +// It returns a channel that will receive changes or pass +// on errors. Upon creation, the current value will first +// be sent to the channel. Providing a non-nil stopCh can +// be used to stop watching. +func (s *Consul) Watch(key string, stopCh <-chan struct{}) (<-chan *store.KVPair, error) { + kv := s.client.KV() + watchCh := make(chan *store.KVPair) + + go func() { + defer close(watchCh) + + // Use a wait time in order to check if we should quit + // from time to time. + opts := &api.QueryOptions{WaitTime: DefaultWatchWaitTime} + + for { + // Check if we should quit + select { + case <-stopCh: + return + default: + } + + // Get the key + pair, meta, err := kv.Get(key, opts) + if err != nil { + return + } + + // If LastIndex didn't change then it means `Get` returned + // because of the WaitTime and the key didn't changed. + if opts.WaitIndex == meta.LastIndex { + continue + } + opts.WaitIndex = meta.LastIndex + + // Return the value to the channel + // FIXME: What happens when a key is deleted? + if pair != nil { + watchCh <- &store.KVPair{ + Key: pair.Key, + Value: pair.Value, + LastIndex: pair.ModifyIndex, + } + } + } + }() + + return watchCh, nil +} + +// WatchTree watches for changes on a "directory" +// It returns a channel that will receive changes or pass +// on errors. Upon creating a watch, the current childs values +// will be sent to the channel .Providing a non-nil stopCh can +// be used to stop watching. +func (s *Consul) WatchTree(directory string, stopCh <-chan struct{}) (<-chan []*store.KVPair, error) { + kv := s.client.KV() + watchCh := make(chan []*store.KVPair) + + go func() { + defer close(watchCh) + + // Use a wait time in order to check if we should quit + // from time to time. + opts := &api.QueryOptions{WaitTime: DefaultWatchWaitTime} + for { + // Check if we should quit + select { + case <-stopCh: + return + default: + } + + // Get all the childrens + pairs, meta, err := kv.List(directory, opts) + if err != nil { + return + } + + // If LastIndex didn't change then it means `Get` returned + // because of the WaitTime and the child keys didn't change. + if opts.WaitIndex == meta.LastIndex { + continue + } + opts.WaitIndex = meta.LastIndex + + // Return children KV pairs to the channel + kvpairs := []*store.KVPair{} + for _, pair := range pairs { + if pair.Key == directory { + continue + } + kvpairs = append(kvpairs, &store.KVPair{ + Key: pair.Key, + Value: pair.Value, + LastIndex: pair.ModifyIndex, + }) + } + watchCh <- kvpairs + } + }() + + return watchCh, nil +} + +// NewLock returns a handle to a lock struct which can +// be used to provide mutual exclusion on a key +func (s *Consul) NewLock(key string, options *store.LockOptions) (store.Locker, error) { + lockOpts := &api.LockOptions{ + Key: s.normalize(key), + } + + lock := &consulLock{} + + if options != nil { + // Set optional TTL on Lock + if options.TTL != 0 { + entry := &api.SessionEntry{ + Behavior: api.SessionBehaviorRelease, // Release the lock when the session expires + TTL: (options.TTL / 2).String(), // Consul multiplies the TTL by 2x + LockDelay: 1 * time.Millisecond, // Virtually disable lock delay + } + + // Create the key session + session, _, err := s.client.Session().Create(entry, nil) + if err != nil { + return nil, err + } + + // Place the session on lock + lockOpts.Session = session + + // Renew the session ttl lock periodically + go s.client.Session().RenewPeriodic(entry.TTL, session, nil, options.RenewLock) + lock.renewCh = options.RenewLock + } + + // Set optional value on Lock + if options.Value != nil { + lockOpts.Value = options.Value + } + } + + l, err := s.client.LockOpts(lockOpts) + if err != nil { + return nil, err + } + + lock.lock = l + return lock, nil +} + +// Lock attempts to acquire the lock and blocks while +// doing so. It returns a channel that is closed if our +// lock is lost or if an error occurs +func (l *consulLock) Lock(stopChan chan struct{}) (<-chan struct{}, error) { + return l.lock.Lock(stopChan) +} + +// Unlock the "key". Calling unlock while +// not holding the lock will throw an error +func (l *consulLock) Unlock() error { + if l.renewCh != nil { + close(l.renewCh) + } + return l.lock.Unlock() +} + +// AtomicPut put a value at "key" if the key has not been +// modified in the meantime, throws an error if this is the case +func (s *Consul) AtomicPut(key string, value []byte, previous *store.KVPair, options *store.WriteOptions) (bool, *store.KVPair, error) { + + p := &api.KVPair{Key: s.normalize(key), Value: value, Flags: api.LockFlagValue} + + if previous == nil { + // Consul interprets ModifyIndex = 0 as new key. + p.ModifyIndex = 0 + } else { + p.ModifyIndex = previous.LastIndex + } + + ok, _, err := s.client.KV().CAS(p, nil) + if err != nil { + return false, nil, err + } + if !ok { + if previous == nil { + return false, nil, store.ErrKeyExists + } + return false, nil, store.ErrKeyModified + } + + pair, err := s.Get(key) + if err != nil { + return false, nil, err + } + + return true, pair, nil +} + +// AtomicDelete deletes a value at "key" if the key has not +// been modified in the meantime, throws an error if this is the case +func (s *Consul) AtomicDelete(key string, previous *store.KVPair) (bool, error) { + if previous == nil { + return false, store.ErrPreviousNotSpecified + } + + p := &api.KVPair{Key: s.normalize(key), ModifyIndex: previous.LastIndex, Flags: api.LockFlagValue} + + // Extra Get operation to check on the key + _, err := s.Get(key) + if err != nil && err == store.ErrKeyNotFound { + return false, err + } + + if work, _, err := s.client.KV().DeleteCAS(p, nil); err != nil { + return false, err + } else if !work { + return false, store.ErrKeyModified + } + + return true, nil +} + +// Close closes the client connection +func (s *Consul) Close() { + return +} diff --git a/Godeps/_workspace/src/github.com/docker/libkv/store/etcd/etcd.go b/Godeps/_workspace/src/github.com/docker/libkv/store/etcd/etcd.go new file mode 100644 index 0000000..76ade11 --- /dev/null +++ b/Godeps/_workspace/src/github.com/docker/libkv/store/etcd/etcd.go @@ -0,0 +1,597 @@ +package etcd + +import ( + "crypto/tls" + "errors" + "log" + "net" + "net/http" + "strings" + "time" + + "github.com/sorintlab/stolon/Godeps/_workspace/src/golang.org/x/net/context" + + etcd "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/coreos/etcd/client" + "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/docker/libkv" + "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/docker/libkv/store" +) + +var ( + // ErrAbortTryLock is thrown when a user stops trying to seek the lock + // by sending a signal to the stop chan, this is used to verify if the + // operation succeeded + ErrAbortTryLock = errors.New("lock operation aborted") +) + +// Etcd is the receiver type for the +// Store interface +type Etcd struct { + client etcd.KeysAPI +} + +type etcdLock struct { + client etcd.KeysAPI + stopLock chan struct{} + stopRenew chan struct{} + key string + value string + last *etcd.Response + ttl time.Duration +} + +const ( + periodicSync = 5 * time.Minute + defaultLockTTL = 20 * time.Second + defaultUpdateTime = 5 * time.Second +) + +// Register registers etcd to libkv +func Register() { + libkv.AddStore(store.ETCD, New) +} + +// New creates a new Etcd client given a list +// of endpoints and an optional tls config +func New(addrs []string, options *store.Config) (store.Store, error) { + s := &Etcd{} + + var ( + entries []string + err error + ) + + entries = store.CreateEndpoints(addrs, "http") + cfg := &etcd.Config{ + Endpoints: entries, + Transport: etcd.DefaultTransport, + HeaderTimeoutPerRequest: 3 * time.Second, + } + + // Set options + if options != nil { + if options.TLS != nil { + setTLS(cfg, options.TLS, addrs) + } + if options.ConnectionTimeout != 0 { + setTimeout(cfg, options.ConnectionTimeout) + } + } + + c, err := etcd.New(*cfg) + if err != nil { + log.Fatal(err) + } + + s.client = etcd.NewKeysAPI(c) + + // Periodic Cluster Sync + go func() { + for { + if err := c.AutoSync(context.Background(), periodicSync); err != nil { + return + } + } + }() + + return s, nil +} + +// SetTLS sets the tls configuration given a tls.Config scheme +func setTLS(cfg *etcd.Config, tls *tls.Config, addrs []string) { + entries := store.CreateEndpoints(addrs, "https") + cfg.Endpoints = entries + + // Set transport + t := http.Transport{ + Dial: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + }).Dial, + TLSHandshakeTimeout: 10 * time.Second, + TLSClientConfig: tls, + } + + cfg.Transport = &t +} + +// setTimeout sets the timeout used for connecting to the store +func setTimeout(cfg *etcd.Config, time time.Duration) { + cfg.HeaderTimeoutPerRequest = time +} + +// Normalize the key for usage in Etcd +func (s *Etcd) normalize(key string) string { + key = store.Normalize(key) + return strings.TrimPrefix(key, "/") +} + +// keyNotFound checks on the error returned by the KeysAPI +// to verify if the key exists in the store or not +func keyNotFound(err error) bool { + if err != nil { + if etcdError, ok := err.(etcd.Error); ok { + if etcdError.Code == etcd.ErrorCodeKeyNotFound || + etcdError.Code == etcd.ErrorCodeNotFile || + etcdError.Code == etcd.ErrorCodeNotDir { + return true + } + } + } + return false +} + +// Get the value at "key", returns the last modified +// index to use in conjunction to Atomic calls +func (s *Etcd) Get(key string) (pair *store.KVPair, err error) { + getOpts := &etcd.GetOptions{ + Quorum: true, + } + + result, err := s.client.Get(context.Background(), s.normalize(key), getOpts) + if err != nil { + if keyNotFound(err) { + return nil, store.ErrKeyNotFound + } + return nil, err + } + + pair = &store.KVPair{ + Key: key, + Value: []byte(result.Node.Value), + LastIndex: result.Node.ModifiedIndex, + } + + return pair, nil +} + +// Put a value at "key" +func (s *Etcd) Put(key string, value []byte, opts *store.WriteOptions) error { + setOpts := &etcd.SetOptions{} + + // Set options + if opts != nil { + setOpts.Dir = opts.IsDir + setOpts.TTL = opts.TTL + } + + _, err := s.client.Set(context.Background(), s.normalize(key), string(value), setOpts) + return err +} + +// Delete a value at "key" +func (s *Etcd) Delete(key string) error { + opts := &etcd.DeleteOptions{ + Recursive: false, + } + + _, err := s.client.Delete(context.Background(), s.normalize(key), opts) + if keyNotFound(err) { + return store.ErrKeyNotFound + } + return err +} + +// Exists checks if the key exists inside the store +func (s *Etcd) Exists(key string) (bool, error) { + _, err := s.Get(key) + if err != nil { + if err == store.ErrKeyNotFound { + return false, nil + } + return false, err + } + return true, nil +} + +// Watch for changes on a "key" +// It returns a channel that will receive changes or pass +// on errors. Upon creation, the current value will first +// be sent to the channel. Providing a non-nil stopCh can +// be used to stop watching. +func (s *Etcd) Watch(key string, stopCh <-chan struct{}) (<-chan *store.KVPair, error) { + opts := &etcd.WatcherOptions{Recursive: false} + watcher := s.client.Watcher(s.normalize(key), opts) + + // watchCh is sending back events to the caller + watchCh := make(chan *store.KVPair) + + go func() { + defer close(watchCh) + + // Get the current value + pair, err := s.Get(key) + if err != nil { + return + } + + // Push the current value through the channel. + watchCh <- pair + + for { + // Check if the watch was stopped by the caller + select { + case <-stopCh: + return + default: + } + + result, err := watcher.Next(context.Background()) + + if err != nil { + return + } + + watchCh <- &store.KVPair{ + Key: key, + Value: []byte(result.Node.Value), + LastIndex: result.Node.ModifiedIndex, + } + } + }() + + return watchCh, nil +} + +// WatchTree watches for changes on a "directory" +// It returns a channel that will receive changes or pass +// on errors. Upon creating a watch, the current childs values +// will be sent to the channel. Providing a non-nil stopCh can +// be used to stop watching. +func (s *Etcd) WatchTree(directory string, stopCh <-chan struct{}) (<-chan []*store.KVPair, error) { + watchOpts := &etcd.WatcherOptions{Recursive: true} + watcher := s.client.Watcher(s.normalize(directory), watchOpts) + + // watchCh is sending back events to the caller + watchCh := make(chan []*store.KVPair) + + go func() { + defer close(watchCh) + + // Get child values + list, err := s.List(directory) + if err != nil { + return + } + + // Push the current value through the channel. + watchCh <- list + + for { + // Check if the watch was stopped by the caller + select { + case <-stopCh: + return + default: + } + + _, err := watcher.Next(context.Background()) + + if err != nil { + return + } + + list, err = s.List(directory) + if err != nil { + return + } + + watchCh <- list + } + }() + + return watchCh, nil +} + +// AtomicPut puts a value at "key" if the key has not been +// modified in the meantime, throws an error if this is the case +func (s *Etcd) AtomicPut(key string, value []byte, previous *store.KVPair, opts *store.WriteOptions) (bool, *store.KVPair, error) { + var ( + meta *etcd.Response + err error + ) + + setOpts := &etcd.SetOptions{} + + if previous != nil { + setOpts.PrevExist = etcd.PrevExist + setOpts.PrevIndex = previous.LastIndex + if previous.Value != nil { + setOpts.PrevValue = string(previous.Value) + } + } else { + setOpts.PrevExist = etcd.PrevNoExist + } + + if opts != nil { + if opts.TTL > 0 { + setOpts.TTL = opts.TTL + } + } + + meta, err = s.client.Set(context.Background(), s.normalize(key), string(value), setOpts) + if err != nil { + if etcdError, ok := err.(etcd.Error); ok { + // Compare failed + if etcdError.Code == etcd.ErrorCodeTestFailed { + return false, nil, store.ErrKeyModified + } + // Node exists error (when PrevNoExist) + if etcdError.Code == etcd.ErrorCodeNodeExist { + return false, nil, store.ErrKeyExists + } + } + return false, nil, err + } + + updated := &store.KVPair{ + Key: key, + Value: value, + LastIndex: meta.Node.ModifiedIndex, + } + + return true, updated, nil +} + +// AtomicDelete deletes a value at "key" if the key +// has not been modified in the meantime, throws an +// error if this is the case +func (s *Etcd) AtomicDelete(key string, previous *store.KVPair) (bool, error) { + if previous == nil { + return false, store.ErrPreviousNotSpecified + } + + delOpts := &etcd.DeleteOptions{} + + if previous != nil { + delOpts.PrevIndex = previous.LastIndex + if previous.Value != nil { + delOpts.PrevValue = string(previous.Value) + } + } + + _, err := s.client.Delete(context.Background(), s.normalize(key), delOpts) + if err != nil { + if etcdError, ok := err.(etcd.Error); ok { + // Key Not Found + if etcdError.Code == etcd.ErrorCodeKeyNotFound { + return false, store.ErrKeyNotFound + } + // Compare failed + if etcdError.Code == etcd.ErrorCodeTestFailed { + return false, store.ErrKeyModified + } + } + return false, err + } + + return true, nil +} + +// List child nodes of a given directory +func (s *Etcd) List(directory string) ([]*store.KVPair, error) { + getOpts := &etcd.GetOptions{ + Quorum: true, + Recursive: true, + Sort: true, + } + + resp, err := s.client.Get(context.Background(), s.normalize(directory), getOpts) + if err != nil { + if keyNotFound(err) { + return nil, store.ErrKeyNotFound + } + return nil, err + } + + kv := []*store.KVPair{} + for _, n := range resp.Node.Nodes { + kv = append(kv, &store.KVPair{ + Key: n.Key, + Value: []byte(n.Value), + LastIndex: n.ModifiedIndex, + }) + } + return kv, nil +} + +// DeleteTree deletes a range of keys under a given directory +func (s *Etcd) DeleteTree(directory string) error { + delOpts := &etcd.DeleteOptions{ + Recursive: true, + } + + _, err := s.client.Delete(context.Background(), s.normalize(directory), delOpts) + if keyNotFound(err) { + return store.ErrKeyNotFound + } + return err +} + +// NewLock returns a handle to a lock struct which can +// be used to provide mutual exclusion on a key +func (s *Etcd) NewLock(key string, options *store.LockOptions) (lock store.Locker, err error) { + var value string + ttl := defaultLockTTL + renewCh := make(chan struct{}) + + // Apply options on Lock + if options != nil { + if options.Value != nil { + value = string(options.Value) + } + if options.TTL != 0 { + ttl = options.TTL + } + if options.RenewLock != nil { + renewCh = options.RenewLock + } + } + + // Create lock object + lock = &etcdLock{ + client: s.client, + stopRenew: renewCh, + key: s.normalize(key), + value: value, + ttl: ttl, + } + + return lock, nil +} + +// Lock attempts to acquire the lock and blocks while +// doing so. It returns a channel that is closed if our +// lock is lost or if an error occurs +func (l *etcdLock) Lock(stopChan chan struct{}) (<-chan struct{}, error) { + + // Lock holder channel + lockHeld := make(chan struct{}) + stopLocking := l.stopRenew + + setOpts := &etcd.SetOptions{ + TTL: l.ttl, + } + + for { + setOpts.PrevExist = etcd.PrevNoExist + resp, err := l.client.Set(context.Background(), l.key, l.value, setOpts) + if err != nil { + if etcdError, ok := err.(etcd.Error); ok { + if etcdError.Code != etcd.ErrorCodeNodeExist { + return nil, err + } + setOpts.PrevIndex = ^uint64(0) + } + } else { + setOpts.PrevIndex = resp.Node.ModifiedIndex + } + + setOpts.PrevExist = etcd.PrevExist + l.last, err = l.client.Set(context.Background(), l.key, l.value, setOpts) + + if err == nil { + // Leader section + l.stopLock = stopLocking + go l.holdLock(l.key, lockHeld, stopLocking) + break + } else { + // If this is a legitimate error, return + if etcdError, ok := err.(etcd.Error); ok { + if etcdError.Code != etcd.ErrorCodeTestFailed { + return nil, err + } + } + + // Seeker section + errorCh := make(chan error) + chWStop := make(chan bool) + free := make(chan bool) + + go l.waitLock(l.key, errorCh, chWStop, free) + + // Wait for the key to be available or for + // a signal to stop trying to lock the key + select { + case _ = <-free: + break + case err := <-errorCh: + return nil, err + case _ = <-stopChan: + return nil, ErrAbortTryLock + } + + // Delete or Expire event occured + // Retry + } + } + + return lockHeld, nil +} + +// Hold the lock as long as we can +// Updates the key ttl periodically until we receive +// an explicit stop signal from the Unlock method +func (l *etcdLock) holdLock(key string, lockHeld chan struct{}, stopLocking <-chan struct{}) { + defer close(lockHeld) + + update := time.NewTicker(l.ttl / 3) + defer update.Stop() + + var err error + setOpts := &etcd.SetOptions{TTL: l.ttl} + + for { + select { + case <-update.C: + setOpts.PrevIndex = l.last.Node.ModifiedIndex + l.last, err = l.client.Set(context.Background(), key, l.value, setOpts) + if err != nil { + return + } + + case <-stopLocking: + return + } + } +} + +// WaitLock simply waits for the key to be available for creation +func (l *etcdLock) waitLock(key string, errorCh chan error, stopWatchCh chan bool, free chan<- bool) { + opts := &etcd.WatcherOptions{Recursive: false} + watcher := l.client.Watcher(key, opts) + + for { + event, err := watcher.Next(context.Background()) + if err != nil { + errorCh <- err + return + } + if event.Action == "delete" || event.Action == "expire" { + free <- true + return + } + } +} + +// Unlock the "key". Calling unlock while +// not holding the lock will throw an error +func (l *etcdLock) Unlock() error { + if l.stopLock != nil { + l.stopLock <- struct{}{} + } + if l.last != nil { + delOpts := &etcd.DeleteOptions{ + PrevIndex: l.last.Node.ModifiedIndex, + } + _, err := l.client.Delete(context.Background(), l.key, delOpts) + if err != nil { + return err + } + } + return nil +} + +// Close closes the client connection +func (s *Etcd) Close() { + return +} diff --git a/Godeps/_workspace/src/github.com/docker/libkv/store/helpers.go b/Godeps/_workspace/src/github.com/docker/libkv/store/helpers.go new file mode 100644 index 0000000..0fb74c9 --- /dev/null +++ b/Godeps/_workspace/src/github.com/docker/libkv/store/helpers.go @@ -0,0 +1,47 @@ +package store + +import ( + "strings" +) + +// CreateEndpoints creates a list of endpoints given the right scheme +func CreateEndpoints(addrs []string, scheme string) (entries []string) { + for _, addr := range addrs { + entries = append(entries, scheme+"://"+addr) + } + return entries +} + +// Normalize the key for each store to the form: +// +// /path/to/key +// +func Normalize(key string) string { + return "/" + join(SplitKey(key)) +} + +// GetDirectory gets the full directory part of +// the key to the form: +// +// /path/to/ +// +func GetDirectory(key string) string { + parts := SplitKey(key) + parts = parts[:len(parts)-1] + return "/" + join(parts) +} + +// SplitKey splits the key to extract path informations +func SplitKey(key string) (path []string) { + if strings.Contains(key, "/") { + path = strings.Split(key, "/") + } else { + path = []string{key} + } + return path +} + +// join the path parts with '/' +func join(parts []string) string { + return strings.Join(parts, "/") +} diff --git a/Godeps/_workspace/src/github.com/docker/libkv/store/mock/mock.go b/Godeps/_workspace/src/github.com/docker/libkv/store/mock/mock.go new file mode 100644 index 0000000..2f2c17c --- /dev/null +++ b/Godeps/_workspace/src/github.com/docker/libkv/store/mock/mock.go @@ -0,0 +1,113 @@ +package mock + +import ( + "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/docker/libkv/store" + "github.com/stretchr/testify/mock" +) + +// Mock store. Mocks all Store functions using testify.Mock +type Mock struct { + mock.Mock + + // Endpoints passed to InitializeMock + Endpoints []string + + // Options passed to InitializeMock + Options *store.Config +} + +// New creates a Mock store +func New(endpoints []string, options *store.Config) (store.Store, error) { + s := &Mock{} + s.Endpoints = endpoints + s.Options = options + return s, nil +} + +// Put mock +func (s *Mock) Put(key string, value []byte, opts *store.WriteOptions) error { + args := s.Mock.Called(key, value, opts) + return args.Error(0) +} + +// Get mock +func (s *Mock) Get(key string) (*store.KVPair, error) { + args := s.Mock.Called(key) + return args.Get(0).(*store.KVPair), args.Error(1) +} + +// Delete mock +func (s *Mock) Delete(key string) error { + args := s.Mock.Called(key) + return args.Error(0) +} + +// Exists mock +func (s *Mock) Exists(key string) (bool, error) { + args := s.Mock.Called(key) + return args.Bool(0), args.Error(1) +} + +// Watch mock +func (s *Mock) Watch(key string, stopCh <-chan struct{}) (<-chan *store.KVPair, error) { + args := s.Mock.Called(key, stopCh) + return args.Get(0).(<-chan *store.KVPair), args.Error(1) +} + +// WatchTree mock +func (s *Mock) WatchTree(prefix string, stopCh <-chan struct{}) (<-chan []*store.KVPair, error) { + args := s.Mock.Called(prefix, stopCh) + return args.Get(0).(chan []*store.KVPair), args.Error(1) +} + +// NewLock mock +func (s *Mock) NewLock(key string, options *store.LockOptions) (store.Locker, error) { + args := s.Mock.Called(key, options) + return args.Get(0).(store.Locker), args.Error(1) +} + +// List mock +func (s *Mock) List(prefix string) ([]*store.KVPair, error) { + args := s.Mock.Called(prefix) + return args.Get(0).([]*store.KVPair), args.Error(1) +} + +// DeleteTree mock +func (s *Mock) DeleteTree(prefix string) error { + args := s.Mock.Called(prefix) + return args.Error(0) +} + +// AtomicPut mock +func (s *Mock) AtomicPut(key string, value []byte, previous *store.KVPair, opts *store.WriteOptions) (bool, *store.KVPair, error) { + args := s.Mock.Called(key, value, previous, opts) + return args.Bool(0), args.Get(1).(*store.KVPair), args.Error(2) +} + +// AtomicDelete mock +func (s *Mock) AtomicDelete(key string, previous *store.KVPair) (bool, error) { + args := s.Mock.Called(key, previous) + return args.Bool(0), args.Error(1) +} + +// Lock mock implementation of Locker +type Lock struct { + mock.Mock +} + +// Lock mock +func (l *Lock) Lock(stopCh chan struct{}) (<-chan struct{}, error) { + args := l.Mock.Called(stopCh) + return args.Get(0).(<-chan struct{}), args.Error(1) +} + +// Unlock mock +func (l *Lock) Unlock() error { + args := l.Mock.Called() + return args.Error(0) +} + +// Close mock +func (s *Mock) Close() { + return +} diff --git a/Godeps/_workspace/src/github.com/docker/libkv/store/store.go b/Godeps/_workspace/src/github.com/docker/libkv/store/store.go new file mode 100644 index 0000000..22b0ce4 --- /dev/null +++ b/Godeps/_workspace/src/github.com/docker/libkv/store/store.go @@ -0,0 +1,130 @@ +package store + +import ( + "crypto/tls" + "errors" + "time" +) + +// Backend represents a KV Store Backend +type Backend string + +const ( + // CONSUL backend + CONSUL Backend = "consul" + // ETCD backend + ETCD Backend = "etcd" + // ZK backend + ZK Backend = "zk" + // BOLTDB backend + BOLTDB Backend = "boltdb" +) + +var ( + // ErrBackendNotSupported is thrown when the backend k/v store is not supported by libkv + ErrBackendNotSupported = errors.New("Backend storage not supported yet, please choose one of") + // ErrCallNotSupported is thrown when a method is not implemented/supported by the current backend + ErrCallNotSupported = errors.New("The current call is not supported with this backend") + // ErrNotReachable is thrown when the API cannot be reached for issuing common store operations + ErrNotReachable = errors.New("Api not reachable") + // ErrCannotLock is thrown when there is an error acquiring a lock on a key + ErrCannotLock = errors.New("Error acquiring the lock") + // ErrKeyModified is thrown during an atomic operation if the index does not match the one in the store + ErrKeyModified = errors.New("Unable to complete atomic operation, key modified") + // ErrKeyNotFound is thrown when the key is not found in the store during a Get operation + ErrKeyNotFound = errors.New("Key not found in store") + // ErrPreviousNotSpecified is thrown when the previous value is not specified for an atomic operation + ErrPreviousNotSpecified = errors.New("Previous K/V pair should be provided for the Atomic operation") + // ErrKeyExists is thrown when the previous value exists in the case of an AtomicPut + ErrKeyExists = errors.New("Previous K/V pair exists, cannnot complete Atomic operation") +) + +// Config contains the options for a storage client +type Config struct { + ClientTLS *ClientTLSConfig + TLS *tls.Config + ConnectionTimeout time.Duration + Bucket string + PersistConnection bool +} + +// ClientTLSConfig contains data for a Client TLS configuration in the form +// the etcd client wants it. Eventually we'll adapt it for ZK and Consul. +type ClientTLSConfig struct { + CertFile string + KeyFile string + CACertFile string +} + +// Store represents the backend K/V storage +// Each store should support every call listed +// here. Or it couldn't be implemented as a K/V +// backend for libkv +type Store interface { + // Put a value at the specified key + Put(key string, value []byte, options *WriteOptions) error + + // Get a value given its key + Get(key string) (*KVPair, error) + + // Delete the value at the specified key + Delete(key string) error + + // Verify if a Key exists in the store + Exists(key string) (bool, error) + + // Watch for changes on a key + Watch(key string, stopCh <-chan struct{}) (<-chan *KVPair, error) + + // WatchTree watches for changes on child nodes under + // a given directory + WatchTree(directory string, stopCh <-chan struct{}) (<-chan []*KVPair, error) + + // NewLock creates a lock for a given key. + // The returned Locker is not held and must be acquired + // with `.Lock`. The Value is optional. + NewLock(key string, options *LockOptions) (Locker, error) + + // List the content of a given prefix + List(directory string) ([]*KVPair, error) + + // DeleteTree deletes a range of keys under a given directory + DeleteTree(directory string) error + + // Atomic CAS operation on a single value. + // Pass previous = nil to create a new key. + AtomicPut(key string, value []byte, previous *KVPair, options *WriteOptions) (bool, *KVPair, error) + + // Atomic delete of a single value + AtomicDelete(key string, previous *KVPair) (bool, error) + + // Close the store connection + Close() +} + +// KVPair represents {Key, Value, Lastindex} tuple +type KVPair struct { + Key string + Value []byte + LastIndex uint64 +} + +// WriteOptions contains optional request parameters +type WriteOptions struct { + IsDir bool + TTL time.Duration +} + +// LockOptions contains optional request parameters +type LockOptions struct { + Value []byte // Optional, value to associate with the lock + TTL time.Duration // Optional, expiration ttl associated with the lock + RenewLock chan struct{} // Optional, chan used to control and stop the session ttl renewal for the lock +} + +// Locker provides locking mechanism on top of the store. +// Similar to `sync.Lock` except it may return errors. +type Locker interface { + Lock(stopChan chan struct{}) (<-chan struct{}, error) + Unlock() error +} diff --git a/Godeps/_workspace/src/github.com/docker/libkv/store/zookeeper/zookeeper.go b/Godeps/_workspace/src/github.com/docker/libkv/store/zookeeper/zookeeper.go new file mode 100644 index 0000000..f4a46ca --- /dev/null +++ b/Godeps/_workspace/src/github.com/docker/libkv/store/zookeeper/zookeeper.go @@ -0,0 +1,429 @@ +package zookeeper + +import ( + "strings" + "time" + + zk "github.com/samuel/go-zookeeper/zk" + "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/docker/libkv" + "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/docker/libkv/store" +) + +const ( + // SOH control character + SOH = "\x01" + + defaultTimeout = 10 * time.Second +) + +// Zookeeper is the receiver type for +// the Store interface +type Zookeeper struct { + timeout time.Duration + client *zk.Conn +} + +type zookeeperLock struct { + client *zk.Conn + lock *zk.Lock + key string + value []byte +} + +// Register registers zookeeper to libkv +func Register() { + libkv.AddStore(store.ZK, New) +} + +// New creates a new Zookeeper client given a +// list of endpoints and an optional tls config +func New(endpoints []string, options *store.Config) (store.Store, error) { + s := &Zookeeper{} + s.timeout = defaultTimeout + + // Set options + if options != nil { + if options.ConnectionTimeout != 0 { + s.setTimeout(options.ConnectionTimeout) + } + } + + // Connect to Zookeeper + conn, _, err := zk.Connect(endpoints, s.timeout) + if err != nil { + return nil, err + } + s.client = conn + + return s, nil +} + +// setTimeout sets the timeout for connecting to Zookeeper +func (s *Zookeeper) setTimeout(time time.Duration) { + s.timeout = time +} + +// Get the value at "key", returns the last modified index +// to use in conjunction to Atomic calls +func (s *Zookeeper) Get(key string) (pair *store.KVPair, err error) { + resp, meta, err := s.client.Get(s.normalize(key)) + + if err != nil { + if err == zk.ErrNoNode { + return nil, store.ErrKeyNotFound + } + return nil, err + } + + // FIXME handle very rare cases where Get returns the + // SOH control character instead of the actual value + if string(resp) == SOH { + return s.Get(store.Normalize(key)) + } + + pair = &store.KVPair{ + Key: key, + Value: resp, + LastIndex: uint64(meta.Version), + } + + return pair, nil +} + +// createFullPath creates the entire path for a directory +// that does not exist +func (s *Zookeeper) createFullPath(path []string, ephemeral bool) error { + for i := 1; i <= len(path); i++ { + newpath := "/" + strings.Join(path[:i], "/") + if i == len(path) && ephemeral { + _, err := s.client.Create(newpath, []byte{}, zk.FlagEphemeral, zk.WorldACL(zk.PermAll)) + return err + } + _, err := s.client.Create(newpath, []byte{}, 0, zk.WorldACL(zk.PermAll)) + if err != nil { + // Skip if node already exists + if err != zk.ErrNodeExists { + return err + } + } + } + return nil +} + +// Put a value at "key" +func (s *Zookeeper) Put(key string, value []byte, opts *store.WriteOptions) error { + fkey := s.normalize(key) + + exists, err := s.Exists(key) + if err != nil { + return err + } + + if !exists { + if opts != nil && opts.TTL > 0 { + s.createFullPath(store.SplitKey(strings.TrimSuffix(key, "/")), true) + } else { + s.createFullPath(store.SplitKey(strings.TrimSuffix(key, "/")), false) + } + } + + _, err = s.client.Set(fkey, value, -1) + return err +} + +// Delete a value at "key" +func (s *Zookeeper) Delete(key string) error { + err := s.client.Delete(s.normalize(key), -1) + if err == zk.ErrNoNode { + return store.ErrKeyNotFound + } + return err +} + +// Exists checks if the key exists inside the store +func (s *Zookeeper) Exists(key string) (bool, error) { + exists, _, err := s.client.Exists(s.normalize(key)) + if err != nil { + return false, err + } + return exists, nil +} + +// Watch for changes on a "key" +// It returns a channel that will receive changes or pass +// on errors. Upon creation, the current value will first +// be sent to the channel. Providing a non-nil stopCh can +// be used to stop watching. +func (s *Zookeeper) Watch(key string, stopCh <-chan struct{}) (<-chan *store.KVPair, error) { + // Get the key first + pair, err := s.Get(key) + if err != nil { + return nil, err + } + + // Catch zk notifications and fire changes into the channel. + watchCh := make(chan *store.KVPair) + go func() { + defer close(watchCh) + + // Get returns the current value to the channel prior + // to listening to any event that may occur on that key + watchCh <- pair + for { + _, _, eventCh, err := s.client.GetW(s.normalize(key)) + if err != nil { + return + } + select { + case e := <-eventCh: + if e.Type == zk.EventNodeDataChanged { + if entry, err := s.Get(key); err == nil { + watchCh <- entry + } + } + case <-stopCh: + // There is no way to stop GetW so just quit + return + } + } + }() + + return watchCh, nil +} + +// WatchTree watches for changes on a "directory" +// It returns a channel that will receive changes or pass +// on errors. Upon creating a watch, the current childs values +// will be sent to the channel .Providing a non-nil stopCh can +// be used to stop watching. +func (s *Zookeeper) WatchTree(directory string, stopCh <-chan struct{}) (<-chan []*store.KVPair, error) { + // List the childrens first + entries, err := s.List(directory) + if err != nil { + return nil, err + } + + // Catch zk notifications and fire changes into the channel. + watchCh := make(chan []*store.KVPair) + go func() { + defer close(watchCh) + + // List returns the children values to the channel + // prior to listening to any events that may occur + // on those keys + watchCh <- entries + + for { + _, _, eventCh, err := s.client.ChildrenW(s.normalize(directory)) + if err != nil { + return + } + select { + case e := <-eventCh: + if e.Type == zk.EventNodeChildrenChanged { + if kv, err := s.List(directory); err == nil { + watchCh <- kv + } + } + case <-stopCh: + // There is no way to stop GetW so just quit + return + } + } + }() + + return watchCh, nil +} + +// List child nodes of a given directory +func (s *Zookeeper) List(directory string) ([]*store.KVPair, error) { + keys, stat, err := s.client.Children(s.normalize(directory)) + if err != nil { + if err == zk.ErrNoNode { + return nil, store.ErrKeyNotFound + } + return nil, err + } + + kv := []*store.KVPair{} + + // FIXME Costly Get request for each child key.. + for _, key := range keys { + pair, err := s.Get(strings.TrimSuffix(directory, "/") + s.normalize(key)) + if err != nil { + // If node is not found: List is out of date, retry + if err == zk.ErrNoNode { + return s.List(directory) + } + return nil, err + } + + kv = append(kv, &store.KVPair{ + Key: key, + Value: []byte(pair.Value), + LastIndex: uint64(stat.Version), + }) + } + + return kv, nil +} + +// DeleteTree deletes a range of keys under a given directory +func (s *Zookeeper) DeleteTree(directory string) error { + pairs, err := s.List(directory) + if err != nil { + return err + } + + var reqs []interface{} + + for _, pair := range pairs { + reqs = append(reqs, &zk.DeleteRequest{ + Path: s.normalize(directory + "/" + pair.Key), + Version: -1, + }) + } + + _, err = s.client.Multi(reqs...) + return err +} + +// AtomicPut put a value at "key" if the key has not been +// modified in the meantime, throws an error if this is the case +func (s *Zookeeper) AtomicPut(key string, value []byte, previous *store.KVPair, _ *store.WriteOptions) (bool, *store.KVPair, error) { + var lastIndex uint64 + + if previous != nil { + meta, err := s.client.Set(s.normalize(key), value, int32(previous.LastIndex)) + if err != nil { + // Compare Failed + if err == zk.ErrBadVersion { + return false, nil, store.ErrKeyModified + } + return false, nil, err + } + lastIndex = uint64(meta.Version) + } else { + // Interpret previous == nil as create operation. + _, err := s.client.Create(s.normalize(key), value, 0, zk.WorldACL(zk.PermAll)) + if err != nil { + // Directory does not exist + if err == zk.ErrNoNode { + + // Create the directory + parts := store.SplitKey(strings.TrimSuffix(key, "/")) + parts = parts[:len(parts)-1] + if err = s.createFullPath(parts, false); err != nil { + // Failed to create the directory. + return false, nil, err + } + + // Create the node + if _, err := s.client.Create(s.normalize(key), value, 0, zk.WorldACL(zk.PermAll)); err != nil { + // Node exist error (when previous nil) + if err == zk.ErrNodeExists { + return false, nil, store.ErrKeyExists + } + return false, nil, err + } + + } else { + // Node Exists error (when previous nil) + if err == zk.ErrNodeExists { + return false, nil, store.ErrKeyExists + } + + // Unhandled error + return false, nil, err + } + } + lastIndex = 0 // Newly created nodes have version 0. + } + + pair := &store.KVPair{ + Key: key, + Value: value, + LastIndex: lastIndex, + } + + return true, pair, nil +} + +// AtomicDelete deletes a value at "key" if the key +// has not been modified in the meantime, throws an +// error if this is the case +func (s *Zookeeper) AtomicDelete(key string, previous *store.KVPair) (bool, error) { + if previous == nil { + return false, store.ErrPreviousNotSpecified + } + + err := s.client.Delete(s.normalize(key), int32(previous.LastIndex)) + if err != nil { + // Key not found + if err == zk.ErrNoNode { + return false, store.ErrKeyNotFound + } + // Compare failed + if err == zk.ErrBadVersion { + return false, store.ErrKeyModified + } + // General store error + return false, err + } + return true, nil +} + +// NewLock returns a handle to a lock struct which can +// be used to provide mutual exclusion on a key +func (s *Zookeeper) NewLock(key string, options *store.LockOptions) (lock store.Locker, err error) { + value := []byte("") + + // Apply options + if options != nil { + if options.Value != nil { + value = options.Value + } + } + + lock = &zookeeperLock{ + client: s.client, + key: s.normalize(key), + value: value, + lock: zk.NewLock(s.client, s.normalize(key), zk.WorldACL(zk.PermAll)), + } + + return lock, err +} + +// Lock attempts to acquire the lock and blocks while +// doing so. It returns a channel that is closed if our +// lock is lost or if an error occurs +func (l *zookeeperLock) Lock(stopChan chan struct{}) (<-chan struct{}, error) { + err := l.lock.Lock() + + if err == nil { + // We hold the lock, we can set our value + // FIXME: The value is left behind + // (problematic for leader election) + _, err = l.client.Set(l.key, l.value, -1) + } + + return make(chan struct{}), err +} + +// Unlock the "key". Calling unlock while +// not holding the lock will throw an error +func (l *zookeeperLock) Unlock() error { + return l.lock.Unlock() +} + +// Close closes the client connection +func (s *Zookeeper) Close() { + s.client.Close() +} + +// Normalize the key for usage in Zookeeper +func (s *Zookeeper) normalize(key string) string { + key = store.Normalize(key) + return strings.TrimSuffix(key, "/") +} diff --git a/Godeps/_workspace/src/github.com/docker/libkv/testutils/utils.go b/Godeps/_workspace/src/github.com/docker/libkv/testutils/utils.go new file mode 100644 index 0000000..99aae6d --- /dev/null +++ b/Godeps/_workspace/src/github.com/docker/libkv/testutils/utils.go @@ -0,0 +1,622 @@ +package testutils + +import ( + "fmt" + "testing" + "time" + + "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/docker/libkv/store" + "github.com/stretchr/testify/assert" +) + +// RunTestCommon tests the minimal required APIs which +// should be supported by all K/V backends +func RunTestCommon(t *testing.T, kv store.Store) { + testPutGetDeleteExists(t, kv) + testList(t, kv) + testDeleteTree(t, kv) +} + +// RunTestAtomic tests the Atomic operations by the K/V +// backends +func RunTestAtomic(t *testing.T, kv store.Store) { + testAtomicPut(t, kv) + testAtomicPutCreate(t, kv) + testAtomicPutWithSlashSuffixKey(t, kv) + testAtomicDelete(t, kv) +} + +// RunTestWatch tests the watch/monitor APIs supported +// by the K/V backends. +func RunTestWatch(t *testing.T, kv store.Store) { + testWatch(t, kv) + testWatchTree(t, kv) +} + +// RunTestLock tests the KV pair Lock/Unlock APIs supported +// by the K/V backends. +func RunTestLock(t *testing.T, kv store.Store) { + testLockUnlock(t, kv) +} + +// RunTestLockTTL tests the KV pair Lock with TTL APIs supported +// by the K/V backends. +func RunTestLockTTL(t *testing.T, kv store.Store, backup store.Store) { + testLockTTL(t, kv, backup) +} + +// RunTestTTL tests the TTL funtionality of the K/V backend. +func RunTestTTL(t *testing.T, kv store.Store, backup store.Store) { + testPutTTL(t, kv, backup) +} + +func testPutGetDeleteExists(t *testing.T, kv store.Store) { + // Get a not exist key should return ErrKeyNotFound + pair, err := kv.Get("testPutGetDelete_not_exist_key") + assert.Equal(t, store.ErrKeyNotFound, err) + + value := []byte("bar") + for _, key := range []string{ + "testPutGetDeleteExists", + "testPutGetDeleteExists/", + "testPutGetDeleteExists/testbar/", + "testPutGetDeleteExists/testbar/testfoobar", + } { + failMsg := fmt.Sprintf("Fail key %s", key) + + // Put the key + err = kv.Put(key, value, nil) + assert.NoError(t, err, failMsg) + + // Get should return the value and an incremented index + pair, err = kv.Get(key) + assert.NoError(t, err, failMsg) + if assert.NotNil(t, pair, failMsg) { + assert.NotNil(t, pair.Value, failMsg) + } + assert.Equal(t, pair.Value, value, failMsg) + assert.NotEqual(t, pair.LastIndex, 0, failMsg) + + // Exists should return true + exists, err := kv.Exists(key) + assert.NoError(t, err, failMsg) + assert.True(t, exists, failMsg) + + // Delete the key + err = kv.Delete(key) + assert.NoError(t, err, failMsg) + + // Get should fail + pair, err = kv.Get(key) + assert.Error(t, err, failMsg) + assert.Nil(t, pair, failMsg) + + // Exists should return false + exists, err = kv.Exists(key) + assert.NoError(t, err, failMsg) + assert.False(t, exists, failMsg) + } +} + +func testWatch(t *testing.T, kv store.Store) { + key := "testWatch" + value := []byte("world") + newValue := []byte("world!") + + // Put the key + err := kv.Put(key, value, nil) + assert.NoError(t, err) + + stopCh := make(<-chan struct{}) + events, err := kv.Watch(key, stopCh) + assert.NoError(t, err) + assert.NotNil(t, events) + + // Update loop + go func() { + timeout := time.After(1 * time.Second) + tick := time.Tick(250 * time.Millisecond) + for { + select { + case <-timeout: + return + case <-tick: + err := kv.Put(key, newValue, nil) + if assert.NoError(t, err) { + continue + } + return + } + } + }() + + // Check for updates + eventCount := 1 + for { + select { + case event := <-events: + assert.NotNil(t, event) + if eventCount == 1 { + assert.Equal(t, event.Key, key) + assert.Equal(t, event.Value, value) + } else { + assert.Equal(t, event.Key, key) + assert.Equal(t, event.Value, newValue) + } + eventCount++ + // We received all the events we wanted to check + if eventCount >= 4 { + return + } + case <-time.After(4 * time.Second): + t.Fatal("Timeout reached") + return + } + } +} + +func testWatchTree(t *testing.T, kv store.Store) { + dir := "testWatchTree" + + node1 := "testWatchTree/node1" + value1 := []byte("node1") + + node2 := "testWatchTree/node2" + value2 := []byte("node2") + + node3 := "testWatchTree/node3" + value3 := []byte("node3") + + err := kv.Put(node1, value1, nil) + assert.NoError(t, err) + err = kv.Put(node2, value2, nil) + assert.NoError(t, err) + err = kv.Put(node3, value3, nil) + assert.NoError(t, err) + + stopCh := make(<-chan struct{}) + events, err := kv.WatchTree(dir, stopCh) + assert.NoError(t, err) + assert.NotNil(t, events) + + // Update loop + go func() { + timeout := time.After(500 * time.Millisecond) + for { + select { + case <-timeout: + err := kv.Delete(node3) + assert.NoError(t, err) + return + } + } + }() + + // Check for updates + eventCount := 1 + for { + select { + case event := <-events: + assert.NotNil(t, event) + // We received the Delete event on a child node + // Exit test successfully + if eventCount == 2 { + return + } + eventCount++ + case <-time.After(4 * time.Second): + t.Fatal("Timeout reached") + return + } + } +} + +func testAtomicPut(t *testing.T, kv store.Store) { + key := "testAtomicPut" + value := []byte("world") + + // Put the key + err := kv.Put(key, value, nil) + assert.NoError(t, err) + + // Get should return the value and an incremented index + pair, err := kv.Get(key) + assert.NoError(t, err) + if assert.NotNil(t, pair) { + assert.NotNil(t, pair.Value) + } + assert.Equal(t, pair.Value, value) + assert.NotEqual(t, pair.LastIndex, 0) + + // This CAS should fail: previous exists. + success, _, err := kv.AtomicPut(key, []byte("WORLD"), nil, nil) + assert.Error(t, err) + assert.False(t, success) + + // This CAS should succeed + success, _, err = kv.AtomicPut(key, []byte("WORLD"), pair, nil) + assert.NoError(t, err) + assert.True(t, success) + + // This CAS should fail, key exists. + pair.LastIndex = 6744 + success, _, err = kv.AtomicPut(key, []byte("WORLDWORLD"), pair, nil) + assert.Error(t, err) + assert.False(t, success) +} + +func testAtomicPutCreate(t *testing.T, kv store.Store) { + // Use a key in a new directory to ensure Stores will create directories + // that don't yet exist. + key := "testAtomicPutCreate/create" + value := []byte("putcreate") + + // AtomicPut the key, previous = nil indicates create. + success, _, err := kv.AtomicPut(key, value, nil, nil) + assert.NoError(t, err) + assert.True(t, success) + + // Get should return the value and an incremented index + pair, err := kv.Get(key) + assert.NoError(t, err) + if assert.NotNil(t, pair) { + assert.NotNil(t, pair.Value) + } + assert.Equal(t, pair.Value, value) + + // Attempting to create again should fail. + success, _, err = kv.AtomicPut(key, value, nil, nil) + assert.Error(t, store.ErrKeyExists) + assert.False(t, success) + + // This CAS should succeed, since it has the value from Get() + success, _, err = kv.AtomicPut(key, []byte("PUTCREATE"), pair, nil) + assert.NoError(t, err) + assert.True(t, success) +} + +func testAtomicPutWithSlashSuffixKey(t *testing.T, kv store.Store) { + k1 := "testAtomicPutWithSlashSuffixKey/key/" + success, _, err := kv.AtomicPut(k1, []byte{}, nil, nil) + assert.Nil(t, err) + assert.True(t, success) +} + +func testAtomicDelete(t *testing.T, kv store.Store) { + key := "testAtomicDelete" + value := []byte("world") + + // Put the key + err := kv.Put(key, value, nil) + assert.NoError(t, err) + + // Get should return the value and an incremented index + pair, err := kv.Get(key) + assert.NoError(t, err) + if assert.NotNil(t, pair) { + assert.NotNil(t, pair.Value) + } + assert.Equal(t, pair.Value, value) + assert.NotEqual(t, pair.LastIndex, 0) + + tempIndex := pair.LastIndex + + // AtomicDelete should fail + pair.LastIndex = 6744 + success, err := kv.AtomicDelete(key, pair) + assert.Error(t, err) + assert.False(t, success) + + // AtomicDelete should succeed + pair.LastIndex = tempIndex + success, err = kv.AtomicDelete(key, pair) + assert.NoError(t, err) + assert.True(t, success) + + // Delete a non-existent key; should fail + success, err = kv.AtomicDelete(key, pair) + assert.Error(t, store.ErrKeyNotFound) + assert.False(t, success) +} + +func testLockUnlock(t *testing.T, kv store.Store) { + key := "testLockUnlock" + value := []byte("bar") + + // We should be able to create a new lock on key + lock, err := kv.NewLock(key, &store.LockOptions{Value: value, TTL: 2 * time.Second}) + assert.NoError(t, err) + assert.NotNil(t, lock) + + // Lock should successfully succeed or block + lockChan, err := lock.Lock(nil) + assert.NoError(t, err) + assert.NotNil(t, lockChan) + + // Get should work + pair, err := kv.Get(key) + assert.NoError(t, err) + if assert.NotNil(t, pair) { + assert.NotNil(t, pair.Value) + } + assert.Equal(t, pair.Value, value) + assert.NotEqual(t, pair.LastIndex, 0) + + // Unlock should succeed + err = lock.Unlock() + assert.NoError(t, err) + + // Lock should succeed again + lockChan, err = lock.Lock(nil) + assert.NoError(t, err) + assert.NotNil(t, lockChan) + + // Get should work + pair, err = kv.Get(key) + assert.NoError(t, err) + if assert.NotNil(t, pair) { + assert.NotNil(t, pair.Value) + } + assert.Equal(t, pair.Value, value) + assert.NotEqual(t, pair.LastIndex, 0) + + err = lock.Unlock() + assert.NoError(t, err) +} + +func testLockTTL(t *testing.T, kv store.Store, otherConn store.Store) { + key := "testLockTTL" + value := []byte("bar") + + renewCh := make(chan struct{}) + + // We should be able to create a new lock on key + lock, err := otherConn.NewLock(key, &store.LockOptions{ + Value: value, + TTL: 2 * time.Second, + RenewLock: renewCh, + }) + assert.NoError(t, err) + assert.NotNil(t, lock) + + // Lock should successfully succeed + lockChan, err := lock.Lock(nil) + assert.NoError(t, err) + assert.NotNil(t, lockChan) + + // Get should work + pair, err := otherConn.Get(key) + assert.NoError(t, err) + if assert.NotNil(t, pair) { + assert.NotNil(t, pair.Value) + } + assert.Equal(t, pair.Value, value) + assert.NotEqual(t, pair.LastIndex, 0) + + time.Sleep(3 * time.Second) + + done := make(chan struct{}) + stop := make(chan struct{}) + + value = []byte("foobar") + + // Create a new lock with another connection + lock, err = kv.NewLock( + key, + &store.LockOptions{ + Value: value, + TTL: 3 * time.Second, + }, + ) + assert.NoError(t, err) + assert.NotNil(t, lock) + + // Lock should block, the session on the lock + // is still active and renewed periodically + go func(<-chan struct{}) { + _, _ = lock.Lock(stop) + done <- struct{}{} + }(done) + + select { + case _ = <-done: + t.Fatal("Lock succeeded on a key that is supposed to be locked by another client") + case <-time.After(4 * time.Second): + // Stop requesting the lock as we are blocked as expected + stop <- struct{}{} + break + } + + // Close the connection + otherConn.Close() + + // Force stop the session renewal for the lock + close(renewCh) + + // Let the session on the lock expire + time.Sleep(3 * time.Second) + locked := make(chan struct{}) + + // Lock should now succeed for the other client + go func(<-chan struct{}) { + lockChan, err = lock.Lock(nil) + assert.NoError(t, err) + assert.NotNil(t, lockChan) + locked <- struct{}{} + }(locked) + + select { + case _ = <-locked: + break + case <-time.After(4 * time.Second): + t.Fatal("Unable to take the lock, timed out") + } + + // Get should work with the new value + pair, err = kv.Get(key) + assert.NoError(t, err) + if assert.NotNil(t, pair) { + assert.NotNil(t, pair.Value) + } + assert.Equal(t, pair.Value, value) + assert.NotEqual(t, pair.LastIndex, 0) + + err = lock.Unlock() + assert.NoError(t, err) +} + +func testPutTTL(t *testing.T, kv store.Store, otherConn store.Store) { + firstKey := "testPutTTL" + firstValue := []byte("foo") + + secondKey := "second" + secondValue := []byte("bar") + + // Put the first key with the Ephemeral flag + err := otherConn.Put(firstKey, firstValue, &store.WriteOptions{TTL: 2 * time.Second}) + assert.NoError(t, err) + + // Put a second key with the Ephemeral flag + err = otherConn.Put(secondKey, secondValue, &store.WriteOptions{TTL: 2 * time.Second}) + assert.NoError(t, err) + + // Get on firstKey should work + pair, err := kv.Get(firstKey) + assert.NoError(t, err) + assert.NotNil(t, pair) + + // Get on secondKey should work + pair, err = kv.Get(secondKey) + assert.NoError(t, err) + assert.NotNil(t, pair) + + // Close the connection + otherConn.Close() + + // Let the session expire + time.Sleep(3 * time.Second) + + // Get on firstKey shouldn't work + pair, err = kv.Get(firstKey) + assert.Error(t, err) + assert.Nil(t, pair) + + // Get on secondKey shouldn't work + pair, err = kv.Get(secondKey) + assert.Error(t, err) + assert.Nil(t, pair) +} + +func testList(t *testing.T, kv store.Store) { + prefix := "testList" + + firstKey := "testList/first" + firstValue := []byte("first") + + secondKey := "testList/second" + secondValue := []byte("second") + + // Put the first key + err := kv.Put(firstKey, firstValue, nil) + assert.NoError(t, err) + + // Put the second key + err = kv.Put(secondKey, secondValue, nil) + assert.NoError(t, err) + + // List should work and return the two correct values + for _, parent := range []string{prefix, prefix + "/"} { + pairs, err := kv.List(parent) + assert.NoError(t, err) + if assert.NotNil(t, pairs) { + assert.Equal(t, len(pairs), 2) + } + + // Check pairs, those are not necessarily in Put order + for _, pair := range pairs { + if pair.Key == firstKey { + assert.Equal(t, pair.Value, firstValue) + } + if pair.Key == secondKey { + assert.Equal(t, pair.Value, secondValue) + } + } + } + + // List should fail: the key does not exist + pairs, err := kv.List("idontexist") + assert.Equal(t, store.ErrKeyNotFound, err) + assert.Nil(t, pairs) +} + +func testDeleteTree(t *testing.T, kv store.Store) { + prefix := "testDeleteTree" + + firstKey := "testDeleteTree/first" + firstValue := []byte("first") + + secondKey := "testDeleteTree/second" + secondValue := []byte("second") + + // Put the first key + err := kv.Put(firstKey, firstValue, nil) + assert.NoError(t, err) + + // Put the second key + err = kv.Put(secondKey, secondValue, nil) + assert.NoError(t, err) + + // Get should work on the first Key + pair, err := kv.Get(firstKey) + assert.NoError(t, err) + if assert.NotNil(t, pair) { + assert.NotNil(t, pair.Value) + } + assert.Equal(t, pair.Value, firstValue) + assert.NotEqual(t, pair.LastIndex, 0) + + // Get should work on the second Key + pair, err = kv.Get(secondKey) + assert.NoError(t, err) + if assert.NotNil(t, pair) { + assert.NotNil(t, pair.Value) + } + assert.Equal(t, pair.Value, secondValue) + assert.NotEqual(t, pair.LastIndex, 0) + + // Delete Values under directory `nodes` + err = kv.DeleteTree(prefix) + assert.NoError(t, err) + + // Get should fail on both keys + pair, err = kv.Get(firstKey) + assert.Error(t, err) + assert.Nil(t, pair) + + pair, err = kv.Get(secondKey) + assert.Error(t, err) + assert.Nil(t, pair) +} + +// RunCleanup cleans up keys introduced by the tests +func RunCleanup(t *testing.T, kv store.Store) { + for _, key := range []string{ + "testAtomicPutWithSlashSuffixKey", + "testPutGetDeleteExists", + "testWatch", + "testWatchTree", + "testAtomicPut", + "testAtomicPutCreate", + "testAtomicDelete", + "testLockUnlock", + "testLockTTL", + "testPutTTL", + "testList", + "testDeleteTree", + } { + err := kv.DeleteTree(key) + assert.True(t, err == nil || err == store.ErrKeyNotFound, fmt.Sprintf("failed to delete tree key %s: %v", key, err)) + err = kv.Delete(key) + assert.True(t, err == nil || err == store.ErrKeyNotFound, fmt.Sprintf("failed to delete key %s: %v", key, err)) + } +} diff --git a/Godeps/_workspace/src/github.com/docker/swarm/leadership/README.md b/Godeps/_workspace/src/github.com/docker/swarm/leadership/README.md new file mode 100644 index 0000000..8b33c2a --- /dev/null +++ b/Godeps/_workspace/src/github.com/docker/swarm/leadership/README.md @@ -0,0 +1,110 @@ +# Leadership: Distributed Leader Election for Clustered Environments. + +Leadership is a library for a cluster leader election on top of a distributed +Key/Value store. + +It's built using Swarm's `pkg/store` and is designed to work across multiple +storage backends. + +You can use `leadership` with `Consul`, `etcd` and `Zookeeper`. + +```go +// Create a store using pkg/store. +client, err := store.NewStore("consul", []string{"127.0.0.1:8500"}, &store.Config{}) +if err != nil { + panic(err) +} + +underwood := leadership.NewCandidate(client, "service/swarm/leader", "underwood", 15*time.Second) +electedCh, _, err := underwood.RunForElection() +if err != nil { + log.Fatal("Cannot run for election, store is probably down") +} + +for isElected := range electedCh { + // This loop will run every time there is a change in our leadership + // status. + + if isElected { + // We won the election - we are now the leader. + // Let's do leader stuff, for example, sleep for a while. + log.Printf("I won the election! I'm now the leader") + time.Sleep(10 * time.Second) + + // Tired of being a leader? You can resign anytime. + candidate.Resign() + } else { + // We lost the election but are still running for leadership. + // `elected == false` is the default state and is the first event + // we'll receive from the channel. After a successful election, + // this event can get triggered if someone else steals the + // leadership or if we resign. + + log.Printf("Lost the election, let's try another time") + } +} +``` + +It is possible to follow an election in real-time and get notified whenever +there is a change in leadership: +```go +follower := leadership.NewFollower(client, "service/swarm/leader") +leaderCh, _, err := follower.FollowElection() +if err != nil { + log.Fatal("Cannot follow the election, store is probably down") +} +for leader := range leaderCh { + // Leader is a string containing the value passed to `NewCandidate`. + log.Printf("%s is now the leader", leader) +} +``` + +A typical use case for this is to be able to always send requests to the current +leader. + +## Fault tolerance + +Leadership returns an error channel for Candidates and Followers that you can use +to be resilient to failures. For example, if the watch on the leader key fails +because the store becomes unavailable, you can retry the process later. + +```go +func participate() { + // Create a store using pkg/store. + client, err := store.NewStore("consul", []string{"127.0.0.1:8500"}, &store.Config{}) + if err != nil { + panic(err) + } + + waitTime := 10 * time.Second + underwood := leadership.NewCandidate(client, "service/swarm/leader", "underwood", 15*time.Second) + + go func() { + for { + run(underwood) + time.Sleep(waitTime) + // retry + } + } +} + +func run(candidate *leadership.Candidate) { + electedCh, errCh, err := candidate.RunForElection() + if err != nil { + return + } + for { + select { + case elected := <-electedCh: + if isElected { + // Do something + } else { + // Do something else + } + + case err := <-errCh: + log.Error(err) + return + } +} +``` diff --git a/Godeps/_workspace/src/github.com/docker/swarm/leadership/candidate.go b/Godeps/_workspace/src/github.com/docker/swarm/leadership/candidate.go new file mode 100644 index 0000000..b1de251 --- /dev/null +++ b/Godeps/_workspace/src/github.com/docker/swarm/leadership/candidate.go @@ -0,0 +1,136 @@ +package leadership + +import ( + "sync" + "time" + + "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/docker/libkv/store" +) + +const ( + defaultLockTTL = 15 * time.Second +) + +// Candidate runs the leader election algorithm asynchronously +type Candidate struct { + client store.Store + key string + node string + + electedCh chan bool + lock sync.Mutex + lockTTL time.Duration + leader bool + stopCh chan struct{} + resignCh chan bool + errCh chan error +} + +// NewCandidate creates a new Candidate +func NewCandidate(client store.Store, key, node string, ttl time.Duration) *Candidate { + return &Candidate{ + client: client, + key: key, + node: node, + + leader: false, + lockTTL: ttl, + resignCh: make(chan bool), + stopCh: make(chan struct{}), + } +} + +// IsLeader returns true if the candidate is currently a leader. +func (c *Candidate) IsLeader() bool { + return c.leader +} + +// RunForElection starts the leader election algorithm. Updates in status are +// pushed through the ElectedCh channel. +// +// ElectedCh is used to get a channel which delivers signals on +// acquiring or losing leadership. It sends true if we become +// the leader, and false if we lose it. +func (c *Candidate) RunForElection() (<-chan bool, <-chan error, error) { + c.electedCh = make(chan bool) + c.errCh = make(chan error) + + lockOpts := &store.LockOptions{ + Value: []byte(c.node), + } + + if c.lockTTL != defaultLockTTL { + lockOpts.TTL = c.lockTTL + lockOpts.RenewLock = make(chan struct{}) + } + + lock, err := c.client.NewLock(c.key, lockOpts) + + if err != nil { + return nil, nil, err + } + + go c.campaign(lock) + + return c.electedCh, c.errCh, nil +} + +// Stop running for election. +func (c *Candidate) Stop() { + close(c.stopCh) +} + +// Resign forces the candidate to step-down and try again. +// If the candidate is not a leader, it doesn't have any effect. +// Candidate will retry immediately to acquire the leadership. If no-one else +// took it, then the Candidate will end up being a leader again. +func (c *Candidate) Resign() { + c.lock.Lock() + defer c.lock.Unlock() + + if c.leader { + c.resignCh <- true + } +} + +func (c *Candidate) update(status bool) { + c.lock.Lock() + defer c.lock.Unlock() + + c.leader = status + c.electedCh <- status +} + +func (c *Candidate) campaign(lock store.Locker) { + defer close(c.electedCh) + defer close(c.errCh) + + for { + // Start as a follower. + c.update(false) + + lostCh, err := lock.Lock(nil) + if err != nil { + c.errCh <- err + return + } + + // Hooray! We acquired the lock therefore we are the new leader. + c.update(true) + + select { + case <-c.resignCh: + // We were asked to resign, give up the lock and go back + // campaigning. + lock.Unlock() + case <-c.stopCh: + // Give up the leadership and quit. + if c.leader { + lock.Unlock() + } + return + case <-lostCh: + // We lost the lock. Someone else is the leader, try again. + } + } +} diff --git a/Godeps/_workspace/src/github.com/docker/swarm/leadership/follower.go b/Godeps/_workspace/src/github.com/docker/swarm/leadership/follower.go new file mode 100644 index 0000000..eab50ee --- /dev/null +++ b/Godeps/_workspace/src/github.com/docker/swarm/leadership/follower.go @@ -0,0 +1,74 @@ +package leadership + +import ( + "errors" + + "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/docker/libkv/store" +) + +// Follower can follow an election in real-time and push notifications whenever +// there is a change in leadership. +type Follower struct { + client store.Store + key string + + leader string + leaderCh chan string + stopCh chan struct{} + errCh chan error +} + +// NewFollower creates a new follower. +func NewFollower(client store.Store, key string) *Follower { + return &Follower{ + client: client, + key: key, + stopCh: make(chan struct{}), + } +} + +// Leader returns the current leader. +func (f *Follower) Leader() string { + return f.leader +} + +// FollowElection starts monitoring the election. +func (f *Follower) FollowElection() (<-chan string, <-chan error, error) { + f.leaderCh = make(chan string) + f.errCh = make(chan error) + + ch, err := f.client.Watch(f.key, f.stopCh) + if err != nil { + return nil, nil, err + } + + go f.follow(ch) + + return f.leaderCh, f.errCh, nil +} + +// Stop stops monitoring an election. +func (f *Follower) Stop() { + close(f.stopCh) +} + +func (f *Follower) follow(ch <-chan *store.KVPair) { + defer close(f.leaderCh) + defer close(f.errCh) + + f.leader = "" + for kv := range ch { + if kv == nil { + continue + } + curr := string(kv.Value) + if curr == f.leader { + continue + } + f.leader = curr + f.leaderCh <- f.leader + } + + // Channel closed, we return an error + f.errCh <- errors.New("Leader Election: watch leader channel closed, the store may be unavailable...") +} diff --git a/Godeps/_workspace/src/github.com/hashicorp/consul/api/README.md b/Godeps/_workspace/src/github.com/hashicorp/consul/api/README.md new file mode 100644 index 0000000..7e64988 --- /dev/null +++ b/Godeps/_workspace/src/github.com/hashicorp/consul/api/README.md @@ -0,0 +1,43 @@ +Consul API client +================= + +This package provides the `api` package which attempts to +provide programmatic access to the full Consul API. + +Currently, all of the Consul APIs included in version 0.6.0 are supported. + +Documentation +============= + +The full documentation is available on [Godoc](https://godoc.org/github.com/hashicorp/consul/api) + +Usage +===== + +Below is an example of using the Consul client: + +```go +// Get a new client +client, err := api.NewClient(api.DefaultConfig()) +if err != nil { + panic(err) +} + +// Get a handle to the KV API +kv := client.KV() + +// PUT a new KV pair +p := &api.KVPair{Key: "foo", Value: []byte("test")} +_, err = kv.Put(p, nil) +if err != nil { + panic(err) +} + +// Lookup the pair +pair, _, err := kv.Get("foo", nil) +if err != nil { + panic(err) +} +fmt.Printf("KV: %v", pair) + +``` diff --git a/Godeps/_workspace/src/github.com/hashicorp/consul/api/acl.go b/Godeps/_workspace/src/github.com/hashicorp/consul/api/acl.go new file mode 100644 index 0000000..c3fb0d5 --- /dev/null +++ b/Godeps/_workspace/src/github.com/hashicorp/consul/api/acl.go @@ -0,0 +1,140 @@ +package api + +const ( + // ACLCLientType is the client type token + ACLClientType = "client" + + // ACLManagementType is the management type token + ACLManagementType = "management" +) + +// ACLEntry is used to represent an ACL entry +type ACLEntry struct { + CreateIndex uint64 + ModifyIndex uint64 + ID string + Name string + Type string + Rules string +} + +// ACL can be used to query the ACL endpoints +type ACL struct { + c *Client +} + +// ACL returns a handle to the ACL endpoints +func (c *Client) ACL() *ACL { + return &ACL{c} +} + +// Create is used to generate a new token with the given parameters +func (a *ACL) Create(acl *ACLEntry, q *WriteOptions) (string, *WriteMeta, error) { + r := a.c.newRequest("PUT", "/v1/acl/create") + r.setWriteOptions(q) + r.obj = acl + rtt, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return "", nil, err + } + defer resp.Body.Close() + + wm := &WriteMeta{RequestTime: rtt} + var out struct{ ID string } + if err := decodeBody(resp, &out); err != nil { + return "", nil, err + } + return out.ID, wm, nil +} + +// Update is used to update the rules of an existing token +func (a *ACL) Update(acl *ACLEntry, q *WriteOptions) (*WriteMeta, error) { + r := a.c.newRequest("PUT", "/v1/acl/update") + r.setWriteOptions(q) + r.obj = acl + rtt, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + wm := &WriteMeta{RequestTime: rtt} + return wm, nil +} + +// Destroy is used to destroy a given ACL token ID +func (a *ACL) Destroy(id string, q *WriteOptions) (*WriteMeta, error) { + r := a.c.newRequest("PUT", "/v1/acl/destroy/"+id) + r.setWriteOptions(q) + rtt, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return nil, err + } + resp.Body.Close() + + wm := &WriteMeta{RequestTime: rtt} + return wm, nil +} + +// Clone is used to return a new token cloned from an existing one +func (a *ACL) Clone(id string, q *WriteOptions) (string, *WriteMeta, error) { + r := a.c.newRequest("PUT", "/v1/acl/clone/"+id) + r.setWriteOptions(q) + rtt, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return "", nil, err + } + defer resp.Body.Close() + + wm := &WriteMeta{RequestTime: rtt} + var out struct{ ID string } + if err := decodeBody(resp, &out); err != nil { + return "", nil, err + } + return out.ID, wm, nil +} + +// Info is used to query for information about an ACL token +func (a *ACL) Info(id string, q *QueryOptions) (*ACLEntry, *QueryMeta, error) { + r := a.c.newRequest("GET", "/v1/acl/info/"+id) + r.setQueryOptions(q) + rtt, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + + qm := &QueryMeta{} + parseQueryMeta(resp, qm) + qm.RequestTime = rtt + + var entries []*ACLEntry + if err := decodeBody(resp, &entries); err != nil { + return nil, nil, err + } + if len(entries) > 0 { + return entries[0], qm, nil + } + return nil, qm, nil +} + +// List is used to get all the ACL tokens +func (a *ACL) List(q *QueryOptions) ([]*ACLEntry, *QueryMeta, error) { + r := a.c.newRequest("GET", "/v1/acl/list") + r.setQueryOptions(q) + rtt, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + + qm := &QueryMeta{} + parseQueryMeta(resp, qm) + qm.RequestTime = rtt + + var entries []*ACLEntry + if err := decodeBody(resp, &entries); err != nil { + return nil, nil, err + } + return entries, qm, nil +} diff --git a/Godeps/_workspace/src/github.com/hashicorp/consul/api/agent.go b/Godeps/_workspace/src/github.com/hashicorp/consul/api/agent.go new file mode 100644 index 0000000..e4466a6 --- /dev/null +++ b/Godeps/_workspace/src/github.com/hashicorp/consul/api/agent.go @@ -0,0 +1,337 @@ +package api + +import ( + "fmt" +) + +// AgentCheck represents a check known to the agent +type AgentCheck struct { + Node string + CheckID string + Name string + Status string + Notes string + Output string + ServiceID string + ServiceName string +} + +// AgentService represents a service known to the agent +type AgentService struct { + ID string + Service string + Tags []string + Port int + Address string +} + +// AgentMember represents a cluster member known to the agent +type AgentMember struct { + Name string + Addr string + Port uint16 + Tags map[string]string + Status int + ProtocolMin uint8 + ProtocolMax uint8 + ProtocolCur uint8 + DelegateMin uint8 + DelegateMax uint8 + DelegateCur uint8 +} + +// AgentServiceRegistration is used to register a new service +type AgentServiceRegistration struct { + ID string `json:",omitempty"` + Name string `json:",omitempty"` + Tags []string `json:",omitempty"` + Port int `json:",omitempty"` + Address string `json:",omitempty"` + Check *AgentServiceCheck + Checks AgentServiceChecks +} + +// AgentCheckRegistration is used to register a new check +type AgentCheckRegistration struct { + ID string `json:",omitempty"` + Name string `json:",omitempty"` + Notes string `json:",omitempty"` + ServiceID string `json:",omitempty"` + AgentServiceCheck +} + +// AgentServiceCheck is used to create an associated +// check for a service +type AgentServiceCheck struct { + Script string `json:",omitempty"` + DockerContainerID string `json:",omitempty"` + Shell string `json:",omitempty"` // Only supported for Docker. + Interval string `json:",omitempty"` + Timeout string `json:",omitempty"` + TTL string `json:",omitempty"` + HTTP string `json:",omitempty"` + TCP string `json:",omitempty"` + Status string `json:",omitempty"` +} +type AgentServiceChecks []*AgentServiceCheck + +// Agent can be used to query the Agent endpoints +type Agent struct { + c *Client + + // cache the node name + nodeName string +} + +// Agent returns a handle to the agent endpoints +func (c *Client) Agent() *Agent { + return &Agent{c: c} +} + +// Self is used to query the agent we are speaking to for +// information about itself +func (a *Agent) Self() (map[string]map[string]interface{}, error) { + r := a.c.newRequest("GET", "/v1/agent/self") + _, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + var out map[string]map[string]interface{} + if err := decodeBody(resp, &out); err != nil { + return nil, err + } + return out, nil +} + +// NodeName is used to get the node name of the agent +func (a *Agent) NodeName() (string, error) { + if a.nodeName != "" { + return a.nodeName, nil + } + info, err := a.Self() + if err != nil { + return "", err + } + name := info["Config"]["NodeName"].(string) + a.nodeName = name + return name, nil +} + +// Checks returns the locally registered checks +func (a *Agent) Checks() (map[string]*AgentCheck, error) { + r := a.c.newRequest("GET", "/v1/agent/checks") + _, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + var out map[string]*AgentCheck + if err := decodeBody(resp, &out); err != nil { + return nil, err + } + return out, nil +} + +// Services returns the locally registered services +func (a *Agent) Services() (map[string]*AgentService, error) { + r := a.c.newRequest("GET", "/v1/agent/services") + _, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + var out map[string]*AgentService + if err := decodeBody(resp, &out); err != nil { + return nil, err + } + return out, nil +} + +// Members returns the known gossip members. The WAN +// flag can be used to query a server for WAN members. +func (a *Agent) Members(wan bool) ([]*AgentMember, error) { + r := a.c.newRequest("GET", "/v1/agent/members") + if wan { + r.params.Set("wan", "1") + } + _, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + var out []*AgentMember + if err := decodeBody(resp, &out); err != nil { + return nil, err + } + return out, nil +} + +// ServiceRegister is used to register a new service with +// the local agent +func (a *Agent) ServiceRegister(service *AgentServiceRegistration) error { + r := a.c.newRequest("PUT", "/v1/agent/service/register") + r.obj = service + _, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return err + } + resp.Body.Close() + return nil +} + +// ServiceDeregister is used to deregister a service with +// the local agent +func (a *Agent) ServiceDeregister(serviceID string) error { + r := a.c.newRequest("PUT", "/v1/agent/service/deregister/"+serviceID) + _, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return err + } + resp.Body.Close() + return nil +} + +// PassTTL is used to set a TTL check to the passing state +func (a *Agent) PassTTL(checkID, note string) error { + return a.UpdateTTL(checkID, note, "pass") +} + +// WarnTTL is used to set a TTL check to the warning state +func (a *Agent) WarnTTL(checkID, note string) error { + return a.UpdateTTL(checkID, note, "warn") +} + +// FailTTL is used to set a TTL check to the failing state +func (a *Agent) FailTTL(checkID, note string) error { + return a.UpdateTTL(checkID, note, "fail") +} + +// UpdateTTL is used to update the TTL of a check +func (a *Agent) UpdateTTL(checkID, note, status string) error { + switch status { + case "pass": + case "warn": + case "fail": + default: + return fmt.Errorf("Invalid status: %s", status) + } + endpoint := fmt.Sprintf("/v1/agent/check/%s/%s", status, checkID) + r := a.c.newRequest("PUT", endpoint) + r.params.Set("note", note) + _, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return err + } + resp.Body.Close() + return nil +} + +// CheckRegister is used to register a new check with +// the local agent +func (a *Agent) CheckRegister(check *AgentCheckRegistration) error { + r := a.c.newRequest("PUT", "/v1/agent/check/register") + r.obj = check + _, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return err + } + resp.Body.Close() + return nil +} + +// CheckDeregister is used to deregister a check with +// the local agent +func (a *Agent) CheckDeregister(checkID string) error { + r := a.c.newRequest("PUT", "/v1/agent/check/deregister/"+checkID) + _, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return err + } + resp.Body.Close() + return nil +} + +// Join is used to instruct the agent to attempt a join to +// another cluster member +func (a *Agent) Join(addr string, wan bool) error { + r := a.c.newRequest("PUT", "/v1/agent/join/"+addr) + if wan { + r.params.Set("wan", "1") + } + _, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return err + } + resp.Body.Close() + return nil +} + +// ForceLeave is used to have the agent eject a failed node +func (a *Agent) ForceLeave(node string) error { + r := a.c.newRequest("PUT", "/v1/agent/force-leave/"+node) + _, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return err + } + resp.Body.Close() + return nil +} + +// EnableServiceMaintenance toggles service maintenance mode on +// for the given service ID. +func (a *Agent) EnableServiceMaintenance(serviceID, reason string) error { + r := a.c.newRequest("PUT", "/v1/agent/service/maintenance/"+serviceID) + r.params.Set("enable", "true") + r.params.Set("reason", reason) + _, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return err + } + resp.Body.Close() + return nil +} + +// DisableServiceMaintenance toggles service maintenance mode off +// for the given service ID. +func (a *Agent) DisableServiceMaintenance(serviceID string) error { + r := a.c.newRequest("PUT", "/v1/agent/service/maintenance/"+serviceID) + r.params.Set("enable", "false") + _, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return err + } + resp.Body.Close() + return nil +} + +// EnableNodeMaintenance toggles node maintenance mode on for the +// agent we are connected to. +func (a *Agent) EnableNodeMaintenance(reason string) error { + r := a.c.newRequest("PUT", "/v1/agent/maintenance") + r.params.Set("enable", "true") + r.params.Set("reason", reason) + _, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return err + } + resp.Body.Close() + return nil +} + +// DisableNodeMaintenance toggles node maintenance mode off for the +// agent we are connected to. +func (a *Agent) DisableNodeMaintenance() error { + r := a.c.newRequest("PUT", "/v1/agent/maintenance") + r.params.Set("enable", "false") + _, resp, err := requireOK(a.c.doRequest(r)) + if err != nil { + return err + } + resp.Body.Close() + return nil +} diff --git a/Godeps/_workspace/src/github.com/hashicorp/consul/api/api.go b/Godeps/_workspace/src/github.com/hashicorp/consul/api/api.go new file mode 100644 index 0000000..330ed0e --- /dev/null +++ b/Godeps/_workspace/src/github.com/hashicorp/consul/api/api.go @@ -0,0 +1,475 @@ +package api + +import ( + "bytes" + "crypto/tls" + "encoding/json" + "fmt" + "io" + "log" + "net" + "net/http" + "net/url" + "os" + "strconv" + "strings" + "time" + + "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/hashicorp/go-cleanhttp" +) + +// QueryOptions are used to parameterize a query +type QueryOptions struct { + // Providing a datacenter overwrites the DC provided + // by the Config + Datacenter string + + // AllowStale allows any Consul server (non-leader) to service + // a read. This allows for lower latency and higher throughput + AllowStale bool + + // RequireConsistent forces the read to be fully consistent. + // This is more expensive but prevents ever performing a stale + // read. + RequireConsistent bool + + // WaitIndex is used to enable a blocking query. Waits + // until the timeout or the next index is reached + WaitIndex uint64 + + // WaitTime is used to bound the duration of a wait. + // Defaults to that of the Config, but can be overridden. + WaitTime time.Duration + + // Token is used to provide a per-request ACL token + // which overrides the agent's default token. + Token string + + // Near is used to provide a node name that will sort the results + // in ascending order based on the estimated round trip time from + // that node. Setting this to "_agent" will use the agent's node + // for the sort. + Near string +} + +// WriteOptions are used to parameterize a write +type WriteOptions struct { + // Providing a datacenter overwrites the DC provided + // by the Config + Datacenter string + + // Token is used to provide a per-request ACL token + // which overrides the agent's default token. + Token string +} + +// QueryMeta is used to return meta data about a query +type QueryMeta struct { + // LastIndex. This can be used as a WaitIndex to perform + // a blocking query + LastIndex uint64 + + // Time of last contact from the leader for the + // server servicing the request + LastContact time.Duration + + // Is there a known leader + KnownLeader bool + + // How long did the request take + RequestTime time.Duration +} + +// WriteMeta is used to return meta data about a write +type WriteMeta struct { + // How long did the request take + RequestTime time.Duration +} + +// HttpBasicAuth is used to authenticate http client with HTTP Basic Authentication +type HttpBasicAuth struct { + // Username to use for HTTP Basic Authentication + Username string + + // Password to use for HTTP Basic Authentication + Password string +} + +// Config is used to configure the creation of a client +type Config struct { + // Address is the address of the Consul server + Address string + + // Scheme is the URI scheme for the Consul server + Scheme string + + // Datacenter to use. If not provided, the default agent datacenter is used. + Datacenter string + + // HttpClient is the client to use. Default will be + // used if not provided. + HttpClient *http.Client + + // HttpAuth is the auth info to use for http access. + HttpAuth *HttpBasicAuth + + // WaitTime limits how long a Watch will block. If not provided, + // the agent default values will be used. + WaitTime time.Duration + + // Token is used to provide a per-request ACL token + // which overrides the agent's default token. + Token string +} + +// DefaultConfig returns a default configuration for the client +func DefaultConfig() *Config { + config := &Config{ + Address: "127.0.0.1:8500", + Scheme: "http", + HttpClient: cleanhttp.DefaultClient(), + } + + if addr := os.Getenv("CONSUL_HTTP_ADDR"); addr != "" { + config.Address = addr + } + + if token := os.Getenv("CONSUL_HTTP_TOKEN"); token != "" { + config.Token = token + } + + if auth := os.Getenv("CONSUL_HTTP_AUTH"); auth != "" { + var username, password string + if strings.Contains(auth, ":") { + split := strings.SplitN(auth, ":", 2) + username = split[0] + password = split[1] + } else { + username = auth + } + + config.HttpAuth = &HttpBasicAuth{ + Username: username, + Password: password, + } + } + + if ssl := os.Getenv("CONSUL_HTTP_SSL"); ssl != "" { + enabled, err := strconv.ParseBool(ssl) + if err != nil { + log.Printf("[WARN] client: could not parse CONSUL_HTTP_SSL: %s", err) + } + + if enabled { + config.Scheme = "https" + } + } + + if verify := os.Getenv("CONSUL_HTTP_SSL_VERIFY"); verify != "" { + doVerify, err := strconv.ParseBool(verify) + if err != nil { + log.Printf("[WARN] client: could not parse CONSUL_HTTP_SSL_VERIFY: %s", err) + } + + if !doVerify { + transport := cleanhttp.DefaultTransport() + transport.TLSClientConfig = &tls.Config{ + InsecureSkipVerify: true, + } + config.HttpClient.Transport = transport + } + } + + return config +} + +// Client provides a client to the Consul API +type Client struct { + config Config +} + +// NewClient returns a new client +func NewClient(config *Config) (*Client, error) { + // bootstrap the config + defConfig := DefaultConfig() + + if len(config.Address) == 0 { + config.Address = defConfig.Address + } + + if len(config.Scheme) == 0 { + config.Scheme = defConfig.Scheme + } + + if config.HttpClient == nil { + config.HttpClient = defConfig.HttpClient + } + + if parts := strings.SplitN(config.Address, "unix://", 2); len(parts) == 2 { + trans := cleanhttp.DefaultTransport() + trans.Dial = func(_, _ string) (net.Conn, error) { + return net.Dial("unix", parts[1]) + } + config.HttpClient = &http.Client{ + Transport: trans, + } + config.Address = parts[1] + } + + client := &Client{ + config: *config, + } + return client, nil +} + +// request is used to help build up a request +type request struct { + config *Config + method string + url *url.URL + params url.Values + body io.Reader + obj interface{} +} + +// setQueryOptions is used to annotate the request with +// additional query options +func (r *request) setQueryOptions(q *QueryOptions) { + if q == nil { + return + } + if q.Datacenter != "" { + r.params.Set("dc", q.Datacenter) + } + if q.AllowStale { + r.params.Set("stale", "") + } + if q.RequireConsistent { + r.params.Set("consistent", "") + } + if q.WaitIndex != 0 { + r.params.Set("index", strconv.FormatUint(q.WaitIndex, 10)) + } + if q.WaitTime != 0 { + r.params.Set("wait", durToMsec(q.WaitTime)) + } + if q.Token != "" { + r.params.Set("token", q.Token) + } + if q.Near != "" { + r.params.Set("near", q.Near) + } +} + +// durToMsec converts a duration to a millisecond specified string. If the +// user selected a positive value that rounds to 0 ms, then we will use 1 ms +// so they get a short delay, otherwise Consul will translate the 0 ms into +// a huge default delay. +func durToMsec(dur time.Duration) string { + ms := dur / time.Millisecond + if dur > 0 && ms == 0 { + ms = 1 + } + return fmt.Sprintf("%dms", ms) +} + +// serverError is a string we look for to detect 500 errors. +const serverError = "Unexpected response code: 500" + +// IsServerError returns true for 500 errors from the Consul servers, these are +// usually retryable at a later time. +func IsServerError(err error) bool { + if err == nil { + return false + } + + // TODO (slackpad) - Make a real error type here instead of using + // a string check. + return strings.Contains(err.Error(), serverError) +} + +// setWriteOptions is used to annotate the request with +// additional write options +func (r *request) setWriteOptions(q *WriteOptions) { + if q == nil { + return + } + if q.Datacenter != "" { + r.params.Set("dc", q.Datacenter) + } + if q.Token != "" { + r.params.Set("token", q.Token) + } +} + +// toHTTP converts the request to an HTTP request +func (r *request) toHTTP() (*http.Request, error) { + // Encode the query parameters + r.url.RawQuery = r.params.Encode() + + // Check if we should encode the body + if r.body == nil && r.obj != nil { + if b, err := encodeBody(r.obj); err != nil { + return nil, err + } else { + r.body = b + } + } + + // Create the HTTP request + req, err := http.NewRequest(r.method, r.url.RequestURI(), r.body) + if err != nil { + return nil, err + } + + req.URL.Host = r.url.Host + req.URL.Scheme = r.url.Scheme + req.Host = r.url.Host + + // Setup auth + if r.config.HttpAuth != nil { + req.SetBasicAuth(r.config.HttpAuth.Username, r.config.HttpAuth.Password) + } + + return req, nil +} + +// newRequest is used to create a new request +func (c *Client) newRequest(method, path string) *request { + r := &request{ + config: &c.config, + method: method, + url: &url.URL{ + Scheme: c.config.Scheme, + Host: c.config.Address, + Path: path, + }, + params: make(map[string][]string), + } + if c.config.Datacenter != "" { + r.params.Set("dc", c.config.Datacenter) + } + if c.config.WaitTime != 0 { + r.params.Set("wait", durToMsec(r.config.WaitTime)) + } + if c.config.Token != "" { + r.params.Set("token", r.config.Token) + } + return r +} + +// doRequest runs a request with our client +func (c *Client) doRequest(r *request) (time.Duration, *http.Response, error) { + req, err := r.toHTTP() + if err != nil { + return 0, nil, err + } + start := time.Now() + resp, err := c.config.HttpClient.Do(req) + diff := time.Now().Sub(start) + return diff, resp, err +} + +// Query is used to do a GET request against an endpoint +// and deserialize the response into an interface using +// standard Consul conventions. +func (c *Client) query(endpoint string, out interface{}, q *QueryOptions) (*QueryMeta, error) { + r := c.newRequest("GET", endpoint) + r.setQueryOptions(q) + rtt, resp, err := requireOK(c.doRequest(r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + qm := &QueryMeta{} + parseQueryMeta(resp, qm) + qm.RequestTime = rtt + + if err := decodeBody(resp, out); err != nil { + return nil, err + } + return qm, nil +} + +// write is used to do a PUT request against an endpoint +// and serialize/deserialized using the standard Consul conventions. +func (c *Client) write(endpoint string, in, out interface{}, q *WriteOptions) (*WriteMeta, error) { + r := c.newRequest("PUT", endpoint) + r.setWriteOptions(q) + r.obj = in + rtt, resp, err := requireOK(c.doRequest(r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + wm := &WriteMeta{RequestTime: rtt} + if out != nil { + if err := decodeBody(resp, &out); err != nil { + return nil, err + } + } + return wm, nil +} + +// parseQueryMeta is used to help parse query meta-data +func parseQueryMeta(resp *http.Response, q *QueryMeta) error { + header := resp.Header + + // Parse the X-Consul-Index + index, err := strconv.ParseUint(header.Get("X-Consul-Index"), 10, 64) + if err != nil { + return fmt.Errorf("Failed to parse X-Consul-Index: %v", err) + } + q.LastIndex = index + + // Parse the X-Consul-LastContact + last, err := strconv.ParseUint(header.Get("X-Consul-LastContact"), 10, 64) + if err != nil { + return fmt.Errorf("Failed to parse X-Consul-LastContact: %v", err) + } + q.LastContact = time.Duration(last) * time.Millisecond + + // Parse the X-Consul-KnownLeader + switch header.Get("X-Consul-KnownLeader") { + case "true": + q.KnownLeader = true + default: + q.KnownLeader = false + } + return nil +} + +// decodeBody is used to JSON decode a body +func decodeBody(resp *http.Response, out interface{}) error { + dec := json.NewDecoder(resp.Body) + return dec.Decode(out) +} + +// encodeBody is used to encode a request body +func encodeBody(obj interface{}) (io.Reader, error) { + buf := bytes.NewBuffer(nil) + enc := json.NewEncoder(buf) + if err := enc.Encode(obj); err != nil { + return nil, err + } + return buf, nil +} + +// requireOK is used to wrap doRequest and check for a 200 +func requireOK(d time.Duration, resp *http.Response, e error) (time.Duration, *http.Response, error) { + if e != nil { + if resp != nil { + resp.Body.Close() + } + return d, nil, e + } + if resp.StatusCode != 200 { + var buf bytes.Buffer + io.Copy(&buf, resp.Body) + resp.Body.Close() + return d, nil, fmt.Errorf("Unexpected response code: %d (%s)", resp.StatusCode, buf.Bytes()) + } + return d, resp, nil +} diff --git a/Godeps/_workspace/src/github.com/hashicorp/consul/api/catalog.go b/Godeps/_workspace/src/github.com/hashicorp/consul/api/catalog.go new file mode 100644 index 0000000..cf64bd9 --- /dev/null +++ b/Godeps/_workspace/src/github.com/hashicorp/consul/api/catalog.go @@ -0,0 +1,182 @@ +package api + +type Node struct { + Node string + Address string +} + +type CatalogService struct { + Node string + Address string + ServiceID string + ServiceName string + ServiceAddress string + ServiceTags []string + ServicePort int +} + +type CatalogNode struct { + Node *Node + Services map[string]*AgentService +} + +type CatalogRegistration struct { + Node string + Address string + Datacenter string + Service *AgentService + Check *AgentCheck +} + +type CatalogDeregistration struct { + Node string + Address string + Datacenter string + ServiceID string + CheckID string +} + +// Catalog can be used to query the Catalog endpoints +type Catalog struct { + c *Client +} + +// Catalog returns a handle to the catalog endpoints +func (c *Client) Catalog() *Catalog { + return &Catalog{c} +} + +func (c *Catalog) Register(reg *CatalogRegistration, q *WriteOptions) (*WriteMeta, error) { + r := c.c.newRequest("PUT", "/v1/catalog/register") + r.setWriteOptions(q) + r.obj = reg + rtt, resp, err := requireOK(c.c.doRequest(r)) + if err != nil { + return nil, err + } + resp.Body.Close() + + wm := &WriteMeta{} + wm.RequestTime = rtt + + return wm, nil +} + +func (c *Catalog) Deregister(dereg *CatalogDeregistration, q *WriteOptions) (*WriteMeta, error) { + r := c.c.newRequest("PUT", "/v1/catalog/deregister") + r.setWriteOptions(q) + r.obj = dereg + rtt, resp, err := requireOK(c.c.doRequest(r)) + if err != nil { + return nil, err + } + resp.Body.Close() + + wm := &WriteMeta{} + wm.RequestTime = rtt + + return wm, nil +} + +// Datacenters is used to query for all the known datacenters +func (c *Catalog) Datacenters() ([]string, error) { + r := c.c.newRequest("GET", "/v1/catalog/datacenters") + _, resp, err := requireOK(c.c.doRequest(r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + var out []string + if err := decodeBody(resp, &out); err != nil { + return nil, err + } + return out, nil +} + +// Nodes is used to query all the known nodes +func (c *Catalog) Nodes(q *QueryOptions) ([]*Node, *QueryMeta, error) { + r := c.c.newRequest("GET", "/v1/catalog/nodes") + r.setQueryOptions(q) + rtt, resp, err := requireOK(c.c.doRequest(r)) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + + qm := &QueryMeta{} + parseQueryMeta(resp, qm) + qm.RequestTime = rtt + + var out []*Node + if err := decodeBody(resp, &out); err != nil { + return nil, nil, err + } + return out, qm, nil +} + +// Services is used to query for all known services +func (c *Catalog) Services(q *QueryOptions) (map[string][]string, *QueryMeta, error) { + r := c.c.newRequest("GET", "/v1/catalog/services") + r.setQueryOptions(q) + rtt, resp, err := requireOK(c.c.doRequest(r)) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + + qm := &QueryMeta{} + parseQueryMeta(resp, qm) + qm.RequestTime = rtt + + var out map[string][]string + if err := decodeBody(resp, &out); err != nil { + return nil, nil, err + } + return out, qm, nil +} + +// Service is used to query catalog entries for a given service +func (c *Catalog) Service(service, tag string, q *QueryOptions) ([]*CatalogService, *QueryMeta, error) { + r := c.c.newRequest("GET", "/v1/catalog/service/"+service) + r.setQueryOptions(q) + if tag != "" { + r.params.Set("tag", tag) + } + rtt, resp, err := requireOK(c.c.doRequest(r)) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + + qm := &QueryMeta{} + parseQueryMeta(resp, qm) + qm.RequestTime = rtt + + var out []*CatalogService + if err := decodeBody(resp, &out); err != nil { + return nil, nil, err + } + return out, qm, nil +} + +// Node is used to query for service information about a single node +func (c *Catalog) Node(node string, q *QueryOptions) (*CatalogNode, *QueryMeta, error) { + r := c.c.newRequest("GET", "/v1/catalog/node/"+node) + r.setQueryOptions(q) + rtt, resp, err := requireOK(c.c.doRequest(r)) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + + qm := &QueryMeta{} + parseQueryMeta(resp, qm) + qm.RequestTime = rtt + + var out *CatalogNode + if err := decodeBody(resp, &out); err != nil { + return nil, nil, err + } + return out, qm, nil +} diff --git a/Godeps/_workspace/src/github.com/hashicorp/consul/api/coordinate.go b/Godeps/_workspace/src/github.com/hashicorp/consul/api/coordinate.go new file mode 100644 index 0000000..108d830 --- /dev/null +++ b/Godeps/_workspace/src/github.com/hashicorp/consul/api/coordinate.go @@ -0,0 +1,66 @@ +package api + +import ( + "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/hashicorp/serf/coordinate" +) + +// CoordinateEntry represents a node and its associated network coordinate. +type CoordinateEntry struct { + Node string + Coord *coordinate.Coordinate +} + +// CoordinateDatacenterMap represents a datacenter and its associated WAN +// nodes and their associates coordinates. +type CoordinateDatacenterMap struct { + Datacenter string + Coordinates []CoordinateEntry +} + +// Coordinate can be used to query the coordinate endpoints +type Coordinate struct { + c *Client +} + +// Coordinate returns a handle to the coordinate endpoints +func (c *Client) Coordinate() *Coordinate { + return &Coordinate{c} +} + +// Datacenters is used to return the coordinates of all the servers in the WAN +// pool. +func (c *Coordinate) Datacenters() ([]*CoordinateDatacenterMap, error) { + r := c.c.newRequest("GET", "/v1/coordinate/datacenters") + _, resp, err := requireOK(c.c.doRequest(r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + var out []*CoordinateDatacenterMap + if err := decodeBody(resp, &out); err != nil { + return nil, err + } + return out, nil +} + +// Nodes is used to return the coordinates of all the nodes in the LAN pool. +func (c *Coordinate) Nodes(q *QueryOptions) ([]*CoordinateEntry, *QueryMeta, error) { + r := c.c.newRequest("GET", "/v1/coordinate/nodes") + r.setQueryOptions(q) + rtt, resp, err := requireOK(c.c.doRequest(r)) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + + qm := &QueryMeta{} + parseQueryMeta(resp, qm) + qm.RequestTime = rtt + + var out []*CoordinateEntry + if err := decodeBody(resp, &out); err != nil { + return nil, nil, err + } + return out, qm, nil +} diff --git a/Godeps/_workspace/src/github.com/hashicorp/consul/api/event.go b/Godeps/_workspace/src/github.com/hashicorp/consul/api/event.go new file mode 100644 index 0000000..85b5b06 --- /dev/null +++ b/Godeps/_workspace/src/github.com/hashicorp/consul/api/event.go @@ -0,0 +1,104 @@ +package api + +import ( + "bytes" + "strconv" +) + +// Event can be used to query the Event endpoints +type Event struct { + c *Client +} + +// UserEvent represents an event that was fired by the user +type UserEvent struct { + ID string + Name string + Payload []byte + NodeFilter string + ServiceFilter string + TagFilter string + Version int + LTime uint64 +} + +// Event returns a handle to the event endpoints +func (c *Client) Event() *Event { + return &Event{c} +} + +// Fire is used to fire a new user event. Only the Name, Payload and Filters +// are respected. This returns the ID or an associated error. Cross DC requests +// are supported. +func (e *Event) Fire(params *UserEvent, q *WriteOptions) (string, *WriteMeta, error) { + r := e.c.newRequest("PUT", "/v1/event/fire/"+params.Name) + r.setWriteOptions(q) + if params.NodeFilter != "" { + r.params.Set("node", params.NodeFilter) + } + if params.ServiceFilter != "" { + r.params.Set("service", params.ServiceFilter) + } + if params.TagFilter != "" { + r.params.Set("tag", params.TagFilter) + } + if params.Payload != nil { + r.body = bytes.NewReader(params.Payload) + } + + rtt, resp, err := requireOK(e.c.doRequest(r)) + if err != nil { + return "", nil, err + } + defer resp.Body.Close() + + wm := &WriteMeta{RequestTime: rtt} + var out UserEvent + if err := decodeBody(resp, &out); err != nil { + return "", nil, err + } + return out.ID, wm, nil +} + +// List is used to get the most recent events an agent has received. +// This list can be optionally filtered by the name. This endpoint supports +// quasi-blocking queries. The index is not monotonic, nor does it provide provide +// LastContact or KnownLeader. +func (e *Event) List(name string, q *QueryOptions) ([]*UserEvent, *QueryMeta, error) { + r := e.c.newRequest("GET", "/v1/event/list") + r.setQueryOptions(q) + if name != "" { + r.params.Set("name", name) + } + rtt, resp, err := requireOK(e.c.doRequest(r)) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + + qm := &QueryMeta{} + parseQueryMeta(resp, qm) + qm.RequestTime = rtt + + var entries []*UserEvent + if err := decodeBody(resp, &entries); err != nil { + return nil, nil, err + } + return entries, qm, nil +} + +// IDToIndex is a bit of a hack. This simulates the index generation to +// convert an event ID into a WaitIndex. +func (e *Event) IDToIndex(uuid string) uint64 { + lower := uuid[0:8] + uuid[9:13] + uuid[14:18] + upper := uuid[19:23] + uuid[24:36] + lowVal, err := strconv.ParseUint(lower, 16, 64) + if err != nil { + panic("Failed to convert " + lower) + } + highVal, err := strconv.ParseUint(upper, 16, 64) + if err != nil { + panic("Failed to convert " + upper) + } + return lowVal ^ highVal +} diff --git a/Godeps/_workspace/src/github.com/hashicorp/consul/api/health.go b/Godeps/_workspace/src/github.com/hashicorp/consul/api/health.go new file mode 100644 index 0000000..1a273e0 --- /dev/null +++ b/Godeps/_workspace/src/github.com/hashicorp/consul/api/health.go @@ -0,0 +1,136 @@ +package api + +import ( + "fmt" +) + +// HealthCheck is used to represent a single check +type HealthCheck struct { + Node string + CheckID string + Name string + Status string + Notes string + Output string + ServiceID string + ServiceName string +} + +// ServiceEntry is used for the health service endpoint +type ServiceEntry struct { + Node *Node + Service *AgentService + Checks []*HealthCheck +} + +// Health can be used to query the Health endpoints +type Health struct { + c *Client +} + +// Health returns a handle to the health endpoints +func (c *Client) Health() *Health { + return &Health{c} +} + +// Node is used to query for checks belonging to a given node +func (h *Health) Node(node string, q *QueryOptions) ([]*HealthCheck, *QueryMeta, error) { + r := h.c.newRequest("GET", "/v1/health/node/"+node) + r.setQueryOptions(q) + rtt, resp, err := requireOK(h.c.doRequest(r)) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + + qm := &QueryMeta{} + parseQueryMeta(resp, qm) + qm.RequestTime = rtt + + var out []*HealthCheck + if err := decodeBody(resp, &out); err != nil { + return nil, nil, err + } + return out, qm, nil +} + +// Checks is used to return the checks associated with a service +func (h *Health) Checks(service string, q *QueryOptions) ([]*HealthCheck, *QueryMeta, error) { + r := h.c.newRequest("GET", "/v1/health/checks/"+service) + r.setQueryOptions(q) + rtt, resp, err := requireOK(h.c.doRequest(r)) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + + qm := &QueryMeta{} + parseQueryMeta(resp, qm) + qm.RequestTime = rtt + + var out []*HealthCheck + if err := decodeBody(resp, &out); err != nil { + return nil, nil, err + } + return out, qm, nil +} + +// Service is used to query health information along with service info +// for a given service. It can optionally do server-side filtering on a tag +// or nodes with passing health checks only. +func (h *Health) Service(service, tag string, passingOnly bool, q *QueryOptions) ([]*ServiceEntry, *QueryMeta, error) { + r := h.c.newRequest("GET", "/v1/health/service/"+service) + r.setQueryOptions(q) + if tag != "" { + r.params.Set("tag", tag) + } + if passingOnly { + r.params.Set("passing", "1") + } + rtt, resp, err := requireOK(h.c.doRequest(r)) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + + qm := &QueryMeta{} + parseQueryMeta(resp, qm) + qm.RequestTime = rtt + + var out []*ServiceEntry + if err := decodeBody(resp, &out); err != nil { + return nil, nil, err + } + return out, qm, nil +} + +// State is used to retrieve all the checks in a given state. +// The wildcard "any" state can also be used for all checks. +func (h *Health) State(state string, q *QueryOptions) ([]*HealthCheck, *QueryMeta, error) { + switch state { + case "any": + case "warning": + case "critical": + case "passing": + case "unknown": + default: + return nil, nil, fmt.Errorf("Unsupported state: %v", state) + } + r := h.c.newRequest("GET", "/v1/health/state/"+state) + r.setQueryOptions(q) + rtt, resp, err := requireOK(h.c.doRequest(r)) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + + qm := &QueryMeta{} + parseQueryMeta(resp, qm) + qm.RequestTime = rtt + + var out []*HealthCheck + if err := decodeBody(resp, &out); err != nil { + return nil, nil, err + } + return out, qm, nil +} diff --git a/Godeps/_workspace/src/github.com/hashicorp/consul/api/kv.go b/Godeps/_workspace/src/github.com/hashicorp/consul/api/kv.go new file mode 100644 index 0000000..688b3a0 --- /dev/null +++ b/Godeps/_workspace/src/github.com/hashicorp/consul/api/kv.go @@ -0,0 +1,240 @@ +package api + +import ( + "bytes" + "fmt" + "io" + "net/http" + "strconv" + "strings" +) + +// KVPair is used to represent a single K/V entry +type KVPair struct { + Key string + CreateIndex uint64 + ModifyIndex uint64 + LockIndex uint64 + Flags uint64 + Value []byte + Session string +} + +// KVPairs is a list of KVPair objects +type KVPairs []*KVPair + +// KV is used to manipulate the K/V API +type KV struct { + c *Client +} + +// KV is used to return a handle to the K/V apis +func (c *Client) KV() *KV { + return &KV{c} +} + +// Get is used to lookup a single key +func (k *KV) Get(key string, q *QueryOptions) (*KVPair, *QueryMeta, error) { + resp, qm, err := k.getInternal(key, nil, q) + if err != nil { + return nil, nil, err + } + if resp == nil { + return nil, qm, nil + } + defer resp.Body.Close() + + var entries []*KVPair + if err := decodeBody(resp, &entries); err != nil { + return nil, nil, err + } + if len(entries) > 0 { + return entries[0], qm, nil + } + return nil, qm, nil +} + +// List is used to lookup all keys under a prefix +func (k *KV) List(prefix string, q *QueryOptions) (KVPairs, *QueryMeta, error) { + resp, qm, err := k.getInternal(prefix, map[string]string{"recurse": ""}, q) + if err != nil { + return nil, nil, err + } + if resp == nil { + return nil, qm, nil + } + defer resp.Body.Close() + + var entries []*KVPair + if err := decodeBody(resp, &entries); err != nil { + return nil, nil, err + } + return entries, qm, nil +} + +// Keys is used to list all the keys under a prefix. Optionally, +// a separator can be used to limit the responses. +func (k *KV) Keys(prefix, separator string, q *QueryOptions) ([]string, *QueryMeta, error) { + params := map[string]string{"keys": ""} + if separator != "" { + params["separator"] = separator + } + resp, qm, err := k.getInternal(prefix, params, q) + if err != nil { + return nil, nil, err + } + if resp == nil { + return nil, qm, nil + } + defer resp.Body.Close() + + var entries []string + if err := decodeBody(resp, &entries); err != nil { + return nil, nil, err + } + return entries, qm, nil +} + +func (k *KV) getInternal(key string, params map[string]string, q *QueryOptions) (*http.Response, *QueryMeta, error) { + r := k.c.newRequest("GET", "/v1/kv/"+key) + r.setQueryOptions(q) + for param, val := range params { + r.params.Set(param, val) + } + rtt, resp, err := k.c.doRequest(r) + if err != nil { + return nil, nil, err + } + + qm := &QueryMeta{} + parseQueryMeta(resp, qm) + qm.RequestTime = rtt + + if resp.StatusCode == 404 { + resp.Body.Close() + return nil, qm, nil + } else if resp.StatusCode != 200 { + resp.Body.Close() + return nil, nil, fmt.Errorf("Unexpected response code: %d", resp.StatusCode) + } + return resp, qm, nil +} + +// Put is used to write a new value. Only the +// Key, Flags and Value is respected. +func (k *KV) Put(p *KVPair, q *WriteOptions) (*WriteMeta, error) { + params := make(map[string]string, 1) + if p.Flags != 0 { + params["flags"] = strconv.FormatUint(p.Flags, 10) + } + _, wm, err := k.put(p.Key, params, p.Value, q) + return wm, err +} + +// CAS is used for a Check-And-Set operation. The Key, +// ModifyIndex, Flags and Value are respected. Returns true +// on success or false on failures. +func (k *KV) CAS(p *KVPair, q *WriteOptions) (bool, *WriteMeta, error) { + params := make(map[string]string, 2) + if p.Flags != 0 { + params["flags"] = strconv.FormatUint(p.Flags, 10) + } + params["cas"] = strconv.FormatUint(p.ModifyIndex, 10) + return k.put(p.Key, params, p.Value, q) +} + +// Acquire is used for a lock acquisition operation. The Key, +// Flags, Value and Session are respected. Returns true +// on success or false on failures. +func (k *KV) Acquire(p *KVPair, q *WriteOptions) (bool, *WriteMeta, error) { + params := make(map[string]string, 2) + if p.Flags != 0 { + params["flags"] = strconv.FormatUint(p.Flags, 10) + } + params["acquire"] = p.Session + return k.put(p.Key, params, p.Value, q) +} + +// Release is used for a lock release operation. The Key, +// Flags, Value and Session are respected. Returns true +// on success or false on failures. +func (k *KV) Release(p *KVPair, q *WriteOptions) (bool, *WriteMeta, error) { + params := make(map[string]string, 2) + if p.Flags != 0 { + params["flags"] = strconv.FormatUint(p.Flags, 10) + } + params["release"] = p.Session + return k.put(p.Key, params, p.Value, q) +} + +func (k *KV) put(key string, params map[string]string, body []byte, q *WriteOptions) (bool, *WriteMeta, error) { + if len(key) > 0 && key[0] == '/' { + return false, nil, fmt.Errorf("Invalid key. Key must not begin with a '/': %s", key) + } + + r := k.c.newRequest("PUT", "/v1/kv/"+key) + r.setWriteOptions(q) + for param, val := range params { + r.params.Set(param, val) + } + r.body = bytes.NewReader(body) + rtt, resp, err := requireOK(k.c.doRequest(r)) + if err != nil { + return false, nil, err + } + defer resp.Body.Close() + + qm := &WriteMeta{} + qm.RequestTime = rtt + + var buf bytes.Buffer + if _, err := io.Copy(&buf, resp.Body); err != nil { + return false, nil, fmt.Errorf("Failed to read response: %v", err) + } + res := strings.Contains(string(buf.Bytes()), "true") + return res, qm, nil +} + +// Delete is used to delete a single key +func (k *KV) Delete(key string, w *WriteOptions) (*WriteMeta, error) { + _, qm, err := k.deleteInternal(key, nil, w) + return qm, err +} + +// DeleteCAS is used for a Delete Check-And-Set operation. The Key +// and ModifyIndex are respected. Returns true on success or false on failures. +func (k *KV) DeleteCAS(p *KVPair, q *WriteOptions) (bool, *WriteMeta, error) { + params := map[string]string{ + "cas": strconv.FormatUint(p.ModifyIndex, 10), + } + return k.deleteInternal(p.Key, params, q) +} + +// DeleteTree is used to delete all keys under a prefix +func (k *KV) DeleteTree(prefix string, w *WriteOptions) (*WriteMeta, error) { + _, qm, err := k.deleteInternal(prefix, map[string]string{"recurse": ""}, w) + return qm, err +} + +func (k *KV) deleteInternal(key string, params map[string]string, q *WriteOptions) (bool, *WriteMeta, error) { + r := k.c.newRequest("DELETE", "/v1/kv/"+key) + r.setWriteOptions(q) + for param, val := range params { + r.params.Set(param, val) + } + rtt, resp, err := requireOK(k.c.doRequest(r)) + if err != nil { + return false, nil, err + } + defer resp.Body.Close() + + qm := &WriteMeta{} + qm.RequestTime = rtt + + var buf bytes.Buffer + if _, err := io.Copy(&buf, resp.Body); err != nil { + return false, nil, fmt.Errorf("Failed to read response: %v", err) + } + res := strings.Contains(string(buf.Bytes()), "true") + return res, qm, nil +} diff --git a/Godeps/_workspace/src/github.com/hashicorp/consul/api/lock.go b/Godeps/_workspace/src/github.com/hashicorp/consul/api/lock.go new file mode 100644 index 0000000..08e8e79 --- /dev/null +++ b/Godeps/_workspace/src/github.com/hashicorp/consul/api/lock.go @@ -0,0 +1,380 @@ +package api + +import ( + "fmt" + "sync" + "time" +) + +const ( + // DefaultLockSessionName is the Session Name we assign if none is provided + DefaultLockSessionName = "Consul API Lock" + + // DefaultLockSessionTTL is the default session TTL if no Session is provided + // when creating a new Lock. This is used because we do not have another + // other check to depend upon. + DefaultLockSessionTTL = "15s" + + // DefaultLockWaitTime is how long we block for at a time to check if lock + // acquisition is possible. This affects the minimum time it takes to cancel + // a Lock acquisition. + DefaultLockWaitTime = 15 * time.Second + + // DefaultLockRetryTime is how long we wait after a failed lock acquisition + // before attempting to do the lock again. This is so that once a lock-delay + // is in effect, we do not hot loop retrying the acquisition. + DefaultLockRetryTime = 5 * time.Second + + // DefaultMonitorRetryTime is how long we wait after a failed monitor check + // of a lock (500 response code). This allows the monitor to ride out brief + // periods of unavailability, subject to the MonitorRetries setting in the + // lock options which is by default set to 0, disabling this feature. This + // affects locks and semaphores. + DefaultMonitorRetryTime = 2 * time.Second + + // LockFlagValue is a magic flag we set to indicate a key + // is being used for a lock. It is used to detect a potential + // conflict with a semaphore. + LockFlagValue = 0x2ddccbc058a50c18 +) + +var ( + // ErrLockHeld is returned if we attempt to double lock + ErrLockHeld = fmt.Errorf("Lock already held") + + // ErrLockNotHeld is returned if we attempt to unlock a lock + // that we do not hold. + ErrLockNotHeld = fmt.Errorf("Lock not held") + + // ErrLockInUse is returned if we attempt to destroy a lock + // that is in use. + ErrLockInUse = fmt.Errorf("Lock in use") + + // ErrLockConflict is returned if the flags on a key + // used for a lock do not match expectation + ErrLockConflict = fmt.Errorf("Existing key does not match lock use") +) + +// Lock is used to implement client-side leader election. It is follows the +// algorithm as described here: https://www.consul.io/docs/guides/leader-election.html. +type Lock struct { + c *Client + opts *LockOptions + + isHeld bool + sessionRenew chan struct{} + lockSession string + l sync.Mutex +} + +// LockOptions is used to parameterize the Lock behavior. +type LockOptions struct { + Key string // Must be set and have write permissions + Value []byte // Optional, value to associate with the lock + Session string // Optional, created if not specified + SessionName string // Optional, defaults to DefaultLockSessionName + SessionTTL string // Optional, defaults to DefaultLockSessionTTL + MonitorRetries int // Optional, defaults to 0 which means no retries + MonitorRetryTime time.Duration // Optional, defaults to DefaultMonitorRetryTime + LockWaitTime time.Duration // Optional, defaults to DefaultLockWaitTime + LockTryOnce bool // Optional, defaults to false which means try forever +} + +// LockKey returns a handle to a lock struct which can be used +// to acquire and release the mutex. The key used must have +// write permissions. +func (c *Client) LockKey(key string) (*Lock, error) { + opts := &LockOptions{ + Key: key, + } + return c.LockOpts(opts) +} + +// LockOpts returns a handle to a lock struct which can be used +// to acquire and release the mutex. The key used must have +// write permissions. +func (c *Client) LockOpts(opts *LockOptions) (*Lock, error) { + if opts.Key == "" { + return nil, fmt.Errorf("missing key") + } + if opts.SessionName == "" { + opts.SessionName = DefaultLockSessionName + } + if opts.SessionTTL == "" { + opts.SessionTTL = DefaultLockSessionTTL + } else { + if _, err := time.ParseDuration(opts.SessionTTL); err != nil { + return nil, fmt.Errorf("invalid SessionTTL: %v", err) + } + } + if opts.MonitorRetryTime == 0 { + opts.MonitorRetryTime = DefaultMonitorRetryTime + } + if opts.LockWaitTime == 0 { + opts.LockWaitTime = DefaultLockWaitTime + } + l := &Lock{ + c: c, + opts: opts, + } + return l, nil +} + +// Lock attempts to acquire the lock and blocks while doing so. +// Providing a non-nil stopCh can be used to abort the lock attempt. +// Returns a channel that is closed if our lock is lost or an error. +// This channel could be closed at any time due to session invalidation, +// communication errors, operator intervention, etc. It is NOT safe to +// assume that the lock is held until Unlock() unless the Session is specifically +// created without any associated health checks. By default Consul sessions +// prefer liveness over safety and an application must be able to handle +// the lock being lost. +func (l *Lock) Lock(stopCh <-chan struct{}) (<-chan struct{}, error) { + // Hold the lock as we try to acquire + l.l.Lock() + defer l.l.Unlock() + + // Check if we already hold the lock + if l.isHeld { + return nil, ErrLockHeld + } + + // Check if we need to create a session first + l.lockSession = l.opts.Session + if l.lockSession == "" { + if s, err := l.createSession(); err != nil { + return nil, fmt.Errorf("failed to create session: %v", err) + } else { + l.sessionRenew = make(chan struct{}) + l.lockSession = s + session := l.c.Session() + go session.RenewPeriodic(l.opts.SessionTTL, s, nil, l.sessionRenew) + + // If we fail to acquire the lock, cleanup the session + defer func() { + if !l.isHeld { + close(l.sessionRenew) + l.sessionRenew = nil + } + }() + } + } + + // Setup the query options + kv := l.c.KV() + qOpts := &QueryOptions{ + WaitTime: l.opts.LockWaitTime, + } + + start := time.Now() + attempts := 0 +WAIT: + // Check if we should quit + select { + case <-stopCh: + return nil, nil + default: + } + + // Handle the one-shot mode. + if l.opts.LockTryOnce && attempts > 0 { + elapsed := time.Now().Sub(start) + if elapsed > qOpts.WaitTime { + return nil, nil + } + + qOpts.WaitTime -= elapsed + } + attempts++ + + // Look for an existing lock, blocking until not taken + pair, meta, err := kv.Get(l.opts.Key, qOpts) + if err != nil { + return nil, fmt.Errorf("failed to read lock: %v", err) + } + if pair != nil && pair.Flags != LockFlagValue { + return nil, ErrLockConflict + } + locked := false + if pair != nil && pair.Session == l.lockSession { + goto HELD + } + if pair != nil && pair.Session != "" { + qOpts.WaitIndex = meta.LastIndex + goto WAIT + } + + // Try to acquire the lock + pair = l.lockEntry(l.lockSession) + locked, _, err = kv.Acquire(pair, nil) + if err != nil { + return nil, fmt.Errorf("failed to acquire lock: %v", err) + } + + // Handle the case of not getting the lock + if !locked { + // Determine why the lock failed + qOpts.WaitIndex = 0 + pair, meta, err = kv.Get(l.opts.Key, qOpts) + if pair != nil && pair.Session != "" { + //If the session is not null, this means that a wait can safely happen + //using a long poll + qOpts.WaitIndex = meta.LastIndex + goto WAIT + } else { + // If the session is empty and the lock failed to acquire, then it means + // a lock-delay is in effect and a timed wait must be used + select { + case <-time.After(DefaultLockRetryTime): + goto WAIT + case <-stopCh: + return nil, nil + } + } + } + +HELD: + // Watch to ensure we maintain leadership + leaderCh := make(chan struct{}) + go l.monitorLock(l.lockSession, leaderCh) + + // Set that we own the lock + l.isHeld = true + + // Locked! All done + return leaderCh, nil +} + +// Unlock released the lock. It is an error to call this +// if the lock is not currently held. +func (l *Lock) Unlock() error { + // Hold the lock as we try to release + l.l.Lock() + defer l.l.Unlock() + + // Ensure the lock is actually held + if !l.isHeld { + return ErrLockNotHeld + } + + // Set that we no longer own the lock + l.isHeld = false + + // Stop the session renew + if l.sessionRenew != nil { + defer func() { + close(l.sessionRenew) + l.sessionRenew = nil + }() + } + + // Get the lock entry, and clear the lock session + lockEnt := l.lockEntry(l.lockSession) + l.lockSession = "" + + // Release the lock explicitly + kv := l.c.KV() + _, _, err := kv.Release(lockEnt, nil) + if err != nil { + return fmt.Errorf("failed to release lock: %v", err) + } + return nil +} + +// Destroy is used to cleanup the lock entry. It is not necessary +// to invoke. It will fail if the lock is in use. +func (l *Lock) Destroy() error { + // Hold the lock as we try to release + l.l.Lock() + defer l.l.Unlock() + + // Check if we already hold the lock + if l.isHeld { + return ErrLockHeld + } + + // Look for an existing lock + kv := l.c.KV() + pair, _, err := kv.Get(l.opts.Key, nil) + if err != nil { + return fmt.Errorf("failed to read lock: %v", err) + } + + // Nothing to do if the lock does not exist + if pair == nil { + return nil + } + + // Check for possible flag conflict + if pair.Flags != LockFlagValue { + return ErrLockConflict + } + + // Check if it is in use + if pair.Session != "" { + return ErrLockInUse + } + + // Attempt the delete + didRemove, _, err := kv.DeleteCAS(pair, nil) + if err != nil { + return fmt.Errorf("failed to remove lock: %v", err) + } + if !didRemove { + return ErrLockInUse + } + return nil +} + +// createSession is used to create a new managed session +func (l *Lock) createSession() (string, error) { + session := l.c.Session() + se := &SessionEntry{ + Name: l.opts.SessionName, + TTL: l.opts.SessionTTL, + } + id, _, err := session.Create(se, nil) + if err != nil { + return "", err + } + return id, nil +} + +// lockEntry returns a formatted KVPair for the lock +func (l *Lock) lockEntry(session string) *KVPair { + return &KVPair{ + Key: l.opts.Key, + Value: l.opts.Value, + Session: session, + Flags: LockFlagValue, + } +} + +// monitorLock is a long running routine to monitor a lock ownership +// It closes the stopCh if we lose our leadership. +func (l *Lock) monitorLock(session string, stopCh chan struct{}) { + defer close(stopCh) + kv := l.c.KV() + opts := &QueryOptions{RequireConsistent: true} +WAIT: + retries := l.opts.MonitorRetries +RETRY: + pair, meta, err := kv.Get(l.opts.Key, opts) + if err != nil { + // If configured we can try to ride out a brief Consul unavailability + // by doing retries. Note that we have to attempt the retry in a non- + // blocking fashion so that we have a clean place to reset the retry + // counter if service is restored. + if retries > 0 && IsServerError(err) { + time.Sleep(l.opts.MonitorRetryTime) + retries-- + opts.WaitIndex = 0 + goto RETRY + } + return + } + if pair != nil && pair.Session == session { + opts.WaitIndex = meta.LastIndex + goto WAIT + } +} diff --git a/Godeps/_workspace/src/github.com/hashicorp/consul/api/prepared_query.go b/Godeps/_workspace/src/github.com/hashicorp/consul/api/prepared_query.go new file mode 100644 index 0000000..c814188 --- /dev/null +++ b/Godeps/_workspace/src/github.com/hashicorp/consul/api/prepared_query.go @@ -0,0 +1,173 @@ +package api + +// QueryDatacenterOptions sets options about how we fail over if there are no +// healthy nodes in the local datacenter. +type QueryDatacenterOptions struct { + // NearestN is set to the number of remote datacenters to try, based on + // network coordinates. + NearestN int + + // Datacenters is a fixed list of datacenters to try after NearestN. We + // never try a datacenter multiple times, so those are subtracted from + // this list before proceeding. + Datacenters []string +} + +// QueryDNSOptions controls settings when query results are served over DNS. +type QueryDNSOptions struct { + // TTL is the time to live for the served DNS results. + TTL string +} + +// ServiceQuery is used to query for a set of healthy nodes offering a specific +// service. +type ServiceQuery struct { + // Service is the service to query. + Service string + + // Failover controls what we do if there are no healthy nodes in the + // local datacenter. + Failover QueryDatacenterOptions + + // If OnlyPassing is true then we will only include nodes with passing + // health checks (critical AND warning checks will cause a node to be + // discarded) + OnlyPassing bool + + // Tags are a set of required and/or disallowed tags. If a tag is in + // this list it must be present. If the tag is preceded with "!" then + // it is disallowed. + Tags []string +} + +// PrepatedQueryDefinition defines a complete prepared query. +type PreparedQueryDefinition struct { + // ID is this UUID-based ID for the query, always generated by Consul. + ID string + + // Name is an optional friendly name for the query supplied by the + // user. NOTE - if this feature is used then it will reduce the security + // of any read ACL associated with this query/service since this name + // can be used to locate nodes with supplying any ACL. + Name string + + // Session is an optional session to tie this query's lifetime to. If + // this is omitted then the query will not expire. + Session string + + // Token is the ACL token used when the query was created, and it is + // used when a query is subsequently executed. This token, or a token + // with management privileges, must be used to change the query later. + Token string + + // Service defines a service query (leaving things open for other types + // later). + Service ServiceQuery + + // DNS has options that control how the results of this query are + // served over DNS. + DNS QueryDNSOptions +} + +// PreparedQueryExecuteResponse has the results of executing a query. +type PreparedQueryExecuteResponse struct { + // Service is the service that was queried. + Service string + + // Nodes has the nodes that were output by the query. + Nodes []ServiceEntry + + // DNS has the options for serving these results over DNS. + DNS QueryDNSOptions + + // Datacenter is the datacenter that these results came from. + Datacenter string + + // Failovers is a count of how many times we had to query a remote + // datacenter. + Failovers int +} + +// PreparedQuery can be used to query the prepared query endpoints. +type PreparedQuery struct { + c *Client +} + +// PreparedQuery returns a handle to the prepared query endpoints. +func (c *Client) PreparedQuery() *PreparedQuery { + return &PreparedQuery{c} +} + +// Create makes a new prepared query. The ID of the new query is returned. +func (c *PreparedQuery) Create(query *PreparedQueryDefinition, q *WriteOptions) (string, *WriteMeta, error) { + r := c.c.newRequest("POST", "/v1/query") + r.setWriteOptions(q) + r.obj = query + rtt, resp, err := requireOK(c.c.doRequest(r)) + if err != nil { + return "", nil, err + } + defer resp.Body.Close() + + wm := &WriteMeta{} + wm.RequestTime = rtt + + var out struct{ ID string } + if err := decodeBody(resp, &out); err != nil { + return "", nil, err + } + return out.ID, wm, nil +} + +// Update makes updates to an existing prepared query. +func (c *PreparedQuery) Update(query *PreparedQueryDefinition, q *WriteOptions) (*WriteMeta, error) { + return c.c.write("/v1/query/"+query.ID, query, nil, q) +} + +// List is used to fetch all the prepared queries (always requires a management +// token). +func (c *PreparedQuery) List(q *QueryOptions) ([]*PreparedQueryDefinition, *QueryMeta, error) { + var out []*PreparedQueryDefinition + qm, err := c.c.query("/v1/query", &out, q) + if err != nil { + return nil, nil, err + } + return out, qm, nil +} + +// Get is used to fetch a specific prepared query. +func (c *PreparedQuery) Get(queryID string, q *QueryOptions) ([]*PreparedQueryDefinition, *QueryMeta, error) { + var out []*PreparedQueryDefinition + qm, err := c.c.query("/v1/query/"+queryID, &out, q) + if err != nil { + return nil, nil, err + } + return out, qm, nil +} + +// Delete is used to delete a specific prepared query. +func (c *PreparedQuery) Delete(queryID string, q *QueryOptions) (*QueryMeta, error) { + r := c.c.newRequest("DELETE", "/v1/query/"+queryID) + r.setQueryOptions(q) + rtt, resp, err := requireOK(c.c.doRequest(r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + qm := &QueryMeta{} + parseQueryMeta(resp, qm) + qm.RequestTime = rtt + return qm, nil +} + +// Execute is used to execute a specific prepared query. You can execute using +// a query ID or name. +func (c *PreparedQuery) Execute(queryIDOrName string, q *QueryOptions) (*PreparedQueryExecuteResponse, *QueryMeta, error) { + var out *PreparedQueryExecuteResponse + qm, err := c.c.query("/v1/query/"+queryIDOrName+"/execute", &out, q) + if err != nil { + return nil, nil, err + } + return out, qm, nil +} diff --git a/Godeps/_workspace/src/github.com/hashicorp/consul/api/raw.go b/Godeps/_workspace/src/github.com/hashicorp/consul/api/raw.go new file mode 100644 index 0000000..745a208 --- /dev/null +++ b/Godeps/_workspace/src/github.com/hashicorp/consul/api/raw.go @@ -0,0 +1,24 @@ +package api + +// Raw can be used to do raw queries against custom endpoints +type Raw struct { + c *Client +} + +// Raw returns a handle to query endpoints +func (c *Client) Raw() *Raw { + return &Raw{c} +} + +// Query is used to do a GET request against an endpoint +// and deserialize the response into an interface using +// standard Consul conventions. +func (raw *Raw) Query(endpoint string, out interface{}, q *QueryOptions) (*QueryMeta, error) { + return raw.c.query(endpoint, out, q) +} + +// Write is used to do a PUT request against an endpoint +// and serialize/deserialized using the standard Consul conventions. +func (raw *Raw) Write(endpoint string, in, out interface{}, q *WriteOptions) (*WriteMeta, error) { + return raw.c.write(endpoint, in, out, q) +} diff --git a/Godeps/_workspace/src/github.com/hashicorp/consul/api/semaphore.go b/Godeps/_workspace/src/github.com/hashicorp/consul/api/semaphore.go new file mode 100644 index 0000000..e6645ac --- /dev/null +++ b/Godeps/_workspace/src/github.com/hashicorp/consul/api/semaphore.go @@ -0,0 +1,512 @@ +package api + +import ( + "encoding/json" + "fmt" + "path" + "sync" + "time" +) + +const ( + // DefaultSemaphoreSessionName is the Session Name we assign if none is provided + DefaultSemaphoreSessionName = "Consul API Semaphore" + + // DefaultSemaphoreSessionTTL is the default session TTL if no Session is provided + // when creating a new Semaphore. This is used because we do not have another + // other check to depend upon. + DefaultSemaphoreSessionTTL = "15s" + + // DefaultSemaphoreWaitTime is how long we block for at a time to check if semaphore + // acquisition is possible. This affects the minimum time it takes to cancel + // a Semaphore acquisition. + DefaultSemaphoreWaitTime = 15 * time.Second + + // DefaultSemaphoreKey is the key used within the prefix to + // use for coordination between all the contenders. + DefaultSemaphoreKey = ".lock" + + // SemaphoreFlagValue is a magic flag we set to indicate a key + // is being used for a semaphore. It is used to detect a potential + // conflict with a lock. + SemaphoreFlagValue = 0xe0f69a2baa414de0 +) + +var ( + // ErrSemaphoreHeld is returned if we attempt to double lock + ErrSemaphoreHeld = fmt.Errorf("Semaphore already held") + + // ErrSemaphoreNotHeld is returned if we attempt to unlock a semaphore + // that we do not hold. + ErrSemaphoreNotHeld = fmt.Errorf("Semaphore not held") + + // ErrSemaphoreInUse is returned if we attempt to destroy a semaphore + // that is in use. + ErrSemaphoreInUse = fmt.Errorf("Semaphore in use") + + // ErrSemaphoreConflict is returned if the flags on a key + // used for a semaphore do not match expectation + ErrSemaphoreConflict = fmt.Errorf("Existing key does not match semaphore use") +) + +// Semaphore is used to implement a distributed semaphore +// using the Consul KV primitives. +type Semaphore struct { + c *Client + opts *SemaphoreOptions + + isHeld bool + sessionRenew chan struct{} + lockSession string + l sync.Mutex +} + +// SemaphoreOptions is used to parameterize the Semaphore +type SemaphoreOptions struct { + Prefix string // Must be set and have write permissions + Limit int // Must be set, and be positive + Value []byte // Optional, value to associate with the contender entry + Session string // Optional, created if not specified + SessionName string // Optional, defaults to DefaultLockSessionName + SessionTTL string // Optional, defaults to DefaultLockSessionTTL + MonitorRetries int // Optional, defaults to 0 which means no retries + MonitorRetryTime time.Duration // Optional, defaults to DefaultMonitorRetryTime + SemaphoreWaitTime time.Duration // Optional, defaults to DefaultSemaphoreWaitTime + SemaphoreTryOnce bool // Optional, defaults to false which means try forever +} + +// semaphoreLock is written under the DefaultSemaphoreKey and +// is used to coordinate between all the contenders. +type semaphoreLock struct { + // Limit is the integer limit of holders. This is used to + // verify that all the holders agree on the value. + Limit int + + // Holders is a list of all the semaphore holders. + // It maps the session ID to true. It is used as a set effectively. + Holders map[string]bool +} + +// SemaphorePrefix is used to created a Semaphore which will operate +// at the given KV prefix and uses the given limit for the semaphore. +// The prefix must have write privileges, and the limit must be agreed +// upon by all contenders. +func (c *Client) SemaphorePrefix(prefix string, limit int) (*Semaphore, error) { + opts := &SemaphoreOptions{ + Prefix: prefix, + Limit: limit, + } + return c.SemaphoreOpts(opts) +} + +// SemaphoreOpts is used to create a Semaphore with the given options. +// The prefix must have write privileges, and the limit must be agreed +// upon by all contenders. If a Session is not provided, one will be created. +func (c *Client) SemaphoreOpts(opts *SemaphoreOptions) (*Semaphore, error) { + if opts.Prefix == "" { + return nil, fmt.Errorf("missing prefix") + } + if opts.Limit <= 0 { + return nil, fmt.Errorf("semaphore limit must be positive") + } + if opts.SessionName == "" { + opts.SessionName = DefaultSemaphoreSessionName + } + if opts.SessionTTL == "" { + opts.SessionTTL = DefaultSemaphoreSessionTTL + } else { + if _, err := time.ParseDuration(opts.SessionTTL); err != nil { + return nil, fmt.Errorf("invalid SessionTTL: %v", err) + } + } + if opts.MonitorRetryTime == 0 { + opts.MonitorRetryTime = DefaultMonitorRetryTime + } + if opts.SemaphoreWaitTime == 0 { + opts.SemaphoreWaitTime = DefaultSemaphoreWaitTime + } + s := &Semaphore{ + c: c, + opts: opts, + } + return s, nil +} + +// Acquire attempts to reserve a slot in the semaphore, blocking until +// success, interrupted via the stopCh or an error is encountered. +// Providing a non-nil stopCh can be used to abort the attempt. +// On success, a channel is returned that represents our slot. +// This channel could be closed at any time due to session invalidation, +// communication errors, operator intervention, etc. It is NOT safe to +// assume that the slot is held until Release() unless the Session is specifically +// created without any associated health checks. By default Consul sessions +// prefer liveness over safety and an application must be able to handle +// the session being lost. +func (s *Semaphore) Acquire(stopCh <-chan struct{}) (<-chan struct{}, error) { + // Hold the lock as we try to acquire + s.l.Lock() + defer s.l.Unlock() + + // Check if we already hold the semaphore + if s.isHeld { + return nil, ErrSemaphoreHeld + } + + // Check if we need to create a session first + s.lockSession = s.opts.Session + if s.lockSession == "" { + if sess, err := s.createSession(); err != nil { + return nil, fmt.Errorf("failed to create session: %v", err) + } else { + s.sessionRenew = make(chan struct{}) + s.lockSession = sess + session := s.c.Session() + go session.RenewPeriodic(s.opts.SessionTTL, sess, nil, s.sessionRenew) + + // If we fail to acquire the lock, cleanup the session + defer func() { + if !s.isHeld { + close(s.sessionRenew) + s.sessionRenew = nil + } + }() + } + } + + // Create the contender entry + kv := s.c.KV() + made, _, err := kv.Acquire(s.contenderEntry(s.lockSession), nil) + if err != nil || !made { + return nil, fmt.Errorf("failed to make contender entry: %v", err) + } + + // Setup the query options + qOpts := &QueryOptions{ + WaitTime: s.opts.SemaphoreWaitTime, + } + + start := time.Now() + attempts := 0 +WAIT: + // Check if we should quit + select { + case <-stopCh: + return nil, nil + default: + } + + // Handle the one-shot mode. + if s.opts.SemaphoreTryOnce && attempts > 0 { + elapsed := time.Now().Sub(start) + if elapsed > qOpts.WaitTime { + return nil, nil + } + + qOpts.WaitTime -= elapsed + } + attempts++ + + // Read the prefix + pairs, meta, err := kv.List(s.opts.Prefix, qOpts) + if err != nil { + return nil, fmt.Errorf("failed to read prefix: %v", err) + } + + // Decode the lock + lockPair := s.findLock(pairs) + if lockPair.Flags != SemaphoreFlagValue { + return nil, ErrSemaphoreConflict + } + lock, err := s.decodeLock(lockPair) + if err != nil { + return nil, err + } + + // Verify we agree with the limit + if lock.Limit != s.opts.Limit { + return nil, fmt.Errorf("semaphore limit conflict (lock: %d, local: %d)", + lock.Limit, s.opts.Limit) + } + + // Prune the dead holders + s.pruneDeadHolders(lock, pairs) + + // Check if the lock is held + if len(lock.Holders) >= lock.Limit { + qOpts.WaitIndex = meta.LastIndex + goto WAIT + } + + // Create a new lock with us as a holder + lock.Holders[s.lockSession] = true + newLock, err := s.encodeLock(lock, lockPair.ModifyIndex) + if err != nil { + return nil, err + } + + // Attempt the acquisition + didSet, _, err := kv.CAS(newLock, nil) + if err != nil { + return nil, fmt.Errorf("failed to update lock: %v", err) + } + if !didSet { + // Update failed, could have been a race with another contender, + // retry the operation + goto WAIT + } + + // Watch to ensure we maintain ownership of the slot + lockCh := make(chan struct{}) + go s.monitorLock(s.lockSession, lockCh) + + // Set that we own the lock + s.isHeld = true + + // Acquired! All done + return lockCh, nil +} + +// Release is used to voluntarily give up our semaphore slot. It is +// an error to call this if the semaphore has not been acquired. +func (s *Semaphore) Release() error { + // Hold the lock as we try to release + s.l.Lock() + defer s.l.Unlock() + + // Ensure the lock is actually held + if !s.isHeld { + return ErrSemaphoreNotHeld + } + + // Set that we no longer own the lock + s.isHeld = false + + // Stop the session renew + if s.sessionRenew != nil { + defer func() { + close(s.sessionRenew) + s.sessionRenew = nil + }() + } + + // Get and clear the lock session + lockSession := s.lockSession + s.lockSession = "" + + // Remove ourselves as a lock holder + kv := s.c.KV() + key := path.Join(s.opts.Prefix, DefaultSemaphoreKey) +READ: + pair, _, err := kv.Get(key, nil) + if err != nil { + return err + } + if pair == nil { + pair = &KVPair{} + } + lock, err := s.decodeLock(pair) + if err != nil { + return err + } + + // Create a new lock without us as a holder + if _, ok := lock.Holders[lockSession]; ok { + delete(lock.Holders, lockSession) + newLock, err := s.encodeLock(lock, pair.ModifyIndex) + if err != nil { + return err + } + + // Swap the locks + didSet, _, err := kv.CAS(newLock, nil) + if err != nil { + return fmt.Errorf("failed to update lock: %v", err) + } + if !didSet { + goto READ + } + } + + // Destroy the contender entry + contenderKey := path.Join(s.opts.Prefix, lockSession) + if _, err := kv.Delete(contenderKey, nil); err != nil { + return err + } + return nil +} + +// Destroy is used to cleanup the semaphore entry. It is not necessary +// to invoke. It will fail if the semaphore is in use. +func (s *Semaphore) Destroy() error { + // Hold the lock as we try to acquire + s.l.Lock() + defer s.l.Unlock() + + // Check if we already hold the semaphore + if s.isHeld { + return ErrSemaphoreHeld + } + + // List for the semaphore + kv := s.c.KV() + pairs, _, err := kv.List(s.opts.Prefix, nil) + if err != nil { + return fmt.Errorf("failed to read prefix: %v", err) + } + + // Find the lock pair, bail if it doesn't exist + lockPair := s.findLock(pairs) + if lockPair.ModifyIndex == 0 { + return nil + } + if lockPair.Flags != SemaphoreFlagValue { + return ErrSemaphoreConflict + } + + // Decode the lock + lock, err := s.decodeLock(lockPair) + if err != nil { + return err + } + + // Prune the dead holders + s.pruneDeadHolders(lock, pairs) + + // Check if there are any holders + if len(lock.Holders) > 0 { + return ErrSemaphoreInUse + } + + // Attempt the delete + didRemove, _, err := kv.DeleteCAS(lockPair, nil) + if err != nil { + return fmt.Errorf("failed to remove semaphore: %v", err) + } + if !didRemove { + return ErrSemaphoreInUse + } + return nil +} + +// createSession is used to create a new managed session +func (s *Semaphore) createSession() (string, error) { + session := s.c.Session() + se := &SessionEntry{ + Name: s.opts.SessionName, + TTL: s.opts.SessionTTL, + Behavior: SessionBehaviorDelete, + } + id, _, err := session.Create(se, nil) + if err != nil { + return "", err + } + return id, nil +} + +// contenderEntry returns a formatted KVPair for the contender +func (s *Semaphore) contenderEntry(session string) *KVPair { + return &KVPair{ + Key: path.Join(s.opts.Prefix, session), + Value: s.opts.Value, + Session: session, + Flags: SemaphoreFlagValue, + } +} + +// findLock is used to find the KV Pair which is used for coordination +func (s *Semaphore) findLock(pairs KVPairs) *KVPair { + key := path.Join(s.opts.Prefix, DefaultSemaphoreKey) + for _, pair := range pairs { + if pair.Key == key { + return pair + } + } + return &KVPair{Flags: SemaphoreFlagValue} +} + +// decodeLock is used to decode a semaphoreLock from an +// entry in Consul +func (s *Semaphore) decodeLock(pair *KVPair) (*semaphoreLock, error) { + // Handle if there is no lock + if pair == nil || pair.Value == nil { + return &semaphoreLock{ + Limit: s.opts.Limit, + Holders: make(map[string]bool), + }, nil + } + + l := &semaphoreLock{} + if err := json.Unmarshal(pair.Value, l); err != nil { + return nil, fmt.Errorf("lock decoding failed: %v", err) + } + return l, nil +} + +// encodeLock is used to encode a semaphoreLock into a KVPair +// that can be PUT +func (s *Semaphore) encodeLock(l *semaphoreLock, oldIndex uint64) (*KVPair, error) { + enc, err := json.Marshal(l) + if err != nil { + return nil, fmt.Errorf("lock encoding failed: %v", err) + } + pair := &KVPair{ + Key: path.Join(s.opts.Prefix, DefaultSemaphoreKey), + Value: enc, + Flags: SemaphoreFlagValue, + ModifyIndex: oldIndex, + } + return pair, nil +} + +// pruneDeadHolders is used to remove all the dead lock holders +func (s *Semaphore) pruneDeadHolders(lock *semaphoreLock, pairs KVPairs) { + // Gather all the live holders + alive := make(map[string]struct{}, len(pairs)) + for _, pair := range pairs { + if pair.Session != "" { + alive[pair.Session] = struct{}{} + } + } + + // Remove any holders that are dead + for holder := range lock.Holders { + if _, ok := alive[holder]; !ok { + delete(lock.Holders, holder) + } + } +} + +// monitorLock is a long running routine to monitor a semaphore ownership +// It closes the stopCh if we lose our slot. +func (s *Semaphore) monitorLock(session string, stopCh chan struct{}) { + defer close(stopCh) + kv := s.c.KV() + opts := &QueryOptions{RequireConsistent: true} +WAIT: + retries := s.opts.MonitorRetries +RETRY: + pairs, meta, err := kv.List(s.opts.Prefix, opts) + if err != nil { + // If configured we can try to ride out a brief Consul unavailability + // by doing retries. Note that we have to attempt the retry in a non- + // blocking fashion so that we have a clean place to reset the retry + // counter if service is restored. + if retries > 0 && IsServerError(err) { + time.Sleep(s.opts.MonitorRetryTime) + retries-- + opts.WaitIndex = 0 + goto RETRY + } + return + } + lockPair := s.findLock(pairs) + lock, err := s.decodeLock(lockPair) + if err != nil { + return + } + s.pruneDeadHolders(lock, pairs) + if _, ok := lock.Holders[session]; ok { + opts.WaitIndex = meta.LastIndex + goto WAIT + } +} diff --git a/Godeps/_workspace/src/github.com/hashicorp/consul/api/session.go b/Godeps/_workspace/src/github.com/hashicorp/consul/api/session.go new file mode 100644 index 0000000..36e99a3 --- /dev/null +++ b/Godeps/_workspace/src/github.com/hashicorp/consul/api/session.go @@ -0,0 +1,217 @@ +package api + +import ( + "errors" + "fmt" + "time" +) + +const ( + // SessionBehaviorRelease is the default behavior and causes + // all associated locks to be released on session invalidation. + SessionBehaviorRelease = "release" + + // SessionBehaviorDelete is new in Consul 0.5 and changes the + // behavior to delete all associated locks on session invalidation. + // It can be used in a way similar to Ephemeral Nodes in ZooKeeper. + SessionBehaviorDelete = "delete" +) + +var ErrSessionExpired = errors.New("session expired") + +// SessionEntry represents a session in consul +type SessionEntry struct { + CreateIndex uint64 + ID string + Name string + Node string + Checks []string + LockDelay time.Duration + Behavior string + TTL string +} + +// Session can be used to query the Session endpoints +type Session struct { + c *Client +} + +// Session returns a handle to the session endpoints +func (c *Client) Session() *Session { + return &Session{c} +} + +// CreateNoChecks is like Create but is used specifically to create +// a session with no associated health checks. +func (s *Session) CreateNoChecks(se *SessionEntry, q *WriteOptions) (string, *WriteMeta, error) { + body := make(map[string]interface{}) + body["Checks"] = []string{} + if se != nil { + if se.Name != "" { + body["Name"] = se.Name + } + if se.Node != "" { + body["Node"] = se.Node + } + if se.LockDelay != 0 { + body["LockDelay"] = durToMsec(se.LockDelay) + } + if se.Behavior != "" { + body["Behavior"] = se.Behavior + } + if se.TTL != "" { + body["TTL"] = se.TTL + } + } + return s.create(body, q) + +} + +// Create makes a new session. Providing a session entry can +// customize the session. It can also be nil to use defaults. +func (s *Session) Create(se *SessionEntry, q *WriteOptions) (string, *WriteMeta, error) { + var obj interface{} + if se != nil { + body := make(map[string]interface{}) + obj = body + if se.Name != "" { + body["Name"] = se.Name + } + if se.Node != "" { + body["Node"] = se.Node + } + if se.LockDelay != 0 { + body["LockDelay"] = durToMsec(se.LockDelay) + } + if len(se.Checks) > 0 { + body["Checks"] = se.Checks + } + if se.Behavior != "" { + body["Behavior"] = se.Behavior + } + if se.TTL != "" { + body["TTL"] = se.TTL + } + } + return s.create(obj, q) +} + +func (s *Session) create(obj interface{}, q *WriteOptions) (string, *WriteMeta, error) { + var out struct{ ID string } + wm, err := s.c.write("/v1/session/create", obj, &out, q) + if err != nil { + return "", nil, err + } + return out.ID, wm, nil +} + +// Destroy invalidates a given session +func (s *Session) Destroy(id string, q *WriteOptions) (*WriteMeta, error) { + wm, err := s.c.write("/v1/session/destroy/"+id, nil, nil, q) + if err != nil { + return nil, err + } + return wm, nil +} + +// Renew renews the TTL on a given session +func (s *Session) Renew(id string, q *WriteOptions) (*SessionEntry, *WriteMeta, error) { + r := s.c.newRequest("PUT", "/v1/session/renew/"+id) + r.setWriteOptions(q) + rtt, resp, err := s.c.doRequest(r) + if err != nil { + return nil, nil, err + } + defer resp.Body.Close() + + wm := &WriteMeta{RequestTime: rtt} + + if resp.StatusCode == 404 { + return nil, wm, nil + } else if resp.StatusCode != 200 { + return nil, nil, fmt.Errorf("Unexpected response code: %d", resp.StatusCode) + } + + var entries []*SessionEntry + if err := decodeBody(resp, &entries); err != nil { + return nil, nil, fmt.Errorf("Failed to read response: %v", err) + } + if len(entries) > 0 { + return entries[0], wm, nil + } + return nil, wm, nil +} + +// RenewPeriodic is used to periodically invoke Session.Renew on a +// session until a doneCh is closed. This is meant to be used in a long running +// goroutine to ensure a session stays valid. +func (s *Session) RenewPeriodic(initialTTL string, id string, q *WriteOptions, doneCh chan struct{}) error { + ttl, err := time.ParseDuration(initialTTL) + if err != nil { + return err + } + + waitDur := ttl / 2 + lastRenewTime := time.Now() + var lastErr error + for { + if time.Since(lastRenewTime) > ttl { + return lastErr + } + select { + case <-time.After(waitDur): + entry, _, err := s.Renew(id, q) + if err != nil { + waitDur = time.Second + lastErr = err + continue + } + if entry == nil { + return ErrSessionExpired + } + + // Handle the server updating the TTL + ttl, _ = time.ParseDuration(entry.TTL) + waitDur = ttl / 2 + lastRenewTime = time.Now() + + case <-doneCh: + // Attempt a session destroy + s.Destroy(id, q) + return nil + } + } +} + +// Info looks up a single session +func (s *Session) Info(id string, q *QueryOptions) (*SessionEntry, *QueryMeta, error) { + var entries []*SessionEntry + qm, err := s.c.query("/v1/session/info/"+id, &entries, q) + if err != nil { + return nil, nil, err + } + if len(entries) > 0 { + return entries[0], qm, nil + } + return nil, qm, nil +} + +// List gets sessions for a node +func (s *Session) Node(node string, q *QueryOptions) ([]*SessionEntry, *QueryMeta, error) { + var entries []*SessionEntry + qm, err := s.c.query("/v1/session/node/"+node, &entries, q) + if err != nil { + return nil, nil, err + } + return entries, qm, nil +} + +// List gets all active sessions +func (s *Session) List(q *QueryOptions) ([]*SessionEntry, *QueryMeta, error) { + var entries []*SessionEntry + qm, err := s.c.query("/v1/session/list", &entries, q) + if err != nil { + return nil, nil, err + } + return entries, qm, nil +} diff --git a/Godeps/_workspace/src/github.com/hashicorp/consul/api/status.go b/Godeps/_workspace/src/github.com/hashicorp/consul/api/status.go new file mode 100644 index 0000000..74ef61a --- /dev/null +++ b/Godeps/_workspace/src/github.com/hashicorp/consul/api/status.go @@ -0,0 +1,43 @@ +package api + +// Status can be used to query the Status endpoints +type Status struct { + c *Client +} + +// Status returns a handle to the status endpoints +func (c *Client) Status() *Status { + return &Status{c} +} + +// Leader is used to query for a known leader +func (s *Status) Leader() (string, error) { + r := s.c.newRequest("GET", "/v1/status/leader") + _, resp, err := requireOK(s.c.doRequest(r)) + if err != nil { + return "", err + } + defer resp.Body.Close() + + var leader string + if err := decodeBody(resp, &leader); err != nil { + return "", err + } + return leader, nil +} + +// Peers is used to query for a known raft peers +func (s *Status) Peers() ([]string, error) { + r := s.c.newRequest("GET", "/v1/status/peers") + _, resp, err := requireOK(s.c.doRequest(r)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + var peers []string + if err := decodeBody(resp, &peers); err != nil { + return nil, err + } + return peers, nil +} diff --git a/Godeps/_workspace/src/github.com/hashicorp/go-cleanhttp/LICENSE b/Godeps/_workspace/src/github.com/hashicorp/go-cleanhttp/LICENSE new file mode 100644 index 0000000..e87a115 --- /dev/null +++ b/Godeps/_workspace/src/github.com/hashicorp/go-cleanhttp/LICENSE @@ -0,0 +1,363 @@ +Mozilla Public License, version 2.0 + +1. Definitions + +1.1. "Contributor" + + means each individual or legal entity that creates, contributes to the + creation of, or owns Covered Software. + +1.2. "Contributor Version" + + means the combination of the Contributions of others (if any) used by a + Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + + means Source Code Form to which the initial Contributor has attached the + notice in Exhibit A, the Executable Form of such Source Code Form, and + Modifications of such Source Code Form, in each case including portions + thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + a. that the initial Contributor has attached the notice described in + Exhibit B to the Covered Software; or + + b. that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the terms of + a Secondary License. + +1.6. "Executable Form" + + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + + means a work that combines Covered Software with other material, in a + separate file or files, that is not Covered Software. + +1.8. "License" + + means this document. + +1.9. "Licensable" + + means having the right to grant, to the maximum extent possible, whether + at the time of the initial grant or subsequently, any and all of the + rights conveyed by this License. + +1.10. "Modifications" + + means any of the following: + + a. any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered Software; or + + b. any new file in Source Code Form that contains any Covered Software. + +1.11. "Patent Claims" of a Contributor + + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the License, + by the making, using, selling, offering for sale, having made, import, + or transfer of either its Contributions or its Contributor Version. + +1.12. "Secondary License" + + means either the GNU General Public License, Version 2.0, the GNU Lesser + General Public License, Version 2.1, the GNU Affero General Public + License, Version 3.0, or any later versions of those licenses. + +1.13. "Source Code Form" + + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that controls, is + controlled by, or is under common control with You. For purposes of this + definition, "control" means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by contract or + otherwise, or (b) ownership of more than fifty percent (50%) of the + outstanding shares or beneficial ownership of such entity. + + +2. License Grants and Conditions + +2.1. Grants + + Each Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: + + a. under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + + b. under Patent Claims of such Contributor to make, use, sell, offer for + sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + + The licenses granted in Section 2.1 with respect to any Contribution + become effective for each Contribution on the date the Contributor first + distributes such Contribution. + +2.3. Limitations on Grant Scope + + The licenses granted in this Section 2 are the only rights granted under + this License. No additional rights or licenses will be implied from the + distribution or licensing of Covered Software under this License. + Notwithstanding Section 2.1(b) above, no patent license is granted by a + Contributor: + + a. for any code that a Contributor has removed from Covered Software; or + + b. for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + + c. under Patent Claims infringed by Covered Software in the absence of + its Contributions. + + This License does not grant any rights in the trademarks, service marks, + or logos of any Contributor (except as may be necessary to comply with + the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + + No Contributor makes additional grants as a result of Your choice to + distribute the Covered Software under a subsequent version of this + License (see Section 10.2) or under the terms of a Secondary License (if + permitted under the terms of Section 3.3). + +2.5. Representation + + Each Contributor represents that the Contributor believes its + Contributions are its original creation(s) or it has sufficient rights to + grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + + This License is not intended to limit any rights You have under + applicable copyright doctrines of fair use, fair dealing, or other + equivalents. + +2.7. Conditions + + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in + Section 2.1. + + +3. Responsibilities + +3.1. Distribution of Source Form + + All distribution of Covered Software in Source Code Form, including any + Modifications that You create or to which You contribute, must be under + the terms of this License. You must inform recipients that the Source + Code Form of the Covered Software is governed by the terms of this + License, and how they can obtain a copy of this License. You may not + attempt to alter or restrict the recipients' rights in the Source Code + Form. + +3.2. Distribution of Executable Form + + If You distribute Covered Software in Executable Form then: + + a. such Covered Software must also be made available in Source Code Form, + as described in Section 3.1, and You must inform recipients of the + Executable Form how they can obtain a copy of such Source Code Form by + reasonable means in a timely manner, at a charge no more than the cost + of distribution to the recipient; and + + b. You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter the + recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + + You may create and distribute a Larger Work under terms of Your choice, + provided that You also comply with the requirements of this License for + the Covered Software. If the Larger Work is a combination of Covered + Software with a work governed by one or more Secondary Licenses, and the + Covered Software is not Incompatible With Secondary Licenses, this + License permits You to additionally distribute such Covered Software + under the terms of such Secondary License(s), so that the recipient of + the Larger Work may, at their option, further distribute the Covered + Software under the terms of either this License or such Secondary + License(s). + +3.4. Notices + + You may not remove or alter the substance of any license notices + (including copyright notices, patent notices, disclaimers of warranty, or + limitations of liability) contained within the Source Code Form of the + Covered Software, except that You may alter any license notices to the + extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + + You may choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of Covered + Software. However, You may do so only on Your own behalf, and not on + behalf of any Contributor. You must make it absolutely clear that any + such warranty, support, indemnity, or liability obligation is offered by + You alone, and You hereby agree to indemnify every Contributor for any + liability incurred by such Contributor as a result of warranty, support, + indemnity or liability terms You offer. You may include additional + disclaimers of warranty and limitations of liability specific to any + jurisdiction. + +4. Inability to Comply Due to Statute or Regulation + + If it is impossible for You to comply with any of the terms of this License + with respect to some or all of the Covered Software due to statute, + judicial order, or regulation then You must: (a) comply with the terms of + this License to the maximum extent possible; and (b) describe the + limitations and the code they affect. Such description must be placed in a + text file included with all distributions of the Covered Software under + this License. Except to the extent prohibited by statute or regulation, + such description must be sufficiently detailed for a recipient of ordinary + skill to be able to understand it. + +5. Termination + +5.1. The rights granted under this License will terminate automatically if You + fail to comply with any of its terms. However, if You become compliant, + then the rights granted under this License from a particular Contributor + are reinstated (a) provisionally, unless and until such Contributor + explicitly and finally terminates Your grants, and (b) on an ongoing + basis, if such Contributor fails to notify You of the non-compliance by + some reasonable means prior to 60 days after You have come back into + compliance. Moreover, Your grants from a particular Contributor are + reinstated on an ongoing basis if such Contributor notifies You of the + non-compliance by some reasonable means, this is the first time You have + received notice of non-compliance with this License from such + Contributor, and You become compliant prior to 30 days after Your receipt + of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent + infringement claim (excluding declaratory judgment actions, + counter-claims, and cross-claims) alleging that a Contributor Version + directly or indirectly infringes any patent, then the rights granted to + You by any and all Contributors for the Covered Software under Section + 2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user + license agreements (excluding distributors and resellers) which have been + validly granted by You or Your distributors under this License prior to + termination shall survive termination. + +6. Disclaimer of Warranty + + Covered Software is provided under this License on an "as is" basis, + without warranty of any kind, either expressed, implied, or statutory, + including, without limitation, warranties that the Covered Software is free + of defects, merchantable, fit for a particular purpose or non-infringing. + The entire risk as to the quality and performance of the Covered Software + is with You. Should any Covered Software prove defective in any respect, + You (not any Contributor) assume the cost of any necessary servicing, + repair, or correction. This disclaimer of warranty constitutes an essential + part of this License. No use of any Covered Software is authorized under + this License except under this disclaimer. + +7. Limitation of Liability + + Under no circumstances and under no legal theory, whether tort (including + negligence), contract, or otherwise, shall any Contributor, or anyone who + distributes Covered Software as permitted above, be liable to You for any + direct, indirect, special, incidental, or consequential damages of any + character including, without limitation, damages for lost profits, loss of + goodwill, work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses, even if such party shall have been + informed of the possibility of such damages. This limitation of liability + shall not apply to liability for death or personal injury resulting from + such party's negligence to the extent applicable law prohibits such + limitation. Some jurisdictions do not allow the exclusion or limitation of + incidental or consequential damages, so this exclusion and limitation may + not apply to You. + +8. Litigation + + Any litigation relating to this License may be brought only in the courts + of a jurisdiction where the defendant maintains its principal place of + business and such litigation shall be governed by laws of that + jurisdiction, without reference to its conflict-of-law provisions. Nothing + in this Section shall prevent a party's ability to bring cross-claims or + counter-claims. + +9. Miscellaneous + + This License represents the complete agreement concerning the subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. Any law or regulation which provides that + the language of a contract shall be construed against the drafter shall not + be used to construe this License against a Contributor. + + +10. Versions of the License + +10.1. New Versions + + Mozilla Foundation is the license steward. Except as provided in Section + 10.3, no one other than the license steward has the right to modify or + publish new versions of this License. Each version will be given a + distinguishing version number. + +10.2. Effect of New Versions + + You may distribute the Covered Software under the terms of the version + of the License under which You originally received the Covered Software, + or under the terms of any subsequent version published by the license + steward. + +10.3. Modified Versions + + If you create software not governed by this License, and you want to + create a new license for such software, you may create and use a + modified version of this License if you rename the license and remove + any references to the name of the license steward (except to note that + such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary + Licenses If You choose to distribute Source Code Form that is + Incompatible With Secondary Licenses under the terms of this version of + the License, the notice described in Exhibit B of this License must be + attached. + +Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the + terms of the Mozilla Public License, v. + 2.0. If a copy of the MPL was not + distributed with this file, You can + obtain one at + http://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular file, +then You may include the notice in a location (such as a LICENSE file in a +relevant directory) where a recipient would be likely to look for such a +notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice + + This Source Code Form is "Incompatible + With Secondary Licenses", as defined by + the Mozilla Public License, v. 2.0. + diff --git a/Godeps/_workspace/src/github.com/hashicorp/go-cleanhttp/README.md b/Godeps/_workspace/src/github.com/hashicorp/go-cleanhttp/README.md new file mode 100644 index 0000000..036e531 --- /dev/null +++ b/Godeps/_workspace/src/github.com/hashicorp/go-cleanhttp/README.md @@ -0,0 +1,30 @@ +# cleanhttp + +Functions for accessing "clean" Go http.Client values + +------------- + +The Go standard library contains a default `http.Client` called +`http.DefaultClient`. It is a common idiom in Go code to start with +`http.DefaultClient` and tweak it as necessary, and in fact, this is +encouraged; from the `http` package documentation: + +> The Client's Transport typically has internal state (cached TCP connections), +so Clients should be reused instead of created as needed. Clients are safe for +concurrent use by multiple goroutines. + +Unfortunately, this is a shared value, and it is not uncommon for libraries to +assume that they are free to modify it at will. With enough dependencies, it +can be very easy to encounter strange problems and race conditions due to +manipulation of this shared value across libraries and goroutines (clients are +safe for concurrent use, but writing values to the client struct itself is not +protected). + +Making things worse is the fact that a bare `http.Client` will use a default +`http.Transport` called `http.DefaultTransport`, which is another global value +that behaves the same way. So it is not simply enough to replace +`http.DefaultClient` with `&http.Client{}`. + +This repository provides some simple functions to get a "clean" `http.Client` +-- one that uses the same default values as the Go standard library, but +returns a client that does not share any state with other clients. diff --git a/Godeps/_workspace/src/github.com/hashicorp/go-cleanhttp/cleanhttp.go b/Godeps/_workspace/src/github.com/hashicorp/go-cleanhttp/cleanhttp.go new file mode 100644 index 0000000..c692e23 --- /dev/null +++ b/Godeps/_workspace/src/github.com/hashicorp/go-cleanhttp/cleanhttp.go @@ -0,0 +1,40 @@ +package cleanhttp + +import ( + "net" + "net/http" + "runtime" + "time" +) + +// DefaultTransport returns a new http.Transport with the same default values +// as http.DefaultTransport +func DefaultTransport() *http.Transport { + transport := &http.Transport{ + Proxy: http.ProxyFromEnvironment, + Dial: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + }).Dial, + TLSHandshakeTimeout: 10 * time.Second, + } + SetTransportFinalizer(transport) + return transport +} + +// DefaultClient returns a new http.Client with the same default values as +// http.Client, but with a non-shared Transport +func DefaultClient() *http.Client { + return &http.Client{ + Transport: DefaultTransport(), + } +} + +// SetTransportFinalizer sets a finalizer on the transport to ensure that +// idle connections are closed prior to garbage collection; otherwise +// these may leak +func SetTransportFinalizer(transport *http.Transport) { + runtime.SetFinalizer(&transport, func(t **http.Transport) { + (*t).CloseIdleConnections() + }) +} diff --git a/Godeps/_workspace/src/github.com/hashicorp/serf/coordinate/README.md b/Godeps/_workspace/src/github.com/hashicorp/serf/coordinate/README.md new file mode 100644 index 0000000..0a96fd3 --- /dev/null +++ b/Godeps/_workspace/src/github.com/hashicorp/serf/coordinate/README.md @@ -0,0 +1 @@ +# TODO - I'll beef this up as I implement each of the enhancements. \ No newline at end of file diff --git a/Godeps/_workspace/src/github.com/hashicorp/serf/coordinate/client.go b/Godeps/_workspace/src/github.com/hashicorp/serf/coordinate/client.go new file mode 100644 index 0000000..613bfff --- /dev/null +++ b/Godeps/_workspace/src/github.com/hashicorp/serf/coordinate/client.go @@ -0,0 +1,180 @@ +package coordinate + +import ( + "fmt" + "math" + "sort" + "sync" + "time" +) + +// Client manages the estimated network coordinate for a given node, and adjusts +// it as the node observes round trip times and estimated coordinates from other +// nodes. The core algorithm is based on Vivaldi, see the documentation for Config +// for more details. +type Client struct { + // coord is the current estimate of the client's network coordinate. + coord *Coordinate + + // origin is a coordinate sitting at the origin. + origin *Coordinate + + // config contains the tuning parameters that govern the performance of + // the algorithm. + config *Config + + // adjustmentIndex is the current index into the adjustmentSamples slice. + adjustmentIndex uint + + // adjustment is used to store samples for the adjustment calculation. + adjustmentSamples []float64 + + // latencyFilterSamples is used to store the last several RTT samples, + // keyed by node name. We will use the config's LatencyFilterSamples + // value to determine how many samples we keep, per node. + latencyFilterSamples map[string][]float64 + + // mutex enables safe concurrent access to the client. + mutex sync.RWMutex +} + +// NewClient creates a new Client and verifies the configuration is valid. +func NewClient(config *Config) (*Client, error) { + if !(config.Dimensionality > 0) { + return nil, fmt.Errorf("dimensionality must be >0") + } + + return &Client{ + coord: NewCoordinate(config), + origin: NewCoordinate(config), + config: config, + adjustmentIndex: 0, + adjustmentSamples: make([]float64, config.AdjustmentWindowSize), + latencyFilterSamples: make(map[string][]float64), + }, nil +} + +// GetCoordinate returns a copy of the coordinate for this client. +func (c *Client) GetCoordinate() *Coordinate { + c.mutex.RLock() + defer c.mutex.RUnlock() + + return c.coord.Clone() +} + +// SetCoordinate forces the client's coordinate to a known state. +func (c *Client) SetCoordinate(coord *Coordinate) { + c.mutex.Lock() + defer c.mutex.Unlock() + + c.coord = coord.Clone() +} + +// ForgetNode removes any client state for the given node. +func (c *Client) ForgetNode(node string) { + c.mutex.Lock() + defer c.mutex.Unlock() + + delete(c.latencyFilterSamples, node) +} + +// latencyFilter applies a simple moving median filter with a new sample for +// a node. This assumes that the mutex has been locked already. +func (c *Client) latencyFilter(node string, rttSeconds float64) float64 { + samples, ok := c.latencyFilterSamples[node] + if !ok { + samples = make([]float64, 0, c.config.LatencyFilterSize) + } + + // Add the new sample and trim the list, if needed. + samples = append(samples, rttSeconds) + if len(samples) > int(c.config.LatencyFilterSize) { + samples = samples[1:] + } + c.latencyFilterSamples[node] = samples + + // Sort a copy of the samples and return the median. + sorted := make([]float64, len(samples)) + copy(sorted, samples) + sort.Float64s(sorted) + return sorted[len(sorted)/2] +} + +// updateVivialdi updates the Vivaldi portion of the client's coordinate. This +// assumes that the mutex has been locked already. +func (c *Client) updateVivaldi(other *Coordinate, rttSeconds float64) { + const zeroThreshold = 1.0e-6 + + dist := c.coord.DistanceTo(other).Seconds() + if rttSeconds < zeroThreshold { + rttSeconds = zeroThreshold + } + wrongness := math.Abs(dist-rttSeconds) / rttSeconds + + totalError := c.coord.Error + other.Error + if totalError < zeroThreshold { + totalError = zeroThreshold + } + weight := c.coord.Error / totalError + + c.coord.Error = c.config.VivaldiCE*weight*wrongness + c.coord.Error*(1.0-c.config.VivaldiCE*weight) + if c.coord.Error > c.config.VivaldiErrorMax { + c.coord.Error = c.config.VivaldiErrorMax + } + + delta := c.config.VivaldiCC * weight + force := delta * (rttSeconds - dist) + c.coord = c.coord.ApplyForce(c.config, force, other) +} + +// updateAdjustment updates the adjustment portion of the client's coordinate, if +// the feature is enabled. This assumes that the mutex has been locked already. +func (c *Client) updateAdjustment(other *Coordinate, rttSeconds float64) { + if c.config.AdjustmentWindowSize == 0 { + return + } + + // Note that the existing adjustment factors don't figure in to this + // calculation so we use the raw distance here. + dist := c.coord.rawDistanceTo(other) + c.adjustmentSamples[c.adjustmentIndex] = rttSeconds - dist + c.adjustmentIndex = (c.adjustmentIndex + 1) % c.config.AdjustmentWindowSize + + sum := 0.0 + for _, sample := range c.adjustmentSamples { + sum += sample + } + c.coord.Adjustment = sum / (2.0 * float64(c.config.AdjustmentWindowSize)) +} + +// updateGravity applies a small amount of gravity to pull coordinates towards +// the center of the coordinate system to combat drift. This assumes that the +// mutex is locked already. +func (c *Client) updateGravity() { + dist := c.origin.DistanceTo(c.coord).Seconds() + force := -1.0 * math.Pow(dist/c.config.GravityRho, 2.0) + c.coord = c.coord.ApplyForce(c.config, force, c.origin) +} + +// Update takes other, a coordinate for another node, and rtt, a round trip +// time observation for a ping to that node, and updates the estimated position of +// the client's coordinate. Returns the updated coordinate. +func (c *Client) Update(node string, other *Coordinate, rtt time.Duration) *Coordinate { + c.mutex.Lock() + defer c.mutex.Unlock() + + rttSeconds := c.latencyFilter(node, rtt.Seconds()) + c.updateVivaldi(other, rttSeconds) + c.updateAdjustment(other, rttSeconds) + c.updateGravity() + return c.coord.Clone() +} + +// DistanceTo returns the estimated RTT from the client's coordinate to other, the +// coordinate for another node. +func (c *Client) DistanceTo(other *Coordinate) time.Duration { + c.mutex.RLock() + defer c.mutex.RUnlock() + + return c.coord.DistanceTo(other) +} diff --git a/Godeps/_workspace/src/github.com/hashicorp/serf/coordinate/config.go b/Godeps/_workspace/src/github.com/hashicorp/serf/coordinate/config.go new file mode 100644 index 0000000..a5b3aad --- /dev/null +++ b/Godeps/_workspace/src/github.com/hashicorp/serf/coordinate/config.go @@ -0,0 +1,70 @@ +package coordinate + +// Config is used to set the parameters of the Vivaldi-based coordinate mapping +// algorithm. +// +// The following references are called out at various points in the documentation +// here: +// +// [1] Dabek, Frank, et al. "Vivaldi: A decentralized network coordinate system." +// ACM SIGCOMM Computer Communication Review. Vol. 34. No. 4. ACM, 2004. +// [2] Ledlie, Jonathan, Paul Gardner, and Margo I. Seltzer. "Network Coordinates +// in the Wild." NSDI. Vol. 7. 2007. +// [3] Lee, Sanghwan, et al. "On suitability of Euclidean embedding for +// host-based network coordinate systems." Networking, IEEE/ACM Transactions +// on 18.1 (2010): 27-40. +type Config struct { + // The dimensionality of the coordinate system. As discussed in [2], more + // dimensions improves the accuracy of the estimates up to a point. Per [2] + // we chose 4 dimensions plus a non-Euclidean height. + Dimensionality uint + + // VivaldiErrorMax is the default error value when a node hasn't yet made + // any observations. It also serves as an upper limit on the error value in + // case observations cause the error value to increase without bound. + VivaldiErrorMax float64 + + // VivaldiCE is a tuning factor that controls the maximum impact an + // observation can have on a node's confidence. See [1] for more details. + VivaldiCE float64 + + // VivaldiCC is a tuning factor that controls the maximum impact an + // observation can have on a node's coordinate. See [1] for more details. + VivaldiCC float64 + + // AdjustmentWindowSize is a tuning factor that determines how many samples + // we retain to calculate the adjustment factor as discussed in [3]. Setting + // this to zero disables this feature. + AdjustmentWindowSize uint + + // HeightMin is the minimum value of the height parameter. Since this + // always must be positive, it will introduce a small amount error, so + // the chosen value should be relatively small compared to "normal" + // coordinates. + HeightMin float64 + + // LatencyFilterSamples is the maximum number of samples that are retained + // per node, in order to compute a median. The intent is to ride out blips + // but still keep the delay low, since our time to probe any given node is + // pretty infrequent. See [2] for more details. + LatencyFilterSize uint + + // GravityRho is a tuning factor that sets how much gravity has an effect + // to try to re-center coordinates. See [2] for more details. + GravityRho float64 +} + +// DefaultConfig returns a Config that has some default values suitable for +// basic testing of the algorithm, but not tuned to any particular type of cluster. +func DefaultConfig() *Config { + return &Config{ + Dimensionality: 8, + VivaldiErrorMax: 1.5, + VivaldiCE: 0.25, + VivaldiCC: 0.25, + AdjustmentWindowSize: 20, + HeightMin: 10.0e-6, + LatencyFilterSize: 3, + GravityRho: 150.0, + } +} diff --git a/Godeps/_workspace/src/github.com/hashicorp/serf/coordinate/coordinate.go b/Godeps/_workspace/src/github.com/hashicorp/serf/coordinate/coordinate.go new file mode 100644 index 0000000..c9194e0 --- /dev/null +++ b/Godeps/_workspace/src/github.com/hashicorp/serf/coordinate/coordinate.go @@ -0,0 +1,183 @@ +package coordinate + +import ( + "math" + "math/rand" + "time" +) + +// Coordinate is a specialized structure for holding network coordinates for the +// Vivaldi-based coordinate mapping algorithm. All of the fields should be public +// to enable this to be serialized. All values in here are in units of seconds. +type Coordinate struct { + // Vec is the Euclidean portion of the coordinate. This is used along + // with the other fields to provide an overall distance estimate. The + // units here are seconds. + Vec []float64 + + // Err reflects the confidence in the given coordinate and is updated + // dynamically by the Vivaldi Client. This is dimensionless. + Error float64 + + // Adjustment is a distance offset computed based on a calculation over + // observations from all other nodes over a fixed window and is updated + // dynamically by the Vivaldi Client. The units here are seconds. + Adjustment float64 + + // Height is a distance offset that accounts for non-Euclidean effects + // which model the access links from nodes to the core Internet. The access + // links are usually set by bandwidth and congestion, and the core links + // usually follow distance based on geography. + Height float64 +} + +const ( + // secondsToNanoseconds is used to convert float seconds to nanoseconds. + secondsToNanoseconds = 1.0e9 + + // zeroThreshold is used to decide if two coordinates are on top of each + // other. + zeroThreshold = 1.0e-6 +) + +// ErrDimensionalityConflict will be panic-d if you try to perform operations +// with incompatible dimensions. +type DimensionalityConflictError struct{} + +// Adds the error interface. +func (e DimensionalityConflictError) Error() string { + return "coordinate dimensionality does not match" +} + +// NewCoordinate creates a new coordinate at the origin, using the given config +// to supply key initial values. +func NewCoordinate(config *Config) *Coordinate { + return &Coordinate{ + Vec: make([]float64, config.Dimensionality), + Error: config.VivaldiErrorMax, + Adjustment: 0.0, + Height: config.HeightMin, + } +} + +// Clone creates an independent copy of this coordinate. +func (c *Coordinate) Clone() *Coordinate { + vec := make([]float64, len(c.Vec)) + copy(vec, c.Vec) + return &Coordinate{ + Vec: vec, + Error: c.Error, + Adjustment: c.Adjustment, + Height: c.Height, + } +} + +// IsCompatibleWith checks to see if the two coordinates are compatible +// dimensionally. If this returns true then you are guaranteed to not get +// any runtime errors operating on them. +func (c *Coordinate) IsCompatibleWith(other *Coordinate) bool { + return len(c.Vec) == len(other.Vec) +} + +// ApplyForce returns the result of applying the force from the direction of the +// other coordinate. +func (c *Coordinate) ApplyForce(config *Config, force float64, other *Coordinate) *Coordinate { + if !c.IsCompatibleWith(other) { + panic(DimensionalityConflictError{}) + } + + ret := c.Clone() + unit, mag := unitVectorAt(c.Vec, other.Vec) + ret.Vec = add(ret.Vec, mul(unit, force)) + if mag > zeroThreshold { + ret.Height = (ret.Height+other.Height)*force/mag + ret.Height + ret.Height = math.Max(ret.Height, config.HeightMin) + } + return ret +} + +// DistanceTo returns the distance between this coordinate and the other +// coordinate, including adjustments. +func (c *Coordinate) DistanceTo(other *Coordinate) time.Duration { + if !c.IsCompatibleWith(other) { + panic(DimensionalityConflictError{}) + } + + dist := c.rawDistanceTo(other) + adjustedDist := dist + c.Adjustment + other.Adjustment + if adjustedDist > 0.0 { + dist = adjustedDist + } + return time.Duration(dist * secondsToNanoseconds) +} + +// rawDistanceTo returns the Vivaldi distance between this coordinate and the +// other coordinate in seconds, not including adjustments. This assumes the +// dimensions have already been checked to be compatible. +func (c *Coordinate) rawDistanceTo(other *Coordinate) float64 { + return magnitude(diff(c.Vec, other.Vec)) + c.Height + other.Height +} + +// add returns the sum of vec1 and vec2. This assumes the dimensions have +// already been checked to be compatible. +func add(vec1 []float64, vec2 []float64) []float64 { + ret := make([]float64, len(vec1)) + for i, _ := range ret { + ret[i] = vec1[i] + vec2[i] + } + return ret +} + +// diff returns the difference between the vec1 and vec2. This assumes the +// dimensions have already been checked to be compatible. +func diff(vec1 []float64, vec2 []float64) []float64 { + ret := make([]float64, len(vec1)) + for i, _ := range ret { + ret[i] = vec1[i] - vec2[i] + } + return ret +} + +// mul returns vec multiplied by a scalar factor. +func mul(vec []float64, factor float64) []float64 { + ret := make([]float64, len(vec)) + for i, _ := range vec { + ret[i] = vec[i] * factor + } + return ret +} + +// magnitude computes the magnitude of the vec. +func magnitude(vec []float64) float64 { + sum := 0.0 + for i, _ := range vec { + sum += vec[i] * vec[i] + } + return math.Sqrt(sum) +} + +// unitVectorAt returns a unit vector pointing at vec1 from vec2. If the two +// positions are the same then a random unit vector is returned. We also return +// the distance between the points for use in the later height calculation. +func unitVectorAt(vec1 []float64, vec2 []float64) ([]float64, float64) { + ret := diff(vec1, vec2) + + // If the coordinates aren't on top of each other we can normalize. + if mag := magnitude(ret); mag > zeroThreshold { + return mul(ret, 1.0/mag), mag + } + + // Otherwise, just return a random unit vector. + for i, _ := range ret { + ret[i] = rand.Float64() - 0.5 + } + if mag := magnitude(ret); mag > zeroThreshold { + return mul(ret, 1.0/mag), 0.0 + } + + // And finally just give up and make a unit vector along the first + // dimension. This should be exceedingly rare. + ret = make([]float64, len(ret)) + ret[0] = 1.0 + return ret, 0.0 +} diff --git a/Godeps/_workspace/src/github.com/hashicorp/serf/coordinate/phantom.go b/Godeps/_workspace/src/github.com/hashicorp/serf/coordinate/phantom.go new file mode 100644 index 0000000..6fb033c --- /dev/null +++ b/Godeps/_workspace/src/github.com/hashicorp/serf/coordinate/phantom.go @@ -0,0 +1,187 @@ +package coordinate + +import ( + "fmt" + "math" + "math/rand" + "time" +) + +// GenerateClients returns a slice with nodes number of clients, all with the +// given config. +func GenerateClients(nodes int, config *Config) ([]*Client, error) { + clients := make([]*Client, nodes) + for i, _ := range clients { + client, err := NewClient(config) + if err != nil { + return nil, err + } + + clients[i] = client + } + return clients, nil +} + +// GenerateLine returns a truth matrix as if all the nodes are in a straight linke +// with the given spacing between them. +func GenerateLine(nodes int, spacing time.Duration) [][]time.Duration { + truth := make([][]time.Duration, nodes) + for i := range truth { + truth[i] = make([]time.Duration, nodes) + } + + for i := 0; i < nodes; i++ { + for j := i + 1; j < nodes; j++ { + rtt := time.Duration(j-i) * spacing + truth[i][j], truth[j][i] = rtt, rtt + } + } + return truth +} + +// GenerateGrid returns a truth matrix as if all the nodes are in a two dimensional +// grid with the given spacing between them. +func GenerateGrid(nodes int, spacing time.Duration) [][]time.Duration { + truth := make([][]time.Duration, nodes) + for i := range truth { + truth[i] = make([]time.Duration, nodes) + } + + n := int(math.Sqrt(float64(nodes))) + for i := 0; i < nodes; i++ { + for j := i + 1; j < nodes; j++ { + x1, y1 := float64(i%n), float64(i/n) + x2, y2 := float64(j%n), float64(j/n) + dx, dy := x2-x1, y2-y1 + dist := math.Sqrt(dx*dx + dy*dy) + rtt := time.Duration(dist * float64(spacing)) + truth[i][j], truth[j][i] = rtt, rtt + } + } + return truth +} + +// GenerateSplit returns a truth matrix as if half the nodes are close together in +// one location and half the nodes are close together in another. The lan factor +// is used to separate the nodes locally and the wan factor represents the split +// between the two sides. +func GenerateSplit(nodes int, lan time.Duration, wan time.Duration) [][]time.Duration { + truth := make([][]time.Duration, nodes) + for i := range truth { + truth[i] = make([]time.Duration, nodes) + } + + split := nodes / 2 + for i := 0; i < nodes; i++ { + for j := i + 1; j < nodes; j++ { + rtt := lan + if (i <= split && j > split) || (i > split && j <= split) { + rtt += wan + } + truth[i][j], truth[j][i] = rtt, rtt + } + } + return truth +} + +// GenerateCircle returns a truth matrix for a set of nodes, evenly distributed +// around a circle with the given radius. The first node is at the "center" of the +// circle because it's equidistant from all the other nodes, but we place it at +// double the radius, so it should show up above all the other nodes in height. +func GenerateCircle(nodes int, radius time.Duration) [][]time.Duration { + truth := make([][]time.Duration, nodes) + for i := range truth { + truth[i] = make([]time.Duration, nodes) + } + + for i := 0; i < nodes; i++ { + for j := i + 1; j < nodes; j++ { + var rtt time.Duration + if i == 0 { + rtt = 2 * radius + } else { + t1 := 2.0 * math.Pi * float64(i) / float64(nodes) + x1, y1 := math.Cos(t1), math.Sin(t1) + t2 := 2.0 * math.Pi * float64(j) / float64(nodes) + x2, y2 := math.Cos(t2), math.Sin(t2) + dx, dy := x2-x1, y2-y1 + dist := math.Sqrt(dx*dx + dy*dy) + rtt = time.Duration(dist * float64(radius)) + } + truth[i][j], truth[j][i] = rtt, rtt + } + } + return truth +} + +// GenerateRandom returns a truth matrix for a set of nodes with normally +// distributed delays, with the given mean and deviation. The RNG is re-seeded +// so you always get the same matrix for a given size. +func GenerateRandom(nodes int, mean time.Duration, deviation time.Duration) [][]time.Duration { + rand.Seed(1) + + truth := make([][]time.Duration, nodes) + for i := range truth { + truth[i] = make([]time.Duration, nodes) + } + + for i := 0; i < nodes; i++ { + for j := i + 1; j < nodes; j++ { + rttSeconds := rand.NormFloat64()*deviation.Seconds() + mean.Seconds() + rtt := time.Duration(rttSeconds * secondsToNanoseconds) + truth[i][j], truth[j][i] = rtt, rtt + } + } + return truth +} + +// Simulate runs the given number of cycles using the given list of clients and +// truth matrix. On each cycle, each client will pick a random node and observe +// the truth RTT, updating its coordinate estimate. The RNG is re-seeded for +// each simulation run to get deterministic results (for this algorithm and the +// underlying algorithm which will use random numbers for position vectors when +// starting out with everything at the origin). +func Simulate(clients []*Client, truth [][]time.Duration, cycles int) { + rand.Seed(1) + + nodes := len(clients) + for cycle := 0; cycle < cycles; cycle++ { + for i, _ := range clients { + if j := rand.Intn(nodes); j != i { + c := clients[j].GetCoordinate() + rtt := truth[i][j] + node := fmt.Sprintf("node_%d", j) + clients[i].Update(node, c, rtt) + } + } + } +} + +// Stats is returned from the Evaluate function with a summary of the algorithm +// performance. +type Stats struct { + ErrorMax float64 + ErrorAvg float64 +} + +// Evaluate uses the coordinates of the given clients to calculate estimated +// distances and compares them with the given truth matrix, returning summary +// stats. +func Evaluate(clients []*Client, truth [][]time.Duration) (stats Stats) { + nodes := len(clients) + count := 0 + for i := 0; i < nodes; i++ { + for j := i + 1; j < nodes; j++ { + est := clients[i].DistanceTo(clients[j].GetCoordinate()).Seconds() + actual := truth[i][j].Seconds() + error := math.Abs(est-actual) / actual + stats.ErrorMax = math.Max(stats.ErrorMax, error) + stats.ErrorAvg += error + count += 1 + } + } + + stats.ErrorAvg /= float64(count) + fmt.Printf("Error avg=%9.6f max=%9.6f\n", stats.ErrorAvg, stats.ErrorMax) + return +} diff --git a/Godeps/_workspace/src/github.com/hashicorp/serf/coordinate/test_util.go b/Godeps/_workspace/src/github.com/hashicorp/serf/coordinate/test_util.go new file mode 100644 index 0000000..116e949 --- /dev/null +++ b/Godeps/_workspace/src/github.com/hashicorp/serf/coordinate/test_util.go @@ -0,0 +1,27 @@ +package coordinate + +import ( + "math" + "testing" +) + +// verifyEqualFloats will compare f1 and f2 and fail if they are not +// "equal" within a threshold. +func verifyEqualFloats(t *testing.T, f1 float64, f2 float64) { + const zeroThreshold = 1.0e-6 + if math.Abs(f1-f2) > zeroThreshold { + t.Fatalf("equal assertion fail, %9.6f != %9.6f", f1, f2) + } +} + +// verifyEqualVectors will compare vec1 and vec2 and fail if they are not +// "equal" within a threshold. +func verifyEqualVectors(t *testing.T, vec1 []float64, vec2 []float64) { + if len(vec1) != len(vec2) { + t.Fatalf("vector length mismatch, %d != %d", len(vec1), len(vec2)) + } + + for i, _ := range vec1 { + verifyEqualFloats(t, vec1[i], vec2[i]) + } +} diff --git a/Godeps/_workspace/src/github.com/lib/pq/.travis.yml b/Godeps/_workspace/src/github.com/lib/pq/.travis.yml index 55eda79..6b8eb40 100644 --- a/Godeps/_workspace/src/github.com/lib/pq/.travis.yml +++ b/Godeps/_workspace/src/github.com/lib/pq/.travis.yml @@ -1,11 +1,11 @@ language: go go: - - 1.0.2 - - 1.0.3 - 1.1 - 1.2 - 1.3 + - 1.4 + - 1.5 - tip before_install: @@ -45,12 +45,20 @@ env: - PGUSER=postgres - PQGOSSLTESTS=1 - PQSSLCERTTEST_PATH=$PWD/certs + - PGHOST=127.0.0.1 matrix: - - PGVERSION=9.3 - - PGVERSION=9.2 - - PGVERSION=9.1 - - PGVERSION=9.0 - - PGVERSION=8.4 + - PGVERSION=9.4 PQTEST_BINARY_PARAMETERS=yes + - PGVERSION=9.3 PQTEST_BINARY_PARAMETERS=yes + - PGVERSION=9.2 PQTEST_BINARY_PARAMETERS=yes + - PGVERSION=9.1 PQTEST_BINARY_PARAMETERS=yes + - PGVERSION=9.0 PQTEST_BINARY_PARAMETERS=yes + - PGVERSION=8.4 PQTEST_BINARY_PARAMETERS=yes + - PGVERSION=9.4 PQTEST_BINARY_PARAMETERS=no + - PGVERSION=9.3 PQTEST_BINARY_PARAMETERS=no + - PGVERSION=9.2 PQTEST_BINARY_PARAMETERS=no + - PGVERSION=9.1 PQTEST_BINARY_PARAMETERS=no + - PGVERSION=9.0 PQTEST_BINARY_PARAMETERS=no + - PGVERSION=8.4 PQTEST_BINARY_PARAMETERS=no script: - go test -v ./... diff --git a/Godeps/_workspace/src/github.com/lib/pq/README.md b/Godeps/_workspace/src/github.com/lib/pq/README.md index fb385a8..358d644 100644 --- a/Godeps/_workspace/src/github.com/lib/pq/README.md +++ b/Godeps/_workspace/src/github.com/lib/pq/README.md @@ -57,9 +57,13 @@ code still exists in here. * Brad Fitzpatrick (bradfitz) * Charlie Melbye (cmelbye) * Chris Bandy (cbandy) +* Chris Gilling (cgilling) * Chris Walsh (cwds) +* Dan Sosedoff (sosedoff) * Daniel Farina (fdr) * Eric Chlebek (echlebek) +* Eric Garrido (minusnine) +* Eric Urban (hydrogen18) * Everyone at The Go Team * Evan Shaw (edsrzf) * Ewan Chou (coocood) @@ -72,6 +76,7 @@ code still exists in here. * Jeremy Jay (pbnjay) * Joakim Sernbrant (serbaut) * John Gallagher (jgallagher) +* Jonathan Rudenberg (titanous) * Joël Stemmer (jstemmer) * Kamil Kisiel (kisielk) * Kelly Dunn (kellydunn) @@ -92,4 +97,7 @@ code still exists in here. * Ryan Smith (ryandotsmith) * Samuel Stauffer (samuel) * Timothée Peignier (cyberdelia) +* Travis Cline (tmc) +* TruongSinh Tran-Nguyen (truongsinh) +* Yaismel Miranda (ympons) * notedit (notedit) diff --git a/Godeps/_workspace/src/github.com/lib/pq/buf.go b/Godeps/_workspace/src/github.com/lib/pq/buf.go index c7f5b6a..6d9441c 100644 --- a/Godeps/_workspace/src/github.com/lib/pq/buf.go +++ b/Godeps/_workspace/src/github.com/lib/pq/buf.go @@ -3,6 +3,7 @@ package pq import ( "bytes" "encoding/binary" + "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/lib/pq/oid" ) @@ -20,6 +21,7 @@ func (b *readBuf) oid() (n oid.Oid) { return } +// N.B: this is actually an unsigned 16-bit integer, unlike int32 func (b *readBuf) int16() (n int) { n = int(binary.BigEndian.Uint16(*b)) *b = (*b)[2:] @@ -46,28 +48,44 @@ func (b *readBuf) byte() byte { return b.next(1)[0] } -type writeBuf []byte +type writeBuf struct { + buf []byte + pos int +} func (b *writeBuf) int32(n int) { x := make([]byte, 4) binary.BigEndian.PutUint32(x, uint32(n)) - *b = append(*b, x...) + b.buf = append(b.buf, x...) } func (b *writeBuf) int16(n int) { x := make([]byte, 2) binary.BigEndian.PutUint16(x, uint16(n)) - *b = append(*b, x...) + b.buf = append(b.buf, x...) } func (b *writeBuf) string(s string) { - *b = append(*b, (s + "\000")...) + b.buf = append(b.buf, (s + "\000")...) } func (b *writeBuf) byte(c byte) { - *b = append(*b, c) + b.buf = append(b.buf, c) } func (b *writeBuf) bytes(v []byte) { - *b = append(*b, v...) + b.buf = append(b.buf, v...) +} + +func (b *writeBuf) wrap() []byte { + p := b.buf[b.pos:] + binary.BigEndian.PutUint32(p, uint32(len(p))) + return b.buf +} + +func (b *writeBuf) next(c byte) { + p := b.buf[b.pos:] + binary.BigEndian.PutUint32(p, uint32(len(p))) + b.pos = len(b.buf) + 1 + b.buf = append(b.buf, c, 0, 0, 0, 0) } diff --git a/Godeps/_workspace/src/github.com/lib/pq/conn.go b/Godeps/_workspace/src/github.com/lib/pq/conn.go index 2bd0262..d3e900d 100644 --- a/Godeps/_workspace/src/github.com/lib/pq/conn.go +++ b/Godeps/_workspace/src/github.com/lib/pq/conn.go @@ -10,7 +10,6 @@ import ( "encoding/binary" "errors" "fmt" - "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/lib/pq/oid" "io" "io/ioutil" "net" @@ -22,6 +21,8 @@ import ( "strings" "time" "unicode" + + "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/lib/pq/oid" ) // Common error types @@ -30,6 +31,7 @@ var ( ErrInFailedTransaction = errors.New("pq: Could not complete operation in a failed transaction") ErrSSLNotSupported = errors.New("pq: SSL is not enabled on the server") ErrSSLKeyHasWorldPermissions = errors.New("pq: Private key file has group or world access. Permissions should be u=rw (0600) or less.") + ErrCouldNotDetectUsername = errors.New("pq: Could not detect default username. Please provide one explicitly.") ) type drv struct{} @@ -71,6 +73,7 @@ func (s transactionStatus) String() string { default: errorf("unknown transactionStatus %d", s) } + panic("not reached") } @@ -103,12 +106,49 @@ type conn struct { // If true, this connection is bad and all public-facing functions should // return ErrBadConn. bad bool + + // If set, this connection should never use the binary format when + // receiving query results from prepared statements. Only provided for + // debugging. + disablePreparedBinaryResult bool + + // Whether to always send []byte parameters over as binary. Enables single + // round-trip mode for non-prepared Query calls. + binaryParameters bool +} + +// Handle driver-side settings in parsed connection string. +func (c *conn) handleDriverSettings(o values) (err error) { + boolSetting := func(key string, val *bool) error { + if value := o.Get(key); value != "" { + if value == "yes" { + *val = true + } else if value == "no" { + *val = false + } else { + return fmt.Errorf("unrecognized value %q for %s", value, key) + } + } + return nil + } + + err = boolSetting("disable_prepared_binary_result", &c.disablePreparedBinaryResult) + if err != nil { + return err + } + err = boolSetting("binary_parameters", &c.binaryParameters) + if err != nil { + return err + } + return nil } func (c *conn) writeBuf(b byte) *writeBuf { c.scratch[0] = b - w := writeBuf(c.scratch[:5]) - return &w + return &writeBuf{ + buf: c.scratch[:5], + pos: 1, + } } func Open(name string) (_ driver.Conn, err error) { @@ -116,22 +156,11 @@ func Open(name string) (_ driver.Conn, err error) { } func DialOpen(d Dialer, name string) (_ driver.Conn, err error) { - defer func() { - // Handle any panics during connection initialization. Note that we - // specifically do *not* want to use errRecover(), as that would turn - // any connection errors into ErrBadConns, hiding the real error - // message from the user. - e := recover() - if e == nil { - // Do nothing - return - } - var ok bool - err, ok = e.(error) - if !ok { - err = fmt.Errorf("pq: unexpected error: %#v", e) - } - }() + // Handle any panics during connection initialization. Note that we + // specifically do *not* want to use errRecover(), as that would turn any + // connection errors into ErrBadConns, hiding the real error message from + // the user. + defer errRecoverNoErrBadConn(&err) o := make(values) @@ -149,7 +178,7 @@ func DialOpen(d Dialer, name string) (_ driver.Conn, err error) { o.Set(k, v) } - if strings.HasPrefix(name, "postgres://") { + if strings.HasPrefix(name, "postgres://") || strings.HasPrefix(name, "postgresql://") { name, err = ParseURL(name) if err != nil { return nil, err @@ -200,27 +229,36 @@ func DialOpen(d Dialer, name string) (_ driver.Conn, err error) { } } - c, err := dial(d, o) + cn := &conn{} + err = cn.handleDriverSettings(o) if err != nil { return nil, err } - cn := &conn{c: c} + cn.c, err = dial(d, o) + if err != nil { + return nil, err + } cn.ssl(o) cn.buf = bufio.NewReader(cn.c) cn.startup(o) + // reset the deadline, in case one was set (see dial) - err = cn.c.SetDeadline(time.Time{}) + if timeout := o.Get("connect_timeout"); timeout != "" && timeout != "0" { + err = cn.c.SetDeadline(time.Time{}) + } return cn, err } func dial(d Dialer, o values) (net.Conn, error) { ntw, addr := network(o) - - timeout := o.Get("connect_timeout") + // SSL is not necessary or supported over UNIX domain sockets + if ntw == "unix" { + o["sslmode"] = "disable" + } // Zero or not specified means wait indefinitely. - if timeout != "" && timeout != "0" { + if timeout := o.Get("connect_timeout"); timeout != "" && timeout != "0" { seconds, err := strconv.ParseInt(timeout, 10, 0) if err != nil { return nil, fmt.Errorf("invalid value for parameter connect_timeout: %s", err) @@ -434,6 +472,9 @@ func (cn *conn) Commit() (err error) { _, commandTag, err := cn.simpleExec("COMMIT") if err != nil { + if cn.isInTransaction() { + cn.bad = true + } return err } if commandTag != "COMMIT" { @@ -453,6 +494,9 @@ func (cn *conn) Rollback() (err error) { cn.checkIsInTransaction(true) _, commandTag, err := cn.simpleExec("ROLLBACK") if err != nil { + if cn.isInTransaction() { + cn.bad = true + } return err } if commandTag != "ROLLBACK" { @@ -490,10 +534,9 @@ func (cn *conn) simpleExec(q string) (res driver.Result, commandTag string, err errorf("unknown response for simple query: %q", t) } } - panic("not reached") } -func (cn *conn) simpleQuery(q string) (res driver.Rows, err error) { +func (cn *conn) simpleQuery(q string) (res *rows, err error) { defer cn.errRecover(&err) st := &stmt{cn: cn, name: ""} @@ -514,7 +557,15 @@ func (cn *conn) simpleQuery(q string) (res driver.Rows, err error) { cn.bad = true errorf("unexpected message %q in simple query execution", t) } - res = &rows{st: st, done: true} + if res == nil { + res = &rows{ + cn: cn, + colNames: st.colNames, + colTyps: st.colTyps, + colFmts: st.colFmts, + } + } + res.done = true case 'Z': cn.processReadyForQuery(r) // done @@ -533,8 +584,8 @@ func (cn *conn) simpleQuery(q string) (res driver.Rows, err error) { case 'T': // res might be non-nil here if we received a previous // CommandComplete, but that's fine; just overwrite it - res = &rows{st: st} - st.cols, st.rowTyps = parseMeta(r) + res = &rows{cn: cn} + res.colNames, res.colFmts, res.colTyps = parsePortalRowDescribe(r) // To work around a bug in QueryRow in Go 1.2 and earlier, wait // until the first DataRow has been received. @@ -543,52 +594,76 @@ func (cn *conn) simpleQuery(q string) (res driver.Rows, err error) { errorf("unknown response for simple query: %q", t) } } - panic("not reached") } -func (cn *conn) prepareTo(q, stmtName string) (_ *stmt, err error) { +// Decides which column formats to use for a prepared statement. The input is +// an array of type oids, one element per result column. +func decideColumnFormats(colTyps []oid.Oid, forceText bool) (colFmts []format, colFmtData []byte) { + if len(colTyps) == 0 { + return nil, colFmtDataAllText + } + + colFmts = make([]format, len(colTyps)) + if forceText { + return colFmts, colFmtDataAllText + } + + allBinary := true + allText := true + for i, o := range colTyps { + switch o { + // This is the list of types to use binary mode for when receiving them + // through a prepared statement. If a type appears in this list, it + // must also be implemented in binaryDecode in encode.go. + case oid.T_bytea: + fallthrough + case oid.T_int8: + fallthrough + case oid.T_int4: + fallthrough + case oid.T_int2: + colFmts[i] = formatBinary + allText = false + + default: + allBinary = false + } + } + + if allBinary { + return colFmts, colFmtDataAllBinary + } else if allText { + return colFmts, colFmtDataAllText + } else { + colFmtData = make([]byte, 2+len(colFmts)*2) + binary.BigEndian.PutUint16(colFmtData, uint16(len(colFmts))) + for i, v := range colFmts { + binary.BigEndian.PutUint16(colFmtData[2+i*2:], uint16(v)) + } + return colFmts, colFmtData + } +} + +func (cn *conn) prepareTo(q, stmtName string) *stmt { st := &stmt{cn: cn, name: stmtName} b := cn.writeBuf('P') b.string(st.name) b.string(q) b.int16(0) - cn.send(b) - b = cn.writeBuf('D') + b.next('D') b.byte('S') b.string(st.name) + + b.next('S') cn.send(b) - cn.send(cn.writeBuf('S')) - - for { - t, r := cn.recv1() - switch t { - case '1': - case 't': - nparams := r.int16() - st.paramTyps = make([]oid.Oid, nparams) - - for i := range st.paramTyps { - st.paramTyps[i] = r.oid() - } - case 'T': - st.cols, st.rowTyps = parseMeta(r) - case 'n': - // no data - case 'Z': - cn.processReadyForQuery(r) - return st, err - case 'E': - err = parseError(r) - default: - cn.bad = true - errorf("unexpected describe rows response: %q", t) - } - } - - panic("not reached") + cn.readParseResponse() + st.paramTyps, st.colNames, st.colTyps = cn.readStatementDescribeResponse() + st.colFmts, st.colFmtData = decideColumnFormats(st.colTyps, cn.disablePreparedBinaryResult) + cn.readReadyForQuery() + return st } func (cn *conn) Prepare(q string) (_ driver.Stmt, err error) { @@ -600,7 +675,7 @@ func (cn *conn) Prepare(q string) (_ driver.Stmt, err error) { if len(q) >= 4 && strings.EqualFold(q[:4], "COPY") { return cn.prepareCopyIn(q) } - return cn.prepareTo(q, cn.gname()) + return cn.prepareTo(q, cn.gname()), nil } func (cn *conn) Close() (err error) { @@ -632,17 +707,29 @@ func (cn *conn) Query(query string, args []driver.Value) (_ driver.Rows, err err return cn.simpleQuery(query) } - st, err := cn.prepareTo(query, "") - if err != nil { - panic(err) - } + if cn.binaryParameters { + cn.sendBinaryModeQuery(query, args) - st.exec(args) - return &rows{st: st}, nil + cn.readParseResponse() + cn.readBindResponse() + rows := &rows{cn: cn} + rows.colNames, rows.colFmts, rows.colTyps = cn.readPortalDescribeResponse() + cn.postExecuteWorkaround() + return rows, nil + } else { + st := cn.prepareTo(query, "") + st.exec(args) + return &rows{ + cn: cn, + colNames: st.colNames, + colTyps: st.colTyps, + colFmts: st.colFmts, + }, nil + } } // Implement the optional "Execer" interface for one-shot queries -func (cn *conn) Exec(query string, args []driver.Value) (_ driver.Result, err error) { +func (cn *conn) Exec(query string, args []driver.Value) (res driver.Result, err error) { if cn.bad { return nil, driver.ErrBadConn } @@ -656,32 +743,42 @@ func (cn *conn) Exec(query string, args []driver.Value) (_ driver.Result, err er return r, err } - // Use the unnamed statement to defer planning until bind - // time, or else value-based selectivity estimates cannot be - // used. - st, err := cn.prepareTo(query, "") - if err != nil { - panic(err) - } + if cn.binaryParameters { + cn.sendBinaryModeQuery(query, args) - r, err := st.Exec(args) - if err != nil { - panic(err) + cn.readParseResponse() + cn.readBindResponse() + cn.readPortalDescribeResponse() + cn.postExecuteWorkaround() + res, _, err = cn.readExecuteResponse("Execute") + return res, err + } else { + // Use the unnamed statement to defer planning until bind + // time, or else value-based selectivity estimates cannot be + // used. + st := cn.prepareTo(query, "") + r, err := st.Exec(args) + if err != nil { + panic(err) + } + return r, err } - - return r, err } -// Assumes len(*m) is > 5 func (cn *conn) send(m *writeBuf) { - b := (*m)[1:] - binary.BigEndian.PutUint32(b, uint32(len(b))) + _, err := cn.c.Write(m.wrap()) + if err != nil { + panic(err) + } +} - if (*m)[0] == 0 { - *m = b +func (cn *conn) sendStartupPacket(m *writeBuf) { + // sanity check + if m.buf[0] != 0 { + panic("oops") } - _, err := cn.c.Write(*m) + _, err := cn.c.Write((m.wrap())[1:]) if err != nil { panic(err) } @@ -766,8 +863,6 @@ func (cn *conn) recv() (t byte, r *readBuf) { return } } - - panic("not reached") } // recv1Buf is exactly equivalent to recv1, except it uses a buffer supplied by @@ -788,8 +883,6 @@ func (cn *conn) recv1Buf(r *readBuf) byte { return t } } - - panic("not reached") } // recv1 receives a message from the backend, panicking if an error occurs @@ -825,7 +918,7 @@ func (cn *conn) ssl(o values) { w := cn.writeBuf(0) w.int32(80877103) - cn.send(w) + cn.sendStartupPacket(w) b := cn.scratch[:1] _, err := io.ReadFull(cn.c, b) @@ -883,7 +976,7 @@ func (cn *conn) setupSSLClientCertificates(tlsConf *tls.Config, o values) { sslkey := o.Get("sslkey") sslcert := o.Get("sslcert") if sslkey != "" && sslcert != "" { - // If the user has set a sslkey and sslcert, they *must* exist. + // If the user has set an sslkey and sslcert, they *must* exist. missingOk = false } else { // Automatically load certificates from ~/.postgresql. @@ -900,7 +993,7 @@ func (cn *conn) setupSSLClientCertificates(tlsConf *tls.Config, o values) { missingOk = true } - // Check that both files exist, and report the error or stop depending on + // Check that both files exist, and report the error or stop, depending on // which behaviour we want. Note that we don't do any more extensive // checks than this (such as checking that the paths aren't directories); // LoadX509KeyPair() will take care of the rest. @@ -947,7 +1040,7 @@ func (cn *conn) setupSSLCA(tlsConf *tls.Config, o values) { } } -// isDriverSetting returns true iff a setting is purely for the configuring the +// isDriverSetting returns true iff a setting is purely for configuring the // driver's options and should not be sent to the server in the connection // startup packet. func isDriverSetting(key string) bool { @@ -962,11 +1055,14 @@ func isDriverSetting(key string) bool { return true case "connect_timeout": return true + case "disable_prepared_binary_result": + return true + case "binary_parameters": + return true default: return false } - panic("not reached") } func (cn *conn) startup(o values) { @@ -990,7 +1086,7 @@ func (cn *conn) startup(o values) { w.string(v) } w.string("") - cn.send(w) + cn.sendStartupPacket(w) for { t, r := cn.recv() @@ -1045,13 +1141,26 @@ func (cn *conn) auth(r *readBuf, o values) { } } +type format int + +const formatText format = 0 +const formatBinary format = 1 + +// One result-column format code with the value 1 (i.e. all binary). +var colFmtDataAllBinary []byte = []byte{0, 1, 0, 1} + +// No result-column format codes (i.e. all text). +var colFmtDataAllText []byte = []byte{0, 0} + type stmt struct { - cn *conn - name string - cols []string - rowTyps []oid.Oid - paramTyps []oid.Oid - closed bool + cn *conn + name string + colNames []string + colFmts []format + colFmtData []byte + colTyps []oid.Oid + paramTyps []oid.Oid + closed bool } func (st *stmt) Close() (err error) { @@ -1094,7 +1203,12 @@ func (st *stmt) Query(v []driver.Value) (r driver.Rows, err error) { defer st.cn.errRecover(&err) st.exec(v) - return &rows{st: st}, nil + return &rows{ + cn: st.cn, + colNames: st.colNames, + colTyps: st.colTyps, + colFmts: st.colFmts, + }, nil } func (st *stmt) Exec(v []driver.Value) (res driver.Result, err error) { @@ -1104,27 +1218,8 @@ func (st *stmt) Exec(v []driver.Value) (res driver.Result, err error) { defer st.cn.errRecover(&err) st.exec(v) - - for { - t, r := st.cn.recv1() - switch t { - case 'E': - err = parseError(r) - case 'C': - res, _ = st.cn.parseComplete(r.string()) - case 'Z': - st.cn.processReadyForQuery(r) - // done - return - case 'T', 'D', 'I': - // ignore any results - default: - st.cn.bad = true - errorf("unknown exec response: %q", t) - } - } - - panic("not reached") + res, _, err = st.cn.readExecuteResponse("simple query") + return res, err } func (st *stmt) exec(v []driver.Value) { @@ -1135,84 +1230,38 @@ func (st *stmt) exec(v []driver.Value) { errorf("got %d parameters but the statement requires %d", len(v), len(st.paramTyps)) } - w := st.cn.writeBuf('B') - w.string("") + cn := st.cn + w := cn.writeBuf('B') + w.byte(0) // unnamed portal w.string(st.name) - w.int16(0) - w.int16(len(v)) - for i, x := range v { - if x == nil { - w.int32(-1) - } else { - b := encode(&st.cn.parameterStatus, x, st.paramTyps[i]) - w.int32(len(b)) - w.bytes(b) + + if cn.binaryParameters { + cn.sendBinaryParameters(w, v) + } else { + w.int16(0) + w.int16(len(v)) + for i, x := range v { + if x == nil { + w.int32(-1) + } else { + b := encode(&cn.parameterStatus, x, st.paramTyps[i]) + w.int32(len(b)) + w.bytes(b) + } } } - w.int16(0) - st.cn.send(w) + w.bytes(st.colFmtData) - w = st.cn.writeBuf('E') - w.string("") + w.next('E') + w.byte(0) w.int32(0) - st.cn.send(w) - st.cn.send(st.cn.writeBuf('S')) + w.next('S') + cn.send(w) - var err error - for { - t, r := st.cn.recv1() - switch t { - case 'E': - err = parseError(r) - case '2': - if err != nil { - panic(err) - } - goto workaround - case 'Z': - st.cn.processReadyForQuery(r) - if err != nil { - panic(err) - } - return - default: - st.cn.bad = true - errorf("unexpected bind response: %q", t) - } - } + cn.readBindResponse() + cn.postExecuteWorkaround() - // Work around a bug in sql.DB.QueryRow: in Go 1.2 and earlier it ignores - // any errors from rows.Next, which masks errors that happened during the - // execution of the query. To avoid the problem in common cases, we wait - // here for one more message from the database. If it's not an error the - // query will likely succeed (or perhaps has already, if it's a - // CommandComplete), so we push the message into the conn struct; recv1 - // will return it as the next message for rows.Next or rows.Close. - // However, if it's an error, we wait until ReadyForQuery and then return - // the error to our caller. -workaround: - for { - t, r := st.cn.recv1() - switch t { - case 'E': - err = parseError(r) - case 'C', 'D', 'I': - // the query didn't fail, but we can't process this message - st.cn.saveMessage(t, r) - return - case 'Z': - if err == nil { - st.cn.bad = true - errorf("unexpected ReadyForQuery during extended query execution") - } - st.cn.processReadyForQuery(r) - panic(err) - default: - st.cn.bad = true - errorf("unexpected message during query execution: %q", t) - } - } } func (st *stmt) NumInput() int { @@ -1269,9 +1318,12 @@ func (cn *conn) parseComplete(commandTag string) (driver.Result, string) { } type rows struct { - st *stmt - done bool - rb readBuf + cn *conn + colNames []string + colTyps []oid.Oid + colFmts []format + done bool + rb readBuf } func (rs *rows) Close() error { @@ -1286,11 +1338,10 @@ func (rs *rows) Close() error { return err } } - panic("not reached") } func (rs *rows) Columns() []string { - return rs.st.cols + return rs.colNames } func (rs *rows) Next(dest []driver.Value) (err error) { @@ -1298,7 +1349,7 @@ func (rs *rows) Next(dest []driver.Value) (err error) { return io.EOF } - conn := rs.st.cn + conn := rs.cn if conn.bad { return driver.ErrBadConn } @@ -1320,6 +1371,10 @@ func (rs *rows) Next(dest []driver.Value) (err error) { return io.EOF case 'D': n := rs.rb.int16() + if err != nil { + conn.bad = true + errorf("unexpected DataRow after error %s", err) + } if n < len(dest) { dest = dest[:n] } @@ -1329,15 +1384,13 @@ func (rs *rows) Next(dest []driver.Value) (err error) { dest[i] = nil continue } - dest[i] = decode(&conn.parameterStatus, rs.rb.next(l), rs.st.rowTyps[i]) + dest[i] = decode(&conn.parameterStatus, rs.rb.next(l), rs.colTyps[i], rs.colFmts[i]) } return default: errorf("unexpected message after execute: %q", t) } } - - panic("not reached") } // QuoteIdentifier quotes an "identifier" (e.g. a table or a column name) to be @@ -1364,6 +1417,68 @@ func md5s(s string) string { return fmt.Sprintf("%x", h.Sum(nil)) } +func (cn *conn) sendBinaryParameters(b *writeBuf, args []driver.Value) { + // Do one pass over the parameters to see if we're going to send any of + // them over in binary. If we are, create a paramFormats array at the + // same time. + var paramFormats []int + for i, x := range args { + _, ok := x.([]byte) + if ok { + if paramFormats == nil { + paramFormats = make([]int, len(args)) + } + paramFormats[i] = 1 + } + } + if paramFormats == nil { + b.int16(0) + } else { + b.int16(len(paramFormats)) + for _, x := range paramFormats { + b.int16(x) + } + } + + b.int16(len(args)) + for _, x := range args { + if x == nil { + b.int32(-1) + } else { + datum := binaryEncode(&cn.parameterStatus, x) + b.int32(len(datum)) + b.bytes(datum) + } + } +} + +func (cn *conn) sendBinaryModeQuery(query string, args []driver.Value) { + if len(args) >= 65536 { + errorf("got %d parameters but PostgreSQL only supports 65535 parameters", len(args)) + } + + b := cn.writeBuf('P') + b.byte(0) // unnamed statement + b.string(query) + b.int16(0) + + b.next('B') + b.int16(0) // unnamed portal and statement + cn.sendBinaryParameters(b, args) + b.bytes(colFmtDataAllText) + + b.next('D') + b.byte('P') + b.byte(0) // unnamed portal + + b.next('E') + b.byte(0) + b.int32(0) + + b.next('S') + cn.send(b) +} + func (c *conn) processParameterStatus(r *readBuf) { var err error @@ -1393,15 +1508,175 @@ func (c *conn) processReadyForQuery(r *readBuf) { c.txnStatus = transactionStatus(r.byte()) } -func parseMeta(r *readBuf) (cols []string, rowTyps []oid.Oid) { +func (cn *conn) readReadyForQuery() { + t, r := cn.recv1() + switch t { + case 'Z': + cn.processReadyForQuery(r) + return + default: + cn.bad = true + errorf("unexpected message %q; expected ReadyForQuery", t) + } +} + +func (cn *conn) readParseResponse() { + t, r := cn.recv1() + switch t { + case '1': + return + case 'E': + err := parseError(r) + cn.readReadyForQuery() + panic(err) + default: + cn.bad = true + errorf("unexpected Parse response %q", t) + } +} + +func (cn *conn) readStatementDescribeResponse() (paramTyps []oid.Oid, colNames []string, colTyps []oid.Oid) { + for { + t, r := cn.recv1() + switch t { + case 't': + nparams := r.int16() + paramTyps = make([]oid.Oid, nparams) + for i := range paramTyps { + paramTyps[i] = r.oid() + } + case 'n': + return paramTyps, nil, nil + case 'T': + colNames, colTyps = parseStatementRowDescribe(r) + return paramTyps, colNames, colTyps + case 'E': + err := parseError(r) + cn.readReadyForQuery() + panic(err) + default: + cn.bad = true + errorf("unexpected Describe statement response %q", t) + } + } +} + +func (cn *conn) readPortalDescribeResponse() (colNames []string, colFmts []format, colTyps []oid.Oid) { + t, r := cn.recv1() + switch t { + case 'T': + return parsePortalRowDescribe(r) + case 'n': + return nil, nil, nil + case 'E': + err := parseError(r) + cn.readReadyForQuery() + panic(err) + default: + cn.bad = true + errorf("unexpected Describe response %q", t) + } + panic("not reached") +} + +func (cn *conn) readBindResponse() { + t, r := cn.recv1() + switch t { + case '2': + return + case 'E': + err := parseError(r) + cn.readReadyForQuery() + panic(err) + default: + cn.bad = true + errorf("unexpected Bind response %q", t) + } +} + +func (cn *conn) postExecuteWorkaround() { + // Work around a bug in sql.DB.QueryRow: in Go 1.2 and earlier it ignores + // any errors from rows.Next, which masks errors that happened during the + // execution of the query. To avoid the problem in common cases, we wait + // here for one more message from the database. If it's not an error the + // query will likely succeed (or perhaps has already, if it's a + // CommandComplete), so we push the message into the conn struct; recv1 + // will return it as the next message for rows.Next or rows.Close. + // However, if it's an error, we wait until ReadyForQuery and then return + // the error to our caller. + for { + t, r := cn.recv1() + switch t { + case 'E': + err := parseError(r) + cn.readReadyForQuery() + panic(err) + case 'C', 'D', 'I': + // the query didn't fail, but we can't process this message + cn.saveMessage(t, r) + return + default: + cn.bad = true + errorf("unexpected message during extended query execution: %q", t) + } + } +} + +// Only for Exec(), since we ignore the returned data +func (cn *conn) readExecuteResponse(protocolState string) (res driver.Result, commandTag string, err error) { + for { + t, r := cn.recv1() + switch t { + case 'C': + if err != nil { + cn.bad = true + errorf("unexpected CommandComplete after error %s", err) + } + res, commandTag = cn.parseComplete(r.string()) + case 'Z': + cn.processReadyForQuery(r) + return res, commandTag, err + case 'E': + err = parseError(r) + case 'T', 'D', 'I': + if err != nil { + cn.bad = true + errorf("unexpected %q after error %s", t, err) + } + // ignore any results + default: + cn.bad = true + errorf("unknown %s response: %q", protocolState, t) + } + } +} + +func parseStatementRowDescribe(r *readBuf) (colNames []string, colTyps []oid.Oid) { n := r.int16() - cols = make([]string, n) - rowTyps = make([]oid.Oid, n) - for i := range cols { - cols[i] = r.string() + colNames = make([]string, n) + colTyps = make([]oid.Oid, n) + for i := range colNames { + colNames[i] = r.string() r.next(6) - rowTyps[i] = r.oid() - r.next(8) + colTyps[i] = r.oid() + r.next(6) + // format code not known when describing a statement; always 0 + r.next(2) + } + return +} + +func parsePortalRowDescribe(r *readBuf) (colNames []string, colFmts []format, colTyps []oid.Oid) { + n := r.int16() + colNames = make([]string, n) + colFmts = make([]format, n) + colTyps = make([]oid.Oid, n) + for i := range colNames { + colNames[i] = r.string() + r.next(6) + colTyps[i] = r.oid() + r.next(6) + colFmts[i] = format(r.int16()) } return } diff --git a/Godeps/_workspace/src/github.com/lib/pq/copy.go b/Godeps/_workspace/src/github.com/lib/pq/copy.go index 472e835..101f111 100644 --- a/Godeps/_workspace/src/github.com/lib/pq/copy.go +++ b/Godeps/_workspace/src/github.com/lib/pq/copy.go @@ -4,7 +4,8 @@ import ( "database/sql/driver" "encoding/binary" "errors" - "sync/atomic" + "fmt" + "sync" ) var ( @@ -48,9 +49,10 @@ type copyin struct { rowData chan []byte done chan bool - closed bool - err error - errorset int32 + closed bool + + sync.Mutex // guards err + err error } const ciBufferSize = 64 * 1024 @@ -67,7 +69,7 @@ func (cn *conn) prepareCopyIn(q string) (_ driver.Stmt, err error) { cn: cn, buffer: make([]byte, 0, ciBufferSize), rowData: make(chan []byte), - done: make(chan bool), + done: make(chan bool, 1), } // add CopyData identifier + 4 bytes for message length ci.buffer = append(ci.buffer, 'd', 0, 0, 0, 0) @@ -123,8 +125,6 @@ awaitCopyInResponse: errorf("unknown response for CopyFail: %q", t) } } - - panic("not reached") } func (ci *copyin) flush(buf []byte) { @@ -139,31 +139,50 @@ func (ci *copyin) flush(buf []byte) { func (ci *copyin) resploop() { for { - t, r := ci.cn.recv1() + var r readBuf + t, err := ci.cn.recvMessage(&r) + if err != nil { + ci.cn.bad = true + ci.setError(err) + ci.done <- true + return + } switch t { case 'C': // complete + case 'N': + // NoticeResponse case 'Z': - ci.cn.processReadyForQuery(r) + ci.cn.processReadyForQuery(&r) ci.done <- true return case 'E': - err := parseError(r) + err := parseError(&r) ci.setError(err) default: ci.cn.bad = true - errorf("unknown response: %q", t) + ci.setError(fmt.Errorf("unknown response during CopyIn: %q", t)) + ci.done <- true + return } } } func (ci *copyin) isErrorSet() bool { - return atomic.LoadInt32(&ci.errorset) != 0 + ci.Lock() + isSet := (ci.err != nil) + ci.Unlock() + return isSet } +// setError() sets ci.err if one has not been set already. Caller must not be +// holding ci.Mutex. func (ci *copyin) setError(err error) { - ci.err = err - atomic.StoreInt32(&ci.errorset, 1) + ci.Lock() + if ci.err == nil { + ci.err = err + } + ci.Unlock() } func (ci *copyin) NumInput() int { @@ -196,9 +215,7 @@ func (ci *copyin) Exec(v []driver.Value) (r driver.Result, err error) { } if len(v) == 0 { - err = ci.Close() - ci.closed = true - return nil, err + return nil, ci.Close() } numValues := len(v) @@ -221,9 +238,10 @@ func (ci *copyin) Exec(v []driver.Value) (r driver.Result, err error) { } func (ci *copyin) Close() (err error) { - if ci.closed { - return errCopyInClosed + if ci.closed { // Don't do anything, we're already closed + return nil } + ci.closed = true if ci.cn.bad { return driver.ErrBadConn diff --git a/Godeps/_workspace/src/github.com/lib/pq/doc.go b/Godeps/_workspace/src/github.com/lib/pq/doc.go index 4d7a0e3..f772117 100644 --- a/Godeps/_workspace/src/github.com/lib/pq/doc.go +++ b/Godeps/_workspace/src/github.com/lib/pq/doc.go @@ -5,8 +5,9 @@ In most cases clients will use the database/sql package instead of using this package directly. For example: import ( - _ "github.com/lib/pq" "database/sql" + + _ "github.com/lib/pq" ) func main() { diff --git a/Godeps/_workspace/src/github.com/lib/pq/encode.go b/Godeps/_workspace/src/github.com/lib/pq/encode.go index e34833e..f9f11a5 100644 --- a/Godeps/_workspace/src/github.com/lib/pq/encode.go +++ b/Godeps/_workspace/src/github.com/lib/pq/encode.go @@ -3,24 +3,34 @@ package pq import ( "bytes" "database/sql/driver" + "encoding/binary" "encoding/hex" "fmt" - "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/lib/pq/oid" "math" "strconv" "strings" "sync" "time" + + "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/lib/pq/oid" ) +func binaryEncode(parameterStatus *parameterStatus, x interface{}) []byte { + switch v := x.(type) { + case []byte: + return v + default: + return encode(parameterStatus, x, oid.T_unknown) + } + panic("not reached") +} + func encode(parameterStatus *parameterStatus, x interface{}, pgtypOid oid.Oid) []byte { switch v := x.(type) { case int64: - return []byte(fmt.Sprintf("%d", v)) - case float32: - return []byte(fmt.Sprintf("%.9f", v)) + return strconv.AppendInt(nil, v, 10) case float64: - return []byte(fmt.Sprintf("%.17f", v)) + return strconv.AppendFloat(nil, v, 'f', -1, 64) case []byte: if pgtypOid == oid.T_bytea { return encodeBytea(parameterStatus.serverVersion, v) @@ -34,7 +44,7 @@ func encode(parameterStatus *parameterStatus, x interface{}, pgtypOid oid.Oid) [ return []byte(v) case bool: - return []byte(fmt.Sprintf("%t", v)) + return strconv.AppendBool(nil, v) case time.Time: return formatTs(v) @@ -45,7 +55,33 @@ func encode(parameterStatus *parameterStatus, x interface{}, pgtypOid oid.Oid) [ panic("not reached") } -func decode(parameterStatus *parameterStatus, s []byte, typ oid.Oid) interface{} { +func decode(parameterStatus *parameterStatus, s []byte, typ oid.Oid, f format) interface{} { + if f == formatBinary { + return binaryDecode(parameterStatus, s, typ) + } else { + return textDecode(parameterStatus, s, typ) + } +} + +func binaryDecode(parameterStatus *parameterStatus, s []byte, typ oid.Oid) interface{} { + switch typ { + case oid.T_bytea: + return s + case oid.T_int8: + return int64(binary.BigEndian.Uint64(s)) + case oid.T_int4: + return int64(int32(binary.BigEndian.Uint32(s))) + case oid.T_int2: + return int64(int16(binary.BigEndian.Uint16(s))) + + default: + errorf("don't know how to decode binary parameter of type %u", uint32(typ)) + } + + panic("not reached") +} + +func textDecode(parameterStatus *parameterStatus, s []byte, typ oid.Oid) interface{} { switch typ { case oid.T_bytea: return parseBytea(s) @@ -59,7 +95,7 @@ func decode(parameterStatus *parameterStatus, s []byte, typ oid.Oid) interface{} return mustParse("15:04:05-07", typ, s) case oid.T_bool: return s[0] == 't' - case oid.T_int8, oid.T_int2, oid.T_int4: + case oid.T_int8, oid.T_int4, oid.T_int2: i, err := strconv.ParseInt(string(s), 10, 64) if err != nil { errorf("%s", err) @@ -86,8 +122,6 @@ func appendEncodedText(parameterStatus *parameterStatus, buf []byte, x interface switch v := x.(type) { case int64: return strconv.AppendInt(buf, v, 10) - case float32: - return strconv.AppendFloat(buf, float64(v), 'f', -1, 32) case float64: return strconv.AppendFloat(buf, v, 'f', -1, 64) case []byte: @@ -149,12 +183,6 @@ func appendEscapedText(buf []byte, text string) []byte { func mustParse(f string, typ oid.Oid, s []byte) time.Time { str := string(s) - // Special case until time.Parse bug is fixed: - // http://code.google.com/p/go/issues/detail?id=3487 - if str[len(str)-2] == '.' { - str += "0" - } - // check for a 30-minute-offset timezone if (typ == oid.T_timestamptz || typ == oid.T_timetz) && str[len(str)-3] == ':' { @@ -212,12 +240,75 @@ func (c *locationCache) getLocation(offset int) *time.Location { return location } +var infinityTsEnabled = false +var infinityTsNegative time.Time +var infinityTsPositive time.Time + +const ( + infinityTsEnabledAlready = "pq: infinity timestamp enabled already" + infinityTsNegativeMustBeSmaller = "pq: infinity timestamp: negative value must be smaller (before) than positive" +) + +/* + * If EnableInfinityTs is not called, "-infinity" and "infinity" will return + * []byte("-infinity") and []byte("infinity") respectively, and potentially + * cause error "sql: Scan error on column index 0: unsupported driver -> Scan pair: []uint8 -> *time.Time", + * when scanning into a time.Time value. + * + * Once EnableInfinityTs has been called, all connections created using this + * driver will decode Postgres' "-infinity" and "infinity" for "timestamp", + * "timestamp with time zone" and "date" types to the predefined minimum and + * maximum times, respectively. When encoding time.Time values, any time which + * equals or preceeds the predefined minimum time will be encoded to + * "-infinity". Any values at or past the maximum time will similarly be + * encoded to "infinity". + * + * + * If EnableInfinityTs is called with negative >= positive, it will panic. + * Calling EnableInfinityTs after a connection has been established results in + * undefined behavior. If EnableInfinityTs is called more than once, it will + * panic. + */ +func EnableInfinityTs(negative time.Time, positive time.Time) { + if infinityTsEnabled { + panic(infinityTsEnabledAlready) + } + if !negative.Before(positive) { + panic(infinityTsNegativeMustBeSmaller) + } + infinityTsEnabled = true + infinityTsNegative = negative + infinityTsPositive = positive +} + +/* + * Testing might want to toggle infinityTsEnabled + */ +func disableInfinityTs() { + infinityTsEnabled = false +} + // This is a time function specific to the Postgres default DateStyle // setting ("ISO, MDY"), the only one we currently support. This // accounts for the discrepancies between the parsing available with // time.Parse and the Postgres date formatting quirks. -func parseTs(currentLocation *time.Location, str string) (result time.Time) { +func parseTs(currentLocation *time.Location, str string) interface{} { + switch str { + case "-infinity": + if infinityTsEnabled { + return infinityTsNegative + } + return []byte(str) + case "infinity": + if infinityTsEnabled { + return infinityTsPositive + } + return []byte(str) + } + monSep := strings.IndexRune(str, '-') + // this is Gregorian year, not ISO Year + // In Gregorian system, the year 1 BC is followed by AD 1 year := mustAtoi(str[:monSep]) daySep := monSep + 3 month := mustAtoi(str[monSep+1 : daySep]) @@ -245,7 +336,6 @@ func parseTs(currentLocation *time.Location, str string) (result time.Time) { nanoSec := 0 tzOff := 0 - bcSign := 1 if remainderIdx < len(str) && str[remainderIdx:remainderIdx+1] == "." { fracStart := remainderIdx + 1 @@ -281,14 +371,17 @@ func parseTs(currentLocation *time.Location, str string) (result time.Time) { } tzOff = tzSign * ((tzHours * 60 * 60) + (tzMin * 60) + tzSec) } + var isoYear int if remainderIdx < len(str) && str[remainderIdx:remainderIdx+3] == " BC" { - bcSign = -1 + isoYear = 1 - year remainderIdx += 3 + } else { + isoYear = year } if remainderIdx < len(str) { errorf("expected end of input, got %v", str[remainderIdx:]) } - t := time.Date(bcSign*year, time.Month(month), day, + t := time.Date(isoYear, time.Month(month), day, hour, minute, second, nanoSec, globalLocationCache.getLocation(tzOff)) @@ -306,31 +399,48 @@ func parseTs(currentLocation *time.Location, str string) (result time.Time) { return t } -// formatTs formats t as time.RFC3339Nano and appends time zone seconds if -// needed. +// formatTs formats t into a format postgres understands. func formatTs(t time.Time) (b []byte) { - b = []byte(t.Format(time.RFC3339Nano)) + if infinityTsEnabled { + // t <= -infinity : ! (t > -infinity) + if !t.After(infinityTsNegative) { + return []byte("-infinity") + } + // t >= infinity : ! (!t < infinity) + if !t.Before(infinityTsPositive) { + return []byte("infinity") + } + } // Need to send dates before 0001 A.D. with " BC" suffix, instead of the // minus sign preferred by Go. - if b[0] == '-' { - b = append(b[1:], ' ', 'B', 'C') + // Beware, "0000" in ISO is "1 BC", "-0001" is "2 BC" and so on + bc := false + if t.Year() <= 0 { + // flip year sign, and add 1, e.g: "0" will be "1", and "-10" will be "11" + t = t.AddDate((-t.Year())*2+1, 0, 0) + bc = true } + b = []byte(t.Format(time.RFC3339Nano)) _, offset := t.Zone() offset = offset % 60 - if offset == 0 { - return b + if offset != 0 { + // RFC3339Nano already printed the minus sign + if offset < 0 { + offset = -offset + } + + b = append(b, ':') + if offset < 10 { + b = append(b, '0') + } + b = strconv.AppendInt(b, int64(offset), 10) } - if offset < 0 { - offset = -offset + if bc { + b = append(b, " BC"...) } - - b = append(b, ':') - if offset < 10 { - b = append(b, '0') - } - return strconv.AppendInt(b, int64(offset), 10) + return b } // Parse a bytea value received from the server. Both "hex" and the legacy @@ -385,7 +495,10 @@ func parseBytea(s []byte) (result []byte) { func encodeBytea(serverVersion int, v []byte) (result []byte) { if serverVersion >= 90000 { // Use the hex format if we know that the server supports it - result = []byte(fmt.Sprintf("\\x%x", v)) + result = make([]byte, 2+hex.EncodedLen(len(v))) + result[0] = '\\' + result[1] = 'x' + hex.Encode(result[2:], v) } else { // .. or resort to "escape" for _, b := range v { diff --git a/Godeps/_workspace/src/github.com/lib/pq/error.go b/Godeps/_workspace/src/github.com/lib/pq/error.go index 0a49364..b4bb44c 100644 --- a/Godeps/_workspace/src/github.com/lib/pq/error.go +++ b/Godeps/_workspace/src/github.com/lib/pq/error.go @@ -459,6 +459,19 @@ func errorf(s string, args ...interface{}) { panic(fmt.Errorf("pq: %s", fmt.Sprintf(s, args...))) } +func errRecoverNoErrBadConn(err *error) { + e := recover() + if e == nil { + // Do nothing + return + } + var ok bool + *err, ok = e.(error) + if !ok { + *err = fmt.Errorf("pq: unexpected error: %#v", e) + } +} + func (c *conn) errRecover(err *error) { e := recover() switch v := e.(type) { diff --git a/Godeps/_workspace/src/github.com/lib/pq/listen_example/doc.go b/Godeps/_workspace/src/github.com/lib/pq/listen_example/doc.go index 34496f4..5bc99f5 100644 --- a/Godeps/_workspace/src/github.com/lib/pq/listen_example/doc.go +++ b/Godeps/_workspace/src/github.com/lib/pq/listen_example/doc.go @@ -18,11 +18,11 @@ mechanism to avoid polling the database while waiting for more work to arrive. package main import ( - "github.com/lib/pq" - "database/sql" "fmt" "time" + + "github.com/lib/pq" ) func doWork(db *sql.DB, work int64) { diff --git a/Godeps/_workspace/src/github.com/lib/pq/notify.go b/Godeps/_workspace/src/github.com/lib/pq/notify.go index 21aafbc..8cad578 100644 --- a/Godeps/_workspace/src/github.com/lib/pq/notify.go +++ b/Godeps/_workspace/src/github.com/lib/pq/notify.go @@ -6,7 +6,6 @@ package pq import ( "errors" "fmt" - "io" "sync" "sync/atomic" "time" @@ -87,12 +86,16 @@ func NewListenerConn(name string, notificationChan chan<- *Notification) (*Liste // Returns an error if an unrecoverable error has occurred and the ListenerConn // should be abandoned. func (l *ListenerConn) acquireSenderLock() error { - l.connectionLock.Lock() - defer l.connectionLock.Unlock() - if l.err != nil { - return l.err - } + // we must acquire senderLock first to avoid deadlocks; see ExecSimpleQuery l.senderLock.Lock() + + l.connectionLock.Lock() + err := l.err + l.connectionLock.Unlock() + if err != nil { + l.senderLock.Unlock() + return err + } return nil } @@ -125,7 +128,7 @@ func (l *ListenerConn) setState(newState int32) bool { // away or should be discarded because we couldn't agree on the state with the // server backend. func (l *ListenerConn) listenerConnLoop() (err error) { - defer l.cn.errRecover(&err) + defer errRecoverNoErrBadConn(&err) r := &readBuf{} for { @@ -140,6 +143,9 @@ func (l *ListenerConn) listenerConnLoop() (err error) { // about the scratch buffer being overwritten. l.notificationChan <- recvNotification(r) + case 'T', 'D': + // only used by tests; ignore + case 'E': // We might receive an ErrorResponse even when not in a query; it // is expected that the server will close the connection after @@ -170,8 +176,6 @@ func (l *ListenerConn) listenerConnLoop() (err error) { return fmt.Errorf("unexpected message %q from server in listenerConnLoop", t) } } - - panic("not reached") } // This is the main routine for the goroutine receiving on the database @@ -240,7 +244,7 @@ func (l *ListenerConn) Ping() error { // The caller must be holding senderLock (see acquireSenderLock and // releaseSenderLock). func (l *ListenerConn) sendSimpleQuery(q string) (err error) { - defer l.cn.errRecover(&err) + defer errRecoverNoErrBadConn(&err) // must set connection state before sending the query if !l.setState(connStateExpectResponse) { @@ -249,8 +253,10 @@ func (l *ListenerConn) sendSimpleQuery(q string) (err error) { // Can't use l.cn.writeBuf here because it uses the scratch buffer which // might get overwritten by listenerConnLoop. - data := writeBuf([]byte("Q\x00\x00\x00\x00")) - b := &data + b := &writeBuf{ + buf: []byte("Q\x00\x00\x00\x00"), + pos: 1, + } b.string(q) l.cn.send(b) @@ -279,13 +285,13 @@ func (l *ListenerConn) ExecSimpleQuery(q string) (executed bool, err error) { // We can't know what state the protocol is in, so we need to abandon // this connection. l.connectionLock.Lock() - defer l.connectionLock.Unlock() // Set the error pointer if it hasn't been set already; see // listenerConnMain. if l.err == nil { l.err = err } - l.cn.Close() + l.connectionLock.Unlock() + l.cn.c.Close() return false, err } @@ -294,8 +300,11 @@ func (l *ListenerConn) ExecSimpleQuery(q string) (executed bool, err error) { m, ok := <-l.replyChan if !ok { // We lost the connection to server, don't bother waiting for a - // a response. - return false, io.EOF + // a response. err should have been set already. + l.connectionLock.Lock() + err := l.err + l.connectionLock.Unlock() + return false, err } switch m.typ { case 'Z': @@ -318,18 +327,19 @@ func (l *ListenerConn) ExecSimpleQuery(q string) (executed bool, err error) { return false, fmt.Errorf("unknown response for simple query: %q", m.typ) } } - - panic("not reached") } func (l *ListenerConn) Close() error { l.connectionLock.Lock() - defer l.connectionLock.Unlock() if l.err != nil { + l.connectionLock.Unlock() return errListenerConnClosed } l.err = errListenerConnClosed - return l.cn.Close() + l.connectionLock.Unlock() + // We can't send anything on the connection without holding senderLock. + // Simply close the net.Conn to wake up everyone operating on it. + return l.cn.c.Close() } // Err() returns the reason the connection was closed. It is not safe to call @@ -428,6 +438,13 @@ func NewListener(name string, return l } +// Returns the notification channel for this listener. This is the same +// channel as Notify, and will not be recreated during the life time of the +// Listener. +func (l *Listener) NotificationChannel() <-chan *Notification { + return l.Notify +} + // Listen starts listening for notifications on a channel. Calls to this // function will block until an acknowledgement has been received from the // server. Note that Listener automatically re-establishes the connection @@ -631,8 +648,6 @@ func (l *Listener) resync(cn *ListenerConn, notificationChan <-chan *Notificatio return err } } - - panic("not reached") } // caller should NOT be holding l.lock diff --git a/Godeps/_workspace/src/github.com/lib/pq/oid/gen.go b/Godeps/_workspace/src/github.com/lib/pq/oid/gen.go index 4d11467..210c468 100644 --- a/Godeps/_workspace/src/github.com/lib/pq/oid/gen.go +++ b/Godeps/_workspace/src/github.com/lib/pq/oid/gen.go @@ -5,12 +5,12 @@ package main import ( + "database/sql" "fmt" "log" "os" "os/exec" - "database/sql" _ "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/lib/pq" ) diff --git a/Godeps/_workspace/src/github.com/lib/pq/url.go b/Godeps/_workspace/src/github.com/lib/pq/url.go index b83e806..9bac95c 100644 --- a/Godeps/_workspace/src/github.com/lib/pq/url.go +++ b/Godeps/_workspace/src/github.com/lib/pq/url.go @@ -34,7 +34,7 @@ func ParseURL(url string) (string, error) { return "", err } - if u.Scheme != "postgres" { + if u.Scheme != "postgres" && u.Scheme != "postgresql" { return "", fmt.Errorf("invalid connection protocol: %s", u.Scheme) } diff --git a/Godeps/_workspace/src/github.com/lib/pq/user_posix.go b/Godeps/_workspace/src/github.com/lib/pq/user_posix.go index aa5a3da..e937d7d 100644 --- a/Godeps/_workspace/src/github.com/lib/pq/user_posix.go +++ b/Godeps/_workspace/src/github.com/lib/pq/user_posix.go @@ -1,15 +1,24 @@ // Package pq is a pure Go Postgres driver for the database/sql package. -// +build darwin freebsd linux nacl netbsd openbsd solaris +// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris package pq -import "os/user" +import ( + "os" + "os/user" +) func userCurrent() (string, error) { u, err := user.Current() - if err != nil { - return "", err + if err == nil { + return u.Username, nil } - return u.Username, nil + + name := os.Getenv("USER") + if name != "" { + return name, nil + } + + return "", ErrCouldNotDetectUsername } diff --git a/Godeps/_workspace/src/github.com/lib/pq/user_windows.go b/Godeps/_workspace/src/github.com/lib/pq/user_windows.go index a7593ff..2b69126 100644 --- a/Godeps/_workspace/src/github.com/lib/pq/user_windows.go +++ b/Godeps/_workspace/src/github.com/lib/pq/user_windows.go @@ -19,7 +19,7 @@ func userCurrent() (string, error) { pwname_size := uint32(len(pw_name)) - 1 err := syscall.GetUserNameEx(syscall.NameSamCompatible, &pw_name[0], &pwname_size) if err != nil { - return "", err + return "", ErrCouldNotDetectUsername } s := syscall.UTF16ToString(pw_name) u := filepath.Base(s) diff --git a/Godeps/_workspace/src/github.com/satori/go.uuid/.travis.yml b/Godeps/_workspace/src/github.com/satori/go.uuid/.travis.yml index c5976ad..2199ce9 100644 --- a/Godeps/_workspace/src/github.com/satori/go.uuid/.travis.yml +++ b/Godeps/_workspace/src/github.com/satori/go.uuid/.travis.yml @@ -3,5 +3,9 @@ go: - 1.0 - 1.1 - 1.2 + - 1.3 + - 1.4 + - 1.5 +sudo: false notifications: email: false diff --git a/Godeps/_workspace/src/github.com/satori/go.uuid/LICENSE b/Godeps/_workspace/src/github.com/satori/go.uuid/LICENSE index f0785e4..6a1fb91 100644 --- a/Godeps/_workspace/src/github.com/satori/go.uuid/LICENSE +++ b/Godeps/_workspace/src/github.com/satori/go.uuid/LICENSE @@ -1,4 +1,4 @@ -Copyright (C) 2013 by Maxim Bublis +Copyright (C) 2013-2015 by Maxim Bublis Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/Godeps/_workspace/src/github.com/satori/go.uuid/README.md b/Godeps/_workspace/src/github.com/satori/go.uuid/README.md index 242b275..48d4937 100644 --- a/Godeps/_workspace/src/github.com/satori/go.uuid/README.md +++ b/Godeps/_workspace/src/github.com/satori/go.uuid/README.md @@ -24,7 +24,7 @@ Use the `go` command: UUID package requires any stable version of Go Programming Language. -It is tested against following versions of Go: 1.0, 1.1, 1.2 +It is tested against following versions of Go: 1.0-1.5 ## Example @@ -60,7 +60,7 @@ func main() { ## Copyright -Copyright (C) 2013 by Maxim Bublis . +Copyright (C) 2013-2015 by Maxim Bublis . UUID package released under MIT License. See [LICENSE](https://github.com/satori/go.uuid/blob/master/LICENSE) for details. diff --git a/Godeps/_workspace/src/github.com/satori/go.uuid/uuid.go b/Godeps/_workspace/src/github.com/satori/go.uuid/uuid.go index 5c5566f..03841d8 100644 --- a/Godeps/_workspace/src/github.com/satori/go.uuid/uuid.go +++ b/Godeps/_workspace/src/github.com/satori/go.uuid/uuid.go @@ -1,4 +1,4 @@ -// Copyright (C) 2013 by Maxim Bublis +// Copyright (C) 2013-2015 by Maxim Bublis // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the @@ -29,13 +29,13 @@ import ( "crypto/md5" "crypto/rand" "crypto/sha1" + "database/sql/driver" "encoding/binary" "encoding/hex" "fmt" "hash" "net" "os" - "strings" "sync" "time" ) @@ -59,9 +59,14 @@ const ( // UUID epoch (October 15, 1582) and Unix epoch (January 1, 1970). const epochStart = 122192928000000000 +// Used in string method conversion +const dash byte = '-' + // UUID v1/v2 storage. var ( storageMutex sync.Mutex + storageOnce sync.Once + epochFunc = unixTimeFunc clockSequence uint16 lastTime uint64 hardwareAddr [6]byte @@ -69,32 +74,46 @@ var ( posixGID = uint32(os.Getgid()) ) -// Epoch calculation function -var epochFunc func() uint64 +// String parse helpers. +var ( + urnPrefix = []byte("urn:uuid:") + byteGroups = []int{8, 4, 4, 4, 12} +) -// Initialize storage -func init() { +func initClockSequence() { buf := make([]byte, 2) - rand.Read(buf) + safeRandom(buf) clockSequence = binary.BigEndian.Uint16(buf) +} - // Initialize hardwareAddr randomly in case - // of real network interfaces absence - rand.Read(hardwareAddr[:]) - - // Set multicast bit as recommended in RFC 4122 - hardwareAddr[0] |= 0x01 - +func initHardwareAddr() { interfaces, err := net.Interfaces() if err == nil { for _, iface := range interfaces { if len(iface.HardwareAddr) >= 6 { copy(hardwareAddr[:], iface.HardwareAddr) - break + return } } } - epochFunc = unixTimeFunc + + // Initialize hardwareAddr randomly in case + // of real network interfaces absence + safeRandom(hardwareAddr[:]) + + // Set multicast bit as recommended in RFC 4122 + hardwareAddr[0] |= 0x01 +} + +func initStorage() { + initClockSequence() + initHardwareAddr() +} + +func safeRandom(dest []byte) { + if _, err := rand.Read(dest); err != nil { + panic(err) + } } // Returns difference in 100-nanosecond intervals between @@ -108,6 +127,10 @@ func unixTimeFunc() uint64 { // described in RFC 4122. type UUID [16]byte +// The nil UUID is special form of UUID that is specified to have all +// 128 bits set to zero. +var Nil = UUID{} + // Predefined namespace UUIDs. var ( NamespaceDNS, _ = FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8") @@ -165,8 +188,19 @@ func (u UUID) Bytes() []byte { // Returns canonical string representation of UUID: // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. func (u UUID) String() string { - return fmt.Sprintf("%x-%x-%x-%x-%x", - u[:4], u[4:6], u[6:8], u[8:10], u[10:]) + buf := make([]byte, 36) + + hex.Encode(buf[0:8], u[0:4]) + buf[8] = dash + hex.Encode(buf[9:13], u[4:6]) + buf[13] = dash + hex.Encode(buf[14:18], u[6:8]) + buf[18] = dash + hex.Encode(buf[19:23], u[8:10]) + buf[23] = dash + hex.Encode(buf[24:], u[10:]) + + return string(buf) } // SetVersion sets version bits. @@ -187,15 +221,40 @@ func (u UUID) MarshalText() (text []byte, err error) { } // UnmarshalText implements the encoding.TextUnmarshaler interface. -// UUID is expected in a form accepted by FromString. -func (u *UUID) UnmarshalText(text []byte) error { - s := string(text) - u2, err := FromString(s) - if err != nil { - return err +// Following formats are supported: +// "6ba7b810-9dad-11d1-80b4-00c04fd430c8", +// "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}", +// "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" +func (u *UUID) UnmarshalText(text []byte) (err error) { + if len(text) < 32 { + err = fmt.Errorf("uuid: invalid UUID string: %s", text) + return } - *u = u2 - return nil + + if bytes.Equal(text[:9], urnPrefix) { + text = text[9:] + } else if text[0] == '{' { + text = text[1:] + } + + b := u[:] + + for _, byteGroup := range byteGroups { + if text[0] == '-' { + text = text[1:] + } + + _, err = hex.Decode(b[:byteGroup/2], text[:byteGroup]) + + if err != nil { + return + } + + text = text[byteGroup:] + b = b[byteGroup/2:] + } + + return } // MarshalBinary implements the encoding.BinaryMarshaler interface. @@ -205,56 +264,79 @@ func (u UUID) MarshalBinary() (data []byte, err error) { } // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. -func (u *UUID) UnmarshalBinary(data []byte) error { - u2, err := FromBytes(data) - if err != nil { - return err +// It will return error if the slice isn't 16 bytes long. +func (u *UUID) UnmarshalBinary(data []byte) (err error) { + if len(data) != 16 { + err = fmt.Errorf("uuid: UUID must be exactly 16 bytes long, got %d bytes", len(data)) + return } - *u = u2 - return nil + copy(u[:], data) + + return +} + +// Value implements the driver.Valuer interface. +func (u UUID) Value() (driver.Value, error) { + return u.String(), nil +} + +// Scan implements the sql.Scanner interface. +// A 16-byte slice is handled by UnmarshalBinary, while +// a longer byte slice or a string is handled by UnmarshalText. +func (u *UUID) Scan(src interface{}) error { + switch src := src.(type) { + case []byte: + if len(src) == 16 { + return u.UnmarshalBinary(src) + } + return u.UnmarshalText(src) + + case string: + return u.UnmarshalText([]byte(src)) + } + + return fmt.Errorf("uuid: cannot convert %T to UUID", src) } // FromBytes returns UUID converted from raw byte slice input. // It will return error if the slice isn't 16 bytes long. func FromBytes(input []byte) (u UUID, err error) { - if len(input) != 16 { - err = fmt.Errorf("uuid: UUID must be exactly 16 bytes long, got %d bytes", len(input)) - return - } - - copy(u[:], input) - + err = u.UnmarshalBinary(input) return } +// FromBytesOrNil returns UUID converted from raw byte slice input. +// Same behavior as FromBytes, but returns a Nil UUID on error. +func FromBytesOrNil(input []byte) UUID { + uuid, err := FromBytes(input) + if err != nil { + return Nil + } + return uuid +} + // FromString returns UUID parsed from string input. -// Following formats are supported: -// "6ba7b810-9dad-11d1-80b4-00c04fd430c8", -// "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}", -// "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" +// Input is expected in a form accepted by UnmarshalText. func FromString(input string) (u UUID, err error) { - s := strings.Replace(input, "-", "", -1) - - if len(s) == 41 && s[:9] == "urn:uuid:" { - s = s[9:] - } else if len(s) == 34 && s[0] == '{' && s[33] == '}' { - s = s[1:33] - } - - if len(s) != 32 { - err = fmt.Errorf("uuid: invalid UUID string: %s", input) - return - } - - b := []byte(s) - _, err = hex.Decode(u[:], b) - + err = u.UnmarshalText([]byte(input)) return } +// FromStringOrNil returns UUID parsed from string input. +// Same behavior as FromString, but returns a Nil UUID on error. +func FromStringOrNil(input string) UUID { + uuid, err := FromString(input) + if err != nil { + return Nil + } + return uuid +} + // Returns UUID v1/v2 storage state. -// Returns epoch timestamp and clock sequence. -func getStorage() (uint64, uint16) { +// Returns epoch timestamp, clock sequence, and hardware address. +func getStorage() (uint64, uint16, []byte) { + storageOnce.Do(initStorage) + storageMutex.Lock() defer storageMutex.Unlock() @@ -266,21 +348,21 @@ func getStorage() (uint64, uint16) { } lastTime = timeNow - return timeNow, clockSequence + return timeNow, clockSequence, hardwareAddr[:] } // NewV1 returns UUID based on current timestamp and MAC address. func NewV1() UUID { u := UUID{} - timeNow, clockSeq := getStorage() + timeNow, clockSeq, hardwareAddr := getStorage() binary.BigEndian.PutUint32(u[0:], uint32(timeNow)) binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32)) binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48)) binary.BigEndian.PutUint16(u[8:], clockSeq) - copy(u[10:], hardwareAddr[:]) + copy(u[10:], hardwareAddr) u.SetVersion(1) u.SetVariant() @@ -292,6 +374,8 @@ func NewV1() UUID { func NewV2(domain byte) UUID { u := UUID{} + timeNow, clockSeq, hardwareAddr := getStorage() + switch domain { case DomainPerson: binary.BigEndian.PutUint32(u[0:], posixUID) @@ -299,14 +383,12 @@ func NewV2(domain byte) UUID { binary.BigEndian.PutUint32(u[0:], posixGID) } - timeNow, clockSeq := getStorage() - binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32)) binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48)) binary.BigEndian.PutUint16(u[8:], clockSeq) u[9] = domain - copy(u[10:], hardwareAddr[:]) + copy(u[10:], hardwareAddr) u.SetVersion(2) u.SetVariant() @@ -326,7 +408,7 @@ func NewV3(ns UUID, name string) UUID { // NewV4 returns random generated UUID. func NewV4() UUID { u := UUID{} - rand.Read(u[:]) + safeRandom(u[:]) u.SetVersion(4) u.SetVariant() diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/0doc.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/0doc.go index dd8b589..bd7361c 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/0doc.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/0doc.go @@ -64,6 +64,7 @@ Rich Feature Set includes: - Never silently skip data when decoding. User decides whether to return an error or silently skip data when keys or indexes in the data stream do not map to fields in the struct. + - Detect and error when encoding a cyclic reference (instead of stack overflow shutdown) - Encode/Decode from/to chan types (for iterative streaming support) - Drop-in replacement for encoding/json. `json:` key in struct tag supported. - Provides a RPC Server and Client Codec for net/rpc communication protocol. @@ -98,7 +99,21 @@ with the standard net/rpc package. 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: // create and configure Handle var ( @@ -148,3 +163,37 @@ Typical usage model: */ 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 } } diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/binc.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/binc.go index 9dadb0a..766d26c 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/binc.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/binc.go @@ -5,6 +5,7 @@ package codec import ( "math" + "reflect" "time" ) @@ -58,8 +59,8 @@ type bincEncDriver struct { e *Encoder w encWriter m map[string]uint16 // symbols - s uint16 // symbols sequencer b [scratchByteArrayLen]byte + s uint16 // symbols sequencer encNoSeparator } @@ -69,7 +70,15 @@ func (e *bincEncDriver) IsBuiltinType(rt uintptr) bool { func (e *bincEncDriver) EncodeBuiltin(rt uintptr, v interface{}) { if rt == timeTypId { - bs := encodeTime(v.(time.Time)) + var bs []byte + switch x := v.(type) { + case time.Time: + bs = encodeTime(x) + case *time.Time: + bs = encodeTime(*x) + default: + e.e.errorf("binc error encoding builtin: expect time.Time, received %T", v) + } e.w.writen1(bincVdTimestamp<<4 | uint8(len(bs))) e.w.writeb(bs) } @@ -309,9 +318,9 @@ func (e *bincEncDriver) encLenNumber(bd byte, v uint64) { //------------------------------------ type bincDecSymbol struct { - i uint16 s string b []byte + i uint16 } type bincDecDriver struct { @@ -320,7 +329,6 @@ type bincDecDriver struct { r decReader br bool // bytes reader bdRead bool - bdType valueType bd byte vd byte vs byte @@ -338,24 +346,23 @@ func (d *bincDecDriver) readNextBd() { d.vd = d.bd >> 4 d.vs = d.bd & 0x0f d.bdRead = true - d.bdType = valueTypeUnset } -func (d *bincDecDriver) IsContainerType(vt valueType) (b bool) { - switch vt { - case valueTypeNil: - return d.vd == bincVdSpecial && d.vs == bincSpNil - case valueTypeBytes: - return d.vd == bincVdByteArray - case valueTypeString: - return d.vd == bincVdString - case valueTypeArray: - return d.vd == bincVdArray - case valueTypeMap: - return d.vd == bincVdMap +func (d *bincDecDriver) ContainerType() (vt valueType) { + if d.vd == bincVdSpecial && d.vs == bincSpNil { + return valueTypeNil + } else if d.vd == bincVdByteArray { + return valueTypeBytes + } else if d.vd == bincVdString { + return valueTypeString + } else if d.vd == bincVdArray { + return valueTypeArray + } else if d.vd == bincVdMap { + return valueTypeMap + } else { + // d.d.errorf("isContainerType: unsupported parameter: %v", vt) } - d.d.errorf("isContainerType: unsupported parameter: %v", vt) - return // "unreachable" + return valueTypeUnset } func (d *bincDecDriver) TryDecodeAsNil() bool { @@ -686,7 +693,7 @@ func (d *bincDecDriver) decStringAndBytes(bs []byte, withString, zerocopy bool) if withString { s = string(bs2) } - d.s = append(d.s, bincDecSymbol{symbol, s, bs2}) + d.s = append(d.s, bincDecSymbol{i: symbol, s: s, b: bs2}) } default: d.d.errorf("Invalid d.vd. Expecting string:0x%x, bytearray:0x%x or symbol: 0x%x. Got: 0x%x", @@ -775,97 +782,95 @@ func (d *bincDecDriver) decodeExtV(verifyTag bool, tag byte) (xtag byte, xbs []b return } -func (d *bincDecDriver) DecodeNaked() (v interface{}, vt valueType, decodeFurther bool) { +func (d *bincDecDriver) DecodeNaked() { if !d.bdRead { d.readNextBd() } + n := &d.d.n + var decodeFurther bool + switch d.vd { case bincVdSpecial: switch d.vs { case bincSpNil: - vt = valueTypeNil + n.v = valueTypeNil case bincSpFalse: - vt = valueTypeBool - v = false + n.v = valueTypeBool + n.b = false case bincSpTrue: - vt = valueTypeBool - v = true + n.v = valueTypeBool + n.b = true case bincSpNan: - vt = valueTypeFloat - v = math.NaN() + n.v = valueTypeFloat + n.f = math.NaN() case bincSpPosInf: - vt = valueTypeFloat - v = math.Inf(1) + n.v = valueTypeFloat + n.f = math.Inf(1) case bincSpNegInf: - vt = valueTypeFloat - v = math.Inf(-1) + n.v = valueTypeFloat + n.f = math.Inf(-1) case bincSpZeroFloat: - vt = valueTypeFloat - v = float64(0) + n.v = valueTypeFloat + n.f = float64(0) case bincSpZero: - vt = valueTypeUint - v = uint64(0) // int8(0) + n.v = valueTypeUint + n.u = uint64(0) // int8(0) case bincSpNegOne: - vt = valueTypeInt - v = int64(-1) // int8(-1) + n.v = valueTypeInt + n.i = int64(-1) // int8(-1) default: d.d.errorf("decodeNaked: Unrecognized special value 0x%x", d.vs) - return } case bincVdSmallInt: - vt = valueTypeUint - v = uint64(int8(d.vs)) + 1 // int8(d.vs) + 1 + n.v = valueTypeUint + n.u = uint64(int8(d.vs)) + 1 // int8(d.vs) + 1 case bincVdPosInt: - vt = valueTypeUint - v = d.decUint() + n.v = valueTypeUint + n.u = d.decUint() case bincVdNegInt: - vt = valueTypeInt - v = -(int64(d.decUint())) + n.v = valueTypeInt + n.i = -(int64(d.decUint())) case bincVdFloat: - vt = valueTypeFloat - v = d.decFloat() + n.v = valueTypeFloat + n.f = d.decFloat() case bincVdSymbol: - vt = valueTypeSymbol - v = d.DecodeString() + n.v = valueTypeSymbol + n.s = d.DecodeString() case bincVdString: - vt = valueTypeString - v = d.DecodeString() + n.v = valueTypeString + n.s = d.DecodeString() case bincVdByteArray: - vt = valueTypeBytes - v = d.DecodeBytes(nil, false, false) + n.v = valueTypeBytes + n.l = d.DecodeBytes(nil, false, false) case bincVdTimestamp: - vt = valueTypeTimestamp + n.v = valueTypeTimestamp tt, err := decodeTime(d.r.readx(int(d.vs))) if err != nil { panic(err) } - v = tt + n.t = tt case bincVdCustomExt: - vt = valueTypeExt + n.v = valueTypeExt l := d.decLen() - var re RawExt - re.Tag = uint64(d.r.readn1()) - re.Data = d.r.readx(l) - v = &re - vt = valueTypeExt + n.u = uint64(d.r.readn1()) + n.l = d.r.readx(l) case bincVdArray: - vt = valueTypeArray + n.v = valueTypeArray decodeFurther = true case bincVdMap: - vt = valueTypeMap + n.v = valueTypeMap decodeFurther = true default: d.d.errorf("decodeNaked: Unrecognized d.vd: 0x%x", d.vd) - return } if !decodeFurther { d.bdRead = false } - if vt == valueTypeUint && d.h.SignedInteger { - d.bdType = valueTypeInt - v = int64(v.(uint64)) + if n.v == valueTypeUint && d.h.SignedInteger { + n.v = valueTypeInt + n.i = int64(n.u) } return } @@ -889,6 +894,10 @@ type BincHandle struct { binaryEncodingType } +func (h *BincHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) { + return h.SetExt(rt, tag, &setExtWrapper{b: ext}) +} + func (h *BincHandle) newEncDriver(e *Encoder) encDriver { return &bincEncDriver{e: e, w: e.w} } @@ -897,5 +906,17 @@ func (h *BincHandle) newDecDriver(d *Decoder) decDriver { return &bincDecDriver{d: d, r: d.r, h: h, br: d.bytes} } +func (e *bincEncDriver) reset() { + e.w = e.e.w + e.s = 0 + e.m = nil +} + +func (d *bincDecDriver) reset() { + d.r = d.d.r + d.s = nil + d.bd, d.bdRead, d.vd, d.vs = 0, false, 0, 0 +} + var _ decDriver = (*bincDecDriver)(nil) var _ encDriver = (*bincEncDriver)(nil) diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/cbor.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/cbor.go index c3b88da..a224cd3 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/cbor.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/cbor.go @@ -3,7 +3,10 @@ package codec -import "math" +import ( + "math" + "reflect" +) const ( cborMajorUint byte = iota @@ -57,11 +60,11 @@ const ( // ------------------- type cborEncDriver struct { + noBuiltInTypes + encNoSeparator e *Encoder w encWriter h *CborHandle - noBuiltInTypes - encNoSeparator x [8]byte } @@ -158,7 +161,11 @@ func (e *cborEncDriver) EncodeSymbol(v string) { } func (e *cborEncDriver) EncodeStringBytes(c charEncoding, v []byte) { - e.encLen(cborBaseBytes, len(v)) + if c == c_RAW { + e.encLen(cborBaseBytes, len(v)) + } else { + e.encLen(cborBaseString, len(v)) + } e.w.writeb(v) } @@ -168,11 +175,10 @@ type cborDecDriver struct { d *Decoder h *CborHandle r decReader + b [scratchByteArrayLen]byte br bool // bytes reader bdRead bool - bdType valueType bd byte - b [scratchByteArrayLen]byte noBuiltInTypes decNoSeparator } @@ -180,24 +186,23 @@ type cborDecDriver struct { func (d *cborDecDriver) readNextBd() { d.bd = d.r.readn1() d.bdRead = true - d.bdType = valueTypeUnset } -func (d *cborDecDriver) IsContainerType(vt valueType) (bv bool) { - switch vt { - case valueTypeNil: - return d.bd == cborBdNil - case valueTypeBytes: - return d.bd == cborBdIndefiniteBytes || (d.bd >= cborBaseBytes && d.bd < cborBaseString) - case valueTypeString: - return d.bd == cborBdIndefiniteString || (d.bd >= cborBaseString && d.bd < cborBaseArray) - case valueTypeArray: - return d.bd == cborBdIndefiniteArray || (d.bd >= cborBaseArray && d.bd < cborBaseMap) - case valueTypeMap: - return d.bd == cborBdIndefiniteMap || (d.bd >= cborBaseMap && d.bd < cborBaseTag) +func (d *cborDecDriver) ContainerType() (vt valueType) { + if d.bd == cborBdNil { + return valueTypeNil + } else if d.bd == cborBdIndefiniteBytes || (d.bd >= cborBaseBytes && d.bd < cborBaseString) { + return valueTypeBytes + } else if d.bd == cborBdIndefiniteString || (d.bd >= cborBaseString && d.bd < cborBaseArray) { + return valueTypeString + } else if d.bd == cborBdIndefiniteArray || (d.bd >= cborBaseArray && d.bd < cborBaseMap) { + return valueTypeArray + } else if d.bd == cborBdIndefiniteMap || (d.bd >= cborBaseMap && d.bd < cborBaseTag) { + return valueTypeMap + } else { + // d.d.errorf("isContainerType: unsupported parameter: %v", vt) } - d.d.errorf("isContainerType: unsupported parameter: %v", vt) - return // "unreachable" + return valueTypeUnset } func (d *cborDecDriver) TryDecodeAsNil() bool { @@ -439,71 +444,72 @@ func (d *cborDecDriver) DecodeExt(rv interface{}, xtag uint64, ext Ext) (realxta return } -func (d *cborDecDriver) DecodeNaked() (v interface{}, vt valueType, decodeFurther bool) { +func (d *cborDecDriver) DecodeNaked() { if !d.bdRead { d.readNextBd() } + n := &d.d.n + var decodeFurther bool + switch d.bd { case cborBdNil: - vt = valueTypeNil + n.v = valueTypeNil case cborBdFalse: - vt = valueTypeBool - v = false + n.v = valueTypeBool + n.b = false case cborBdTrue: - vt = valueTypeBool - v = true + n.v = valueTypeBool + n.b = true case cborBdFloat16, cborBdFloat32: - vt = valueTypeFloat - v = d.DecodeFloat(true) + n.v = valueTypeFloat + n.f = d.DecodeFloat(true) case cborBdFloat64: - vt = valueTypeFloat - v = d.DecodeFloat(false) + n.v = valueTypeFloat + n.f = d.DecodeFloat(false) case cborBdIndefiniteBytes: - vt = valueTypeBytes - v = d.DecodeBytes(nil, false, false) + n.v = valueTypeBytes + n.l = d.DecodeBytes(nil, false, false) case cborBdIndefiniteString: - vt = valueTypeString - v = d.DecodeString() + n.v = valueTypeString + n.s = d.DecodeString() case cborBdIndefiniteArray: - vt = valueTypeArray + n.v = valueTypeArray decodeFurther = true case cborBdIndefiniteMap: - vt = valueTypeMap + n.v = valueTypeMap decodeFurther = true default: switch { case d.bd >= cborBaseUint && d.bd < cborBaseNegInt: if d.h.SignedInteger { - vt = valueTypeInt - v = d.DecodeInt(64) + n.v = valueTypeInt + n.i = d.DecodeInt(64) } else { - vt = valueTypeUint - v = d.DecodeUint(64) + n.v = valueTypeUint + n.u = d.DecodeUint(64) } case d.bd >= cborBaseNegInt && d.bd < cborBaseBytes: - vt = valueTypeInt - v = d.DecodeInt(64) + n.v = valueTypeInt + n.i = d.DecodeInt(64) case d.bd >= cborBaseBytes && d.bd < cborBaseString: - vt = valueTypeBytes - v = d.DecodeBytes(nil, false, false) + n.v = valueTypeBytes + n.l = d.DecodeBytes(nil, false, false) case d.bd >= cborBaseString && d.bd < cborBaseArray: - vt = valueTypeString - v = d.DecodeString() + n.v = valueTypeString + n.s = d.DecodeString() case d.bd >= cborBaseArray && d.bd < cborBaseMap: - vt = valueTypeArray + n.v = valueTypeArray decodeFurther = true case d.bd >= cborBaseMap && d.bd < cborBaseTag: - vt = valueTypeMap + n.v = valueTypeMap decodeFurther = true case d.bd >= cborBaseTag && d.bd < cborBaseSimple: - vt = valueTypeExt - var re RawExt - ui := d.decUint() - d.bdRead = false - re.Tag = ui - d.d.decode(&re.Value) - v = &re + n.v = valueTypeExt + n.u = d.decUint() + n.l = nil + // d.bdRead = false + // d.d.decode(&re.Value) // handled by decode itself. // decodeFurther = true default: d.d.errorf("decodeNaked: Unrecognized d.bd: 0x%x", d.bd) @@ -550,8 +556,12 @@ func (d *cborDecDriver) DecodeNaked() (v interface{}, vt valueType, decodeFurthe // // Now, vv contains the same string "one-byte" // type CborHandle struct { - BasicHandle binaryEncodingType + BasicHandle +} + +func (h *CborHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) { + return h.SetExt(rt, tag, &setExtWrapper{i: ext}) } func (h *CborHandle) newEncDriver(e *Encoder) encDriver { @@ -562,5 +572,14 @@ func (h *CborHandle) newDecDriver(d *Decoder) decDriver { return &cborDecDriver{d: d, r: d.r, h: h, br: d.bytes} } +func (e *cborEncDriver) reset() { + e.w = e.e.w +} + +func (d *cborDecDriver) reset() { + d.r = d.d.r + d.bd, d.bdRead = 0, false +} + var _ decDriver = (*cborDecDriver)(nil) var _ encDriver = (*cborEncDriver)(nil) diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/codecgen/gen.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/codecgen/gen.go index 892df59..f370b4c 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/codecgen/gen.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/codecgen/gen.go @@ -14,6 +14,7 @@ import ( "go/build" "go/parser" "go/token" + "math/rand" "os" "os/exec" "path/filepath" @@ -23,6 +24,8 @@ import ( "time" ) +const genCodecPkg = "codec1978" // keep this in sync with codec.genCodecPkg + const genFrunMainTmpl = `//+build ignore package main @@ -38,24 +41,13 @@ package {{ $.PackageName }} import ( {{ if not .CodecPkgFiles }}{{ .CodecPkgName }} "{{ .CodecImportPath }}"{{ end }} -{{/* - {{ if .Types }}"{{ .ImportPath }}"{{ end }} - "io" -*/}} "os" "reflect" "bytes" + "strings" "go/format" ) -{{/* This is not used anymore. Remove it. -func write(w io.Writer, s string) { - if _, err := io.WriteString(w, s); err != nil { - panic(err) - } -} -*/}} - func CodecGenTempWrite{{ .RandString }}() { fout, err := os.Create("{{ .OutFile }}") if err != nil { @@ -69,7 +61,7 @@ func CodecGenTempWrite{{ .RandString }}() { var t{{ $index }} {{ . }} typs = append(typs, reflect.TypeOf(t{{ $index }})) {{ end }} - {{ if not .CodecPkgFiles }}{{ .CodecPkgName }}.{{ end }}Gen(&out, "{{ .BuildTag }}", "{{ .PackageName }}", {{ .UseUnsafe }}, typs...) + {{ if not .CodecPkgFiles }}{{ .CodecPkgName }}.{{ end }}Gen(&out, "{{ .BuildTag }}", "{{ .PackageName }}", "{{ .RandString }}", {{ .UseUnsafe }}, {{ if not .CodecPkgFiles }}{{ .CodecPkgName }}.{{ end }}NewTypeInfos(strings.Split("{{ .StructTags }}", ",")), typs...) bout, err := format.Source(out.Bytes()) if err != nil { fout.Write(out.Bytes()) @@ -89,8 +81,8 @@ func CodecGenTempWrite{{ .RandString }}() { // Tool then executes: "go run __frun__" which creates fout. // fout contains Codec(En|De)codeSelf implementations for every type T. // -func Generate(outfile, buildTag, codecPkgPath string, useUnsafe bool, goRunTag string, - regexName *regexp.Regexp, deleteTempFile bool, infiles ...string) (err error) { +func Generate(outfile, buildTag, codecPkgPath string, uid int64, useUnsafe bool, goRunTag string, + st string, regexName *regexp.Regexp, deleteTempFile bool, infiles ...string) (err error) { // For each file, grab AST, find each type, and write a call to it. if len(infiles) == 0 { return @@ -99,6 +91,13 @@ func Generate(outfile, buildTag, codecPkgPath string, useUnsafe bool, goRunTag s err = errors.New("outfile and codec package path cannot be blank") return } + if uid < 0 { + uid = -uid + } + if uid == 0 { + rr := rand.New(rand.NewSource(time.Now().UnixNano())) + uid = 101 + rr.Int63n(9777) + } // We have to parse dir for package, before opening the temp file for writing (else ImportDir fails). // Also, ImportDir(...) must take an absolute path. lastdir := filepath.Dir(outfile) @@ -118,17 +117,19 @@ func Generate(outfile, buildTag, codecPkgPath string, useUnsafe bool, goRunTag s PackageName string RandString string BuildTag string + StructTags string Types []string CodecPkgFiles bool UseUnsafe bool } tv := tmplT{ - CodecPkgName: "codec1978", + CodecPkgName: genCodecPkg, OutFile: outfile, CodecImportPath: codecPkgPath, BuildTag: buildTag, UseUnsafe: useUnsafe, - RandString: strconv.FormatInt(time.Now().UnixNano(), 10), + RandString: strconv.FormatInt(uid, 10), + StructTags: st, } tv.ImportPath = pkg.ImportPath if tv.ImportPath == tv.CodecImportPath { @@ -259,11 +260,12 @@ func main() { t := flag.String("t", "", "build tag to put in file") r := flag.String("r", ".*", "regex for type name to match") rt := flag.String("rt", "", "tags for go run") + st := flag.String("st", "codec,json", "struct tag keys to introspect") x := flag.Bool("x", false, "keep temp file") u := flag.Bool("u", false, "Use unsafe, e.g. to avoid unnecessary allocation on []byte->string") - + d := flag.Int64("d", 0, "random identifier for use in generated code") flag.Parse() - if err := Generate(*o, *t, *c, *u, *rt, + if err := Generate(*o, *t, *c, *d, *u, *rt, *st, regexp.MustCompile(*r), !*x, flag.Args()...); err != nil { fmt.Fprintf(os.Stderr, "codecgen error: %v\n", err) os.Exit(1) diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/decode.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/decode.go index a2e35d7..7e56f1e 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/decode.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/decode.go @@ -9,6 +9,7 @@ import ( "fmt" "io" "reflect" + "time" ) // Some tagging information for error messages. @@ -25,10 +26,6 @@ var ( // 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 { - // TODO: - // Add method to get num bytes read. - // This will be used to annotate errors, so user knows at what point the error occurred. - unreadn1() // readx will use the implementation scratch buffer if possible i.e. n < len(scratchbuf), OR @@ -38,6 +35,9 @@ type decReader interface { readb([]byte) readn1() uint8 readn1eof() (v uint8, eof bool) + numread() int // number of bytes read + track() + stopTrack() []byte } type decReaderByteScanner interface { @@ -49,16 +49,23 @@ type decDriver interface { // this will check if the next token is a break. CheckBreak() bool TryDecodeAsNil() bool - // check if a container type: vt is one of: Bytes, String, Nil, Slice or Map. - // if vt param == valueTypeNil, and nil is seen in stream, consume the nil. - IsContainerType(vt valueType) bool + // vt is one of: Bytes, String, Nil, Slice or Map. Return unSet if not known. + ContainerType() (vt valueType) IsBuiltinType(rt uintptr) bool DecodeBuiltin(rt uintptr, v interface{}) - //decodeNaked: Numbers are decoded as int64, uint64, float64 only (no smaller sized number types). - //for extensions, decodeNaked must completely decode them as a *RawExt. - //extensions should also use readx to decode them, for efficiency. - //kInterface will extract the detached byte slice if it has to pass it outside its realm. - DecodeNaked() (v interface{}, vt valueType, decodeFurther bool) + + // DecodeNaked will decode primitives (number, bool, string, []byte) and RawExt. + // For maps and arrays, it will not do the decoding in-band, but will signal + // the decoder, so that is done later, by setting the decNaked.valueType field. + // + // Note: Numbers are decoded as int64, uint64, float64 only (no smaller sized number types). + // for extensions, DecodeNaked must read the tag and the []byte if it exists. + // if the []byte is not read, then kInterfaceNaked will treat it as a Handle + // that stores the subsequent value in-band, and complete reading the RawExt. + // + // extensions should also use readx to decode them, for efficiency. + // kInterface will extract the detached byte slice if it has to pass it outside its realm. + DecodeNaked() DecodeInt(bitsize uint8) (i int64) DecodeUint(bitsize uint8) (ui uint64) DecodeFloat(chkOverflow32 bool) (f float64) @@ -79,20 +86,15 @@ type decDriver interface { // decodeExt(verifyTag bool, tag byte) (xtag byte, xbs []byte) ReadMapStart() int ReadArrayStart() int - ReadMapEnd() - ReadArrayEnd() - ReadArrayEntrySeparator() - ReadMapEntrySeparator() - ReadMapKVSeparator() + + reset() + uncacheRead() } type decNoSeparator struct{} -func (_ decNoSeparator) ReadMapEnd() {} -func (_ decNoSeparator) ReadArrayEnd() {} -func (_ decNoSeparator) ReadArrayEntrySeparator() {} -func (_ decNoSeparator) ReadMapEntrySeparator() {} -func (_ decNoSeparator) ReadMapKVSeparator() {} +func (_ decNoSeparator) ReadEnd() {} +func (_ decNoSeparator) uncacheRead() {} type DecodeOptions struct { // MapType specifies type to use during schema-less decoding of a map in the stream. @@ -103,6 +105,14 @@ type DecodeOptions struct { // If nil, we use []interface{} SliceType reflect.Type + // MaxInitLen defines the initial length that we "make" a collection (slice, chan or map) with. + // If 0 or negative, we default to a sensible value based on the size of an element in the collection. + // + // For example, when decoding, a stream may say that it has MAX_UINT elements. + // We should not auto-matically provision a slice of that length, to prevent Out-Of-Memory crash. + // Instead, we provision up to MaxInitLen, fill that up, and start appending after that. + MaxInitLen int + // If ErrorIfNoField, return an error when decoding a map // from a codec stream into a struct, and no matching struct field is found. ErrorIfNoField bool @@ -114,6 +124,43 @@ type DecodeOptions struct { // If SignedInteger, use the int64 during schema-less decoding of unsigned values (not uint64). SignedInteger bool + + // MapValueReset controls how we decode into a map value. + // + // By default, we MAY retrieve the mapping for a key, and then decode into that. + // However, especially with big maps, that retrieval may be expensive and unnecessary + // if the stream already contains all that is necessary to recreate the value. + // + // If true, we will never retrieve the previous mapping, + // but rather decode into a new value and set that in the map. + // + // If false, we will retrieve the previous mapping if necessary e.g. + // the previous mapping is a pointer, or is a struct or array with pre-set state, + // or is an interface. + MapValueReset bool + + // InterfaceReset controls how we decode into an interface. + // + // By default, when we see a field that is an interface{...}, + // or a map with interface{...} value, we will attempt decoding into the + // "contained" value. + // + // However, this prevents us from reading a string into an interface{} + // that formerly contained a number. + // + // If true, we will decode into a new "blank" value, and set that in the interface. + // If false, we will decode into whatever is contained in the interface. + InterfaceReset bool + + // InternString controls interning of strings during decoding. + // + // Some handles, e.g. json, typically will read map keys as strings. + // If the set of keys are finite, it may help reduce allocation to + // look them up from a map (than to allocate them afresh). + // + // Note: Handles will be smart when using the intern functionality. + // So everything will not be interned. + InternString bool } // ------------------------------------ @@ -181,8 +228,15 @@ type ioDecReader struct { br decReaderByteScanner // temp byte array re-used internally for efficiency during read. // shares buffer with Decoder, so we keep size of struct within 8 words. - x *[scratchByteArrayLen]byte - bs ioDecByteScanner + x *[scratchByteArrayLen]byte + bs ioDecByteScanner + n int // num read + tr []byte // tracking bytes read + trb bool +} + +func (z *ioDecReader) numread() int { + return z.n } func (z *ioDecReader) readx(n int) (bs []byte) { @@ -197,6 +251,10 @@ func (z *ioDecReader) readx(n int) (bs []byte) { if _, err := io.ReadAtLeast(z.br, bs, n); err != nil { panic(err) } + z.n += len(bs) + if z.trb { + z.tr = append(z.tr, bs...) + } return } @@ -204,9 +262,14 @@ func (z *ioDecReader) readb(bs []byte) { if len(bs) == 0 { return } - if _, err := io.ReadAtLeast(z.br, bs, len(bs)); err != nil { + n, err := io.ReadAtLeast(z.br, bs, len(bs)) + z.n += n + if err != nil { panic(err) } + if z.trb { + z.tr = append(z.tr, bs...) + } } func (z *ioDecReader) readn1() (b uint8) { @@ -214,12 +277,20 @@ func (z *ioDecReader) readn1() (b uint8) { if err != nil { panic(err) } + z.n++ + if z.trb { + z.tr = append(z.tr, b) + } return b } func (z *ioDecReader) readn1eof() (b uint8, eof bool) { b, err := z.br.ReadByte() if err == nil { + z.n++ + if z.trb { + z.tr = append(z.tr, b) + } } else if err == io.EOF { eof = true } else { @@ -229,9 +300,28 @@ func (z *ioDecReader) readn1eof() (b uint8, eof bool) { } func (z *ioDecReader) unreadn1() { - if err := z.br.UnreadByte(); err != nil { + err := z.br.UnreadByte() + if err != nil { panic(err) } + z.n-- + if z.trb { + if l := len(z.tr) - 1; l >= 0 { + z.tr = z.tr[:l] + } + } +} + +func (z *ioDecReader) track() { + if z.tr != nil { + z.tr = z.tr[:0] + } + z.trb = true +} + +func (z *ioDecReader) stopTrack() (bs []byte) { + z.trb = false + return z.tr } // ------------------------------------ @@ -243,6 +333,18 @@ type bytesDecReader struct { b []byte // data c int // cursor a int // available + t int // track start +} + +func (z *bytesDecReader) reset(in []byte) { + z.b = in + z.a = len(in) + z.c = 0 + z.t = 0 +} + +func (z *bytesDecReader) numread() int { + return z.c } func (z *bytesDecReader) unreadn1() { @@ -298,9 +400,17 @@ func (z *bytesDecReader) readb(bs []byte) { copy(bs, z.readx(len(bs))) } +func (z *bytesDecReader) track() { + z.t = z.c +} + +func (z *bytesDecReader) stopTrack() (bs []byte) { + return z.b[z.t:z.c] +} + // ------------------------------------ -type decFnInfoX struct { +type decFnInfo struct { d *Decoder ti *typeInfo xfFn Ext @@ -308,40 +418,26 @@ type decFnInfoX struct { seq seqType } -// decFnInfo has methods for handling decoding of a specific type -// based on some characteristics (builtin, extension, reflect Kind, etc) -type decFnInfo struct { - // use decFnInfo as a value receiver. - // keep most of it less-used variables accessible via a pointer (*decFnInfoX). - // As sweet spot for value-receiver is 3 words, keep everything except - // decDriver (which everyone needs) directly accessible. - // ensure decFnInfoX is set for everyone who needs it i.e. - // rawExt, ext, builtin, (selfer|binary|text)Marshal, kSlice, kStruct, kMap, kInterface, fastpath - - dd decDriver - *decFnInfoX -} - // ---------------------------------------- type decFn struct { i decFnInfo - f func(decFnInfo, reflect.Value) + f func(*decFnInfo, reflect.Value) } -func (f decFnInfo) builtin(rv reflect.Value) { - f.dd.DecodeBuiltin(f.ti.rtid, rv.Addr().Interface()) +func (f *decFnInfo) builtin(rv reflect.Value) { + f.d.d.DecodeBuiltin(f.ti.rtid, rv.Addr().Interface()) } -func (f decFnInfo) rawExt(rv reflect.Value) { - f.dd.DecodeExt(rv.Addr().Interface(), 0, nil) +func (f *decFnInfo) rawExt(rv reflect.Value) { + f.d.d.DecodeExt(rv.Addr().Interface(), 0, nil) } -func (f decFnInfo) ext(rv reflect.Value) { - f.dd.DecodeExt(rv.Addr().Interface(), f.xfTag, f.xfFn) +func (f *decFnInfo) ext(rv reflect.Value) { + f.d.d.DecodeExt(rv.Addr().Interface(), f.xfTag, f.xfFn) } -func (f decFnInfo) getValueForUnmarshalInterface(rv reflect.Value, indir int8) (v interface{}) { +func (f *decFnInfo) getValueForUnmarshalInterface(rv reflect.Value, indir int8) (v interface{}) { if indir == -1 { v = rv.Addr().Interface() } else if indir == 0 { @@ -358,95 +454,101 @@ func (f decFnInfo) getValueForUnmarshalInterface(rv reflect.Value, indir int8) ( return } -func (f decFnInfo) selferUnmarshal(rv reflect.Value) { +func (f *decFnInfo) selferUnmarshal(rv reflect.Value) { f.getValueForUnmarshalInterface(rv, f.ti.csIndir).(Selfer).CodecDecodeSelf(f.d) } -func (f decFnInfo) binaryUnmarshal(rv reflect.Value) { +func (f *decFnInfo) binaryUnmarshal(rv reflect.Value) { bm := f.getValueForUnmarshalInterface(rv, f.ti.bunmIndir).(encoding.BinaryUnmarshaler) - xbs := f.dd.DecodeBytes(nil, false, true) + xbs := f.d.d.DecodeBytes(nil, false, true) if fnerr := bm.UnmarshalBinary(xbs); fnerr != nil { panic(fnerr) } } -func (f decFnInfo) textUnmarshal(rv reflect.Value) { +func (f *decFnInfo) textUnmarshal(rv reflect.Value) { tm := f.getValueForUnmarshalInterface(rv, f.ti.tunmIndir).(encoding.TextUnmarshaler) - fnerr := tm.UnmarshalText(f.dd.DecodeBytes(f.d.b[:], true, true)) - // fnerr := tm.UnmarshalText(f.dd.DecodeStringAsBytes(f.d.b[:])) - - // var fnerr error - // if sb, sbok := f.dd.(decDriverStringAsBytes); sbok { - // fnerr = tm.UnmarshalText(sb.decStringAsBytes(f.d.b[:0])) - // } else { - // fnerr = tm.UnmarshalText([]byte(f.dd.decodeString())) - // } + fnerr := tm.UnmarshalText(f.d.d.DecodeBytes(f.d.b[:], true, true)) if fnerr != nil { panic(fnerr) } } -func (f decFnInfo) kErr(rv reflect.Value) { +func (f *decFnInfo) jsonUnmarshal(rv reflect.Value) { + tm := f.getValueForUnmarshalInterface(rv, f.ti.junmIndir).(jsonUnmarshaler) + // bs := f.d.d.DecodeBytes(f.d.b[:], true, true) + // 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) + } +} + +func (f *decFnInfo) kErr(rv reflect.Value) { f.d.errorf("no decoding function defined for kind %v", rv.Kind()) } -func (f decFnInfo) kString(rv reflect.Value) { - rv.SetString(f.dd.DecodeString()) +func (f *decFnInfo) kString(rv reflect.Value) { + rv.SetString(f.d.d.DecodeString()) } -func (f decFnInfo) kBool(rv reflect.Value) { - rv.SetBool(f.dd.DecodeBool()) +func (f *decFnInfo) kBool(rv reflect.Value) { + rv.SetBool(f.d.d.DecodeBool()) } -func (f decFnInfo) kInt(rv reflect.Value) { - rv.SetInt(f.dd.DecodeInt(intBitsize)) +func (f *decFnInfo) kInt(rv reflect.Value) { + rv.SetInt(f.d.d.DecodeInt(intBitsize)) } -func (f decFnInfo) kInt64(rv reflect.Value) { - rv.SetInt(f.dd.DecodeInt(64)) +func (f *decFnInfo) kInt64(rv reflect.Value) { + rv.SetInt(f.d.d.DecodeInt(64)) } -func (f decFnInfo) kInt32(rv reflect.Value) { - rv.SetInt(f.dd.DecodeInt(32)) +func (f *decFnInfo) kInt32(rv reflect.Value) { + rv.SetInt(f.d.d.DecodeInt(32)) } -func (f decFnInfo) kInt8(rv reflect.Value) { - rv.SetInt(f.dd.DecodeInt(8)) +func (f *decFnInfo) kInt8(rv reflect.Value) { + rv.SetInt(f.d.d.DecodeInt(8)) } -func (f decFnInfo) kInt16(rv reflect.Value) { - rv.SetInt(f.dd.DecodeInt(16)) +func (f *decFnInfo) kInt16(rv reflect.Value) { + rv.SetInt(f.d.d.DecodeInt(16)) } -func (f decFnInfo) kFloat32(rv reflect.Value) { - rv.SetFloat(f.dd.DecodeFloat(true)) +func (f *decFnInfo) kFloat32(rv reflect.Value) { + rv.SetFloat(f.d.d.DecodeFloat(true)) } -func (f decFnInfo) kFloat64(rv reflect.Value) { - rv.SetFloat(f.dd.DecodeFloat(false)) +func (f *decFnInfo) kFloat64(rv reflect.Value) { + rv.SetFloat(f.d.d.DecodeFloat(false)) } -func (f decFnInfo) kUint8(rv reflect.Value) { - rv.SetUint(f.dd.DecodeUint(8)) +func (f *decFnInfo) kUint8(rv reflect.Value) { + rv.SetUint(f.d.d.DecodeUint(8)) } -func (f decFnInfo) kUint64(rv reflect.Value) { - rv.SetUint(f.dd.DecodeUint(64)) +func (f *decFnInfo) kUint64(rv reflect.Value) { + rv.SetUint(f.d.d.DecodeUint(64)) } -func (f decFnInfo) kUint(rv reflect.Value) { - rv.SetUint(f.dd.DecodeUint(uintBitsize)) +func (f *decFnInfo) kUint(rv reflect.Value) { + rv.SetUint(f.d.d.DecodeUint(uintBitsize)) } -func (f decFnInfo) kUint32(rv reflect.Value) { - rv.SetUint(f.dd.DecodeUint(32)) +func (f *decFnInfo) kUintptr(rv reflect.Value) { + rv.SetUint(f.d.d.DecodeUint(uintBitsize)) } -func (f decFnInfo) kUint16(rv reflect.Value) { - rv.SetUint(f.dd.DecodeUint(16)) +func (f *decFnInfo) kUint32(rv reflect.Value) { + rv.SetUint(f.d.d.DecodeUint(32)) } -// func (f decFnInfo) kPtr(rv reflect.Value) { +func (f *decFnInfo) kUint16(rv reflect.Value) { + rv.SetUint(f.d.d.DecodeUint(16)) +} + +// func (f *decFnInfo) kPtr(rv reflect.Value) { // debugf(">>>>>>> ??? decode kPtr called - shouldn't get called") // if rv.IsNil() { // rv.Set(reflect.New(rv.Type().Elem())) @@ -456,72 +558,108 @@ func (f decFnInfo) kUint16(rv reflect.Value) { // var kIntfCtr uint64 -func (f decFnInfo) kInterfaceNaked() (rvn reflect.Value) { +func (f *decFnInfo) kInterfaceNaked() (rvn reflect.Value) { // nil interface: // use some hieristics to decode it appropriately // based on the detected next value in the stream. - v, vt, decodeFurther := f.dd.DecodeNaked() - if vt == valueTypeNil { + d := f.d + d.d.DecodeNaked() + n := &d.n + if n.v == valueTypeNil { return } // We cannot decode non-nil stream value into nil interface with methods (e.g. io.Reader). - if num := f.ti.rt.NumMethod(); num > 0 { - f.d.errorf("cannot decode non-nil codec value into nil %v (%v methods)", f.ti.rt, num) + // if num := f.ti.rt.NumMethod(); num > 0 { + if f.ti.numMeth > 0 { + d.errorf("cannot decode non-nil codec value into nil %v (%v methods)", f.ti.rt, f.ti.numMeth) return } - var useRvn bool - switch vt { + // var useRvn bool + switch n.v { case valueTypeMap: - if f.d.h.MapType == nil { - var m2 map[interface{}]interface{} - v = &m2 + // if d.h.MapType == nil || d.h.MapType == mapIntfIntfTyp { + // } else if d.h.MapType == mapStrIntfTyp { // for json performance + // } + if d.mtid == 0 || d.mtid == mapIntfIntfTypId { + l := len(n.ms) + n.ms = append(n.ms, nil) + var v2 interface{} = &n.ms[l] + d.decode(v2) + rvn = reflect.ValueOf(v2).Elem() + n.ms = n.ms[:l] + } else if d.mtid == mapStrIntfTypId { // for json performance + l := len(n.ns) + n.ns = append(n.ns, nil) + var v2 interface{} = &n.ns[l] + d.decode(v2) + rvn = reflect.ValueOf(v2).Elem() + n.ns = n.ns[:l] } else { - rvn = reflect.New(f.d.h.MapType).Elem() - useRvn = true + rvn = reflect.New(d.h.MapType).Elem() + d.decodeValue(rvn, nil) } case valueTypeArray: - if f.d.h.SliceType == nil { - var m2 []interface{} - v = &m2 + // if d.h.SliceType == nil || d.h.SliceType == intfSliceTyp { + if d.stid == 0 || d.stid == intfSliceTypId { + l := len(n.ss) + n.ss = append(n.ss, nil) + var v2 interface{} = &n.ss[l] + d.decode(v2) + rvn = reflect.ValueOf(v2).Elem() + n.ss = n.ss[:l] } else { - rvn = reflect.New(f.d.h.SliceType).Elem() - useRvn = true + rvn = reflect.New(d.h.SliceType).Elem() + d.decodeValue(rvn, nil) } case valueTypeExt: - re := v.(*RawExt) - bfn := f.d.h.getExtForTag(re.Tag) + var v interface{} + tag, bytes := n.u, n.l // calling decode below might taint the values + if bytes == nil { + l := len(n.is) + n.is = append(n.is, nil) + v2 := &n.is[l] + d.decode(v2) + v = *v2 + n.is = n.is[:l] + } + bfn := d.h.getExtForTag(tag) if bfn == nil { - re.Data = detachZeroCopyBytes(f.d.bytes, nil, re.Data) - rvn = reflect.ValueOf(*re) + var re RawExt + re.Tag = tag + re.Data = detachZeroCopyBytes(d.bytes, nil, bytes) + rvn = reflect.ValueOf(re) } else { rvnA := reflect.New(bfn.rt) rvn = rvnA.Elem() - if re.Data != nil { - bfn.ext.ReadExt(rvnA.Interface(), re.Data) + if bytes != nil { + bfn.ext.ReadExt(rvnA.Interface(), bytes) } else { - bfn.ext.UpdateExt(rvnA.Interface(), re.Value) + bfn.ext.UpdateExt(rvnA.Interface(), v) } } - return - } - if decodeFurther { - if useRvn { - f.d.decodeValue(rvn, decFn{}) - } else if v != nil { - // this v is a pointer, so we need to dereference it when done - f.d.decode(v) - rvn = reflect.ValueOf(v).Elem() - useRvn = true - } - } - - if !useRvn && v != nil { - rvn = reflect.ValueOf(v) + case valueTypeNil: + // no-op + case valueTypeInt: + rvn = reflect.ValueOf(&n.i).Elem() + case valueTypeUint: + rvn = reflect.ValueOf(&n.u).Elem() + case valueTypeFloat: + rvn = reflect.ValueOf(&n.f).Elem() + case valueTypeBool: + rvn = reflect.ValueOf(&n.b).Elem() + case valueTypeString, valueTypeSymbol: + rvn = reflect.ValueOf(&n.s).Elem() + case valueTypeBytes: + rvn = reflect.ValueOf(&n.l).Elem() + case valueTypeTimestamp: + rvn = reflect.ValueOf(&n.t).Elem() + default: + panic(fmt.Errorf("kInterfaceNaked: unexpected valueType: %d", n.v)) } return } -func (f decFnInfo) kInterface(rv reflect.Value) { +func (f *decFnInfo) kInterface(rv reflect.Value) { // debugf("\t===> kInterface") // Note: @@ -530,82 +668,108 @@ func (f decFnInfo) kInterface(rv reflect.Value) { // to decode into what was there before. // We do not replace with a generic value (as got from decodeNaked). + var rvn reflect.Value if rv.IsNil() { - rvn := f.kInterfaceNaked() + rvn = f.kInterfaceNaked() if rvn.IsValid() { rv.Set(rvn) } + } else if f.d.h.InterfaceReset { + rvn = f.kInterfaceNaked() + if rvn.IsValid() { + rv.Set(rvn) + } else { + // reset to zero value based on current type in there. + rv.Set(reflect.Zero(rv.Elem().Type())) + } } else { - rve := rv.Elem() + rvn = rv.Elem() // Note: interface{} is settable, but underlying type may not be. // Consequently, we have to set the reflect.Value directly. // if underlying type is settable (e.g. ptr or interface), // we just decode into it. // Else we create a settable value, decode into it, and set on the interface. - if rve.CanSet() { - f.d.decodeValue(rve, decFn{}) + if rvn.CanSet() { + f.d.decodeValue(rvn, nil) } else { - rve2 := reflect.New(rve.Type()).Elem() - rve2.Set(rve) - f.d.decodeValue(rve2, decFn{}) - rv.Set(rve2) + rvn2 := reflect.New(rvn.Type()).Elem() + rvn2.Set(rvn) + f.d.decodeValue(rvn2, nil) + rv.Set(rvn2) } } } -func (f decFnInfo) kStruct(rv reflect.Value) { +func (f *decFnInfo) kStruct(rv reflect.Value) { fti := f.ti d := f.d - if f.dd.IsContainerType(valueTypeMap) { - containerLen := f.dd.ReadMapStart() + dd := d.d + cr := d.cr + ctyp := dd.ContainerType() + if ctyp == valueTypeMap { + containerLen := dd.ReadMapStart() if containerLen == 0 { - f.dd.ReadMapEnd() + if cr != nil { + cr.sendContainerState(containerMapEnd) + } return } tisfi := fti.sfi hasLen := containerLen >= 0 if hasLen { for j := 0; j < containerLen; j++ { - // rvkencname := f.dd.DecodeString() - rvkencname := stringView(f.dd.DecodeBytes(f.d.b[:], true, true)) + // rvkencname := dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + rvkencname := stringView(dd.DecodeBytes(f.d.b[:], true, true)) // rvksi := ti.getForEncName(rvkencname) + if cr != nil { + cr.sendContainerState(containerMapValue) + } if k := fti.indexForEncName(rvkencname); k > -1 { si := tisfi[k] - if f.dd.TryDecodeAsNil() { + if dd.TryDecodeAsNil() { si.setToZeroValue(rv) } else { - d.decodeValue(si.field(rv, true), decFn{}) + d.decodeValue(si.field(rv, true), nil) } } else { d.structFieldNotFound(-1, rvkencname) } } } else { - for j := 0; !f.dd.CheckBreak(); j++ { - if j > 0 { - f.dd.ReadMapEntrySeparator() + for j := 0; !dd.CheckBreak(); j++ { + // rvkencname := dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapKey) } - // rvkencname := f.dd.DecodeString() - rvkencname := stringView(f.dd.DecodeBytes(f.d.b[:], true, true)) - f.dd.ReadMapKVSeparator() + rvkencname := stringView(dd.DecodeBytes(f.d.b[:], true, true)) // rvksi := ti.getForEncName(rvkencname) + if cr != nil { + cr.sendContainerState(containerMapValue) + } if k := fti.indexForEncName(rvkencname); k > -1 { si := tisfi[k] - if f.dd.TryDecodeAsNil() { + if dd.TryDecodeAsNil() { si.setToZeroValue(rv) } else { - d.decodeValue(si.field(rv, true), decFn{}) + d.decodeValue(si.field(rv, true), nil) } } else { d.structFieldNotFound(-1, rvkencname) } } - f.dd.ReadMapEnd() } - } else if f.dd.IsContainerType(valueTypeArray) { - containerLen := f.dd.ReadArrayStart() + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + } else if ctyp == valueTypeArray { + containerLen := dd.ReadArrayStart() if containerLen == 0 { - f.dd.ReadArrayEnd() + if cr != nil { + cr.sendContainerState(containerArrayEnd) + } return } // Not much gain from doing it two ways for array. @@ -616,137 +780,144 @@ func (f decFnInfo) kStruct(rv reflect.Value) { if j == containerLen { break } - } else if f.dd.CheckBreak() { + } else if dd.CheckBreak() { break } - if j > 0 { - f.dd.ReadArrayEntrySeparator() + if cr != nil { + cr.sendContainerState(containerArrayElem) } - if f.dd.TryDecodeAsNil() { + if dd.TryDecodeAsNil() { si.setToZeroValue(rv) } else { - d.decodeValue(si.field(rv, true), decFn{}) + d.decodeValue(si.field(rv, true), nil) } - // if si.i != -1 { - // d.decodeValue(rv.Field(int(si.i)), decFn{}) - // } else { - // d.decEmbeddedField(rv, si.is) - // } } if containerLen > len(fti.sfip) { // read remaining values and throw away for j := len(fti.sfip); j < containerLen; j++ { - if j > 0 { - f.dd.ReadArrayEntrySeparator() + if cr != nil { + cr.sendContainerState(containerArrayElem) } d.structFieldNotFound(j, "") } } - f.dd.ReadArrayEnd() + if cr != nil { + cr.sendContainerState(containerArrayEnd) + } } else { f.d.error(onlyMapOrArrayCanDecodeIntoStructErr) return } } -func (f decFnInfo) kSlice(rv reflect.Value) { +func (f *decFnInfo) kSlice(rv reflect.Value) { // A slice can be set from a map or array in stream. // This way, the order can be kept (as order is lost with map). ti := f.ti d := f.d - if f.dd.IsContainerType(valueTypeBytes) || f.dd.IsContainerType(valueTypeString) { - if ti.rtid == uint8SliceTypId || ti.rt.Elem().Kind() == reflect.Uint8 { - if f.seq == seqTypeChan { - bs2 := f.dd.DecodeBytes(nil, false, true) - ch := rv.Interface().(chan<- byte) - for _, b := range bs2 { - ch <- b - } - } else { - rvbs := rv.Bytes() - bs2 := f.dd.DecodeBytes(rvbs, false, false) - if rvbs == nil && bs2 != nil || rvbs != nil && bs2 == nil || len(bs2) != len(rvbs) { - if rv.CanSet() { - rv.SetBytes(bs2) - } else { - copy(rvbs, bs2) - } + dd := d.d + rtelem0 := ti.rt.Elem() + ctyp := dd.ContainerType() + if ctyp == valueTypeBytes || ctyp == valueTypeString { + // you can only decode bytes or string in the stream into a slice or array of bytes + if !(ti.rtid == uint8SliceTypId || rtelem0.Kind() == reflect.Uint8) { + f.d.errorf("bytes or string in the stream must be decoded into a slice or array of bytes, not %v", ti.rt) + } + if f.seq == seqTypeChan { + bs2 := dd.DecodeBytes(nil, false, true) + ch := rv.Interface().(chan<- byte) + for _, b := range bs2 { + ch <- b + } + } else { + rvbs := rv.Bytes() + bs2 := dd.DecodeBytes(rvbs, false, false) + if rvbs == nil && bs2 != nil || rvbs != nil && bs2 == nil || len(bs2) != len(rvbs) { + if rv.CanSet() { + rv.SetBytes(bs2) + } else { + copy(rvbs, bs2) } } - return } + return } // array := f.seq == seqTypeChan - slh, containerLenS := d.decSliceHelperStart() + slh, containerLenS := d.decSliceHelperStart() // only expects valueType(Array|Map) - // an array can never return a nil slice. so no need to check f.array here. - if rv.IsNil() { - // either chan or slice + // // an array can never return a nil slice. so no need to check f.array here. + if containerLenS == 0 { if f.seq == seqTypeSlice { - if containerLenS <= 0 { + if rv.IsNil() { rv.Set(reflect.MakeSlice(ti.rt, 0, 0)) } else { - rv.Set(reflect.MakeSlice(ti.rt, containerLenS, containerLenS)) + rv.SetLen(0) } } else if f.seq == seqTypeChan { - if containerLenS <= 0 { + if rv.IsNil() { rv.Set(reflect.MakeChan(ti.rt, 0)) - } else { - rv.Set(reflect.MakeChan(ti.rt, containerLenS)) } } - } - - rvlen := rv.Len() - if containerLenS == 0 { - if f.seq == seqTypeSlice && rvlen != 0 { - rv.SetLen(0) - } - // slh.End() // f.dd.ReadArrayEnd() + slh.End() return } - rtelem0 := ti.rt.Elem() rtelem := rtelem0 for rtelem.Kind() == reflect.Ptr { rtelem = rtelem.Elem() } fn := d.getDecFn(rtelem, true, true) - rv0 := rv + var rv0, rv9 reflect.Value + rv0 = rv rvChanged := false - rvcap := rv.Cap() - // for j := 0; j < containerLenS; j++ { - - hasLen := containerLenS >= 0 - if hasLen { + var rvlen int + if containerLenS > 0 { // hasLen if f.seq == seqTypeChan { + if rv.IsNil() { + rvlen, _ = decInferLen(containerLenS, f.d.h.MaxInitLen, int(rtelem0.Size())) + rv.Set(reflect.MakeChan(ti.rt, rvlen)) + } // handle chan specially: for j := 0; j < containerLenS; j++ { - rv0 := reflect.New(rtelem0).Elem() - d.decodeValue(rv0, fn) - rv.Send(rv0) + rv9 = reflect.New(rtelem0).Elem() + slh.ElemContainerState(j) + d.decodeValue(rv9, fn) + rv.Send(rv9) } - } else { - numToRead := containerLenS + } else { // slice or array + var truncated bool // says len of sequence is not same as expected number of elements + numToRead := containerLenS // if truncated, reset numToRead + + rvcap := rv.Cap() + rvlen = rv.Len() if containerLenS > rvcap { if f.seq == seqTypeArray { - d.arrayCannotExpand(rv.Len(), containerLenS) - numToRead = rvlen + d.arrayCannotExpand(rvlen, containerLenS) } else { - rv = reflect.MakeSlice(ti.rt, containerLenS, containerLenS) - if rvlen > 0 && !isMutableKind(ti.rt.Kind()) { - rv1 := rv0 - rv1.SetLen(rvcap) - reflect.Copy(rv, rv1) + oldRvlenGtZero := rvlen > 0 + rvlen, truncated = decInferLen(containerLenS, f.d.h.MaxInitLen, int(rtelem0.Size())) + if truncated { + if rvlen <= rvcap { + rv.SetLen(rvlen) + } else { + rv = reflect.MakeSlice(ti.rt, rvlen, rvlen) + rvChanged = true + } + } else { + rv = reflect.MakeSlice(ti.rt, rvlen, rvlen) + rvChanged = true } - rvChanged = true - rvlen = containerLenS + if rvChanged && oldRvlenGtZero && !isImmutableKind(rtelem0.Kind()) { + reflect.Copy(rv, rv0) // only copy up to length NOT cap i.e. rv0.Slice(0, rvcap) + } + rvcap = rvlen } + numToRead = rvlen } else if containerLenS != rvlen { if f.seq == seqTypeSlice { rv.SetLen(containerLenS) @@ -754,73 +925,112 @@ func (f decFnInfo) kSlice(rv reflect.Value) { } } j := 0 + // we read up to the numToRead for ; j < numToRead; j++ { + slh.ElemContainerState(j) d.decodeValue(rv.Index(j), fn) } + + // if slice, expand and read up to containerLenS (or EOF) iff truncated + // if array, swallow all the rest. + if f.seq == seqTypeArray { for ; j < containerLenS; j++ { + slh.ElemContainerState(j) d.swallow() } + } else if truncated { // slice was truncated, as chan NOT in this block + for ; j < containerLenS; j++ { + rv = expandSliceValue(rv, 1) + rv9 = rv.Index(j) + if resetSliceElemToZeroValue { + rv9.Set(reflect.Zero(rtelem0)) + } + slh.ElemContainerState(j) + d.decodeValue(rv9, fn) + } } } } else { - for j := 0; !f.dd.CheckBreak(); j++ { - var decodeIntoBlank bool - // if indefinite, etc, then expand the slice if necessary - if j >= rvlen { - if f.seq == seqTypeArray { - d.arrayCannotExpand(rvlen, j+1) - decodeIntoBlank = true - } else if f.seq == seqTypeSlice { - rv = reflect.Append(rv, reflect.Zero(rtelem0)) - rvlen++ - rvChanged = true + rvlen = rv.Len() + j := 0 + for ; !dd.CheckBreak(); j++ { + if f.seq == seqTypeChan { + slh.ElemContainerState(j) + rv9 = reflect.New(rtelem0).Elem() + d.decodeValue(rv9, fn) + rv.Send(rv9) + } else { + // if indefinite, etc, then expand the slice if necessary + var decodeIntoBlank bool + if j >= rvlen { + if f.seq == seqTypeArray { + d.arrayCannotExpand(rvlen, j+1) + decodeIntoBlank = true + } else { // if f.seq == seqTypeSlice + // rv = reflect.Append(rv, reflect.Zero(rtelem0)) // uses append logic, plus varargs + rv = expandSliceValue(rv, 1) + rv9 = rv.Index(j) + // rv.Index(rv.Len() - 1).Set(reflect.Zero(rtelem0)) + if resetSliceElemToZeroValue { + rv9.Set(reflect.Zero(rtelem0)) + } + rvlen++ + rvChanged = true + } + } else { // slice or array + rv9 = rv.Index(j) + } + slh.ElemContainerState(j) + if decodeIntoBlank { + d.swallow() + } else { // seqTypeSlice + d.decodeValue(rv9, fn) } } - if j > 0 { - slh.Sep(j) - } - if f.seq == seqTypeChan { - rv0 := reflect.New(rtelem0).Elem() - d.decodeValue(rv0, fn) - rv.Send(rv0) - } else if decodeIntoBlank { - d.swallow() - } else { - d.decodeValue(rv.Index(j), fn) + } + if f.seq == seqTypeSlice { + if j < rvlen { + rv.SetLen(j) + } else if j == 0 && rv.IsNil() { + rv = reflect.MakeSlice(ti.rt, 0, 0) + rvChanged = true } } - slh.End() } + slh.End() if rvChanged { rv0.Set(rv) } } -func (f decFnInfo) kArray(rv reflect.Value) { +func (f *decFnInfo) kArray(rv reflect.Value) { // f.d.decodeValue(rv.Slice(0, rv.Len())) f.kSlice(rv.Slice(0, rv.Len())) } -func (f decFnInfo) kMap(rv reflect.Value) { - containerLen := f.dd.ReadMapStart() - +func (f *decFnInfo) kMap(rv reflect.Value) { + d := f.d + dd := d.d + containerLen := dd.ReadMapStart() + cr := d.cr ti := f.ti if rv.IsNil() { rv.Set(reflect.MakeMap(ti.rt)) } if containerLen == 0 { - // f.dd.ReadMapEnd() + if cr != nil { + cr.sendContainerState(containerMapEnd) + } return } - d := f.d - ktype, vtype := ti.rt.Key(), ti.rt.Elem() ktypeId := reflect.ValueOf(ktype).Pointer() - var keyFn, valFn decFn + vtypeKind := vtype.Kind() + var keyFn, valFn *decFn var xtyp reflect.Type for xtyp = ktype; xtyp.Kind() == reflect.Ptr; xtyp = xtyp.Elem() { } @@ -828,90 +1038,276 @@ func (f decFnInfo) kMap(rv reflect.Value) { for xtyp = vtype; xtyp.Kind() == reflect.Ptr; xtyp = xtyp.Elem() { } valFn = d.getDecFn(xtyp, true, true) + var mapGet, mapSet bool + if !f.d.h.MapValueReset { + // if pointer, mapGet = true + // if interface, mapGet = true if !DecodeNakedAlways (else false) + // if builtin, mapGet = false + // else mapGet = true + if vtypeKind == reflect.Ptr { + mapGet = true + } else if vtypeKind == reflect.Interface { + if !f.d.h.InterfaceReset { + mapGet = true + } + } else if !isImmutableKind(vtypeKind) { + mapGet = true + } + } + + var rvk, rvv, rvz reflect.Value + // for j := 0; j < containerLen; j++ { if containerLen > 0 { for j := 0; j < containerLen; j++ { - rvk := reflect.New(ktype).Elem() + rvk = reflect.New(ktype).Elem() + if cr != nil { + cr.sendContainerState(containerMapKey) + } d.decodeValue(rvk, keyFn) // special case if a byte array. if ktypeId == intfTypId { rvk = rvk.Elem() if rvk.Type() == uint8SliceTyp { - rvk = reflect.ValueOf(string(rvk.Bytes())) + rvk = reflect.ValueOf(d.string(rvk.Bytes())) } } - rvv := rv.MapIndex(rvk) - // TODO: is !IsValid check required? - if !rvv.IsValid() { - rvv = reflect.New(vtype).Elem() + mapSet = true // set to false if u do a get, and its a pointer, and exists + if mapGet { + rvv = rv.MapIndex(rvk) + if rvv.IsValid() { + if vtypeKind == reflect.Ptr { + mapSet = false + } + } else { + if rvz.IsValid() { + rvz.Set(reflect.Zero(vtype)) + } else { + rvz = reflect.New(vtype).Elem() + } + rvv = rvz + } + } else { + if rvz.IsValid() { + rvz.Set(reflect.Zero(vtype)) + } else { + rvz = reflect.New(vtype).Elem() + } + rvv = rvz + } + if cr != nil { + cr.sendContainerState(containerMapValue) } d.decodeValue(rvv, valFn) - rv.SetMapIndex(rvk, rvv) + if mapSet { + rv.SetMapIndex(rvk, rvv) + } } } else { - for j := 0; !f.dd.CheckBreak(); j++ { - if j > 0 { - f.dd.ReadMapEntrySeparator() + for j := 0; !dd.CheckBreak(); j++ { + rvk = reflect.New(ktype).Elem() + if cr != nil { + cr.sendContainerState(containerMapKey) } - rvk := reflect.New(ktype).Elem() d.decodeValue(rvk, keyFn) // special case if a byte array. if ktypeId == intfTypId { rvk = rvk.Elem() if rvk.Type() == uint8SliceTyp { - rvk = reflect.ValueOf(string(rvk.Bytes())) + rvk = reflect.ValueOf(d.string(rvk.Bytes())) } } - rvv := rv.MapIndex(rvk) - if !rvv.IsValid() { - rvv = reflect.New(vtype).Elem() + mapSet = true // set to false if u do a get, and its a pointer, and exists + if mapGet { + rvv = rv.MapIndex(rvk) + if rvv.IsValid() { + if vtypeKind == reflect.Ptr { + mapSet = false + } + } else { + if rvz.IsValid() { + rvz.Set(reflect.Zero(vtype)) + } else { + rvz = reflect.New(vtype).Elem() + } + rvv = rvz + } + } else { + if rvz.IsValid() { + rvz.Set(reflect.Zero(vtype)) + } else { + rvz = reflect.New(vtype).Elem() + } + rvv = rvz + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - f.dd.ReadMapKVSeparator() d.decodeValue(rvv, valFn) - rv.SetMapIndex(rvk, rvv) + if mapSet { + rv.SetMapIndex(rvk, rvv) + } } - f.dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -type rtidDecFn struct { +type decRtidFn struct { rtid uintptr fn decFn } +// decNaked is used to keep track of the primitives decoded. +// Without it, we would have to decode each primitive and wrap it +// in an interface{}, causing an allocation. +// In this model, the primitives are decoded in a "pseudo-atomic" fashion, +// so we can rest assured that no other decoding happens while these +// primitives are being decoded. +// +// maps and arrays are not handled by this mechanism. +// However, RawExt is, and we accomodate for extensions that decode +// RawExt from DecodeNaked, but need to decode the value subsequently. +// kInterfaceNaked and swallow, which call DecodeNaked, handle this caveat. +// +// However, decNaked also keeps some arrays of default maps and slices +// used in DecodeNaked. This way, we can get a pointer to it +// without causing a new heap allocation. +// +// kInterfaceNaked will ensure that there is no allocation for the common +// uses. +type decNaked struct { + // r RawExt // used for RawExt, uint, []byte. + u uint64 + i int64 + f float64 + l []byte + s string + t time.Time + b bool + v valueType + + // stacks for reducing allocation + is []interface{} + ms []map[interface{}]interface{} + ns []map[string]interface{} + ss [][]interface{} + // rs []RawExt + + // keep arrays at the bottom? Chance is that they are not used much. + ia [4]interface{} + ma [4]map[interface{}]interface{} + na [4]map[string]interface{} + sa [4][]interface{} + // ra [2]RawExt +} + +func (n *decNaked) reset() { + if n.ss != nil { + n.ss = n.ss[:0] + } + if n.is != nil { + n.is = n.is[:0] + } + if n.ms != nil { + n.ms = n.ms[:0] + } + if n.ns != nil { + n.ns = n.ns[:0] + } +} + // A Decoder reads and decodes an object from an input stream in the codec format. type Decoder struct { // hopefully, reduce derefencing cost by laying the decReader inside the Decoder. // Try to put things that go together to fit within a cache line (8 words). d decDriver + // NOTE: Decoder shouldn't call it's read methods, + // as the handler MAY need to do some coordination. r decReader - //sa [32]rtidDecFn - s []rtidDecFn - h *BasicHandle + // sa [initCollectionCap]decRtidFn + h *BasicHandle + hh Handle - rb bytesDecReader - hh Handle be bool // is binary encoding bytes bool // is bytes reader + js bool // is json handle + rb bytesDecReader ri ioDecReader - f map[uintptr]decFn - _ uintptr // for alignment purposes, so next one starts from a cache line + cr containerStateRecv - b [scratchByteArrayLen]byte + s []decRtidFn + f map[uintptr]*decFn + + // _ uintptr // for alignment purposes, so next one starts from a cache line + + // cache the mapTypeId and sliceTypeId for faster comparisons + mtid uintptr + stid uintptr + + n decNaked + b [scratchByteArrayLen]byte + is map[string]string // used for interning strings } // NewDecoder returns a Decoder for decoding a stream of bytes from an io.Reader. // // For efficiency, Users are encouraged to pass in a memory buffered reader // (eg bufio.Reader, bytes.Buffer). -func NewDecoder(r io.Reader, h Handle) (d *Decoder) { - d = &Decoder{hh: h, h: h.getBasicHandle(), be: h.isBinary()} - //d.s = d.sa[:0] +func NewDecoder(r io.Reader, h Handle) *Decoder { + d := newDecoder(h) + d.Reset(r) + return d +} + +// NewDecoderBytes returns a Decoder which efficiently decodes directly +// from a byte slice with zero copying. +func NewDecoderBytes(in []byte, h Handle) *Decoder { + d := newDecoder(h) + d.ResetBytes(in) + return d +} + +func newDecoder(h Handle) *Decoder { + d := &Decoder{hh: h, h: h.getBasicHandle(), be: h.isBinary()} + n := &d.n + // n.rs = n.ra[:0] + n.ms = n.ma[:0] + n.is = n.ia[:0] + n.ns = n.na[:0] + n.ss = n.sa[:0] + _, d.js = h.(*JsonHandle) + if d.h.InternString { + d.is = make(map[string]string, 32) + } + d.d = h.newDecDriver(d) + d.cr, _ = d.d.(containerStateRecv) + // d.d = h.newDecDriver(decReaderT{true, &d.rb, &d.ri}) + return d +} + +func (d *Decoder) resetCommon() { + d.n.reset() + d.d.reset() + // reset all things which were cached from the Handle, + // but could be changed. + d.mtid, d.stid = 0, 0 + if d.h.MapType != nil { + d.mtid = reflect.ValueOf(d.h.MapType).Pointer() + } + if d.h.SliceType != nil { + d.stid = reflect.ValueOf(d.h.SliceType).Pointer() + } +} + +func (d *Decoder) Reset(r io.Reader) { d.ri.x = &d.b + // d.s = d.sa[:0] d.ri.bs.r = r var ok bool d.ri.br, ok = r.(decReaderByteScanner) @@ -919,23 +1315,22 @@ func NewDecoder(r io.Reader, h Handle) (d *Decoder) { d.ri.br = &d.ri.bs } d.r = &d.ri - d.d = h.newDecDriver(d) - return + d.resetCommon() } -// NewDecoderBytes returns a Decoder which efficiently decodes directly -// from a byte slice with zero copying. -func NewDecoderBytes(in []byte, h Handle) (d *Decoder) { - d = &Decoder{hh: h, h: h.getBasicHandle(), be: h.isBinary(), bytes: true} - //d.s = d.sa[:0] - d.rb.b = in - d.rb.a = len(in) +func (d *Decoder) ResetBytes(in []byte) { + // d.s = d.sa[:0] + d.rb.reset(in) d.r = &d.rb - d.d = h.newDecDriver(d) - // d.d = h.newDecDriver(decReaderT{true, &d.rb, &d.ri}) - return + d.resetCommon() } +// func (d *Decoder) sendContainerState(c containerState) { +// if d.cr != nil { +// d.cr.sendContainerState(c) +// } +// } + // Decode decodes the stream from reader and stores the result in the // value pointed to by v. v cannot be a nil pointer. v can also be // a reflect.Value of a pointer. @@ -995,15 +1390,18 @@ func (d *Decoder) Decode(v interface{}) (err error) { // this is not a smart swallow, as it allocates objects and does unnecessary work. func (d *Decoder) swallowViaHammer() { var blank interface{} - d.decodeValue(reflect.ValueOf(&blank).Elem(), decFn{}) + d.decodeValue(reflect.ValueOf(&blank).Elem(), nil) } func (d *Decoder) swallow() { // smarter decode that just swallows the content dd := d.d - switch { - case dd.TryDecodeAsNil(): - case dd.IsContainerType(valueTypeMap): + if dd.TryDecodeAsNil() { + return + } + cr := d.cr + switch dd.ContainerType() { + case valueTypeMap: containerLen := dd.ReadMapStart() clenGtEqualZero := containerLen >= 0 for j := 0; ; j++ { @@ -1014,15 +1412,19 @@ func (d *Decoder) swallow() { } else if dd.CheckBreak() { break } - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } d.swallow() - dd.ReadMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } d.swallow() } - dd.ReadMapEnd() - case dd.IsContainerType(valueTypeArray): + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + case valueTypeArray: containerLenS := dd.ReadArrayStart() clenGtEqualZero := containerLenS >= 0 for j := 0; ; j++ { @@ -1033,20 +1435,30 @@ func (d *Decoder) swallow() { } else if dd.CheckBreak() { break } - if j > 0 { - dd.ReadArrayEntrySeparator() + if cr != nil { + cr.sendContainerState(containerArrayElem) } d.swallow() } - dd.ReadArrayEnd() - case dd.IsContainerType(valueTypeBytes): + if cr != nil { + cr.sendContainerState(containerArrayEnd) + } + case valueTypeBytes: dd.DecodeBytes(d.b[:], false, true) - case dd.IsContainerType(valueTypeString): + case valueTypeString: dd.DecodeBytes(d.b[:], true, true) // dd.DecodeStringAsBytes(d.b[:]) default: // these are all primitives, which we can get from decodeNaked + // if RawExt using Value, complete the processing. dd.DecodeNaked() + if n := &d.n; n.v == valueTypeExt && n.l == nil { + l := len(n.is) + n.is = append(n.is, nil) + v2 := &n.is[l] + d.decode(v2) + n.is = n.is[:l] + } } } @@ -1096,14 +1508,20 @@ func (d *Decoder) decode(iv interface{}) { case *[]uint8: *v = nil case reflect.Value: - d.chkPtrValue(v) + if v.Kind() != reflect.Ptr || v.IsNil() { + d.errNotValidPtrValue(v) + } + // d.chkPtrValue(v) v = v.Elem() if v.IsValid() { v.Set(reflect.Zero(v.Type())) } default: rv := reflect.ValueOf(iv) - d.chkPtrValue(rv) + if rv.Kind() != reflect.Ptr || rv.IsNil() { + d.errNotValidPtrValue(rv) + } + // d.chkPtrValue(rv) rv = rv.Elem() if rv.IsValid() { rv.Set(reflect.Zero(rv.Type())) @@ -1121,8 +1539,11 @@ func (d *Decoder) decode(iv interface{}) { v.CodecDecodeSelf(d) case reflect.Value: - d.chkPtrValue(v) - d.decodeValueNotNil(v.Elem(), decFn{}) + if v.Kind() != reflect.Ptr || v.IsNil() { + d.errNotValidPtrValue(v) + } + // d.chkPtrValue(v) + d.decodeValueNotNil(v.Elem(), nil) case *string: @@ -1157,7 +1578,7 @@ func (d *Decoder) decode(iv interface{}) { *v = d.d.DecodeBytes(*v, false, false) case *interface{}: - d.decodeValueNotNil(reflect.ValueOf(iv).Elem(), decFn{}) + d.decodeValueNotNil(reflect.ValueOf(iv).Elem(), nil) default: if !fastpathDecodeTypeSwitch(iv, d) { @@ -1191,34 +1612,37 @@ func (d *Decoder) preDecodeValue(rv reflect.Value, tryNil bool) (rv2 reflect.Val func (d *Decoder) decodeI(iv interface{}, checkPtr, tryNil, checkFastpath, checkCodecSelfer bool) { rv := reflect.ValueOf(iv) if checkPtr { - d.chkPtrValue(rv) + if rv.Kind() != reflect.Ptr || rv.IsNil() { + d.errNotValidPtrValue(rv) + } + // d.chkPtrValue(rv) } rv, proceed := d.preDecodeValue(rv, tryNil) if proceed { fn := d.getDecFn(rv.Type(), checkFastpath, checkCodecSelfer) - fn.f(fn.i, rv) + fn.f(&fn.i, rv) } } -func (d *Decoder) decodeValue(rv reflect.Value, fn decFn) { +func (d *Decoder) decodeValue(rv reflect.Value, fn *decFn) { if rv, proceed := d.preDecodeValue(rv, true); proceed { - if fn.f == nil { + if fn == nil { fn = d.getDecFn(rv.Type(), true, true) } - fn.f(fn.i, rv) + fn.f(&fn.i, rv) } } -func (d *Decoder) decodeValueNotNil(rv reflect.Value, fn decFn) { +func (d *Decoder) decodeValueNotNil(rv reflect.Value, fn *decFn) { if rv, proceed := d.preDecodeValue(rv, false); proceed { - if fn.f == nil { + if fn == nil { fn = d.getDecFn(rv.Type(), true, true) } - fn.f(fn.i, rv) + fn.f(&fn.i, rv) } } -func (d *Decoder) getDecFn(rt reflect.Type, checkFastpath, checkCodecSelfer bool) (fn decFn) { +func (d *Decoder) getDecFn(rt reflect.Type, checkFastpath, checkCodecSelfer bool) (fn *decFn) { rtid := reflect.ValueOf(rt).Pointer() // retrieve or register a focus'ed function for this type @@ -1229,9 +1653,10 @@ func (d *Decoder) getDecFn(rt reflect.Type, checkFastpath, checkCodecSelfer bool if useMapForCodecCache { fn, ok = d.f[rtid] } else { - for _, v := range d.s { + for i := range d.s { + v := &(d.s[i]) if v.rtid == rtid { - fn, ok = v.fn, true + fn, ok = &(v.fn), true break } } @@ -1240,11 +1665,25 @@ func (d *Decoder) getDecFn(rt reflect.Type, checkFastpath, checkCodecSelfer bool return } + if useMapForCodecCache { + if d.f == nil { + d.f = make(map[uintptr]*decFn, initCollectionCap) + } + fn = new(decFn) + d.f[rtid] = fn + } else { + if d.s == nil { + d.s = make([]decRtidFn, 0, initCollectionCap) + } + d.s = append(d.s, decRtidFn{rtid: rtid}) + fn = &(d.s[len(d.s)-1]).fn + } + // debugf("\tCreating new dec fn for type: %v\n", rt) - ti := getTypeInfo(rtid, rt) - var fi decFnInfo - fi.dd = d.d - // fi.decFnInfoX = new(decFnInfoX) + ti := d.h.getTypeInfo(rtid, rt) + fi := &(fn.i) + fi.d = d + fi.ti = ti // An extension can be registered for any type, regardless of the Kind // (e.g. type BitSet int64, type MyStruct { / * unexported fields * / }, type X []int, etc. @@ -1256,31 +1695,26 @@ func (d *Decoder) getDecFn(rt reflect.Type, checkFastpath, checkCodecSelfer bool // NOTE: if decoding into a nil interface{}, we return a non-nil // value except even if the container registers a length of 0. if checkCodecSelfer && ti.cs { - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti} - fn.f = (decFnInfo).selferUnmarshal + fn.f = (*decFnInfo).selferUnmarshal } else if rtid == rawExtTypId { - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti} - fn.f = (decFnInfo).rawExt + fn.f = (*decFnInfo).rawExt } else if d.d.IsBuiltinType(rtid) { - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti} - fn.f = (decFnInfo).builtin + fn.f = (*decFnInfo).builtin } else if xfFn := d.h.getExt(rtid); xfFn != nil { - // fi.decFnInfoX = &decFnInfoX{xfTag: xfFn.tag, xfFn: xfFn.ext} - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti} fi.xfTag, fi.xfFn = xfFn.tag, xfFn.ext - fn.f = (decFnInfo).ext + fn.f = (*decFnInfo).ext } else if supportMarshalInterfaces && d.be && ti.bunm { - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti} - fn.f = (decFnInfo).binaryUnmarshal + fn.f = (*decFnInfo).binaryUnmarshal + } else if supportMarshalInterfaces && !d.be && d.js && ti.junm { + //If JSON, we should check JSONUnmarshal before textUnmarshal + fn.f = (*decFnInfo).jsonUnmarshal } else if supportMarshalInterfaces && !d.be && ti.tunm { - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti} - fn.f = (decFnInfo).textUnmarshal + fn.f = (*decFnInfo).textUnmarshal } else { rk := rt.Kind() if fastpathEnabled && checkFastpath && (rk == reflect.Map || rk == reflect.Slice) { if rt.PkgPath() == "" { if idx := fastpathAV.index(rtid); idx != -1 { - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti} fn.f = fastpathAV[idx].decfn } } else { @@ -1296,8 +1730,7 @@ func (d *Decoder) getDecFn(rt reflect.Type, checkFastpath, checkCodecSelfer bool if idx := fastpathAV.index(rtuid); idx != -1 { xfnf := fastpathAV[idx].decfn xrt := fastpathAV[idx].rt - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti} - fn.f = func(xf decFnInfo, xrv reflect.Value) { + fn.f = func(xf *decFnInfo, xrv reflect.Value) { // xfnf(xf, xrv.Convert(xrt)) xfnf(xf, xrv.Addr().Convert(reflect.PtrTo(xrt)).Elem()) } @@ -1307,72 +1740,58 @@ func (d *Decoder) getDecFn(rt reflect.Type, checkFastpath, checkCodecSelfer bool if fn.f == nil { switch rk { case reflect.String: - fn.f = (decFnInfo).kString + fn.f = (*decFnInfo).kString case reflect.Bool: - fn.f = (decFnInfo).kBool + fn.f = (*decFnInfo).kBool case reflect.Int: - fn.f = (decFnInfo).kInt + fn.f = (*decFnInfo).kInt case reflect.Int64: - fn.f = (decFnInfo).kInt64 + fn.f = (*decFnInfo).kInt64 case reflect.Int32: - fn.f = (decFnInfo).kInt32 + fn.f = (*decFnInfo).kInt32 case reflect.Int8: - fn.f = (decFnInfo).kInt8 + fn.f = (*decFnInfo).kInt8 case reflect.Int16: - fn.f = (decFnInfo).kInt16 + fn.f = (*decFnInfo).kInt16 case reflect.Float32: - fn.f = (decFnInfo).kFloat32 + fn.f = (*decFnInfo).kFloat32 case reflect.Float64: - fn.f = (decFnInfo).kFloat64 + fn.f = (*decFnInfo).kFloat64 case reflect.Uint8: - fn.f = (decFnInfo).kUint8 + fn.f = (*decFnInfo).kUint8 case reflect.Uint64: - fn.f = (decFnInfo).kUint64 + fn.f = (*decFnInfo).kUint64 case reflect.Uint: - fn.f = (decFnInfo).kUint + fn.f = (*decFnInfo).kUint case reflect.Uint32: - fn.f = (decFnInfo).kUint32 + fn.f = (*decFnInfo).kUint32 case reflect.Uint16: - fn.f = (decFnInfo).kUint16 + fn.f = (*decFnInfo).kUint16 // case reflect.Ptr: - // fn.f = (decFnInfo).kPtr + // fn.f = (*decFnInfo).kPtr + case reflect.Uintptr: + fn.f = (*decFnInfo).kUintptr case reflect.Interface: - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti} - fn.f = (decFnInfo).kInterface + fn.f = (*decFnInfo).kInterface case reflect.Struct: - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti} - fn.f = (decFnInfo).kStruct + fn.f = (*decFnInfo).kStruct case reflect.Chan: - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti, seq: seqTypeChan} - fn.f = (decFnInfo).kSlice + fi.seq = seqTypeChan + fn.f = (*decFnInfo).kSlice case reflect.Slice: - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti, seq: seqTypeSlice} - fn.f = (decFnInfo).kSlice + fi.seq = seqTypeSlice + fn.f = (*decFnInfo).kSlice case reflect.Array: - // fi.decFnInfoX = &decFnInfoX{array: true} - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti, seq: seqTypeArray} - fn.f = (decFnInfo).kArray + fi.seq = seqTypeArray + fn.f = (*decFnInfo).kArray case reflect.Map: - fi.decFnInfoX = &decFnInfoX{d: d, ti: ti} - fn.f = (decFnInfo).kMap + fn.f = (*decFnInfo).kMap default: - fn.f = (decFnInfo).kErr + fn.f = (*decFnInfo).kErr } } } - fn.i = fi - if useMapForCodecCache { - if d.f == nil { - d.f = make(map[uintptr]decFn, 32) - } - d.f[rtid] = fn - } else { - if d.s == nil { - d.s = make([]rtidDecFn, 0, 32) - } - d.s = append(d.s, rtidDecFn{rtid, fn}) - } return } @@ -1400,6 +1819,10 @@ func (d *Decoder) chkPtrValue(rv reflect.Value) { if rv.Kind() == reflect.Ptr && !rv.IsNil() { return } + d.errNotValidPtrValue(rv) +} + +func (d *Decoder) errNotValidPtrValue(rv reflect.Value) { if !rv.IsValid() { d.error(cannotDecodeIntoNilErr) return @@ -1417,57 +1840,93 @@ func (d *Decoder) error(err error) { } func (d *Decoder) errorf(format string, params ...interface{}) { - err := fmt.Errorf(format, params...) + params2 := make([]interface{}, len(params)+1) + params2[0] = d.r.numread() + copy(params2[1:], params) + err := fmt.Errorf("[pos %d]: "+format, params2...) panic(err) } +func (d *Decoder) string(v []byte) (s string) { + if d.is != nil { + s, ok := d.is[string(v)] // no allocation here. + if !ok { + s = string(v) + d.is[s] = s + } + return s + } + return string(v) // don't return stringView, as we need a real string here. +} + +func (d *Decoder) intern(s string) { + if d.is != nil { + d.is[s] = s + } +} + +// nextValueBytes returns the next value in the stream as a set of bytes. +func (d *Decoder) nextValueBytes() []byte { + d.d.uncacheRead() + d.r.track() + d.swallow() + return d.r.stopTrack() +} + // -------------------------------------------------- // decSliceHelper assists when decoding into a slice, from a map or an array in the stream. // A slice can be set from a map or array in stream. This supports the MapBySlice interface. type decSliceHelper struct { - dd decDriver - ct valueType + d *Decoder + // ct valueType + array bool } func (d *Decoder) decSliceHelperStart() (x decSliceHelper, clen int) { - x.dd = d.d - if x.dd.IsContainerType(valueTypeArray) { - x.ct = valueTypeArray - clen = x.dd.ReadArrayStart() - } else if x.dd.IsContainerType(valueTypeMap) { - x.ct = valueTypeMap - clen = x.dd.ReadMapStart() * 2 + dd := d.d + ctyp := dd.ContainerType() + if ctyp == valueTypeArray { + x.array = true + clen = dd.ReadArrayStart() + } else if ctyp == valueTypeMap { + clen = dd.ReadMapStart() * 2 } else { - d.errorf("only encoded map or array can be decoded into a slice") + d.errorf("only encoded map or array can be decoded into a slice (%d)", ctyp) } + // x.ct = ctyp + x.d = d return } -func (x decSliceHelper) Sep(index int) { - if x.ct == valueTypeArray { - x.dd.ReadArrayEntrySeparator() +func (x decSliceHelper) End() { + cr := x.d.cr + if cr == nil { + return + } + if x.array { + cr.sendContainerState(containerArrayEnd) + } else { + cr.sendContainerState(containerMapEnd) + } +} + +func (x decSliceHelper) ElemContainerState(index int) { + cr := x.d.cr + if cr == nil { + return + } + if x.array { + cr.sendContainerState(containerArrayElem) } else { if index%2 == 0 { - x.dd.ReadMapEntrySeparator() + cr.sendContainerState(containerMapKey) } else { - x.dd.ReadMapKVSeparator() + cr.sendContainerState(containerMapValue) } } } -func (x decSliceHelper) End() { - if x.ct == valueTypeArray { - x.dd.ReadArrayEnd() - } else { - x.dd.ReadMapEnd() - } -} - -// func decErr(format string, params ...interface{}) { -// doPanic(msgTagDec, format, params...) -// } - func decByteSlice(r decReader, clen int, bs []byte) (bsOut []byte) { if clen == 0 { return zeroByteSlice @@ -1498,6 +1957,46 @@ func detachZeroCopyBytes(isBytesReader bool, dest []byte, in []byte) (out []byte return in } +// decInferLen will infer a sensible length, given the following: +// - clen: length wanted. +// - maxlen: max length to be returned. +// if <= 0, it is unset, and we infer it based on the unit size +// - unit: number of bytes for each element of the collection +func decInferLen(clen, maxlen, unit int) (rvlen int, truncated bool) { + // handle when maxlen is not set i.e. <= 0 + if clen <= 0 { + return + } + if maxlen <= 0 { + // no maxlen defined. Use maximum of 256K memory, with a floor of 4K items. + // maxlen = 256 * 1024 / unit + // if maxlen < (4 * 1024) { + // maxlen = 4 * 1024 + // } + if unit < (256 / 4) { + maxlen = 256 * 1024 / unit + } else { + maxlen = 4 * 1024 + } + } + if clen > maxlen { + rvlen = maxlen + truncated = true + } else { + rvlen = clen + } + return + // if clen <= 0 { + // rvlen = 0 + // } else if maxlen > 0 && clen > maxlen { + // rvlen = maxlen + // truncated = true + // } else { + // rvlen = clen + // } + // return +} + // // implement overall decReader wrapping both, for possible use inline: // type decReaderT struct { // bytes bool @@ -1516,37 +2015,5 @@ func detachZeroCopyBytes(isBytesReader bool, dest []byte, in []byte) (out []byte // d.ri.unreadn1() // } // } - -// func (d *Decoder) readb(b []byte) { -// if d.bytes { -// d.rb.readb(b) -// } else { -// d.ri.readb(b) -// } -// } - -// func (d *Decoder) readx(n int) []byte { -// if d.bytes { -// return d.rb.readx(n) -// } else { -// return d.ri.readx(n) -// } -// } - -// func (d *Decoder) readn1() uint8 { -// if d.bytes { -// return d.rb.readn1() -// } else { -// return d.ri.readn1() -// } -// } - -// func (d *Decoder) readn1eof() (v uint8, eof bool) { -// if d.bytes { -// return d.rb.readn1eof() -// } else { -// return d.ri.readn1eof() -// } -// } - -// var _ decReader = (*Decoder)(nil) // decReaderT{} // +// ... for other methods of decReader. +// Testing showed that performance improvement was negligible. diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/encode.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/encode.go index 38c55be..a874c74 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/encode.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/encode.go @@ -4,9 +4,7 @@ package codec import ( - "bytes" "encoding" - "errors" "fmt" "io" "reflect" @@ -63,38 +61,24 @@ type encDriver interface { EncodeRawExt(re *RawExt, e *Encoder) EncodeExt(v interface{}, xtag uint64, ext Ext, e *Encoder) EncodeArrayStart(length int) - EncodeArrayEnd() - EncodeArrayEntrySeparator() EncodeMapStart(length int) - EncodeMapEnd() - EncodeMapEntrySeparator() - EncodeMapKVSeparator() EncodeString(c charEncoding, v string) EncodeSymbol(v string) EncodeStringBytes(c charEncoding, v []byte) //TODO //encBignum(f *big.Int) //encStringRunes(c charEncoding, v []rune) + + reset() +} + +type encDriverAsis interface { + EncodeAsis(v []byte) } type encNoSeparator struct{} -func (_ encNoSeparator) EncodeMapEnd() {} -func (_ encNoSeparator) EncodeArrayEnd() {} -func (_ encNoSeparator) EncodeArrayEntrySeparator() {} -func (_ encNoSeparator) EncodeMapEntrySeparator() {} -func (_ encNoSeparator) EncodeMapKVSeparator() {} - -type encStructFieldBytesV struct { - b []byte - v reflect.Value -} - -type encStructFieldBytesVslice []encStructFieldBytesV - -func (p encStructFieldBytesVslice) Len() int { return len(p) } -func (p encStructFieldBytesVslice) Less(i, j int) bool { return bytes.Compare(p[i].b, p[j].b) == -1 } -func (p encStructFieldBytesVslice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } +func (_ encNoSeparator) EncodeEnd() {} type ioEncWriterWriter interface { WriteByte(c byte) error @@ -113,10 +97,28 @@ type EncodeOptions struct { // Canonical representation means that encoding a value will always result in the same // sequence of bytes. // - // This mostly will apply to maps. In this case, codec will do more work to encode the - // map keys out of band, and then sort them, before writing out the map to the stream. + // This only affects maps, as the iteration order for maps is random. + // + // The implementation MAY use the natural sort order for the map keys if possible: + // + // - If there is a natural sort order (ie for number, bool, string or []byte keys), + // then the map keys are first sorted in natural order and then written + // with corresponding map values to the strema. + // - If there is no natural sort order, then the map keys will first be + // encoded into []byte, and then sorted, + // before writing the sorted keys and the corresponding map values to the stream. + // Canonical bool + // CheckCircularRef controls whether we check for circular references + // and error fast during an encode. + // + // If enabled, an error is received if a pointer to a struct + // references itself either directly or through one of its fields (iteratively). + // + // This is opt-in, as there may be a performance hit to checking circular references. + CheckCircularRef bool + // AsSymbols defines what should be encoded as symbols. // // Encoding as symbols can reduce the encoded size significantly. @@ -166,6 +168,7 @@ func (o *simpleIoEncWriterWriter) Write(p []byte) (n int, err error) { // ioEncWriter implements encWriter and can write to an io.Writer implementation type ioEncWriter struct { w ioEncWriterWriter + s simpleIoEncWriterWriter // x [8]byte // temp byte array re-used internally for efficiency } @@ -249,10 +252,10 @@ func (z *bytesEncWriter) grow(n int) (oldcursor int) { z.c = oldcursor + n if z.c > len(z.b) { if z.c > cap(z.b) { - // Tried using appendslice logic: (if cap < 1024, *2, else *1.25). - // However, it was too expensive, causing too many iterations of copy. - // Using bytes.Buffer model was much better (2*cap + n) - bs := make([]byte, 2*cap(z.b)+n) + // appendslice logic (if cap < 1024, *2, else *1.25): more expensive. many copy calls. + // bytes.Buffer model (2*cap + n): much better + // bs := make([]byte, 2*cap(z.b)+n) + bs := make([]byte, growCap(cap(z.b), 1, n)) copy(bs, z.b[:oldcursor]) z.b = bs } else { @@ -264,7 +267,7 @@ func (z *bytesEncWriter) grow(n int) (oldcursor int) { // --------------------------------------------- -type encFnInfoX struct { +type encFnInfo struct { e *Encoder ti *typeInfo xfFn Ext @@ -272,25 +275,13 @@ type encFnInfoX struct { seq seqType } -type encFnInfo struct { - // use encFnInfo as a value receiver. - // keep most of it less-used variables accessible via a pointer (*encFnInfoX). - // As sweet spot for value-receiver is 3 words, keep everything except - // encDriver (which everyone needs) directly accessible. - // ensure encFnInfoX is set for everyone who needs it i.e. - // rawExt, ext, builtin, (selfer|binary|text)Marshal, kSlice, kStruct, kMap, kInterface, fastpath - - ee encDriver - *encFnInfoX +func (f *encFnInfo) builtin(rv reflect.Value) { + f.e.e.EncodeBuiltin(f.ti.rtid, rv.Interface()) } -func (f encFnInfo) builtin(rv reflect.Value) { - f.ee.EncodeBuiltin(f.ti.rtid, rv.Interface()) -} - -func (f encFnInfo) rawExt(rv reflect.Value) { +func (f *encFnInfo) rawExt(rv reflect.Value) { // rev := rv.Interface().(RawExt) - // f.ee.EncodeRawExt(&rev, f.e) + // f.e.e.EncodeRawExt(&rev, f.e) var re *RawExt if rv.CanAddr() { re = rv.Addr().Interface().(*RawExt) @@ -298,26 +289,35 @@ func (f encFnInfo) rawExt(rv reflect.Value) { rev := rv.Interface().(RawExt) re = &rev } - f.ee.EncodeRawExt(re, f.e) + f.e.e.EncodeRawExt(re, f.e) } -func (f encFnInfo) ext(rv reflect.Value) { - // if this is a struct and it was addressable, then pass the address directly (not the value) - if rv.CanAddr() && rv.Kind() == reflect.Struct { +func (f *encFnInfo) ext(rv reflect.Value) { + // if this is a struct|array and it was addressable, then pass the address directly (not the value) + if k := rv.Kind(); (k == reflect.Struct || k == reflect.Array) && rv.CanAddr() { rv = rv.Addr() } - f.ee.EncodeExt(rv.Interface(), f.xfTag, f.xfFn, f.e) + f.e.e.EncodeExt(rv.Interface(), f.xfTag, f.xfFn, f.e) } -func (f encFnInfo) getValueForMarshalInterface(rv reflect.Value, indir int8) (v interface{}, proceed bool) { +func (f *encFnInfo) getValueForMarshalInterface(rv reflect.Value, indir int8) (v interface{}, proceed bool) { if indir == 0 { v = rv.Interface() } else if indir == -1 { - v = rv.Addr().Interface() + // If a non-pointer was passed to Encode(), then that value is not addressable. + // Take addr if addresable, else copy value to an addressable value. + if rv.CanAddr() { + v = rv.Addr().Interface() + } else { + rv2 := reflect.New(rv.Type()) + rv2.Elem().Set(rv) + v = rv2.Interface() + // fmt.Printf("rv.Type: %v, rv2.Type: %v, v: %v\n", rv.Type(), rv2.Type(), v) + } } else { for j := int8(0); j < indir; j++ { if rv.IsNil() { - f.ee.EncodeNil() + f.e.e.EncodeNil() return } rv = rv.Elem() @@ -327,103 +327,98 @@ func (f encFnInfo) getValueForMarshalInterface(rv reflect.Value, indir int8) (v return v, true } -func (f encFnInfo) selferMarshal(rv reflect.Value) { +func (f *encFnInfo) selferMarshal(rv reflect.Value) { if v, proceed := f.getValueForMarshalInterface(rv, f.ti.csIndir); proceed { v.(Selfer).CodecEncodeSelf(f.e) } } -func (f encFnInfo) binaryMarshal(rv reflect.Value) { +func (f *encFnInfo) binaryMarshal(rv reflect.Value) { if v, proceed := f.getValueForMarshalInterface(rv, f.ti.bmIndir); proceed { bs, fnerr := v.(encoding.BinaryMarshaler).MarshalBinary() - if fnerr != nil { - panic(fnerr) - } - if bs == nil { - f.ee.EncodeNil() - } else { - f.ee.EncodeStringBytes(c_RAW, bs) - } + f.e.marshal(bs, fnerr, false, c_RAW) } } -func (f encFnInfo) textMarshal(rv reflect.Value) { +func (f *encFnInfo) textMarshal(rv reflect.Value) { if v, proceed := f.getValueForMarshalInterface(rv, f.ti.tmIndir); proceed { // debugf(">>>> encoding.TextMarshaler: %T", rv.Interface()) bs, fnerr := v.(encoding.TextMarshaler).MarshalText() - if fnerr != nil { - panic(fnerr) - } - if bs == nil { - f.ee.EncodeNil() - } else { - f.ee.EncodeStringBytes(c_UTF8, bs) - } + f.e.marshal(bs, fnerr, false, c_UTF8) } } -func (f encFnInfo) kBool(rv reflect.Value) { - f.ee.EncodeBool(rv.Bool()) +func (f *encFnInfo) jsonMarshal(rv reflect.Value) { + if v, proceed := f.getValueForMarshalInterface(rv, f.ti.jmIndir); proceed { + bs, fnerr := v.(jsonMarshaler).MarshalJSON() + f.e.marshal(bs, fnerr, true, c_UTF8) + } } -func (f encFnInfo) kString(rv reflect.Value) { - f.ee.EncodeString(c_UTF8, rv.String()) +func (f *encFnInfo) kBool(rv reflect.Value) { + f.e.e.EncodeBool(rv.Bool()) } -func (f encFnInfo) kFloat64(rv reflect.Value) { - f.ee.EncodeFloat64(rv.Float()) +func (f *encFnInfo) kString(rv reflect.Value) { + f.e.e.EncodeString(c_UTF8, rv.String()) } -func (f encFnInfo) kFloat32(rv reflect.Value) { - f.ee.EncodeFloat32(float32(rv.Float())) +func (f *encFnInfo) kFloat64(rv reflect.Value) { + f.e.e.EncodeFloat64(rv.Float()) } -func (f encFnInfo) kInt(rv reflect.Value) { - f.ee.EncodeInt(rv.Int()) +func (f *encFnInfo) kFloat32(rv reflect.Value) { + f.e.e.EncodeFloat32(float32(rv.Float())) } -func (f encFnInfo) kUint(rv reflect.Value) { - f.ee.EncodeUint(rv.Uint()) +func (f *encFnInfo) kInt(rv reflect.Value) { + f.e.e.EncodeInt(rv.Int()) } -func (f encFnInfo) kInvalid(rv reflect.Value) { - f.ee.EncodeNil() +func (f *encFnInfo) kUint(rv reflect.Value) { + f.e.e.EncodeUint(rv.Uint()) } -func (f encFnInfo) kErr(rv reflect.Value) { +func (f *encFnInfo) kInvalid(rv reflect.Value) { + f.e.e.EncodeNil() +} + +func (f *encFnInfo) kErr(rv reflect.Value) { f.e.errorf("unsupported kind %s, for %#v", rv.Kind(), rv) } -func (f encFnInfo) kSlice(rv reflect.Value) { +func (f *encFnInfo) kSlice(rv reflect.Value) { ti := f.ti // array may be non-addressable, so we have to manage with care // (don't call rv.Bytes, rv.Slice, etc). // E.g. type struct S{B [2]byte}; // Encode(S{}) will bomb on "panic: slice of unaddressable array". + e := f.e if f.seq != seqTypeArray { if rv.IsNil() { - f.ee.EncodeNil() + e.e.EncodeNil() return } // If in this method, then there was no extension function defined. // So it's okay to treat as []byte. if ti.rtid == uint8SliceTypId { - f.ee.EncodeStringBytes(c_RAW, rv.Bytes()) + e.e.EncodeStringBytes(c_RAW, rv.Bytes()) return } } + cr := e.cr rtelem := ti.rt.Elem() l := rv.Len() - if rtelem.Kind() == reflect.Uint8 { + if ti.rtid == uint8SliceTypId || rtelem.Kind() == reflect.Uint8 { switch f.seq { case seqTypeArray: - // if l == 0 { f.ee.encodeStringBytes(c_RAW, nil) } else + // if l == 0 { e.e.encodeStringBytes(c_RAW, nil) } else if rv.CanAddr() { - f.ee.EncodeStringBytes(c_RAW, rv.Slice(0, l).Bytes()) + e.e.EncodeStringBytes(c_RAW, rv.Slice(0, l).Bytes()) } else { var bs []byte - if l <= cap(f.e.b) { - bs = f.e.b[:l] + if l <= cap(e.b) { + bs = e.b[:l] } else { bs = make([]byte, l) } @@ -432,12 +427,12 @@ func (f encFnInfo) kSlice(rv reflect.Value) { // for i := 0; i < l; i++ { // bs[i] = byte(rv.Index(i).Uint()) // } - f.ee.EncodeStringBytes(c_RAW, bs) + e.e.EncodeStringBytes(c_RAW, bs) } case seqTypeSlice: - f.ee.EncodeStringBytes(c_RAW, rv.Bytes()) + e.e.EncodeStringBytes(c_RAW, rv.Bytes()) case seqTypeChan: - bs := f.e.b[:0] + bs := e.b[:0] // do not use range, so that the number of elements encoded // does not change, and encoding does not hang waiting on someone to close chan. // for b := range rv.Interface().(<-chan byte) { @@ -447,23 +442,21 @@ func (f encFnInfo) kSlice(rv reflect.Value) { for i := 0; i < l; i++ { bs = append(bs, <-ch) } - f.ee.EncodeStringBytes(c_RAW, bs) + e.e.EncodeStringBytes(c_RAW, bs) } return } if ti.mbs { if l%2 == 1 { - f.e.errorf("mapBySlice requires even slice length, but got %v", l) + e.errorf("mapBySlice requires even slice length, but got %v", l) return } - f.ee.EncodeMapStart(l / 2) + e.e.EncodeMapStart(l / 2) } else { - f.ee.EncodeArrayStart(l) + e.e.EncodeArrayStart(l) } - e := f.e - sep := !e.be if l > 0 { for rtelem.Kind() == reflect.Ptr { rtelem = rtelem.Elem() @@ -471,114 +464,78 @@ func (f encFnInfo) kSlice(rv reflect.Value) { // if kind is reflect.Interface, do not pre-determine the // encoding type, because preEncodeValue may break it down to // a concrete type and kInterface will bomb. - var fn encFn + var fn *encFn if rtelem.Kind() != reflect.Interface { rtelemid := reflect.ValueOf(rtelem).Pointer() fn = e.getEncFn(rtelemid, rtelem, true, true) } // TODO: Consider perf implication of encoding odd index values as symbols if type is string - if sep { - for j := 0; j < l; j++ { - if j > 0 { - if ti.mbs { - if j%2 == 0 { - f.ee.EncodeMapEntrySeparator() - } else { - f.ee.EncodeMapKVSeparator() - } + for j := 0; j < l; j++ { + if cr != nil { + if ti.mbs { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) } else { - f.ee.EncodeArrayEntrySeparator() - } - } - if f.seq == seqTypeChan { - if rv2, ok2 := rv.Recv(); ok2 { - e.encodeValue(rv2, fn) + cr.sendContainerState(containerMapValue) } } else { - e.encodeValue(rv.Index(j), fn) + cr.sendContainerState(containerArrayElem) } } - } else { - for j := 0; j < l; j++ { - if f.seq == seqTypeChan { - if rv2, ok2 := rv.Recv(); ok2 { - e.encodeValue(rv2, fn) - } + if f.seq == seqTypeChan { + if rv2, ok2 := rv.Recv(); ok2 { + e.encodeValue(rv2, fn) } else { - e.encodeValue(rv.Index(j), fn) + e.encode(nil) // WE HAVE TO DO SOMETHING, so nil if nothing received. } + } else { + e.encodeValue(rv.Index(j), fn) } } } - if sep { + if cr != nil { if ti.mbs { - f.ee.EncodeMapEnd() + cr.sendContainerState(containerMapEnd) } else { - f.ee.EncodeArrayEnd() + cr.sendContainerState(containerArrayEnd) } } } -func (f encFnInfo) kStruct(rv reflect.Value) { +func (f *encFnInfo) kStruct(rv reflect.Value) { fti := f.ti e := f.e + cr := e.cr tisfi := fti.sfip toMap := !(fti.toArray || e.h.StructToArray) newlen := len(fti.sfi) - // Use sync.Pool to reduce allocating slices unnecessarily. - // The cost of the occasional locking is less than the cost of locking. - var fkvs []encStructFieldKV - var pool *sync.Pool - var poolv interface{} - idxpool := newlen / 8 - if encStructPoolLen != 4 { - panic(errors.New("encStructPoolLen must be equal to 4")) // defensive, in case it is changed - } - if idxpool < encStructPoolLen { - pool = &encStructPool[idxpool] - poolv = pool.Get() - switch vv := poolv.(type) { - case *[8]encStructFieldKV: - fkvs = vv[:newlen] - case *[16]encStructFieldKV: - fkvs = vv[:newlen] - case *[32]encStructFieldKV: - fkvs = vv[:newlen] - case *[64]encStructFieldKV: - fkvs = vv[:newlen] - } - } - if fkvs == nil { - fkvs = make([]encStructFieldKV, newlen) - } + // Use sync.Pool to reduce allocating slices unnecessarily. + // The cost of sync.Pool is less than the cost of new allocation. + pool, poolv, fkvs := encStructPoolGet(newlen) + // if toMap, use the sorted array. If toArray, use unsorted array (to match sequence in struct) if toMap { tisfi = fti.sfi } newlen = 0 - var kv encStructFieldKV + var kv stringRv for _, si := range tisfi { - kv.v = si.field(rv, false) - // if si.i != -1 { - // rvals[newlen] = rv.Field(int(si.i)) - // } else { - // rvals[newlen] = rv.FieldByIndex(si.is) - // } + kv.r = si.field(rv, false) if toMap { - if si.omitEmpty && isEmptyValue(kv.v) { + if si.omitEmpty && isEmptyValue(kv.r) { continue } - kv.k = si.encName + kv.v = si.encName } else { // use the zero value. // if a reference or struct, set to nil (so you do not output too much) - if si.omitEmpty && isEmptyValue(kv.v) { - switch kv.v.Kind() { + if si.omitEmpty && isEmptyValue(kv.r) { + switch kv.r.Kind() { case reflect.Struct, reflect.Interface, reflect.Ptr, reflect.Array, reflect.Map, reflect.Slice: - kv.v = reflect.Value{} //encode as nil + kv.r = reflect.Value{} //encode as nil } } } @@ -587,58 +544,42 @@ func (f encFnInfo) kStruct(rv reflect.Value) { } // debugf(">>>> kStruct: newlen: %v", newlen) - sep := !e.be - ee := f.ee //don't dereference everytime - if sep { - if toMap { - ee.EncodeMapStart(newlen) - // asSymbols := e.h.AsSymbols&AsSymbolStructFieldNameFlag != 0 - asSymbols := e.h.AsSymbols == AsSymbolDefault || e.h.AsSymbols&AsSymbolStructFieldNameFlag != 0 - for j := 0; j < newlen; j++ { - kv = fkvs[j] - if j > 0 { - ee.EncodeMapEntrySeparator() - } - if asSymbols { - ee.EncodeSymbol(kv.k) - } else { - ee.EncodeString(c_UTF8, kv.k) - } - ee.EncodeMapKVSeparator() - e.encodeValue(kv.v, encFn{}) + // sep := !e.be + ee := e.e //don't dereference everytime + + if toMap { + ee.EncodeMapStart(newlen) + // asSymbols := e.h.AsSymbols&AsSymbolStructFieldNameFlag != 0 + asSymbols := e.h.AsSymbols == AsSymbolDefault || e.h.AsSymbols&AsSymbolStructFieldNameFlag != 0 + for j := 0; j < newlen; j++ { + kv = fkvs[j] + if cr != nil { + cr.sendContainerState(containerMapKey) } - ee.EncodeMapEnd() - } else { - ee.EncodeArrayStart(newlen) - for j := 0; j < newlen; j++ { - kv = fkvs[j] - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - e.encodeValue(kv.v, encFn{}) + if asSymbols { + ee.EncodeSymbol(kv.v) + } else { + ee.EncodeString(c_UTF8, kv.v) } - ee.EncodeArrayEnd() + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encodeValue(kv.r, nil) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } else { - if toMap { - ee.EncodeMapStart(newlen) - // asSymbols := e.h.AsSymbols&AsSymbolStructFieldNameFlag != 0 - asSymbols := e.h.AsSymbols == AsSymbolDefault || e.h.AsSymbols&AsSymbolStructFieldNameFlag != 0 - for j := 0; j < newlen; j++ { - kv = fkvs[j] - if asSymbols { - ee.EncodeSymbol(kv.k) - } else { - ee.EncodeString(c_UTF8, kv.k) - } - e.encodeValue(kv.v, encFn{}) - } - } else { - ee.EncodeArrayStart(newlen) - for j := 0; j < newlen; j++ { - kv = fkvs[j] - e.encodeValue(kv.v, encFn{}) + ee.EncodeArrayStart(newlen) + for j := 0; j < newlen; j++ { + kv = fkvs[j] + if cr != nil { + cr.sendContainerState(containerArrayElem) } + e.encodeValue(kv.r, nil) + } + if cr != nil { + cr.sendContainerState(containerArrayEnd) } } @@ -650,36 +591,39 @@ func (f encFnInfo) kStruct(rv reflect.Value) { } } -// func (f encFnInfo) kPtr(rv reflect.Value) { +// func (f *encFnInfo) kPtr(rv reflect.Value) { // debugf(">>>>>>> ??? encode kPtr called - shouldn't get called") // if rv.IsNil() { -// f.ee.encodeNil() +// f.e.e.encodeNil() // return // } // f.e.encodeValue(rv.Elem()) // } -func (f encFnInfo) kInterface(rv reflect.Value) { - if rv.IsNil() { - f.ee.EncodeNil() - return - } - f.e.encodeValue(rv.Elem(), encFn{}) -} +// func (f *encFnInfo) kInterface(rv reflect.Value) { +// println("kInterface called") +// debug.PrintStack() +// if rv.IsNil() { +// f.e.e.EncodeNil() +// return +// } +// f.e.encodeValue(rv.Elem(), nil) +// } -func (f encFnInfo) kMap(rv reflect.Value) { +func (f *encFnInfo) kMap(rv reflect.Value) { + ee := f.e.e if rv.IsNil() { - f.ee.EncodeNil() + ee.EncodeNil() return } l := rv.Len() - f.ee.EncodeMapStart(l) + ee.EncodeMapStart(l) e := f.e - sep := !e.be + cr := e.cr if l == 0 { - if sep { - f.ee.EncodeMapEnd() + if cr != nil { + cr.sendContainerState(containerMapEnd) } return } @@ -691,7 +635,7 @@ func (f encFnInfo) kMap(rv reflect.Value) { // However, if kind is reflect.Interface, do not pre-determine the // encoding type, because preEncodeValue may break it down to // a concrete type and kInterface will bomb. - var keyFn, valFn encFn + var keyFn, valFn *encFn ti := f.ti rtkey := ti.rt.Key() rtval := ti.rt.Elem() @@ -718,49 +662,14 @@ func (f encFnInfo) kMap(rv reflect.Value) { } mks := rv.MapKeys() // for j, lmks := 0, len(mks); j < lmks; j++ { - ee := f.ee //don't dereference everytime + if e.h.Canonical { - // first encode each key to a []byte first, then sort them, then record - // println(">>>>>>>> CANONICAL <<<<<<<<") - var mksv []byte // temporary byte slice for the encoding - e2 := NewEncoderBytes(&mksv, e.hh) - mksbv := make([]encStructFieldBytesV, len(mks)) - for i, k := range mks { - l := len(mksv) - e2.MustEncode(k) - mksbv[i].v = k - mksbv[i].b = mksv[l:] - } - sort.Sort(encStructFieldBytesVslice(mksbv)) - for j := range mksbv { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - e.w.writeb(mksbv[j].b) - ee.EncodeMapKVSeparator() - e.encodeValue(rv.MapIndex(mksbv[j].v), valFn) - } - ee.EncodeMapEnd() - } else if sep { - for j := range mks { - if j > 0 { - ee.EncodeMapEntrySeparator() - } - if keyTypeIsString { - if asSymbols { - ee.EncodeSymbol(mks[j].String()) - } else { - ee.EncodeString(c_UTF8, mks[j].String()) - } - } else { - e.encodeValue(mks[j], keyFn) - } - ee.EncodeMapKVSeparator() - e.encodeValue(rv.MapIndex(mks[j]), valFn) - } - ee.EncodeMapEnd() + e.kMapCanonical(rtkeyid, rtkey, rv, mks, valFn, asSymbols) } else { for j := range mks { + if cr != nil { + cr.sendContainerState(containerMapKey) + } if keyTypeIsString { if asSymbols { ee.EncodeSymbol(mks[j].String()) @@ -770,9 +679,182 @@ func (f encFnInfo) kMap(rv reflect.Value) { } else { e.encodeValue(mks[j], keyFn) } + if cr != nil { + cr.sendContainerState(containerMapValue) + } e.encodeValue(rv.MapIndex(mks[j]), valFn) } } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (e *Encoder) kMapCanonical(rtkeyid uintptr, rtkey reflect.Type, rv reflect.Value, mks []reflect.Value, valFn *encFn, asSymbols bool) { + ee := e.e + cr := e.cr + // we previously did out-of-band if an extension was registered. + // This is not necessary, as the natural kind is sufficient for ordering. + + if rtkeyid == uint8SliceTypId { + mksv := make([]bytesRv, len(mks)) + for i, k := range mks { + v := &mksv[i] + v.r = k + v.v = k.Bytes() + } + sort.Sort(bytesRvSlice(mksv)) + for i := range mksv { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeStringBytes(c_RAW, mksv[i].v) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encodeValue(rv.MapIndex(mksv[i].r), valFn) + } + } else { + switch rtkey.Kind() { + case reflect.Bool: + mksv := make([]boolRv, len(mks)) + for i, k := range mks { + v := &mksv[i] + v.r = k + v.v = k.Bool() + } + sort.Sort(boolRvSlice(mksv)) + for i := range mksv { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeBool(mksv[i].v) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encodeValue(rv.MapIndex(mksv[i].r), valFn) + } + case reflect.String: + mksv := make([]stringRv, len(mks)) + for i, k := range mks { + v := &mksv[i] + v.r = k + v.v = k.String() + } + sort.Sort(stringRvSlice(mksv)) + for i := range mksv { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + if asSymbols { + ee.EncodeSymbol(mksv[i].v) + } else { + ee.EncodeString(c_UTF8, mksv[i].v) + } + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encodeValue(rv.MapIndex(mksv[i].r), valFn) + } + case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint, reflect.Uintptr: + mksv := make([]uintRv, len(mks)) + for i, k := range mks { + v := &mksv[i] + v.r = k + v.v = k.Uint() + } + sort.Sort(uintRvSlice(mksv)) + for i := range mksv { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(mksv[i].v) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encodeValue(rv.MapIndex(mksv[i].r), valFn) + } + case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int: + mksv := make([]intRv, len(mks)) + for i, k := range mks { + v := &mksv[i] + v.r = k + v.v = k.Int() + } + sort.Sort(intRvSlice(mksv)) + for i := range mksv { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(mksv[i].v) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encodeValue(rv.MapIndex(mksv[i].r), valFn) + } + case reflect.Float32: + mksv := make([]floatRv, len(mks)) + for i, k := range mks { + v := &mksv[i] + v.r = k + v.v = k.Float() + } + sort.Sort(floatRvSlice(mksv)) + for i := range mksv { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat32(float32(mksv[i].v)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encodeValue(rv.MapIndex(mksv[i].r), valFn) + } + case reflect.Float64: + mksv := make([]floatRv, len(mks)) + for i, k := range mks { + v := &mksv[i] + v.r = k + v.v = k.Float() + } + sort.Sort(floatRvSlice(mksv)) + for i := range mksv { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat64(mksv[i].v) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encodeValue(rv.MapIndex(mksv[i].r), valFn) + } + default: + // out-of-band + // first encode each key to a []byte first, then sort them, then record + var mksv []byte = make([]byte, 0, len(mks)*16) // temporary byte slice for the encoding + e2 := NewEncoderBytes(&mksv, e.hh) + mksbv := make([]bytesRv, len(mks)) + for i, k := range mks { + v := &mksbv[i] + l := len(mksv) + e2.MustEncode(k) + v.r = k + v.v = mksv[l:] + // fmt.Printf(">>>>> %s\n", mksv[l:]) + } + sort.Sort(bytesRvSlice(mksbv)) + for j := range mksbv { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.asis(mksbv[j].v) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encodeValue(rv.MapIndex(mksbv[j].r), valFn) + } + } + } } // -------------------------------------------------- @@ -783,12 +865,12 @@ func (f encFnInfo) kMap(rv reflect.Value) { // instead of executing the checks every time. type encFn struct { i encFnInfo - f func(encFnInfo, reflect.Value) + f func(*encFnInfo, reflect.Value) } // -------------------------------------------------- -type rtidEncFn struct { +type encRtidFn struct { rtid uintptr fn encFn } @@ -796,18 +878,26 @@ type rtidEncFn struct { // An Encoder writes an object to an output stream in the codec format. type Encoder struct { // hopefully, reduce derefencing cost by laying the encWriter inside the Encoder - e encDriver + e encDriver + // NOTE: Encoder shouldn't call it's write methods, + // as the handler MAY need to do some coordination. w encWriter - s []rtidEncFn + s []encRtidFn + ci set be bool // is binary encoding + js bool // is json handle wi ioEncWriter wb bytesEncWriter - h *BasicHandle + h *BasicHandle hh Handle - f map[uintptr]encFn - b [scratchByteArrayLen]byte + + cr containerStateRecv + as encDriverAsis + + f map[uintptr]*encFn + b [scratchByteArrayLen]byte } // NewEncoder returns an Encoder for encoding into an io.Writer. @@ -815,18 +905,8 @@ type Encoder struct { // For efficiency, Users are encouraged to pass in a memory buffered writer // (eg bufio.Writer, bytes.Buffer). func NewEncoder(w io.Writer, h Handle) *Encoder { - e := &Encoder{hh: h, h: h.getBasicHandle(), be: h.isBinary()} - ww, ok := w.(ioEncWriterWriter) - if !ok { - sww := simpleIoEncWriterWriter{w: w} - sww.bw, _ = w.(io.ByteWriter) - sww.sw, _ = w.(ioEncStringWriter) - ww = &sww - //ww = bufio.NewWriterSize(w, defEncByteBufSize) - } - e.wi.w = ww - e.w = &e.wi - e.e = h.newEncDriver(e) + e := newEncoder(h) + e.Reset(w) return e } @@ -836,17 +916,56 @@ func NewEncoder(w io.Writer, h Handle) *Encoder { // It will potentially replace the output byte slice pointed to. // After encoding, the out parameter contains the encoded contents. func NewEncoderBytes(out *[]byte, h Handle) *Encoder { + e := newEncoder(h) + e.ResetBytes(out) + return e +} + +func newEncoder(h Handle) *Encoder { e := &Encoder{hh: h, h: h.getBasicHandle(), be: h.isBinary()} + _, e.js = h.(*JsonHandle) + e.e = h.newEncDriver(e) + e.as, _ = e.e.(encDriverAsis) + e.cr, _ = e.e.(containerStateRecv) + return e +} + +// Reset the Encoder with a new output stream. +// +// This accomodates using the state of the Encoder, +// where it has "cached" information about sub-engines. +func (e *Encoder) Reset(w io.Writer) { + ww, ok := w.(ioEncWriterWriter) + if ok { + e.wi.w = ww + } else { + sww := &e.wi.s + sww.w = w + sww.bw, _ = w.(io.ByteWriter) + sww.sw, _ = w.(ioEncStringWriter) + e.wi.w = sww + //ww = bufio.NewWriterSize(w, defEncByteBufSize) + } + e.w = &e.wi + e.e.reset() +} + +func (e *Encoder) ResetBytes(out *[]byte) { in := *out if in == nil { in = make([]byte, defEncByteBufSize) } - e.wb.b, e.wb.out = in, out + e.wb.b, e.wb.out, e.wb.c = in, out, 0 e.w = &e.wb - e.e = h.newEncDriver(e) - return e + e.e.reset() } +// func (e *Encoder) sendContainerState(c containerState) { +// if e.cr != nil { +// e.cr.sendContainerState(c) +// } +// } + // Encode writes an object into a stream. // // Encoding can be configured via the struct tag for the fields. @@ -873,8 +992,9 @@ func NewEncoderBytes(out *[]byte, h Handle) *Encoder { // The empty values (for omitempty option) are false, 0, any nil pointer // or interface value, and any array, slice, map, or string of length zero. // -// Anonymous fields are encoded inline if no struct tag is present. -// Else they are encoded as regular fields. +// Anonymous fields are encoded inline except: +// - the struct tag specifies a replacement name (first value) +// - the field is of an interface type // // Examples: // @@ -885,6 +1005,9 @@ func NewEncoderBytes(out *[]byte, h Handle) *Encoder { // Field2 int `codec:"myName"` //Use key "myName" in encode stream // Field3 int32 `codec:",omitempty"` //use key "Field3". Omit if empty. // Field4 bool `codec:"f4,omitempty"` //use key "f4". Omit if empty. +// io.Reader //use key "Reader". +// MyStruct `codec:"my1" //use key "my1". +// MyStruct //inline it // ... // } // @@ -894,8 +1017,9 @@ func NewEncoderBytes(out *[]byte, h Handle) *Encoder { // } // // The mode of encoding is based on the type of the value. When a value is seen: +// - If a Selfer, call its CodecEncodeSelf method // - If an extension is registered for it, call that extension function -// - If it implements BinaryMarshaler, call its MarshalBinary() (data []byte, err error) +// - If it implements encoding.(Binary|Text|JSON)Marshaler, call its Marshal(Binary|Text|JSON) method // - Else encode it based on its reflect.Kind // // Note that struct field names and keys in map[string]XXX will be treated as symbols. @@ -942,7 +1066,7 @@ func (e *Encoder) encode(iv interface{}) { v.CodecEncodeSelf(e) case reflect.Value: - e.encodeValue(v, encFn{}) + e.encodeValue(v, nil) case string: e.e.EncodeString(c_UTF8, v) @@ -1009,73 +1133,93 @@ func (e *Encoder) encode(iv interface{}) { e.e.EncodeStringBytes(c_RAW, *v) default: - // canonical mode is not supported for fastpath of maps (but is fine for slices) - if e.h.Canonical { - if !fastpathEncodeTypeSwitchSlice(iv, e) { - e.encodeI(iv, false, false) - } - } else if !fastpathEncodeTypeSwitch(iv, e) { - e.encodeI(iv, false, false) + const checkCodecSelfer1 = true // in case T is passed, where *T is a Selfer, still checkCodecSelfer + if !fastpathEncodeTypeSwitch(iv, e) { + e.encodeI(iv, false, checkCodecSelfer1) } } } +func (e *Encoder) preEncodeValue(rv reflect.Value) (rv2 reflect.Value, sptr uintptr, proceed bool) { + // use a goto statement instead of a recursive function for ptr/interface. +TOP: + switch rv.Kind() { + case reflect.Ptr: + if rv.IsNil() { + e.e.EncodeNil() + return + } + rv = rv.Elem() + if e.h.CheckCircularRef && rv.Kind() == reflect.Struct { + // TODO: Movable pointers will be an issue here. Future problem. + sptr = rv.UnsafeAddr() + break TOP + } + goto TOP + case reflect.Interface: + if rv.IsNil() { + e.e.EncodeNil() + return + } + rv = rv.Elem() + goto TOP + case reflect.Slice, reflect.Map: + if rv.IsNil() { + e.e.EncodeNil() + return + } + case reflect.Invalid, reflect.Func: + e.e.EncodeNil() + return + } + + proceed = true + rv2 = rv + return +} + +func (e *Encoder) doEncodeValue(rv reflect.Value, fn *encFn, sptr uintptr, + checkFastpath, checkCodecSelfer bool) { + if sptr != 0 { + if (&e.ci).add(sptr) { + e.errorf("circular reference found: # %d", sptr) + } + } + if fn == nil { + rt := rv.Type() + rtid := reflect.ValueOf(rt).Pointer() + // fn = e.getEncFn(rtid, rt, true, true) + fn = e.getEncFn(rtid, rt, checkFastpath, checkCodecSelfer) + } + fn.f(&fn.i, rv) + if sptr != 0 { + (&e.ci).remove(sptr) + } +} + func (e *Encoder) encodeI(iv interface{}, checkFastpath, checkCodecSelfer bool) { - if rv, proceed := e.preEncodeValue(reflect.ValueOf(iv)); proceed { - rt := rv.Type() - rtid := reflect.ValueOf(rt).Pointer() - fn := e.getEncFn(rtid, rt, checkFastpath, checkCodecSelfer) - fn.f(fn.i, rv) + if rv, sptr, proceed := e.preEncodeValue(reflect.ValueOf(iv)); proceed { + e.doEncodeValue(rv, nil, sptr, checkFastpath, checkCodecSelfer) } } -func (e *Encoder) preEncodeValue(rv reflect.Value) (rv2 reflect.Value, proceed bool) { -LOOP: - for { - switch rv.Kind() { - case reflect.Ptr, reflect.Interface: - if rv.IsNil() { - e.e.EncodeNil() - return - } - rv = rv.Elem() - continue LOOP - case reflect.Slice, reflect.Map: - if rv.IsNil() { - e.e.EncodeNil() - return - } - case reflect.Invalid, reflect.Func: - e.e.EncodeNil() - return - } - break - } - - return rv, true -} - -func (e *Encoder) encodeValue(rv reflect.Value, fn encFn) { +func (e *Encoder) encodeValue(rv reflect.Value, fn *encFn) { // if a valid fn is passed, it MUST BE for the dereferenced type of rv - if rv, proceed := e.preEncodeValue(rv); proceed { - if fn.f == nil { - rt := rv.Type() - rtid := reflect.ValueOf(rt).Pointer() - fn = e.getEncFn(rtid, rt, true, true) - } - fn.f(fn.i, rv) + if rv, sptr, proceed := e.preEncodeValue(rv); proceed { + e.doEncodeValue(rv, fn, sptr, true, true) } } -func (e *Encoder) getEncFn(rtid uintptr, rt reflect.Type, checkFastpath, checkCodecSelfer bool) (fn encFn) { +func (e *Encoder) getEncFn(rtid uintptr, rt reflect.Type, checkFastpath, checkCodecSelfer bool) (fn *encFn) { // rtid := reflect.ValueOf(rt).Pointer() var ok bool if useMapForCodecCache { fn, ok = e.f[rtid] } else { - for _, v := range e.s { + for i := range e.s { + v := &(e.s[i]) if v.rtid == rtid { - fn, ok = v.fn, true + fn, ok = &(v.fn), true break } } @@ -1083,37 +1227,47 @@ func (e *Encoder) getEncFn(rtid uintptr, rt reflect.Type, checkFastpath, checkCo if ok { return } - // fi.encFnInfoX = new(encFnInfoX) - ti := getTypeInfo(rtid, rt) - var fi encFnInfo - fi.ee = e.e + + if useMapForCodecCache { + if e.f == nil { + e.f = make(map[uintptr]*encFn, initCollectionCap) + } + fn = new(encFn) + e.f[rtid] = fn + } else { + if e.s == nil { + e.s = make([]encRtidFn, 0, initCollectionCap) + } + e.s = append(e.s, encRtidFn{rtid: rtid}) + fn = &(e.s[len(e.s)-1]).fn + } + + ti := e.h.getTypeInfo(rtid, rt) + fi := &(fn.i) + fi.e = e + fi.ti = ti if checkCodecSelfer && ti.cs { - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti} - fn.f = (encFnInfo).selferMarshal + fn.f = (*encFnInfo).selferMarshal } else if rtid == rawExtTypId { - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti} - fn.f = (encFnInfo).rawExt + fn.f = (*encFnInfo).rawExt } else if e.e.IsBuiltinType(rtid) { - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti} - fn.f = (encFnInfo).builtin + fn.f = (*encFnInfo).builtin } else if xfFn := e.h.getExt(rtid); xfFn != nil { - // fi.encFnInfoX = new(encFnInfoX) - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti} fi.xfTag, fi.xfFn = xfFn.tag, xfFn.ext - fn.f = (encFnInfo).ext + fn.f = (*encFnInfo).ext } else if supportMarshalInterfaces && e.be && ti.bm { - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti} - fn.f = (encFnInfo).binaryMarshal + fn.f = (*encFnInfo).binaryMarshal + } else if supportMarshalInterfaces && !e.be && e.js && ti.jm { + //If JSON, we should check JSONMarshal before textMarshal + fn.f = (*encFnInfo).jsonMarshal } else if supportMarshalInterfaces && !e.be && ti.tm { - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti} - fn.f = (encFnInfo).textMarshal + fn.f = (*encFnInfo).textMarshal } else { rk := rt.Kind() if fastpathEnabled && checkFastpath && (rk == reflect.Map || rk == reflect.Slice) { - if rt.PkgPath() == "" { + if rt.PkgPath() == "" { // un-named slice or map if idx := fastpathAV.index(rtid); idx != -1 { - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti} fn.f = fastpathAV[idx].encfn } } else { @@ -1129,8 +1283,7 @@ func (e *Encoder) getEncFn(rtid uintptr, rt reflect.Type, checkFastpath, checkCo if idx := fastpathAV.index(rtuid); idx != -1 { xfnf := fastpathAV[idx].encfn xrt := fastpathAV[idx].rt - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti} - fn.f = func(xf encFnInfo, xrv reflect.Value) { + fn.f = func(xf *encFnInfo, xrv reflect.Value) { xfnf(xf, xrv.Convert(xrt)) } } @@ -1139,60 +1292,67 @@ func (e *Encoder) getEncFn(rtid uintptr, rt reflect.Type, checkFastpath, checkCo if fn.f == nil { switch rk { case reflect.Bool: - fn.f = (encFnInfo).kBool + fn.f = (*encFnInfo).kBool case reflect.String: - fn.f = (encFnInfo).kString + fn.f = (*encFnInfo).kString case reflect.Float64: - fn.f = (encFnInfo).kFloat64 + fn.f = (*encFnInfo).kFloat64 case reflect.Float32: - fn.f = (encFnInfo).kFloat32 + fn.f = (*encFnInfo).kFloat32 case reflect.Int, reflect.Int8, reflect.Int64, reflect.Int32, reflect.Int16: - fn.f = (encFnInfo).kInt - case reflect.Uint8, reflect.Uint64, reflect.Uint, reflect.Uint32, reflect.Uint16: - fn.f = (encFnInfo).kUint + fn.f = (*encFnInfo).kInt + case reflect.Uint8, reflect.Uint64, reflect.Uint, reflect.Uint32, reflect.Uint16, reflect.Uintptr: + fn.f = (*encFnInfo).kUint case reflect.Invalid: - fn.f = (encFnInfo).kInvalid + fn.f = (*encFnInfo).kInvalid case reflect.Chan: - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti, seq: seqTypeChan} - fn.f = (encFnInfo).kSlice + fi.seq = seqTypeChan + fn.f = (*encFnInfo).kSlice case reflect.Slice: - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti, seq: seqTypeSlice} - fn.f = (encFnInfo).kSlice + fi.seq = seqTypeSlice + fn.f = (*encFnInfo).kSlice case reflect.Array: - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti, seq: seqTypeArray} - fn.f = (encFnInfo).kSlice + fi.seq = seqTypeArray + fn.f = (*encFnInfo).kSlice case reflect.Struct: - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti} - fn.f = (encFnInfo).kStruct + fn.f = (*encFnInfo).kStruct + // reflect.Ptr and reflect.Interface are handled already by preEncodeValue // case reflect.Ptr: - // fn.f = (encFnInfo).kPtr - case reflect.Interface: - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti} - fn.f = (encFnInfo).kInterface + // fn.f = (*encFnInfo).kPtr + // case reflect.Interface: + // fn.f = (*encFnInfo).kInterface case reflect.Map: - fi.encFnInfoX = &encFnInfoX{e: e, ti: ti} - fn.f = (encFnInfo).kMap + fn.f = (*encFnInfo).kMap default: - fn.f = (encFnInfo).kErr + fn.f = (*encFnInfo).kErr } } } - fn.i = fi - if useMapForCodecCache { - if e.f == nil { - e.f = make(map[uintptr]encFn, 32) - } - e.f[rtid] = fn - } else { - if e.s == nil { - e.s = make([]rtidEncFn, 0, 32) - } - e.s = append(e.s, rtidEncFn{rtid, fn}) - } return } +func (e *Encoder) marshal(bs []byte, fnerr error, asis bool, c charEncoding) { + if fnerr != nil { + panic(fnerr) + } + if bs == nil { + e.e.EncodeNil() + } else if asis { + e.asis(bs) + } else { + e.e.EncodeStringBytes(c, bs) + } +} + +func (e *Encoder) asis(v []byte) { + if e.as == nil { + e.w.writeb(v) + } else { + e.as.EncodeAsis(v) + } +} + func (e *Encoder) errorf(format string, params ...interface{}) { err := fmt.Errorf(format, params...) panic(err) @@ -1200,12 +1360,7 @@ func (e *Encoder) errorf(format string, params ...interface{}) { // ---------------------------------------- -type encStructFieldKV struct { - k string - v reflect.Value -} - -const encStructPoolLen = 4 +const encStructPoolLen = 5 // encStructPool is an array of sync.Pool. // Each element of the array pools one of encStructPool(8|16|32|64). @@ -1219,10 +1374,42 @@ const encStructPoolLen = 4 var encStructPool [encStructPoolLen]sync.Pool func init() { - encStructPool[0].New = func() interface{} { return new([8]encStructFieldKV) } - encStructPool[1].New = func() interface{} { return new([16]encStructFieldKV) } - encStructPool[2].New = func() interface{} { return new([32]encStructFieldKV) } - encStructPool[3].New = func() interface{} { return new([64]encStructFieldKV) } + encStructPool[0].New = func() interface{} { return new([8]stringRv) } + encStructPool[1].New = func() interface{} { return new([16]stringRv) } + encStructPool[2].New = func() interface{} { return new([32]stringRv) } + encStructPool[3].New = func() interface{} { return new([64]stringRv) } + encStructPool[4].New = func() interface{} { return new([128]stringRv) } +} + +func encStructPoolGet(newlen int) (p *sync.Pool, v interface{}, s []stringRv) { + // if encStructPoolLen != 5 { // constant chec, so removed at build time. + // panic(errors.New("encStructPoolLen must be equal to 4")) // defensive, in case it is changed + // } + // idxpool := newlen / 8 + if newlen <= 8 { + p = &encStructPool[0] + v = p.Get() + s = v.(*[8]stringRv)[:newlen] + } else if newlen <= 16 { + p = &encStructPool[1] + v = p.Get() + s = v.(*[16]stringRv)[:newlen] + } else if newlen <= 32 { + p = &encStructPool[2] + v = p.Get() + s = v.(*[32]stringRv)[:newlen] + } else if newlen <= 64 { + p = &encStructPool[3] + v = p.Get() + s = v.(*[64]stringRv)[:newlen] + } else if newlen <= 128 { + p = &encStructPool[4] + v = p.Get() + s = v.(*[128]stringRv)[:newlen] + } else { + s = make([]stringRv, newlen) + } + return } // ---------------------------------------- diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/fast-path.generated.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/fast-path.generated.go index b0f7f80..cf6e00d 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/fast-path.generated.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/fast-path.generated.go @@ -1,4 +1,4 @@ -// //+build ignore +// +build !notfastpath // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // Use of this source code is governed by a MIT license found in the LICENSE file. @@ -48,15 +48,15 @@ var fastpathTV fastpathT type fastpathE struct { rtid uintptr rt reflect.Type - encfn func(encFnInfo, reflect.Value) - decfn func(decFnInfo, reflect.Value) + encfn func(*encFnInfo, reflect.Value) + decfn func(*decFnInfo, reflect.Value) } -type fastpathA [239]fastpathE +type fastpathA [271]fastpathE func (x *fastpathA) index(rtid uintptr) int { // use binary search to grab the index (adapted from sort/search.go) - h, i, j := 0, 0, 239 // len(x) + h, i, j := 0, 0, 271 // len(x) for i < j { h = i + (j-i)/2 if x[h].rtid < rtid { @@ -65,7 +65,7 @@ func (x *fastpathA) index(rtid uintptr) int { j = h } } - if i < 239 && x[i].rtid == rtid { + if i < 271 && x[i].rtid == rtid { return i } return -1 @@ -85,7 +85,7 @@ func init() { return } i := 0 - fn := func(v interface{}, fe func(encFnInfo, reflect.Value), fd func(decFnInfo, reflect.Value)) (f fastpathE) { + fn := func(v interface{}, fe func(*encFnInfo, reflect.Value), fd func(*decFnInfo, reflect.Value)) (f fastpathE) { xrt := reflect.TypeOf(v) xptr := reflect.ValueOf(xrt).Pointer() fastpathAV[i] = fastpathE{xptr, xrt, fe, fd} @@ -93,246 +93,278 @@ func init() { return } - fn([]interface{}(nil), (encFnInfo).fastpathEncSliceIntfR, (decFnInfo).fastpathDecSliceIntfR) - fn([]string(nil), (encFnInfo).fastpathEncSliceStringR, (decFnInfo).fastpathDecSliceStringR) - fn([]float32(nil), (encFnInfo).fastpathEncSliceFloat32R, (decFnInfo).fastpathDecSliceFloat32R) - fn([]float64(nil), (encFnInfo).fastpathEncSliceFloat64R, (decFnInfo).fastpathDecSliceFloat64R) - fn([]uint(nil), (encFnInfo).fastpathEncSliceUintR, (decFnInfo).fastpathDecSliceUintR) - fn([]uint16(nil), (encFnInfo).fastpathEncSliceUint16R, (decFnInfo).fastpathDecSliceUint16R) - fn([]uint32(nil), (encFnInfo).fastpathEncSliceUint32R, (decFnInfo).fastpathDecSliceUint32R) - fn([]uint64(nil), (encFnInfo).fastpathEncSliceUint64R, (decFnInfo).fastpathDecSliceUint64R) - fn([]int(nil), (encFnInfo).fastpathEncSliceIntR, (decFnInfo).fastpathDecSliceIntR) - fn([]int8(nil), (encFnInfo).fastpathEncSliceInt8R, (decFnInfo).fastpathDecSliceInt8R) - fn([]int16(nil), (encFnInfo).fastpathEncSliceInt16R, (decFnInfo).fastpathDecSliceInt16R) - fn([]int32(nil), (encFnInfo).fastpathEncSliceInt32R, (decFnInfo).fastpathDecSliceInt32R) - fn([]int64(nil), (encFnInfo).fastpathEncSliceInt64R, (decFnInfo).fastpathDecSliceInt64R) - fn([]bool(nil), (encFnInfo).fastpathEncSliceBoolR, (decFnInfo).fastpathDecSliceBoolR) + fn([]interface{}(nil), (*encFnInfo).fastpathEncSliceIntfR, (*decFnInfo).fastpathDecSliceIntfR) + fn([]string(nil), (*encFnInfo).fastpathEncSliceStringR, (*decFnInfo).fastpathDecSliceStringR) + fn([]float32(nil), (*encFnInfo).fastpathEncSliceFloat32R, (*decFnInfo).fastpathDecSliceFloat32R) + fn([]float64(nil), (*encFnInfo).fastpathEncSliceFloat64R, (*decFnInfo).fastpathDecSliceFloat64R) + fn([]uint(nil), (*encFnInfo).fastpathEncSliceUintR, (*decFnInfo).fastpathDecSliceUintR) + fn([]uint16(nil), (*encFnInfo).fastpathEncSliceUint16R, (*decFnInfo).fastpathDecSliceUint16R) + fn([]uint32(nil), (*encFnInfo).fastpathEncSliceUint32R, (*decFnInfo).fastpathDecSliceUint32R) + fn([]uint64(nil), (*encFnInfo).fastpathEncSliceUint64R, (*decFnInfo).fastpathDecSliceUint64R) + fn([]uintptr(nil), (*encFnInfo).fastpathEncSliceUintptrR, (*decFnInfo).fastpathDecSliceUintptrR) + fn([]int(nil), (*encFnInfo).fastpathEncSliceIntR, (*decFnInfo).fastpathDecSliceIntR) + fn([]int8(nil), (*encFnInfo).fastpathEncSliceInt8R, (*decFnInfo).fastpathDecSliceInt8R) + fn([]int16(nil), (*encFnInfo).fastpathEncSliceInt16R, (*decFnInfo).fastpathDecSliceInt16R) + fn([]int32(nil), (*encFnInfo).fastpathEncSliceInt32R, (*decFnInfo).fastpathDecSliceInt32R) + fn([]int64(nil), (*encFnInfo).fastpathEncSliceInt64R, (*decFnInfo).fastpathDecSliceInt64R) + fn([]bool(nil), (*encFnInfo).fastpathEncSliceBoolR, (*decFnInfo).fastpathDecSliceBoolR) - fn(map[interface{}]interface{}(nil), (encFnInfo).fastpathEncMapIntfIntfR, (decFnInfo).fastpathDecMapIntfIntfR) - fn(map[interface{}]string(nil), (encFnInfo).fastpathEncMapIntfStringR, (decFnInfo).fastpathDecMapIntfStringR) - fn(map[interface{}]uint(nil), (encFnInfo).fastpathEncMapIntfUintR, (decFnInfo).fastpathDecMapIntfUintR) - fn(map[interface{}]uint8(nil), (encFnInfo).fastpathEncMapIntfUint8R, (decFnInfo).fastpathDecMapIntfUint8R) - fn(map[interface{}]uint16(nil), (encFnInfo).fastpathEncMapIntfUint16R, (decFnInfo).fastpathDecMapIntfUint16R) - fn(map[interface{}]uint32(nil), (encFnInfo).fastpathEncMapIntfUint32R, (decFnInfo).fastpathDecMapIntfUint32R) - fn(map[interface{}]uint64(nil), (encFnInfo).fastpathEncMapIntfUint64R, (decFnInfo).fastpathDecMapIntfUint64R) - fn(map[interface{}]int(nil), (encFnInfo).fastpathEncMapIntfIntR, (decFnInfo).fastpathDecMapIntfIntR) - fn(map[interface{}]int8(nil), (encFnInfo).fastpathEncMapIntfInt8R, (decFnInfo).fastpathDecMapIntfInt8R) - fn(map[interface{}]int16(nil), (encFnInfo).fastpathEncMapIntfInt16R, (decFnInfo).fastpathDecMapIntfInt16R) - fn(map[interface{}]int32(nil), (encFnInfo).fastpathEncMapIntfInt32R, (decFnInfo).fastpathDecMapIntfInt32R) - fn(map[interface{}]int64(nil), (encFnInfo).fastpathEncMapIntfInt64R, (decFnInfo).fastpathDecMapIntfInt64R) - fn(map[interface{}]float32(nil), (encFnInfo).fastpathEncMapIntfFloat32R, (decFnInfo).fastpathDecMapIntfFloat32R) - fn(map[interface{}]float64(nil), (encFnInfo).fastpathEncMapIntfFloat64R, (decFnInfo).fastpathDecMapIntfFloat64R) - fn(map[interface{}]bool(nil), (encFnInfo).fastpathEncMapIntfBoolR, (decFnInfo).fastpathDecMapIntfBoolR) - fn(map[string]interface{}(nil), (encFnInfo).fastpathEncMapStringIntfR, (decFnInfo).fastpathDecMapStringIntfR) - fn(map[string]string(nil), (encFnInfo).fastpathEncMapStringStringR, (decFnInfo).fastpathDecMapStringStringR) - fn(map[string]uint(nil), (encFnInfo).fastpathEncMapStringUintR, (decFnInfo).fastpathDecMapStringUintR) - fn(map[string]uint8(nil), (encFnInfo).fastpathEncMapStringUint8R, (decFnInfo).fastpathDecMapStringUint8R) - fn(map[string]uint16(nil), (encFnInfo).fastpathEncMapStringUint16R, (decFnInfo).fastpathDecMapStringUint16R) - fn(map[string]uint32(nil), (encFnInfo).fastpathEncMapStringUint32R, (decFnInfo).fastpathDecMapStringUint32R) - fn(map[string]uint64(nil), (encFnInfo).fastpathEncMapStringUint64R, (decFnInfo).fastpathDecMapStringUint64R) - fn(map[string]int(nil), (encFnInfo).fastpathEncMapStringIntR, (decFnInfo).fastpathDecMapStringIntR) - fn(map[string]int8(nil), (encFnInfo).fastpathEncMapStringInt8R, (decFnInfo).fastpathDecMapStringInt8R) - fn(map[string]int16(nil), (encFnInfo).fastpathEncMapStringInt16R, (decFnInfo).fastpathDecMapStringInt16R) - fn(map[string]int32(nil), (encFnInfo).fastpathEncMapStringInt32R, (decFnInfo).fastpathDecMapStringInt32R) - fn(map[string]int64(nil), (encFnInfo).fastpathEncMapStringInt64R, (decFnInfo).fastpathDecMapStringInt64R) - fn(map[string]float32(nil), (encFnInfo).fastpathEncMapStringFloat32R, (decFnInfo).fastpathDecMapStringFloat32R) - fn(map[string]float64(nil), (encFnInfo).fastpathEncMapStringFloat64R, (decFnInfo).fastpathDecMapStringFloat64R) - fn(map[string]bool(nil), (encFnInfo).fastpathEncMapStringBoolR, (decFnInfo).fastpathDecMapStringBoolR) - fn(map[float32]interface{}(nil), (encFnInfo).fastpathEncMapFloat32IntfR, (decFnInfo).fastpathDecMapFloat32IntfR) - fn(map[float32]string(nil), (encFnInfo).fastpathEncMapFloat32StringR, (decFnInfo).fastpathDecMapFloat32StringR) - fn(map[float32]uint(nil), (encFnInfo).fastpathEncMapFloat32UintR, (decFnInfo).fastpathDecMapFloat32UintR) - fn(map[float32]uint8(nil), (encFnInfo).fastpathEncMapFloat32Uint8R, (decFnInfo).fastpathDecMapFloat32Uint8R) - fn(map[float32]uint16(nil), (encFnInfo).fastpathEncMapFloat32Uint16R, (decFnInfo).fastpathDecMapFloat32Uint16R) - fn(map[float32]uint32(nil), (encFnInfo).fastpathEncMapFloat32Uint32R, (decFnInfo).fastpathDecMapFloat32Uint32R) - fn(map[float32]uint64(nil), (encFnInfo).fastpathEncMapFloat32Uint64R, (decFnInfo).fastpathDecMapFloat32Uint64R) - fn(map[float32]int(nil), (encFnInfo).fastpathEncMapFloat32IntR, (decFnInfo).fastpathDecMapFloat32IntR) - fn(map[float32]int8(nil), (encFnInfo).fastpathEncMapFloat32Int8R, (decFnInfo).fastpathDecMapFloat32Int8R) - fn(map[float32]int16(nil), (encFnInfo).fastpathEncMapFloat32Int16R, (decFnInfo).fastpathDecMapFloat32Int16R) - fn(map[float32]int32(nil), (encFnInfo).fastpathEncMapFloat32Int32R, (decFnInfo).fastpathDecMapFloat32Int32R) - fn(map[float32]int64(nil), (encFnInfo).fastpathEncMapFloat32Int64R, (decFnInfo).fastpathDecMapFloat32Int64R) - fn(map[float32]float32(nil), (encFnInfo).fastpathEncMapFloat32Float32R, (decFnInfo).fastpathDecMapFloat32Float32R) - fn(map[float32]float64(nil), (encFnInfo).fastpathEncMapFloat32Float64R, (decFnInfo).fastpathDecMapFloat32Float64R) - fn(map[float32]bool(nil), (encFnInfo).fastpathEncMapFloat32BoolR, (decFnInfo).fastpathDecMapFloat32BoolR) - fn(map[float64]interface{}(nil), (encFnInfo).fastpathEncMapFloat64IntfR, (decFnInfo).fastpathDecMapFloat64IntfR) - fn(map[float64]string(nil), (encFnInfo).fastpathEncMapFloat64StringR, (decFnInfo).fastpathDecMapFloat64StringR) - fn(map[float64]uint(nil), (encFnInfo).fastpathEncMapFloat64UintR, (decFnInfo).fastpathDecMapFloat64UintR) - fn(map[float64]uint8(nil), (encFnInfo).fastpathEncMapFloat64Uint8R, (decFnInfo).fastpathDecMapFloat64Uint8R) - fn(map[float64]uint16(nil), (encFnInfo).fastpathEncMapFloat64Uint16R, (decFnInfo).fastpathDecMapFloat64Uint16R) - fn(map[float64]uint32(nil), (encFnInfo).fastpathEncMapFloat64Uint32R, (decFnInfo).fastpathDecMapFloat64Uint32R) - fn(map[float64]uint64(nil), (encFnInfo).fastpathEncMapFloat64Uint64R, (decFnInfo).fastpathDecMapFloat64Uint64R) - fn(map[float64]int(nil), (encFnInfo).fastpathEncMapFloat64IntR, (decFnInfo).fastpathDecMapFloat64IntR) - fn(map[float64]int8(nil), (encFnInfo).fastpathEncMapFloat64Int8R, (decFnInfo).fastpathDecMapFloat64Int8R) - fn(map[float64]int16(nil), (encFnInfo).fastpathEncMapFloat64Int16R, (decFnInfo).fastpathDecMapFloat64Int16R) - fn(map[float64]int32(nil), (encFnInfo).fastpathEncMapFloat64Int32R, (decFnInfo).fastpathDecMapFloat64Int32R) - fn(map[float64]int64(nil), (encFnInfo).fastpathEncMapFloat64Int64R, (decFnInfo).fastpathDecMapFloat64Int64R) - fn(map[float64]float32(nil), (encFnInfo).fastpathEncMapFloat64Float32R, (decFnInfo).fastpathDecMapFloat64Float32R) - fn(map[float64]float64(nil), (encFnInfo).fastpathEncMapFloat64Float64R, (decFnInfo).fastpathDecMapFloat64Float64R) - fn(map[float64]bool(nil), (encFnInfo).fastpathEncMapFloat64BoolR, (decFnInfo).fastpathDecMapFloat64BoolR) - fn(map[uint]interface{}(nil), (encFnInfo).fastpathEncMapUintIntfR, (decFnInfo).fastpathDecMapUintIntfR) - fn(map[uint]string(nil), (encFnInfo).fastpathEncMapUintStringR, (decFnInfo).fastpathDecMapUintStringR) - fn(map[uint]uint(nil), (encFnInfo).fastpathEncMapUintUintR, (decFnInfo).fastpathDecMapUintUintR) - fn(map[uint]uint8(nil), (encFnInfo).fastpathEncMapUintUint8R, (decFnInfo).fastpathDecMapUintUint8R) - fn(map[uint]uint16(nil), (encFnInfo).fastpathEncMapUintUint16R, (decFnInfo).fastpathDecMapUintUint16R) - fn(map[uint]uint32(nil), (encFnInfo).fastpathEncMapUintUint32R, (decFnInfo).fastpathDecMapUintUint32R) - fn(map[uint]uint64(nil), (encFnInfo).fastpathEncMapUintUint64R, (decFnInfo).fastpathDecMapUintUint64R) - fn(map[uint]int(nil), (encFnInfo).fastpathEncMapUintIntR, (decFnInfo).fastpathDecMapUintIntR) - fn(map[uint]int8(nil), (encFnInfo).fastpathEncMapUintInt8R, (decFnInfo).fastpathDecMapUintInt8R) - fn(map[uint]int16(nil), (encFnInfo).fastpathEncMapUintInt16R, (decFnInfo).fastpathDecMapUintInt16R) - fn(map[uint]int32(nil), (encFnInfo).fastpathEncMapUintInt32R, (decFnInfo).fastpathDecMapUintInt32R) - fn(map[uint]int64(nil), (encFnInfo).fastpathEncMapUintInt64R, (decFnInfo).fastpathDecMapUintInt64R) - fn(map[uint]float32(nil), (encFnInfo).fastpathEncMapUintFloat32R, (decFnInfo).fastpathDecMapUintFloat32R) - fn(map[uint]float64(nil), (encFnInfo).fastpathEncMapUintFloat64R, (decFnInfo).fastpathDecMapUintFloat64R) - fn(map[uint]bool(nil), (encFnInfo).fastpathEncMapUintBoolR, (decFnInfo).fastpathDecMapUintBoolR) - fn(map[uint8]interface{}(nil), (encFnInfo).fastpathEncMapUint8IntfR, (decFnInfo).fastpathDecMapUint8IntfR) - fn(map[uint8]string(nil), (encFnInfo).fastpathEncMapUint8StringR, (decFnInfo).fastpathDecMapUint8StringR) - fn(map[uint8]uint(nil), (encFnInfo).fastpathEncMapUint8UintR, (decFnInfo).fastpathDecMapUint8UintR) - fn(map[uint8]uint8(nil), (encFnInfo).fastpathEncMapUint8Uint8R, (decFnInfo).fastpathDecMapUint8Uint8R) - fn(map[uint8]uint16(nil), (encFnInfo).fastpathEncMapUint8Uint16R, (decFnInfo).fastpathDecMapUint8Uint16R) - fn(map[uint8]uint32(nil), (encFnInfo).fastpathEncMapUint8Uint32R, (decFnInfo).fastpathDecMapUint8Uint32R) - fn(map[uint8]uint64(nil), (encFnInfo).fastpathEncMapUint8Uint64R, (decFnInfo).fastpathDecMapUint8Uint64R) - fn(map[uint8]int(nil), (encFnInfo).fastpathEncMapUint8IntR, (decFnInfo).fastpathDecMapUint8IntR) - fn(map[uint8]int8(nil), (encFnInfo).fastpathEncMapUint8Int8R, (decFnInfo).fastpathDecMapUint8Int8R) - fn(map[uint8]int16(nil), (encFnInfo).fastpathEncMapUint8Int16R, (decFnInfo).fastpathDecMapUint8Int16R) - fn(map[uint8]int32(nil), (encFnInfo).fastpathEncMapUint8Int32R, (decFnInfo).fastpathDecMapUint8Int32R) - fn(map[uint8]int64(nil), (encFnInfo).fastpathEncMapUint8Int64R, (decFnInfo).fastpathDecMapUint8Int64R) - fn(map[uint8]float32(nil), (encFnInfo).fastpathEncMapUint8Float32R, (decFnInfo).fastpathDecMapUint8Float32R) - fn(map[uint8]float64(nil), (encFnInfo).fastpathEncMapUint8Float64R, (decFnInfo).fastpathDecMapUint8Float64R) - fn(map[uint8]bool(nil), (encFnInfo).fastpathEncMapUint8BoolR, (decFnInfo).fastpathDecMapUint8BoolR) - fn(map[uint16]interface{}(nil), (encFnInfo).fastpathEncMapUint16IntfR, (decFnInfo).fastpathDecMapUint16IntfR) - fn(map[uint16]string(nil), (encFnInfo).fastpathEncMapUint16StringR, (decFnInfo).fastpathDecMapUint16StringR) - fn(map[uint16]uint(nil), (encFnInfo).fastpathEncMapUint16UintR, (decFnInfo).fastpathDecMapUint16UintR) - fn(map[uint16]uint8(nil), (encFnInfo).fastpathEncMapUint16Uint8R, (decFnInfo).fastpathDecMapUint16Uint8R) - fn(map[uint16]uint16(nil), (encFnInfo).fastpathEncMapUint16Uint16R, (decFnInfo).fastpathDecMapUint16Uint16R) - fn(map[uint16]uint32(nil), (encFnInfo).fastpathEncMapUint16Uint32R, (decFnInfo).fastpathDecMapUint16Uint32R) - fn(map[uint16]uint64(nil), (encFnInfo).fastpathEncMapUint16Uint64R, (decFnInfo).fastpathDecMapUint16Uint64R) - fn(map[uint16]int(nil), (encFnInfo).fastpathEncMapUint16IntR, (decFnInfo).fastpathDecMapUint16IntR) - fn(map[uint16]int8(nil), (encFnInfo).fastpathEncMapUint16Int8R, (decFnInfo).fastpathDecMapUint16Int8R) - fn(map[uint16]int16(nil), (encFnInfo).fastpathEncMapUint16Int16R, (decFnInfo).fastpathDecMapUint16Int16R) - fn(map[uint16]int32(nil), (encFnInfo).fastpathEncMapUint16Int32R, (decFnInfo).fastpathDecMapUint16Int32R) - fn(map[uint16]int64(nil), (encFnInfo).fastpathEncMapUint16Int64R, (decFnInfo).fastpathDecMapUint16Int64R) - fn(map[uint16]float32(nil), (encFnInfo).fastpathEncMapUint16Float32R, (decFnInfo).fastpathDecMapUint16Float32R) - fn(map[uint16]float64(nil), (encFnInfo).fastpathEncMapUint16Float64R, (decFnInfo).fastpathDecMapUint16Float64R) - fn(map[uint16]bool(nil), (encFnInfo).fastpathEncMapUint16BoolR, (decFnInfo).fastpathDecMapUint16BoolR) - fn(map[uint32]interface{}(nil), (encFnInfo).fastpathEncMapUint32IntfR, (decFnInfo).fastpathDecMapUint32IntfR) - fn(map[uint32]string(nil), (encFnInfo).fastpathEncMapUint32StringR, (decFnInfo).fastpathDecMapUint32StringR) - fn(map[uint32]uint(nil), (encFnInfo).fastpathEncMapUint32UintR, (decFnInfo).fastpathDecMapUint32UintR) - fn(map[uint32]uint8(nil), (encFnInfo).fastpathEncMapUint32Uint8R, (decFnInfo).fastpathDecMapUint32Uint8R) - fn(map[uint32]uint16(nil), (encFnInfo).fastpathEncMapUint32Uint16R, (decFnInfo).fastpathDecMapUint32Uint16R) - fn(map[uint32]uint32(nil), (encFnInfo).fastpathEncMapUint32Uint32R, (decFnInfo).fastpathDecMapUint32Uint32R) - fn(map[uint32]uint64(nil), (encFnInfo).fastpathEncMapUint32Uint64R, (decFnInfo).fastpathDecMapUint32Uint64R) - fn(map[uint32]int(nil), (encFnInfo).fastpathEncMapUint32IntR, (decFnInfo).fastpathDecMapUint32IntR) - fn(map[uint32]int8(nil), (encFnInfo).fastpathEncMapUint32Int8R, (decFnInfo).fastpathDecMapUint32Int8R) - fn(map[uint32]int16(nil), (encFnInfo).fastpathEncMapUint32Int16R, (decFnInfo).fastpathDecMapUint32Int16R) - fn(map[uint32]int32(nil), (encFnInfo).fastpathEncMapUint32Int32R, (decFnInfo).fastpathDecMapUint32Int32R) - fn(map[uint32]int64(nil), (encFnInfo).fastpathEncMapUint32Int64R, (decFnInfo).fastpathDecMapUint32Int64R) - fn(map[uint32]float32(nil), (encFnInfo).fastpathEncMapUint32Float32R, (decFnInfo).fastpathDecMapUint32Float32R) - fn(map[uint32]float64(nil), (encFnInfo).fastpathEncMapUint32Float64R, (decFnInfo).fastpathDecMapUint32Float64R) - fn(map[uint32]bool(nil), (encFnInfo).fastpathEncMapUint32BoolR, (decFnInfo).fastpathDecMapUint32BoolR) - fn(map[uint64]interface{}(nil), (encFnInfo).fastpathEncMapUint64IntfR, (decFnInfo).fastpathDecMapUint64IntfR) - fn(map[uint64]string(nil), (encFnInfo).fastpathEncMapUint64StringR, (decFnInfo).fastpathDecMapUint64StringR) - fn(map[uint64]uint(nil), (encFnInfo).fastpathEncMapUint64UintR, (decFnInfo).fastpathDecMapUint64UintR) - fn(map[uint64]uint8(nil), (encFnInfo).fastpathEncMapUint64Uint8R, (decFnInfo).fastpathDecMapUint64Uint8R) - fn(map[uint64]uint16(nil), (encFnInfo).fastpathEncMapUint64Uint16R, (decFnInfo).fastpathDecMapUint64Uint16R) - fn(map[uint64]uint32(nil), (encFnInfo).fastpathEncMapUint64Uint32R, (decFnInfo).fastpathDecMapUint64Uint32R) - fn(map[uint64]uint64(nil), (encFnInfo).fastpathEncMapUint64Uint64R, (decFnInfo).fastpathDecMapUint64Uint64R) - fn(map[uint64]int(nil), (encFnInfo).fastpathEncMapUint64IntR, (decFnInfo).fastpathDecMapUint64IntR) - fn(map[uint64]int8(nil), (encFnInfo).fastpathEncMapUint64Int8R, (decFnInfo).fastpathDecMapUint64Int8R) - fn(map[uint64]int16(nil), (encFnInfo).fastpathEncMapUint64Int16R, (decFnInfo).fastpathDecMapUint64Int16R) - fn(map[uint64]int32(nil), (encFnInfo).fastpathEncMapUint64Int32R, (decFnInfo).fastpathDecMapUint64Int32R) - fn(map[uint64]int64(nil), (encFnInfo).fastpathEncMapUint64Int64R, (decFnInfo).fastpathDecMapUint64Int64R) - fn(map[uint64]float32(nil), (encFnInfo).fastpathEncMapUint64Float32R, (decFnInfo).fastpathDecMapUint64Float32R) - fn(map[uint64]float64(nil), (encFnInfo).fastpathEncMapUint64Float64R, (decFnInfo).fastpathDecMapUint64Float64R) - fn(map[uint64]bool(nil), (encFnInfo).fastpathEncMapUint64BoolR, (decFnInfo).fastpathDecMapUint64BoolR) - fn(map[int]interface{}(nil), (encFnInfo).fastpathEncMapIntIntfR, (decFnInfo).fastpathDecMapIntIntfR) - fn(map[int]string(nil), (encFnInfo).fastpathEncMapIntStringR, (decFnInfo).fastpathDecMapIntStringR) - fn(map[int]uint(nil), (encFnInfo).fastpathEncMapIntUintR, (decFnInfo).fastpathDecMapIntUintR) - fn(map[int]uint8(nil), (encFnInfo).fastpathEncMapIntUint8R, (decFnInfo).fastpathDecMapIntUint8R) - fn(map[int]uint16(nil), (encFnInfo).fastpathEncMapIntUint16R, (decFnInfo).fastpathDecMapIntUint16R) - fn(map[int]uint32(nil), (encFnInfo).fastpathEncMapIntUint32R, (decFnInfo).fastpathDecMapIntUint32R) - fn(map[int]uint64(nil), (encFnInfo).fastpathEncMapIntUint64R, (decFnInfo).fastpathDecMapIntUint64R) - fn(map[int]int(nil), (encFnInfo).fastpathEncMapIntIntR, (decFnInfo).fastpathDecMapIntIntR) - fn(map[int]int8(nil), (encFnInfo).fastpathEncMapIntInt8R, (decFnInfo).fastpathDecMapIntInt8R) - fn(map[int]int16(nil), (encFnInfo).fastpathEncMapIntInt16R, (decFnInfo).fastpathDecMapIntInt16R) - fn(map[int]int32(nil), (encFnInfo).fastpathEncMapIntInt32R, (decFnInfo).fastpathDecMapIntInt32R) - fn(map[int]int64(nil), (encFnInfo).fastpathEncMapIntInt64R, (decFnInfo).fastpathDecMapIntInt64R) - fn(map[int]float32(nil), (encFnInfo).fastpathEncMapIntFloat32R, (decFnInfo).fastpathDecMapIntFloat32R) - fn(map[int]float64(nil), (encFnInfo).fastpathEncMapIntFloat64R, (decFnInfo).fastpathDecMapIntFloat64R) - fn(map[int]bool(nil), (encFnInfo).fastpathEncMapIntBoolR, (decFnInfo).fastpathDecMapIntBoolR) - fn(map[int8]interface{}(nil), (encFnInfo).fastpathEncMapInt8IntfR, (decFnInfo).fastpathDecMapInt8IntfR) - fn(map[int8]string(nil), (encFnInfo).fastpathEncMapInt8StringR, (decFnInfo).fastpathDecMapInt8StringR) - fn(map[int8]uint(nil), (encFnInfo).fastpathEncMapInt8UintR, (decFnInfo).fastpathDecMapInt8UintR) - fn(map[int8]uint8(nil), (encFnInfo).fastpathEncMapInt8Uint8R, (decFnInfo).fastpathDecMapInt8Uint8R) - fn(map[int8]uint16(nil), (encFnInfo).fastpathEncMapInt8Uint16R, (decFnInfo).fastpathDecMapInt8Uint16R) - fn(map[int8]uint32(nil), (encFnInfo).fastpathEncMapInt8Uint32R, (decFnInfo).fastpathDecMapInt8Uint32R) - fn(map[int8]uint64(nil), (encFnInfo).fastpathEncMapInt8Uint64R, (decFnInfo).fastpathDecMapInt8Uint64R) - fn(map[int8]int(nil), (encFnInfo).fastpathEncMapInt8IntR, (decFnInfo).fastpathDecMapInt8IntR) - fn(map[int8]int8(nil), (encFnInfo).fastpathEncMapInt8Int8R, (decFnInfo).fastpathDecMapInt8Int8R) - fn(map[int8]int16(nil), (encFnInfo).fastpathEncMapInt8Int16R, (decFnInfo).fastpathDecMapInt8Int16R) - fn(map[int8]int32(nil), (encFnInfo).fastpathEncMapInt8Int32R, (decFnInfo).fastpathDecMapInt8Int32R) - fn(map[int8]int64(nil), (encFnInfo).fastpathEncMapInt8Int64R, (decFnInfo).fastpathDecMapInt8Int64R) - fn(map[int8]float32(nil), (encFnInfo).fastpathEncMapInt8Float32R, (decFnInfo).fastpathDecMapInt8Float32R) - fn(map[int8]float64(nil), (encFnInfo).fastpathEncMapInt8Float64R, (decFnInfo).fastpathDecMapInt8Float64R) - fn(map[int8]bool(nil), (encFnInfo).fastpathEncMapInt8BoolR, (decFnInfo).fastpathDecMapInt8BoolR) - fn(map[int16]interface{}(nil), (encFnInfo).fastpathEncMapInt16IntfR, (decFnInfo).fastpathDecMapInt16IntfR) - fn(map[int16]string(nil), (encFnInfo).fastpathEncMapInt16StringR, (decFnInfo).fastpathDecMapInt16StringR) - fn(map[int16]uint(nil), (encFnInfo).fastpathEncMapInt16UintR, (decFnInfo).fastpathDecMapInt16UintR) - fn(map[int16]uint8(nil), (encFnInfo).fastpathEncMapInt16Uint8R, (decFnInfo).fastpathDecMapInt16Uint8R) - fn(map[int16]uint16(nil), (encFnInfo).fastpathEncMapInt16Uint16R, (decFnInfo).fastpathDecMapInt16Uint16R) - fn(map[int16]uint32(nil), (encFnInfo).fastpathEncMapInt16Uint32R, (decFnInfo).fastpathDecMapInt16Uint32R) - fn(map[int16]uint64(nil), (encFnInfo).fastpathEncMapInt16Uint64R, (decFnInfo).fastpathDecMapInt16Uint64R) - fn(map[int16]int(nil), (encFnInfo).fastpathEncMapInt16IntR, (decFnInfo).fastpathDecMapInt16IntR) - fn(map[int16]int8(nil), (encFnInfo).fastpathEncMapInt16Int8R, (decFnInfo).fastpathDecMapInt16Int8R) - fn(map[int16]int16(nil), (encFnInfo).fastpathEncMapInt16Int16R, (decFnInfo).fastpathDecMapInt16Int16R) - fn(map[int16]int32(nil), (encFnInfo).fastpathEncMapInt16Int32R, (decFnInfo).fastpathDecMapInt16Int32R) - fn(map[int16]int64(nil), (encFnInfo).fastpathEncMapInt16Int64R, (decFnInfo).fastpathDecMapInt16Int64R) - fn(map[int16]float32(nil), (encFnInfo).fastpathEncMapInt16Float32R, (decFnInfo).fastpathDecMapInt16Float32R) - fn(map[int16]float64(nil), (encFnInfo).fastpathEncMapInt16Float64R, (decFnInfo).fastpathDecMapInt16Float64R) - fn(map[int16]bool(nil), (encFnInfo).fastpathEncMapInt16BoolR, (decFnInfo).fastpathDecMapInt16BoolR) - fn(map[int32]interface{}(nil), (encFnInfo).fastpathEncMapInt32IntfR, (decFnInfo).fastpathDecMapInt32IntfR) - fn(map[int32]string(nil), (encFnInfo).fastpathEncMapInt32StringR, (decFnInfo).fastpathDecMapInt32StringR) - fn(map[int32]uint(nil), (encFnInfo).fastpathEncMapInt32UintR, (decFnInfo).fastpathDecMapInt32UintR) - fn(map[int32]uint8(nil), (encFnInfo).fastpathEncMapInt32Uint8R, (decFnInfo).fastpathDecMapInt32Uint8R) - fn(map[int32]uint16(nil), (encFnInfo).fastpathEncMapInt32Uint16R, (decFnInfo).fastpathDecMapInt32Uint16R) - fn(map[int32]uint32(nil), (encFnInfo).fastpathEncMapInt32Uint32R, (decFnInfo).fastpathDecMapInt32Uint32R) - fn(map[int32]uint64(nil), (encFnInfo).fastpathEncMapInt32Uint64R, (decFnInfo).fastpathDecMapInt32Uint64R) - fn(map[int32]int(nil), (encFnInfo).fastpathEncMapInt32IntR, (decFnInfo).fastpathDecMapInt32IntR) - fn(map[int32]int8(nil), (encFnInfo).fastpathEncMapInt32Int8R, (decFnInfo).fastpathDecMapInt32Int8R) - fn(map[int32]int16(nil), (encFnInfo).fastpathEncMapInt32Int16R, (decFnInfo).fastpathDecMapInt32Int16R) - fn(map[int32]int32(nil), (encFnInfo).fastpathEncMapInt32Int32R, (decFnInfo).fastpathDecMapInt32Int32R) - fn(map[int32]int64(nil), (encFnInfo).fastpathEncMapInt32Int64R, (decFnInfo).fastpathDecMapInt32Int64R) - fn(map[int32]float32(nil), (encFnInfo).fastpathEncMapInt32Float32R, (decFnInfo).fastpathDecMapInt32Float32R) - fn(map[int32]float64(nil), (encFnInfo).fastpathEncMapInt32Float64R, (decFnInfo).fastpathDecMapInt32Float64R) - fn(map[int32]bool(nil), (encFnInfo).fastpathEncMapInt32BoolR, (decFnInfo).fastpathDecMapInt32BoolR) - fn(map[int64]interface{}(nil), (encFnInfo).fastpathEncMapInt64IntfR, (decFnInfo).fastpathDecMapInt64IntfR) - fn(map[int64]string(nil), (encFnInfo).fastpathEncMapInt64StringR, (decFnInfo).fastpathDecMapInt64StringR) - fn(map[int64]uint(nil), (encFnInfo).fastpathEncMapInt64UintR, (decFnInfo).fastpathDecMapInt64UintR) - fn(map[int64]uint8(nil), (encFnInfo).fastpathEncMapInt64Uint8R, (decFnInfo).fastpathDecMapInt64Uint8R) - fn(map[int64]uint16(nil), (encFnInfo).fastpathEncMapInt64Uint16R, (decFnInfo).fastpathDecMapInt64Uint16R) - fn(map[int64]uint32(nil), (encFnInfo).fastpathEncMapInt64Uint32R, (decFnInfo).fastpathDecMapInt64Uint32R) - fn(map[int64]uint64(nil), (encFnInfo).fastpathEncMapInt64Uint64R, (decFnInfo).fastpathDecMapInt64Uint64R) - fn(map[int64]int(nil), (encFnInfo).fastpathEncMapInt64IntR, (decFnInfo).fastpathDecMapInt64IntR) - fn(map[int64]int8(nil), (encFnInfo).fastpathEncMapInt64Int8R, (decFnInfo).fastpathDecMapInt64Int8R) - fn(map[int64]int16(nil), (encFnInfo).fastpathEncMapInt64Int16R, (decFnInfo).fastpathDecMapInt64Int16R) - fn(map[int64]int32(nil), (encFnInfo).fastpathEncMapInt64Int32R, (decFnInfo).fastpathDecMapInt64Int32R) - fn(map[int64]int64(nil), (encFnInfo).fastpathEncMapInt64Int64R, (decFnInfo).fastpathDecMapInt64Int64R) - fn(map[int64]float32(nil), (encFnInfo).fastpathEncMapInt64Float32R, (decFnInfo).fastpathDecMapInt64Float32R) - fn(map[int64]float64(nil), (encFnInfo).fastpathEncMapInt64Float64R, (decFnInfo).fastpathDecMapInt64Float64R) - fn(map[int64]bool(nil), (encFnInfo).fastpathEncMapInt64BoolR, (decFnInfo).fastpathDecMapInt64BoolR) - fn(map[bool]interface{}(nil), (encFnInfo).fastpathEncMapBoolIntfR, (decFnInfo).fastpathDecMapBoolIntfR) - fn(map[bool]string(nil), (encFnInfo).fastpathEncMapBoolStringR, (decFnInfo).fastpathDecMapBoolStringR) - fn(map[bool]uint(nil), (encFnInfo).fastpathEncMapBoolUintR, (decFnInfo).fastpathDecMapBoolUintR) - fn(map[bool]uint8(nil), (encFnInfo).fastpathEncMapBoolUint8R, (decFnInfo).fastpathDecMapBoolUint8R) - fn(map[bool]uint16(nil), (encFnInfo).fastpathEncMapBoolUint16R, (decFnInfo).fastpathDecMapBoolUint16R) - fn(map[bool]uint32(nil), (encFnInfo).fastpathEncMapBoolUint32R, (decFnInfo).fastpathDecMapBoolUint32R) - fn(map[bool]uint64(nil), (encFnInfo).fastpathEncMapBoolUint64R, (decFnInfo).fastpathDecMapBoolUint64R) - fn(map[bool]int(nil), (encFnInfo).fastpathEncMapBoolIntR, (decFnInfo).fastpathDecMapBoolIntR) - fn(map[bool]int8(nil), (encFnInfo).fastpathEncMapBoolInt8R, (decFnInfo).fastpathDecMapBoolInt8R) - fn(map[bool]int16(nil), (encFnInfo).fastpathEncMapBoolInt16R, (decFnInfo).fastpathDecMapBoolInt16R) - fn(map[bool]int32(nil), (encFnInfo).fastpathEncMapBoolInt32R, (decFnInfo).fastpathDecMapBoolInt32R) - fn(map[bool]int64(nil), (encFnInfo).fastpathEncMapBoolInt64R, (decFnInfo).fastpathDecMapBoolInt64R) - fn(map[bool]float32(nil), (encFnInfo).fastpathEncMapBoolFloat32R, (decFnInfo).fastpathDecMapBoolFloat32R) - fn(map[bool]float64(nil), (encFnInfo).fastpathEncMapBoolFloat64R, (decFnInfo).fastpathDecMapBoolFloat64R) - fn(map[bool]bool(nil), (encFnInfo).fastpathEncMapBoolBoolR, (decFnInfo).fastpathDecMapBoolBoolR) + fn(map[interface{}]interface{}(nil), (*encFnInfo).fastpathEncMapIntfIntfR, (*decFnInfo).fastpathDecMapIntfIntfR) + fn(map[interface{}]string(nil), (*encFnInfo).fastpathEncMapIntfStringR, (*decFnInfo).fastpathDecMapIntfStringR) + fn(map[interface{}]uint(nil), (*encFnInfo).fastpathEncMapIntfUintR, (*decFnInfo).fastpathDecMapIntfUintR) + fn(map[interface{}]uint8(nil), (*encFnInfo).fastpathEncMapIntfUint8R, (*decFnInfo).fastpathDecMapIntfUint8R) + fn(map[interface{}]uint16(nil), (*encFnInfo).fastpathEncMapIntfUint16R, (*decFnInfo).fastpathDecMapIntfUint16R) + fn(map[interface{}]uint32(nil), (*encFnInfo).fastpathEncMapIntfUint32R, (*decFnInfo).fastpathDecMapIntfUint32R) + fn(map[interface{}]uint64(nil), (*encFnInfo).fastpathEncMapIntfUint64R, (*decFnInfo).fastpathDecMapIntfUint64R) + fn(map[interface{}]uintptr(nil), (*encFnInfo).fastpathEncMapIntfUintptrR, (*decFnInfo).fastpathDecMapIntfUintptrR) + fn(map[interface{}]int(nil), (*encFnInfo).fastpathEncMapIntfIntR, (*decFnInfo).fastpathDecMapIntfIntR) + fn(map[interface{}]int8(nil), (*encFnInfo).fastpathEncMapIntfInt8R, (*decFnInfo).fastpathDecMapIntfInt8R) + fn(map[interface{}]int16(nil), (*encFnInfo).fastpathEncMapIntfInt16R, (*decFnInfo).fastpathDecMapIntfInt16R) + fn(map[interface{}]int32(nil), (*encFnInfo).fastpathEncMapIntfInt32R, (*decFnInfo).fastpathDecMapIntfInt32R) + fn(map[interface{}]int64(nil), (*encFnInfo).fastpathEncMapIntfInt64R, (*decFnInfo).fastpathDecMapIntfInt64R) + fn(map[interface{}]float32(nil), (*encFnInfo).fastpathEncMapIntfFloat32R, (*decFnInfo).fastpathDecMapIntfFloat32R) + fn(map[interface{}]float64(nil), (*encFnInfo).fastpathEncMapIntfFloat64R, (*decFnInfo).fastpathDecMapIntfFloat64R) + fn(map[interface{}]bool(nil), (*encFnInfo).fastpathEncMapIntfBoolR, (*decFnInfo).fastpathDecMapIntfBoolR) + fn(map[string]interface{}(nil), (*encFnInfo).fastpathEncMapStringIntfR, (*decFnInfo).fastpathDecMapStringIntfR) + fn(map[string]string(nil), (*encFnInfo).fastpathEncMapStringStringR, (*decFnInfo).fastpathDecMapStringStringR) + fn(map[string]uint(nil), (*encFnInfo).fastpathEncMapStringUintR, (*decFnInfo).fastpathDecMapStringUintR) + fn(map[string]uint8(nil), (*encFnInfo).fastpathEncMapStringUint8R, (*decFnInfo).fastpathDecMapStringUint8R) + fn(map[string]uint16(nil), (*encFnInfo).fastpathEncMapStringUint16R, (*decFnInfo).fastpathDecMapStringUint16R) + fn(map[string]uint32(nil), (*encFnInfo).fastpathEncMapStringUint32R, (*decFnInfo).fastpathDecMapStringUint32R) + fn(map[string]uint64(nil), (*encFnInfo).fastpathEncMapStringUint64R, (*decFnInfo).fastpathDecMapStringUint64R) + fn(map[string]uintptr(nil), (*encFnInfo).fastpathEncMapStringUintptrR, (*decFnInfo).fastpathDecMapStringUintptrR) + fn(map[string]int(nil), (*encFnInfo).fastpathEncMapStringIntR, (*decFnInfo).fastpathDecMapStringIntR) + fn(map[string]int8(nil), (*encFnInfo).fastpathEncMapStringInt8R, (*decFnInfo).fastpathDecMapStringInt8R) + fn(map[string]int16(nil), (*encFnInfo).fastpathEncMapStringInt16R, (*decFnInfo).fastpathDecMapStringInt16R) + fn(map[string]int32(nil), (*encFnInfo).fastpathEncMapStringInt32R, (*decFnInfo).fastpathDecMapStringInt32R) + fn(map[string]int64(nil), (*encFnInfo).fastpathEncMapStringInt64R, (*decFnInfo).fastpathDecMapStringInt64R) + fn(map[string]float32(nil), (*encFnInfo).fastpathEncMapStringFloat32R, (*decFnInfo).fastpathDecMapStringFloat32R) + fn(map[string]float64(nil), (*encFnInfo).fastpathEncMapStringFloat64R, (*decFnInfo).fastpathDecMapStringFloat64R) + fn(map[string]bool(nil), (*encFnInfo).fastpathEncMapStringBoolR, (*decFnInfo).fastpathDecMapStringBoolR) + fn(map[float32]interface{}(nil), (*encFnInfo).fastpathEncMapFloat32IntfR, (*decFnInfo).fastpathDecMapFloat32IntfR) + fn(map[float32]string(nil), (*encFnInfo).fastpathEncMapFloat32StringR, (*decFnInfo).fastpathDecMapFloat32StringR) + fn(map[float32]uint(nil), (*encFnInfo).fastpathEncMapFloat32UintR, (*decFnInfo).fastpathDecMapFloat32UintR) + fn(map[float32]uint8(nil), (*encFnInfo).fastpathEncMapFloat32Uint8R, (*decFnInfo).fastpathDecMapFloat32Uint8R) + fn(map[float32]uint16(nil), (*encFnInfo).fastpathEncMapFloat32Uint16R, (*decFnInfo).fastpathDecMapFloat32Uint16R) + fn(map[float32]uint32(nil), (*encFnInfo).fastpathEncMapFloat32Uint32R, (*decFnInfo).fastpathDecMapFloat32Uint32R) + fn(map[float32]uint64(nil), (*encFnInfo).fastpathEncMapFloat32Uint64R, (*decFnInfo).fastpathDecMapFloat32Uint64R) + fn(map[float32]uintptr(nil), (*encFnInfo).fastpathEncMapFloat32UintptrR, (*decFnInfo).fastpathDecMapFloat32UintptrR) + fn(map[float32]int(nil), (*encFnInfo).fastpathEncMapFloat32IntR, (*decFnInfo).fastpathDecMapFloat32IntR) + fn(map[float32]int8(nil), (*encFnInfo).fastpathEncMapFloat32Int8R, (*decFnInfo).fastpathDecMapFloat32Int8R) + fn(map[float32]int16(nil), (*encFnInfo).fastpathEncMapFloat32Int16R, (*decFnInfo).fastpathDecMapFloat32Int16R) + fn(map[float32]int32(nil), (*encFnInfo).fastpathEncMapFloat32Int32R, (*decFnInfo).fastpathDecMapFloat32Int32R) + fn(map[float32]int64(nil), (*encFnInfo).fastpathEncMapFloat32Int64R, (*decFnInfo).fastpathDecMapFloat32Int64R) + fn(map[float32]float32(nil), (*encFnInfo).fastpathEncMapFloat32Float32R, (*decFnInfo).fastpathDecMapFloat32Float32R) + fn(map[float32]float64(nil), (*encFnInfo).fastpathEncMapFloat32Float64R, (*decFnInfo).fastpathDecMapFloat32Float64R) + fn(map[float32]bool(nil), (*encFnInfo).fastpathEncMapFloat32BoolR, (*decFnInfo).fastpathDecMapFloat32BoolR) + fn(map[float64]interface{}(nil), (*encFnInfo).fastpathEncMapFloat64IntfR, (*decFnInfo).fastpathDecMapFloat64IntfR) + fn(map[float64]string(nil), (*encFnInfo).fastpathEncMapFloat64StringR, (*decFnInfo).fastpathDecMapFloat64StringR) + fn(map[float64]uint(nil), (*encFnInfo).fastpathEncMapFloat64UintR, (*decFnInfo).fastpathDecMapFloat64UintR) + fn(map[float64]uint8(nil), (*encFnInfo).fastpathEncMapFloat64Uint8R, (*decFnInfo).fastpathDecMapFloat64Uint8R) + fn(map[float64]uint16(nil), (*encFnInfo).fastpathEncMapFloat64Uint16R, (*decFnInfo).fastpathDecMapFloat64Uint16R) + fn(map[float64]uint32(nil), (*encFnInfo).fastpathEncMapFloat64Uint32R, (*decFnInfo).fastpathDecMapFloat64Uint32R) + fn(map[float64]uint64(nil), (*encFnInfo).fastpathEncMapFloat64Uint64R, (*decFnInfo).fastpathDecMapFloat64Uint64R) + fn(map[float64]uintptr(nil), (*encFnInfo).fastpathEncMapFloat64UintptrR, (*decFnInfo).fastpathDecMapFloat64UintptrR) + fn(map[float64]int(nil), (*encFnInfo).fastpathEncMapFloat64IntR, (*decFnInfo).fastpathDecMapFloat64IntR) + fn(map[float64]int8(nil), (*encFnInfo).fastpathEncMapFloat64Int8R, (*decFnInfo).fastpathDecMapFloat64Int8R) + fn(map[float64]int16(nil), (*encFnInfo).fastpathEncMapFloat64Int16R, (*decFnInfo).fastpathDecMapFloat64Int16R) + fn(map[float64]int32(nil), (*encFnInfo).fastpathEncMapFloat64Int32R, (*decFnInfo).fastpathDecMapFloat64Int32R) + fn(map[float64]int64(nil), (*encFnInfo).fastpathEncMapFloat64Int64R, (*decFnInfo).fastpathDecMapFloat64Int64R) + fn(map[float64]float32(nil), (*encFnInfo).fastpathEncMapFloat64Float32R, (*decFnInfo).fastpathDecMapFloat64Float32R) + fn(map[float64]float64(nil), (*encFnInfo).fastpathEncMapFloat64Float64R, (*decFnInfo).fastpathDecMapFloat64Float64R) + fn(map[float64]bool(nil), (*encFnInfo).fastpathEncMapFloat64BoolR, (*decFnInfo).fastpathDecMapFloat64BoolR) + fn(map[uint]interface{}(nil), (*encFnInfo).fastpathEncMapUintIntfR, (*decFnInfo).fastpathDecMapUintIntfR) + fn(map[uint]string(nil), (*encFnInfo).fastpathEncMapUintStringR, (*decFnInfo).fastpathDecMapUintStringR) + fn(map[uint]uint(nil), (*encFnInfo).fastpathEncMapUintUintR, (*decFnInfo).fastpathDecMapUintUintR) + fn(map[uint]uint8(nil), (*encFnInfo).fastpathEncMapUintUint8R, (*decFnInfo).fastpathDecMapUintUint8R) + fn(map[uint]uint16(nil), (*encFnInfo).fastpathEncMapUintUint16R, (*decFnInfo).fastpathDecMapUintUint16R) + fn(map[uint]uint32(nil), (*encFnInfo).fastpathEncMapUintUint32R, (*decFnInfo).fastpathDecMapUintUint32R) + fn(map[uint]uint64(nil), (*encFnInfo).fastpathEncMapUintUint64R, (*decFnInfo).fastpathDecMapUintUint64R) + fn(map[uint]uintptr(nil), (*encFnInfo).fastpathEncMapUintUintptrR, (*decFnInfo).fastpathDecMapUintUintptrR) + fn(map[uint]int(nil), (*encFnInfo).fastpathEncMapUintIntR, (*decFnInfo).fastpathDecMapUintIntR) + fn(map[uint]int8(nil), (*encFnInfo).fastpathEncMapUintInt8R, (*decFnInfo).fastpathDecMapUintInt8R) + fn(map[uint]int16(nil), (*encFnInfo).fastpathEncMapUintInt16R, (*decFnInfo).fastpathDecMapUintInt16R) + fn(map[uint]int32(nil), (*encFnInfo).fastpathEncMapUintInt32R, (*decFnInfo).fastpathDecMapUintInt32R) + fn(map[uint]int64(nil), (*encFnInfo).fastpathEncMapUintInt64R, (*decFnInfo).fastpathDecMapUintInt64R) + fn(map[uint]float32(nil), (*encFnInfo).fastpathEncMapUintFloat32R, (*decFnInfo).fastpathDecMapUintFloat32R) + fn(map[uint]float64(nil), (*encFnInfo).fastpathEncMapUintFloat64R, (*decFnInfo).fastpathDecMapUintFloat64R) + fn(map[uint]bool(nil), (*encFnInfo).fastpathEncMapUintBoolR, (*decFnInfo).fastpathDecMapUintBoolR) + fn(map[uint8]interface{}(nil), (*encFnInfo).fastpathEncMapUint8IntfR, (*decFnInfo).fastpathDecMapUint8IntfR) + fn(map[uint8]string(nil), (*encFnInfo).fastpathEncMapUint8StringR, (*decFnInfo).fastpathDecMapUint8StringR) + fn(map[uint8]uint(nil), (*encFnInfo).fastpathEncMapUint8UintR, (*decFnInfo).fastpathDecMapUint8UintR) + fn(map[uint8]uint8(nil), (*encFnInfo).fastpathEncMapUint8Uint8R, (*decFnInfo).fastpathDecMapUint8Uint8R) + fn(map[uint8]uint16(nil), (*encFnInfo).fastpathEncMapUint8Uint16R, (*decFnInfo).fastpathDecMapUint8Uint16R) + fn(map[uint8]uint32(nil), (*encFnInfo).fastpathEncMapUint8Uint32R, (*decFnInfo).fastpathDecMapUint8Uint32R) + fn(map[uint8]uint64(nil), (*encFnInfo).fastpathEncMapUint8Uint64R, (*decFnInfo).fastpathDecMapUint8Uint64R) + fn(map[uint8]uintptr(nil), (*encFnInfo).fastpathEncMapUint8UintptrR, (*decFnInfo).fastpathDecMapUint8UintptrR) + fn(map[uint8]int(nil), (*encFnInfo).fastpathEncMapUint8IntR, (*decFnInfo).fastpathDecMapUint8IntR) + fn(map[uint8]int8(nil), (*encFnInfo).fastpathEncMapUint8Int8R, (*decFnInfo).fastpathDecMapUint8Int8R) + fn(map[uint8]int16(nil), (*encFnInfo).fastpathEncMapUint8Int16R, (*decFnInfo).fastpathDecMapUint8Int16R) + fn(map[uint8]int32(nil), (*encFnInfo).fastpathEncMapUint8Int32R, (*decFnInfo).fastpathDecMapUint8Int32R) + fn(map[uint8]int64(nil), (*encFnInfo).fastpathEncMapUint8Int64R, (*decFnInfo).fastpathDecMapUint8Int64R) + fn(map[uint8]float32(nil), (*encFnInfo).fastpathEncMapUint8Float32R, (*decFnInfo).fastpathDecMapUint8Float32R) + fn(map[uint8]float64(nil), (*encFnInfo).fastpathEncMapUint8Float64R, (*decFnInfo).fastpathDecMapUint8Float64R) + fn(map[uint8]bool(nil), (*encFnInfo).fastpathEncMapUint8BoolR, (*decFnInfo).fastpathDecMapUint8BoolR) + fn(map[uint16]interface{}(nil), (*encFnInfo).fastpathEncMapUint16IntfR, (*decFnInfo).fastpathDecMapUint16IntfR) + fn(map[uint16]string(nil), (*encFnInfo).fastpathEncMapUint16StringR, (*decFnInfo).fastpathDecMapUint16StringR) + fn(map[uint16]uint(nil), (*encFnInfo).fastpathEncMapUint16UintR, (*decFnInfo).fastpathDecMapUint16UintR) + fn(map[uint16]uint8(nil), (*encFnInfo).fastpathEncMapUint16Uint8R, (*decFnInfo).fastpathDecMapUint16Uint8R) + fn(map[uint16]uint16(nil), (*encFnInfo).fastpathEncMapUint16Uint16R, (*decFnInfo).fastpathDecMapUint16Uint16R) + fn(map[uint16]uint32(nil), (*encFnInfo).fastpathEncMapUint16Uint32R, (*decFnInfo).fastpathDecMapUint16Uint32R) + fn(map[uint16]uint64(nil), (*encFnInfo).fastpathEncMapUint16Uint64R, (*decFnInfo).fastpathDecMapUint16Uint64R) + fn(map[uint16]uintptr(nil), (*encFnInfo).fastpathEncMapUint16UintptrR, (*decFnInfo).fastpathDecMapUint16UintptrR) + fn(map[uint16]int(nil), (*encFnInfo).fastpathEncMapUint16IntR, (*decFnInfo).fastpathDecMapUint16IntR) + fn(map[uint16]int8(nil), (*encFnInfo).fastpathEncMapUint16Int8R, (*decFnInfo).fastpathDecMapUint16Int8R) + fn(map[uint16]int16(nil), (*encFnInfo).fastpathEncMapUint16Int16R, (*decFnInfo).fastpathDecMapUint16Int16R) + fn(map[uint16]int32(nil), (*encFnInfo).fastpathEncMapUint16Int32R, (*decFnInfo).fastpathDecMapUint16Int32R) + fn(map[uint16]int64(nil), (*encFnInfo).fastpathEncMapUint16Int64R, (*decFnInfo).fastpathDecMapUint16Int64R) + fn(map[uint16]float32(nil), (*encFnInfo).fastpathEncMapUint16Float32R, (*decFnInfo).fastpathDecMapUint16Float32R) + fn(map[uint16]float64(nil), (*encFnInfo).fastpathEncMapUint16Float64R, (*decFnInfo).fastpathDecMapUint16Float64R) + fn(map[uint16]bool(nil), (*encFnInfo).fastpathEncMapUint16BoolR, (*decFnInfo).fastpathDecMapUint16BoolR) + fn(map[uint32]interface{}(nil), (*encFnInfo).fastpathEncMapUint32IntfR, (*decFnInfo).fastpathDecMapUint32IntfR) + fn(map[uint32]string(nil), (*encFnInfo).fastpathEncMapUint32StringR, (*decFnInfo).fastpathDecMapUint32StringR) + fn(map[uint32]uint(nil), (*encFnInfo).fastpathEncMapUint32UintR, (*decFnInfo).fastpathDecMapUint32UintR) + fn(map[uint32]uint8(nil), (*encFnInfo).fastpathEncMapUint32Uint8R, (*decFnInfo).fastpathDecMapUint32Uint8R) + fn(map[uint32]uint16(nil), (*encFnInfo).fastpathEncMapUint32Uint16R, (*decFnInfo).fastpathDecMapUint32Uint16R) + fn(map[uint32]uint32(nil), (*encFnInfo).fastpathEncMapUint32Uint32R, (*decFnInfo).fastpathDecMapUint32Uint32R) + fn(map[uint32]uint64(nil), (*encFnInfo).fastpathEncMapUint32Uint64R, (*decFnInfo).fastpathDecMapUint32Uint64R) + fn(map[uint32]uintptr(nil), (*encFnInfo).fastpathEncMapUint32UintptrR, (*decFnInfo).fastpathDecMapUint32UintptrR) + fn(map[uint32]int(nil), (*encFnInfo).fastpathEncMapUint32IntR, (*decFnInfo).fastpathDecMapUint32IntR) + fn(map[uint32]int8(nil), (*encFnInfo).fastpathEncMapUint32Int8R, (*decFnInfo).fastpathDecMapUint32Int8R) + fn(map[uint32]int16(nil), (*encFnInfo).fastpathEncMapUint32Int16R, (*decFnInfo).fastpathDecMapUint32Int16R) + fn(map[uint32]int32(nil), (*encFnInfo).fastpathEncMapUint32Int32R, (*decFnInfo).fastpathDecMapUint32Int32R) + fn(map[uint32]int64(nil), (*encFnInfo).fastpathEncMapUint32Int64R, (*decFnInfo).fastpathDecMapUint32Int64R) + fn(map[uint32]float32(nil), (*encFnInfo).fastpathEncMapUint32Float32R, (*decFnInfo).fastpathDecMapUint32Float32R) + fn(map[uint32]float64(nil), (*encFnInfo).fastpathEncMapUint32Float64R, (*decFnInfo).fastpathDecMapUint32Float64R) + fn(map[uint32]bool(nil), (*encFnInfo).fastpathEncMapUint32BoolR, (*decFnInfo).fastpathDecMapUint32BoolR) + fn(map[uint64]interface{}(nil), (*encFnInfo).fastpathEncMapUint64IntfR, (*decFnInfo).fastpathDecMapUint64IntfR) + fn(map[uint64]string(nil), (*encFnInfo).fastpathEncMapUint64StringR, (*decFnInfo).fastpathDecMapUint64StringR) + fn(map[uint64]uint(nil), (*encFnInfo).fastpathEncMapUint64UintR, (*decFnInfo).fastpathDecMapUint64UintR) + fn(map[uint64]uint8(nil), (*encFnInfo).fastpathEncMapUint64Uint8R, (*decFnInfo).fastpathDecMapUint64Uint8R) + fn(map[uint64]uint16(nil), (*encFnInfo).fastpathEncMapUint64Uint16R, (*decFnInfo).fastpathDecMapUint64Uint16R) + fn(map[uint64]uint32(nil), (*encFnInfo).fastpathEncMapUint64Uint32R, (*decFnInfo).fastpathDecMapUint64Uint32R) + fn(map[uint64]uint64(nil), (*encFnInfo).fastpathEncMapUint64Uint64R, (*decFnInfo).fastpathDecMapUint64Uint64R) + fn(map[uint64]uintptr(nil), (*encFnInfo).fastpathEncMapUint64UintptrR, (*decFnInfo).fastpathDecMapUint64UintptrR) + fn(map[uint64]int(nil), (*encFnInfo).fastpathEncMapUint64IntR, (*decFnInfo).fastpathDecMapUint64IntR) + fn(map[uint64]int8(nil), (*encFnInfo).fastpathEncMapUint64Int8R, (*decFnInfo).fastpathDecMapUint64Int8R) + fn(map[uint64]int16(nil), (*encFnInfo).fastpathEncMapUint64Int16R, (*decFnInfo).fastpathDecMapUint64Int16R) + fn(map[uint64]int32(nil), (*encFnInfo).fastpathEncMapUint64Int32R, (*decFnInfo).fastpathDecMapUint64Int32R) + fn(map[uint64]int64(nil), (*encFnInfo).fastpathEncMapUint64Int64R, (*decFnInfo).fastpathDecMapUint64Int64R) + fn(map[uint64]float32(nil), (*encFnInfo).fastpathEncMapUint64Float32R, (*decFnInfo).fastpathDecMapUint64Float32R) + fn(map[uint64]float64(nil), (*encFnInfo).fastpathEncMapUint64Float64R, (*decFnInfo).fastpathDecMapUint64Float64R) + fn(map[uint64]bool(nil), (*encFnInfo).fastpathEncMapUint64BoolR, (*decFnInfo).fastpathDecMapUint64BoolR) + fn(map[uintptr]interface{}(nil), (*encFnInfo).fastpathEncMapUintptrIntfR, (*decFnInfo).fastpathDecMapUintptrIntfR) + fn(map[uintptr]string(nil), (*encFnInfo).fastpathEncMapUintptrStringR, (*decFnInfo).fastpathDecMapUintptrStringR) + fn(map[uintptr]uint(nil), (*encFnInfo).fastpathEncMapUintptrUintR, (*decFnInfo).fastpathDecMapUintptrUintR) + fn(map[uintptr]uint8(nil), (*encFnInfo).fastpathEncMapUintptrUint8R, (*decFnInfo).fastpathDecMapUintptrUint8R) + fn(map[uintptr]uint16(nil), (*encFnInfo).fastpathEncMapUintptrUint16R, (*decFnInfo).fastpathDecMapUintptrUint16R) + fn(map[uintptr]uint32(nil), (*encFnInfo).fastpathEncMapUintptrUint32R, (*decFnInfo).fastpathDecMapUintptrUint32R) + fn(map[uintptr]uint64(nil), (*encFnInfo).fastpathEncMapUintptrUint64R, (*decFnInfo).fastpathDecMapUintptrUint64R) + fn(map[uintptr]uintptr(nil), (*encFnInfo).fastpathEncMapUintptrUintptrR, (*decFnInfo).fastpathDecMapUintptrUintptrR) + fn(map[uintptr]int(nil), (*encFnInfo).fastpathEncMapUintptrIntR, (*decFnInfo).fastpathDecMapUintptrIntR) + fn(map[uintptr]int8(nil), (*encFnInfo).fastpathEncMapUintptrInt8R, (*decFnInfo).fastpathDecMapUintptrInt8R) + fn(map[uintptr]int16(nil), (*encFnInfo).fastpathEncMapUintptrInt16R, (*decFnInfo).fastpathDecMapUintptrInt16R) + fn(map[uintptr]int32(nil), (*encFnInfo).fastpathEncMapUintptrInt32R, (*decFnInfo).fastpathDecMapUintptrInt32R) + fn(map[uintptr]int64(nil), (*encFnInfo).fastpathEncMapUintptrInt64R, (*decFnInfo).fastpathDecMapUintptrInt64R) + fn(map[uintptr]float32(nil), (*encFnInfo).fastpathEncMapUintptrFloat32R, (*decFnInfo).fastpathDecMapUintptrFloat32R) + fn(map[uintptr]float64(nil), (*encFnInfo).fastpathEncMapUintptrFloat64R, (*decFnInfo).fastpathDecMapUintptrFloat64R) + fn(map[uintptr]bool(nil), (*encFnInfo).fastpathEncMapUintptrBoolR, (*decFnInfo).fastpathDecMapUintptrBoolR) + fn(map[int]interface{}(nil), (*encFnInfo).fastpathEncMapIntIntfR, (*decFnInfo).fastpathDecMapIntIntfR) + fn(map[int]string(nil), (*encFnInfo).fastpathEncMapIntStringR, (*decFnInfo).fastpathDecMapIntStringR) + fn(map[int]uint(nil), (*encFnInfo).fastpathEncMapIntUintR, (*decFnInfo).fastpathDecMapIntUintR) + fn(map[int]uint8(nil), (*encFnInfo).fastpathEncMapIntUint8R, (*decFnInfo).fastpathDecMapIntUint8R) + fn(map[int]uint16(nil), (*encFnInfo).fastpathEncMapIntUint16R, (*decFnInfo).fastpathDecMapIntUint16R) + fn(map[int]uint32(nil), (*encFnInfo).fastpathEncMapIntUint32R, (*decFnInfo).fastpathDecMapIntUint32R) + fn(map[int]uint64(nil), (*encFnInfo).fastpathEncMapIntUint64R, (*decFnInfo).fastpathDecMapIntUint64R) + fn(map[int]uintptr(nil), (*encFnInfo).fastpathEncMapIntUintptrR, (*decFnInfo).fastpathDecMapIntUintptrR) + fn(map[int]int(nil), (*encFnInfo).fastpathEncMapIntIntR, (*decFnInfo).fastpathDecMapIntIntR) + fn(map[int]int8(nil), (*encFnInfo).fastpathEncMapIntInt8R, (*decFnInfo).fastpathDecMapIntInt8R) + fn(map[int]int16(nil), (*encFnInfo).fastpathEncMapIntInt16R, (*decFnInfo).fastpathDecMapIntInt16R) + fn(map[int]int32(nil), (*encFnInfo).fastpathEncMapIntInt32R, (*decFnInfo).fastpathDecMapIntInt32R) + fn(map[int]int64(nil), (*encFnInfo).fastpathEncMapIntInt64R, (*decFnInfo).fastpathDecMapIntInt64R) + fn(map[int]float32(nil), (*encFnInfo).fastpathEncMapIntFloat32R, (*decFnInfo).fastpathDecMapIntFloat32R) + fn(map[int]float64(nil), (*encFnInfo).fastpathEncMapIntFloat64R, (*decFnInfo).fastpathDecMapIntFloat64R) + fn(map[int]bool(nil), (*encFnInfo).fastpathEncMapIntBoolR, (*decFnInfo).fastpathDecMapIntBoolR) + fn(map[int8]interface{}(nil), (*encFnInfo).fastpathEncMapInt8IntfR, (*decFnInfo).fastpathDecMapInt8IntfR) + fn(map[int8]string(nil), (*encFnInfo).fastpathEncMapInt8StringR, (*decFnInfo).fastpathDecMapInt8StringR) + fn(map[int8]uint(nil), (*encFnInfo).fastpathEncMapInt8UintR, (*decFnInfo).fastpathDecMapInt8UintR) + fn(map[int8]uint8(nil), (*encFnInfo).fastpathEncMapInt8Uint8R, (*decFnInfo).fastpathDecMapInt8Uint8R) + fn(map[int8]uint16(nil), (*encFnInfo).fastpathEncMapInt8Uint16R, (*decFnInfo).fastpathDecMapInt8Uint16R) + fn(map[int8]uint32(nil), (*encFnInfo).fastpathEncMapInt8Uint32R, (*decFnInfo).fastpathDecMapInt8Uint32R) + fn(map[int8]uint64(nil), (*encFnInfo).fastpathEncMapInt8Uint64R, (*decFnInfo).fastpathDecMapInt8Uint64R) + fn(map[int8]uintptr(nil), (*encFnInfo).fastpathEncMapInt8UintptrR, (*decFnInfo).fastpathDecMapInt8UintptrR) + fn(map[int8]int(nil), (*encFnInfo).fastpathEncMapInt8IntR, (*decFnInfo).fastpathDecMapInt8IntR) + fn(map[int8]int8(nil), (*encFnInfo).fastpathEncMapInt8Int8R, (*decFnInfo).fastpathDecMapInt8Int8R) + fn(map[int8]int16(nil), (*encFnInfo).fastpathEncMapInt8Int16R, (*decFnInfo).fastpathDecMapInt8Int16R) + fn(map[int8]int32(nil), (*encFnInfo).fastpathEncMapInt8Int32R, (*decFnInfo).fastpathDecMapInt8Int32R) + fn(map[int8]int64(nil), (*encFnInfo).fastpathEncMapInt8Int64R, (*decFnInfo).fastpathDecMapInt8Int64R) + fn(map[int8]float32(nil), (*encFnInfo).fastpathEncMapInt8Float32R, (*decFnInfo).fastpathDecMapInt8Float32R) + fn(map[int8]float64(nil), (*encFnInfo).fastpathEncMapInt8Float64R, (*decFnInfo).fastpathDecMapInt8Float64R) + fn(map[int8]bool(nil), (*encFnInfo).fastpathEncMapInt8BoolR, (*decFnInfo).fastpathDecMapInt8BoolR) + fn(map[int16]interface{}(nil), (*encFnInfo).fastpathEncMapInt16IntfR, (*decFnInfo).fastpathDecMapInt16IntfR) + fn(map[int16]string(nil), (*encFnInfo).fastpathEncMapInt16StringR, (*decFnInfo).fastpathDecMapInt16StringR) + fn(map[int16]uint(nil), (*encFnInfo).fastpathEncMapInt16UintR, (*decFnInfo).fastpathDecMapInt16UintR) + fn(map[int16]uint8(nil), (*encFnInfo).fastpathEncMapInt16Uint8R, (*decFnInfo).fastpathDecMapInt16Uint8R) + fn(map[int16]uint16(nil), (*encFnInfo).fastpathEncMapInt16Uint16R, (*decFnInfo).fastpathDecMapInt16Uint16R) + fn(map[int16]uint32(nil), (*encFnInfo).fastpathEncMapInt16Uint32R, (*decFnInfo).fastpathDecMapInt16Uint32R) + fn(map[int16]uint64(nil), (*encFnInfo).fastpathEncMapInt16Uint64R, (*decFnInfo).fastpathDecMapInt16Uint64R) + fn(map[int16]uintptr(nil), (*encFnInfo).fastpathEncMapInt16UintptrR, (*decFnInfo).fastpathDecMapInt16UintptrR) + fn(map[int16]int(nil), (*encFnInfo).fastpathEncMapInt16IntR, (*decFnInfo).fastpathDecMapInt16IntR) + fn(map[int16]int8(nil), (*encFnInfo).fastpathEncMapInt16Int8R, (*decFnInfo).fastpathDecMapInt16Int8R) + fn(map[int16]int16(nil), (*encFnInfo).fastpathEncMapInt16Int16R, (*decFnInfo).fastpathDecMapInt16Int16R) + fn(map[int16]int32(nil), (*encFnInfo).fastpathEncMapInt16Int32R, (*decFnInfo).fastpathDecMapInt16Int32R) + fn(map[int16]int64(nil), (*encFnInfo).fastpathEncMapInt16Int64R, (*decFnInfo).fastpathDecMapInt16Int64R) + fn(map[int16]float32(nil), (*encFnInfo).fastpathEncMapInt16Float32R, (*decFnInfo).fastpathDecMapInt16Float32R) + fn(map[int16]float64(nil), (*encFnInfo).fastpathEncMapInt16Float64R, (*decFnInfo).fastpathDecMapInt16Float64R) + fn(map[int16]bool(nil), (*encFnInfo).fastpathEncMapInt16BoolR, (*decFnInfo).fastpathDecMapInt16BoolR) + fn(map[int32]interface{}(nil), (*encFnInfo).fastpathEncMapInt32IntfR, (*decFnInfo).fastpathDecMapInt32IntfR) + fn(map[int32]string(nil), (*encFnInfo).fastpathEncMapInt32StringR, (*decFnInfo).fastpathDecMapInt32StringR) + fn(map[int32]uint(nil), (*encFnInfo).fastpathEncMapInt32UintR, (*decFnInfo).fastpathDecMapInt32UintR) + fn(map[int32]uint8(nil), (*encFnInfo).fastpathEncMapInt32Uint8R, (*decFnInfo).fastpathDecMapInt32Uint8R) + fn(map[int32]uint16(nil), (*encFnInfo).fastpathEncMapInt32Uint16R, (*decFnInfo).fastpathDecMapInt32Uint16R) + fn(map[int32]uint32(nil), (*encFnInfo).fastpathEncMapInt32Uint32R, (*decFnInfo).fastpathDecMapInt32Uint32R) + fn(map[int32]uint64(nil), (*encFnInfo).fastpathEncMapInt32Uint64R, (*decFnInfo).fastpathDecMapInt32Uint64R) + fn(map[int32]uintptr(nil), (*encFnInfo).fastpathEncMapInt32UintptrR, (*decFnInfo).fastpathDecMapInt32UintptrR) + fn(map[int32]int(nil), (*encFnInfo).fastpathEncMapInt32IntR, (*decFnInfo).fastpathDecMapInt32IntR) + fn(map[int32]int8(nil), (*encFnInfo).fastpathEncMapInt32Int8R, (*decFnInfo).fastpathDecMapInt32Int8R) + fn(map[int32]int16(nil), (*encFnInfo).fastpathEncMapInt32Int16R, (*decFnInfo).fastpathDecMapInt32Int16R) + fn(map[int32]int32(nil), (*encFnInfo).fastpathEncMapInt32Int32R, (*decFnInfo).fastpathDecMapInt32Int32R) + fn(map[int32]int64(nil), (*encFnInfo).fastpathEncMapInt32Int64R, (*decFnInfo).fastpathDecMapInt32Int64R) + fn(map[int32]float32(nil), (*encFnInfo).fastpathEncMapInt32Float32R, (*decFnInfo).fastpathDecMapInt32Float32R) + fn(map[int32]float64(nil), (*encFnInfo).fastpathEncMapInt32Float64R, (*decFnInfo).fastpathDecMapInt32Float64R) + fn(map[int32]bool(nil), (*encFnInfo).fastpathEncMapInt32BoolR, (*decFnInfo).fastpathDecMapInt32BoolR) + fn(map[int64]interface{}(nil), (*encFnInfo).fastpathEncMapInt64IntfR, (*decFnInfo).fastpathDecMapInt64IntfR) + fn(map[int64]string(nil), (*encFnInfo).fastpathEncMapInt64StringR, (*decFnInfo).fastpathDecMapInt64StringR) + fn(map[int64]uint(nil), (*encFnInfo).fastpathEncMapInt64UintR, (*decFnInfo).fastpathDecMapInt64UintR) + fn(map[int64]uint8(nil), (*encFnInfo).fastpathEncMapInt64Uint8R, (*decFnInfo).fastpathDecMapInt64Uint8R) + fn(map[int64]uint16(nil), (*encFnInfo).fastpathEncMapInt64Uint16R, (*decFnInfo).fastpathDecMapInt64Uint16R) + fn(map[int64]uint32(nil), (*encFnInfo).fastpathEncMapInt64Uint32R, (*decFnInfo).fastpathDecMapInt64Uint32R) + fn(map[int64]uint64(nil), (*encFnInfo).fastpathEncMapInt64Uint64R, (*decFnInfo).fastpathDecMapInt64Uint64R) + fn(map[int64]uintptr(nil), (*encFnInfo).fastpathEncMapInt64UintptrR, (*decFnInfo).fastpathDecMapInt64UintptrR) + fn(map[int64]int(nil), (*encFnInfo).fastpathEncMapInt64IntR, (*decFnInfo).fastpathDecMapInt64IntR) + fn(map[int64]int8(nil), (*encFnInfo).fastpathEncMapInt64Int8R, (*decFnInfo).fastpathDecMapInt64Int8R) + fn(map[int64]int16(nil), (*encFnInfo).fastpathEncMapInt64Int16R, (*decFnInfo).fastpathDecMapInt64Int16R) + fn(map[int64]int32(nil), (*encFnInfo).fastpathEncMapInt64Int32R, (*decFnInfo).fastpathDecMapInt64Int32R) + fn(map[int64]int64(nil), (*encFnInfo).fastpathEncMapInt64Int64R, (*decFnInfo).fastpathDecMapInt64Int64R) + fn(map[int64]float32(nil), (*encFnInfo).fastpathEncMapInt64Float32R, (*decFnInfo).fastpathDecMapInt64Float32R) + fn(map[int64]float64(nil), (*encFnInfo).fastpathEncMapInt64Float64R, (*decFnInfo).fastpathDecMapInt64Float64R) + fn(map[int64]bool(nil), (*encFnInfo).fastpathEncMapInt64BoolR, (*decFnInfo).fastpathDecMapInt64BoolR) + fn(map[bool]interface{}(nil), (*encFnInfo).fastpathEncMapBoolIntfR, (*decFnInfo).fastpathDecMapBoolIntfR) + fn(map[bool]string(nil), (*encFnInfo).fastpathEncMapBoolStringR, (*decFnInfo).fastpathDecMapBoolStringR) + fn(map[bool]uint(nil), (*encFnInfo).fastpathEncMapBoolUintR, (*decFnInfo).fastpathDecMapBoolUintR) + fn(map[bool]uint8(nil), (*encFnInfo).fastpathEncMapBoolUint8R, (*decFnInfo).fastpathDecMapBoolUint8R) + fn(map[bool]uint16(nil), (*encFnInfo).fastpathEncMapBoolUint16R, (*decFnInfo).fastpathDecMapBoolUint16R) + fn(map[bool]uint32(nil), (*encFnInfo).fastpathEncMapBoolUint32R, (*decFnInfo).fastpathDecMapBoolUint32R) + fn(map[bool]uint64(nil), (*encFnInfo).fastpathEncMapBoolUint64R, (*decFnInfo).fastpathDecMapBoolUint64R) + fn(map[bool]uintptr(nil), (*encFnInfo).fastpathEncMapBoolUintptrR, (*decFnInfo).fastpathDecMapBoolUintptrR) + fn(map[bool]int(nil), (*encFnInfo).fastpathEncMapBoolIntR, (*decFnInfo).fastpathDecMapBoolIntR) + fn(map[bool]int8(nil), (*encFnInfo).fastpathEncMapBoolInt8R, (*decFnInfo).fastpathDecMapBoolInt8R) + fn(map[bool]int16(nil), (*encFnInfo).fastpathEncMapBoolInt16R, (*decFnInfo).fastpathDecMapBoolInt16R) + fn(map[bool]int32(nil), (*encFnInfo).fastpathEncMapBoolInt32R, (*decFnInfo).fastpathDecMapBoolInt32R) + fn(map[bool]int64(nil), (*encFnInfo).fastpathEncMapBoolInt64R, (*decFnInfo).fastpathDecMapBoolInt64R) + fn(map[bool]float32(nil), (*encFnInfo).fastpathEncMapBoolFloat32R, (*decFnInfo).fastpathDecMapBoolFloat32R) + fn(map[bool]float64(nil), (*encFnInfo).fastpathEncMapBoolFloat64R, (*decFnInfo).fastpathDecMapBoolFloat64R) + fn(map[bool]bool(nil), (*encFnInfo).fastpathEncMapBoolBoolR, (*decFnInfo).fastpathDecMapBoolBoolR) sort.Sort(fastpathAslice(fastpathAV[:])) } @@ -341,6 +373,9 @@ func init() { // -- -- fast path type switch func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { + if !fastpathEnabled { + return false + } switch v := iv.(type) { case []interface{}: @@ -383,6 +418,11 @@ func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { case *map[interface{}]uint64: fastpathTV.EncMapIntfUint64V(*v, fastpathCheckNilTrue, e) + case map[interface{}]uintptr: + fastpathTV.EncMapIntfUintptrV(v, fastpathCheckNilTrue, e) + case *map[interface{}]uintptr: + fastpathTV.EncMapIntfUintptrV(*v, fastpathCheckNilTrue, e) + case map[interface{}]int: fastpathTV.EncMapIntfIntV(v, fastpathCheckNilTrue, e) case *map[interface{}]int: @@ -463,6 +503,11 @@ func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { case *map[string]uint64: fastpathTV.EncMapStringUint64V(*v, fastpathCheckNilTrue, e) + case map[string]uintptr: + fastpathTV.EncMapStringUintptrV(v, fastpathCheckNilTrue, e) + case *map[string]uintptr: + fastpathTV.EncMapStringUintptrV(*v, fastpathCheckNilTrue, e) + case map[string]int: fastpathTV.EncMapStringIntV(v, fastpathCheckNilTrue, e) case *map[string]int: @@ -543,6 +588,11 @@ func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { case *map[float32]uint64: fastpathTV.EncMapFloat32Uint64V(*v, fastpathCheckNilTrue, e) + case map[float32]uintptr: + fastpathTV.EncMapFloat32UintptrV(v, fastpathCheckNilTrue, e) + case *map[float32]uintptr: + fastpathTV.EncMapFloat32UintptrV(*v, fastpathCheckNilTrue, e) + case map[float32]int: fastpathTV.EncMapFloat32IntV(v, fastpathCheckNilTrue, e) case *map[float32]int: @@ -623,6 +673,11 @@ func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { case *map[float64]uint64: fastpathTV.EncMapFloat64Uint64V(*v, fastpathCheckNilTrue, e) + case map[float64]uintptr: + fastpathTV.EncMapFloat64UintptrV(v, fastpathCheckNilTrue, e) + case *map[float64]uintptr: + fastpathTV.EncMapFloat64UintptrV(*v, fastpathCheckNilTrue, e) + case map[float64]int: fastpathTV.EncMapFloat64IntV(v, fastpathCheckNilTrue, e) case *map[float64]int: @@ -703,6 +758,11 @@ func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { case *map[uint]uint64: fastpathTV.EncMapUintUint64V(*v, fastpathCheckNilTrue, e) + case map[uint]uintptr: + fastpathTV.EncMapUintUintptrV(v, fastpathCheckNilTrue, e) + case *map[uint]uintptr: + fastpathTV.EncMapUintUintptrV(*v, fastpathCheckNilTrue, e) + case map[uint]int: fastpathTV.EncMapUintIntV(v, fastpathCheckNilTrue, e) case *map[uint]int: @@ -778,6 +838,11 @@ func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { case *map[uint8]uint64: fastpathTV.EncMapUint8Uint64V(*v, fastpathCheckNilTrue, e) + case map[uint8]uintptr: + fastpathTV.EncMapUint8UintptrV(v, fastpathCheckNilTrue, e) + case *map[uint8]uintptr: + fastpathTV.EncMapUint8UintptrV(*v, fastpathCheckNilTrue, e) + case map[uint8]int: fastpathTV.EncMapUint8IntV(v, fastpathCheckNilTrue, e) case *map[uint8]int: @@ -858,6 +923,11 @@ func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { case *map[uint16]uint64: fastpathTV.EncMapUint16Uint64V(*v, fastpathCheckNilTrue, e) + case map[uint16]uintptr: + fastpathTV.EncMapUint16UintptrV(v, fastpathCheckNilTrue, e) + case *map[uint16]uintptr: + fastpathTV.EncMapUint16UintptrV(*v, fastpathCheckNilTrue, e) + case map[uint16]int: fastpathTV.EncMapUint16IntV(v, fastpathCheckNilTrue, e) case *map[uint16]int: @@ -938,6 +1008,11 @@ func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { case *map[uint32]uint64: fastpathTV.EncMapUint32Uint64V(*v, fastpathCheckNilTrue, e) + case map[uint32]uintptr: + fastpathTV.EncMapUint32UintptrV(v, fastpathCheckNilTrue, e) + case *map[uint32]uintptr: + fastpathTV.EncMapUint32UintptrV(*v, fastpathCheckNilTrue, e) + case map[uint32]int: fastpathTV.EncMapUint32IntV(v, fastpathCheckNilTrue, e) case *map[uint32]int: @@ -1018,6 +1093,11 @@ func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { case *map[uint64]uint64: fastpathTV.EncMapUint64Uint64V(*v, fastpathCheckNilTrue, e) + case map[uint64]uintptr: + fastpathTV.EncMapUint64UintptrV(v, fastpathCheckNilTrue, e) + case *map[uint64]uintptr: + fastpathTV.EncMapUint64UintptrV(*v, fastpathCheckNilTrue, e) + case map[uint64]int: fastpathTV.EncMapUint64IntV(v, fastpathCheckNilTrue, e) case *map[uint64]int: @@ -1058,6 +1138,91 @@ func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { case *map[uint64]bool: fastpathTV.EncMapUint64BoolV(*v, fastpathCheckNilTrue, e) + case []uintptr: + fastpathTV.EncSliceUintptrV(v, fastpathCheckNilTrue, e) + case *[]uintptr: + fastpathTV.EncSliceUintptrV(*v, fastpathCheckNilTrue, e) + + case map[uintptr]interface{}: + fastpathTV.EncMapUintptrIntfV(v, fastpathCheckNilTrue, e) + case *map[uintptr]interface{}: + fastpathTV.EncMapUintptrIntfV(*v, fastpathCheckNilTrue, e) + + case map[uintptr]string: + fastpathTV.EncMapUintptrStringV(v, fastpathCheckNilTrue, e) + case *map[uintptr]string: + fastpathTV.EncMapUintptrStringV(*v, fastpathCheckNilTrue, e) + + case map[uintptr]uint: + fastpathTV.EncMapUintptrUintV(v, fastpathCheckNilTrue, e) + case *map[uintptr]uint: + fastpathTV.EncMapUintptrUintV(*v, fastpathCheckNilTrue, e) + + case map[uintptr]uint8: + fastpathTV.EncMapUintptrUint8V(v, fastpathCheckNilTrue, e) + case *map[uintptr]uint8: + fastpathTV.EncMapUintptrUint8V(*v, fastpathCheckNilTrue, e) + + case map[uintptr]uint16: + fastpathTV.EncMapUintptrUint16V(v, fastpathCheckNilTrue, e) + case *map[uintptr]uint16: + fastpathTV.EncMapUintptrUint16V(*v, fastpathCheckNilTrue, e) + + case map[uintptr]uint32: + fastpathTV.EncMapUintptrUint32V(v, fastpathCheckNilTrue, e) + case *map[uintptr]uint32: + fastpathTV.EncMapUintptrUint32V(*v, fastpathCheckNilTrue, e) + + case map[uintptr]uint64: + fastpathTV.EncMapUintptrUint64V(v, fastpathCheckNilTrue, e) + case *map[uintptr]uint64: + fastpathTV.EncMapUintptrUint64V(*v, fastpathCheckNilTrue, e) + + case map[uintptr]uintptr: + fastpathTV.EncMapUintptrUintptrV(v, fastpathCheckNilTrue, e) + case *map[uintptr]uintptr: + fastpathTV.EncMapUintptrUintptrV(*v, fastpathCheckNilTrue, e) + + case map[uintptr]int: + fastpathTV.EncMapUintptrIntV(v, fastpathCheckNilTrue, e) + case *map[uintptr]int: + fastpathTV.EncMapUintptrIntV(*v, fastpathCheckNilTrue, e) + + case map[uintptr]int8: + fastpathTV.EncMapUintptrInt8V(v, fastpathCheckNilTrue, e) + case *map[uintptr]int8: + fastpathTV.EncMapUintptrInt8V(*v, fastpathCheckNilTrue, e) + + case map[uintptr]int16: + fastpathTV.EncMapUintptrInt16V(v, fastpathCheckNilTrue, e) + case *map[uintptr]int16: + fastpathTV.EncMapUintptrInt16V(*v, fastpathCheckNilTrue, e) + + case map[uintptr]int32: + fastpathTV.EncMapUintptrInt32V(v, fastpathCheckNilTrue, e) + case *map[uintptr]int32: + fastpathTV.EncMapUintptrInt32V(*v, fastpathCheckNilTrue, e) + + case map[uintptr]int64: + fastpathTV.EncMapUintptrInt64V(v, fastpathCheckNilTrue, e) + case *map[uintptr]int64: + fastpathTV.EncMapUintptrInt64V(*v, fastpathCheckNilTrue, e) + + case map[uintptr]float32: + fastpathTV.EncMapUintptrFloat32V(v, fastpathCheckNilTrue, e) + case *map[uintptr]float32: + fastpathTV.EncMapUintptrFloat32V(*v, fastpathCheckNilTrue, e) + + case map[uintptr]float64: + fastpathTV.EncMapUintptrFloat64V(v, fastpathCheckNilTrue, e) + case *map[uintptr]float64: + fastpathTV.EncMapUintptrFloat64V(*v, fastpathCheckNilTrue, e) + + case map[uintptr]bool: + fastpathTV.EncMapUintptrBoolV(v, fastpathCheckNilTrue, e) + case *map[uintptr]bool: + fastpathTV.EncMapUintptrBoolV(*v, fastpathCheckNilTrue, e) + case []int: fastpathTV.EncSliceIntV(v, fastpathCheckNilTrue, e) case *[]int: @@ -1098,6 +1263,11 @@ func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { case *map[int]uint64: fastpathTV.EncMapIntUint64V(*v, fastpathCheckNilTrue, e) + case map[int]uintptr: + fastpathTV.EncMapIntUintptrV(v, fastpathCheckNilTrue, e) + case *map[int]uintptr: + fastpathTV.EncMapIntUintptrV(*v, fastpathCheckNilTrue, e) + case map[int]int: fastpathTV.EncMapIntIntV(v, fastpathCheckNilTrue, e) case *map[int]int: @@ -1178,6 +1348,11 @@ func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { case *map[int8]uint64: fastpathTV.EncMapInt8Uint64V(*v, fastpathCheckNilTrue, e) + case map[int8]uintptr: + fastpathTV.EncMapInt8UintptrV(v, fastpathCheckNilTrue, e) + case *map[int8]uintptr: + fastpathTV.EncMapInt8UintptrV(*v, fastpathCheckNilTrue, e) + case map[int8]int: fastpathTV.EncMapInt8IntV(v, fastpathCheckNilTrue, e) case *map[int8]int: @@ -1258,6 +1433,11 @@ func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { case *map[int16]uint64: fastpathTV.EncMapInt16Uint64V(*v, fastpathCheckNilTrue, e) + case map[int16]uintptr: + fastpathTV.EncMapInt16UintptrV(v, fastpathCheckNilTrue, e) + case *map[int16]uintptr: + fastpathTV.EncMapInt16UintptrV(*v, fastpathCheckNilTrue, e) + case map[int16]int: fastpathTV.EncMapInt16IntV(v, fastpathCheckNilTrue, e) case *map[int16]int: @@ -1338,6 +1518,11 @@ func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { case *map[int32]uint64: fastpathTV.EncMapInt32Uint64V(*v, fastpathCheckNilTrue, e) + case map[int32]uintptr: + fastpathTV.EncMapInt32UintptrV(v, fastpathCheckNilTrue, e) + case *map[int32]uintptr: + fastpathTV.EncMapInt32UintptrV(*v, fastpathCheckNilTrue, e) + case map[int32]int: fastpathTV.EncMapInt32IntV(v, fastpathCheckNilTrue, e) case *map[int32]int: @@ -1418,6 +1603,11 @@ func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { case *map[int64]uint64: fastpathTV.EncMapInt64Uint64V(*v, fastpathCheckNilTrue, e) + case map[int64]uintptr: + fastpathTV.EncMapInt64UintptrV(v, fastpathCheckNilTrue, e) + case *map[int64]uintptr: + fastpathTV.EncMapInt64UintptrV(*v, fastpathCheckNilTrue, e) + case map[int64]int: fastpathTV.EncMapInt64IntV(v, fastpathCheckNilTrue, e) case *map[int64]int: @@ -1498,6 +1688,11 @@ func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { case *map[bool]uint64: fastpathTV.EncMapBoolUint64V(*v, fastpathCheckNilTrue, e) + case map[bool]uintptr: + fastpathTV.EncMapBoolUintptrV(v, fastpathCheckNilTrue, e) + case *map[bool]uintptr: + fastpathTV.EncMapBoolUintptrV(*v, fastpathCheckNilTrue, e) + case map[bool]int: fastpathTV.EncMapBoolIntV(v, fastpathCheckNilTrue, e) case *map[bool]int: @@ -1539,12 +1734,16 @@ func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { fastpathTV.EncMapBoolBoolV(*v, fastpathCheckNilTrue, e) 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) { case []interface{}: @@ -1587,6 +1786,11 @@ func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool { case *[]uint64: fastpathTV.EncSliceUint64V(*v, fastpathCheckNilTrue, e) + case []uintptr: + fastpathTV.EncSliceUintptrV(v, fastpathCheckNilTrue, e) + case *[]uintptr: + fastpathTV.EncSliceUintptrV(*v, fastpathCheckNilTrue, e) + case []int: fastpathTV.EncSliceIntV(v, fastpathCheckNilTrue, e) case *[]int: @@ -1618,12 +1822,16 @@ func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool { fastpathTV.EncSliceBoolV(*v, fastpathCheckNilTrue, e) default: + _ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release) return false } return true } func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { + if !fastpathEnabled { + return false + } switch v := iv.(type) { case map[interface{}]interface{}: @@ -1661,6 +1869,11 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { case *map[interface{}]uint64: fastpathTV.EncMapIntfUint64V(*v, fastpathCheckNilTrue, e) + case map[interface{}]uintptr: + fastpathTV.EncMapIntfUintptrV(v, fastpathCheckNilTrue, e) + case *map[interface{}]uintptr: + fastpathTV.EncMapIntfUintptrV(*v, fastpathCheckNilTrue, e) + case map[interface{}]int: fastpathTV.EncMapIntfIntV(v, fastpathCheckNilTrue, e) case *map[interface{}]int: @@ -1736,6 +1949,11 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { case *map[string]uint64: fastpathTV.EncMapStringUint64V(*v, fastpathCheckNilTrue, e) + case map[string]uintptr: + fastpathTV.EncMapStringUintptrV(v, fastpathCheckNilTrue, e) + case *map[string]uintptr: + fastpathTV.EncMapStringUintptrV(*v, fastpathCheckNilTrue, e) + case map[string]int: fastpathTV.EncMapStringIntV(v, fastpathCheckNilTrue, e) case *map[string]int: @@ -1811,6 +2029,11 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { case *map[float32]uint64: fastpathTV.EncMapFloat32Uint64V(*v, fastpathCheckNilTrue, e) + case map[float32]uintptr: + fastpathTV.EncMapFloat32UintptrV(v, fastpathCheckNilTrue, e) + case *map[float32]uintptr: + fastpathTV.EncMapFloat32UintptrV(*v, fastpathCheckNilTrue, e) + case map[float32]int: fastpathTV.EncMapFloat32IntV(v, fastpathCheckNilTrue, e) case *map[float32]int: @@ -1886,6 +2109,11 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { case *map[float64]uint64: fastpathTV.EncMapFloat64Uint64V(*v, fastpathCheckNilTrue, e) + case map[float64]uintptr: + fastpathTV.EncMapFloat64UintptrV(v, fastpathCheckNilTrue, e) + case *map[float64]uintptr: + fastpathTV.EncMapFloat64UintptrV(*v, fastpathCheckNilTrue, e) + case map[float64]int: fastpathTV.EncMapFloat64IntV(v, fastpathCheckNilTrue, e) case *map[float64]int: @@ -1961,6 +2189,11 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { case *map[uint]uint64: fastpathTV.EncMapUintUint64V(*v, fastpathCheckNilTrue, e) + case map[uint]uintptr: + fastpathTV.EncMapUintUintptrV(v, fastpathCheckNilTrue, e) + case *map[uint]uintptr: + fastpathTV.EncMapUintUintptrV(*v, fastpathCheckNilTrue, e) + case map[uint]int: fastpathTV.EncMapUintIntV(v, fastpathCheckNilTrue, e) case *map[uint]int: @@ -2036,6 +2269,11 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { case *map[uint8]uint64: fastpathTV.EncMapUint8Uint64V(*v, fastpathCheckNilTrue, e) + case map[uint8]uintptr: + fastpathTV.EncMapUint8UintptrV(v, fastpathCheckNilTrue, e) + case *map[uint8]uintptr: + fastpathTV.EncMapUint8UintptrV(*v, fastpathCheckNilTrue, e) + case map[uint8]int: fastpathTV.EncMapUint8IntV(v, fastpathCheckNilTrue, e) case *map[uint8]int: @@ -2111,6 +2349,11 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { case *map[uint16]uint64: fastpathTV.EncMapUint16Uint64V(*v, fastpathCheckNilTrue, e) + case map[uint16]uintptr: + fastpathTV.EncMapUint16UintptrV(v, fastpathCheckNilTrue, e) + case *map[uint16]uintptr: + fastpathTV.EncMapUint16UintptrV(*v, fastpathCheckNilTrue, e) + case map[uint16]int: fastpathTV.EncMapUint16IntV(v, fastpathCheckNilTrue, e) case *map[uint16]int: @@ -2186,6 +2429,11 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { case *map[uint32]uint64: fastpathTV.EncMapUint32Uint64V(*v, fastpathCheckNilTrue, e) + case map[uint32]uintptr: + fastpathTV.EncMapUint32UintptrV(v, fastpathCheckNilTrue, e) + case *map[uint32]uintptr: + fastpathTV.EncMapUint32UintptrV(*v, fastpathCheckNilTrue, e) + case map[uint32]int: fastpathTV.EncMapUint32IntV(v, fastpathCheckNilTrue, e) case *map[uint32]int: @@ -2261,6 +2509,11 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { case *map[uint64]uint64: fastpathTV.EncMapUint64Uint64V(*v, fastpathCheckNilTrue, e) + case map[uint64]uintptr: + fastpathTV.EncMapUint64UintptrV(v, fastpathCheckNilTrue, e) + case *map[uint64]uintptr: + fastpathTV.EncMapUint64UintptrV(*v, fastpathCheckNilTrue, e) + case map[uint64]int: fastpathTV.EncMapUint64IntV(v, fastpathCheckNilTrue, e) case *map[uint64]int: @@ -2301,6 +2554,86 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { case *map[uint64]bool: fastpathTV.EncMapUint64BoolV(*v, fastpathCheckNilTrue, e) + case map[uintptr]interface{}: + fastpathTV.EncMapUintptrIntfV(v, fastpathCheckNilTrue, e) + case *map[uintptr]interface{}: + fastpathTV.EncMapUintptrIntfV(*v, fastpathCheckNilTrue, e) + + case map[uintptr]string: + fastpathTV.EncMapUintptrStringV(v, fastpathCheckNilTrue, e) + case *map[uintptr]string: + fastpathTV.EncMapUintptrStringV(*v, fastpathCheckNilTrue, e) + + case map[uintptr]uint: + fastpathTV.EncMapUintptrUintV(v, fastpathCheckNilTrue, e) + case *map[uintptr]uint: + fastpathTV.EncMapUintptrUintV(*v, fastpathCheckNilTrue, e) + + case map[uintptr]uint8: + fastpathTV.EncMapUintptrUint8V(v, fastpathCheckNilTrue, e) + case *map[uintptr]uint8: + fastpathTV.EncMapUintptrUint8V(*v, fastpathCheckNilTrue, e) + + case map[uintptr]uint16: + fastpathTV.EncMapUintptrUint16V(v, fastpathCheckNilTrue, e) + case *map[uintptr]uint16: + fastpathTV.EncMapUintptrUint16V(*v, fastpathCheckNilTrue, e) + + case map[uintptr]uint32: + fastpathTV.EncMapUintptrUint32V(v, fastpathCheckNilTrue, e) + case *map[uintptr]uint32: + fastpathTV.EncMapUintptrUint32V(*v, fastpathCheckNilTrue, e) + + case map[uintptr]uint64: + fastpathTV.EncMapUintptrUint64V(v, fastpathCheckNilTrue, e) + case *map[uintptr]uint64: + fastpathTV.EncMapUintptrUint64V(*v, fastpathCheckNilTrue, e) + + case map[uintptr]uintptr: + fastpathTV.EncMapUintptrUintptrV(v, fastpathCheckNilTrue, e) + case *map[uintptr]uintptr: + fastpathTV.EncMapUintptrUintptrV(*v, fastpathCheckNilTrue, e) + + case map[uintptr]int: + fastpathTV.EncMapUintptrIntV(v, fastpathCheckNilTrue, e) + case *map[uintptr]int: + fastpathTV.EncMapUintptrIntV(*v, fastpathCheckNilTrue, e) + + case map[uintptr]int8: + fastpathTV.EncMapUintptrInt8V(v, fastpathCheckNilTrue, e) + case *map[uintptr]int8: + fastpathTV.EncMapUintptrInt8V(*v, fastpathCheckNilTrue, e) + + case map[uintptr]int16: + fastpathTV.EncMapUintptrInt16V(v, fastpathCheckNilTrue, e) + case *map[uintptr]int16: + fastpathTV.EncMapUintptrInt16V(*v, fastpathCheckNilTrue, e) + + case map[uintptr]int32: + fastpathTV.EncMapUintptrInt32V(v, fastpathCheckNilTrue, e) + case *map[uintptr]int32: + fastpathTV.EncMapUintptrInt32V(*v, fastpathCheckNilTrue, e) + + case map[uintptr]int64: + fastpathTV.EncMapUintptrInt64V(v, fastpathCheckNilTrue, e) + case *map[uintptr]int64: + fastpathTV.EncMapUintptrInt64V(*v, fastpathCheckNilTrue, e) + + case map[uintptr]float32: + fastpathTV.EncMapUintptrFloat32V(v, fastpathCheckNilTrue, e) + case *map[uintptr]float32: + fastpathTV.EncMapUintptrFloat32V(*v, fastpathCheckNilTrue, e) + + case map[uintptr]float64: + fastpathTV.EncMapUintptrFloat64V(v, fastpathCheckNilTrue, e) + case *map[uintptr]float64: + fastpathTV.EncMapUintptrFloat64V(*v, fastpathCheckNilTrue, e) + + case map[uintptr]bool: + fastpathTV.EncMapUintptrBoolV(v, fastpathCheckNilTrue, e) + case *map[uintptr]bool: + fastpathTV.EncMapUintptrBoolV(*v, fastpathCheckNilTrue, e) + case map[int]interface{}: fastpathTV.EncMapIntIntfV(v, fastpathCheckNilTrue, e) case *map[int]interface{}: @@ -2336,6 +2669,11 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { case *map[int]uint64: fastpathTV.EncMapIntUint64V(*v, fastpathCheckNilTrue, e) + case map[int]uintptr: + fastpathTV.EncMapIntUintptrV(v, fastpathCheckNilTrue, e) + case *map[int]uintptr: + fastpathTV.EncMapIntUintptrV(*v, fastpathCheckNilTrue, e) + case map[int]int: fastpathTV.EncMapIntIntV(v, fastpathCheckNilTrue, e) case *map[int]int: @@ -2411,6 +2749,11 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { case *map[int8]uint64: fastpathTV.EncMapInt8Uint64V(*v, fastpathCheckNilTrue, e) + case map[int8]uintptr: + fastpathTV.EncMapInt8UintptrV(v, fastpathCheckNilTrue, e) + case *map[int8]uintptr: + fastpathTV.EncMapInt8UintptrV(*v, fastpathCheckNilTrue, e) + case map[int8]int: fastpathTV.EncMapInt8IntV(v, fastpathCheckNilTrue, e) case *map[int8]int: @@ -2486,6 +2829,11 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { case *map[int16]uint64: fastpathTV.EncMapInt16Uint64V(*v, fastpathCheckNilTrue, e) + case map[int16]uintptr: + fastpathTV.EncMapInt16UintptrV(v, fastpathCheckNilTrue, e) + case *map[int16]uintptr: + fastpathTV.EncMapInt16UintptrV(*v, fastpathCheckNilTrue, e) + case map[int16]int: fastpathTV.EncMapInt16IntV(v, fastpathCheckNilTrue, e) case *map[int16]int: @@ -2561,6 +2909,11 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { case *map[int32]uint64: fastpathTV.EncMapInt32Uint64V(*v, fastpathCheckNilTrue, e) + case map[int32]uintptr: + fastpathTV.EncMapInt32UintptrV(v, fastpathCheckNilTrue, e) + case *map[int32]uintptr: + fastpathTV.EncMapInt32UintptrV(*v, fastpathCheckNilTrue, e) + case map[int32]int: fastpathTV.EncMapInt32IntV(v, fastpathCheckNilTrue, e) case *map[int32]int: @@ -2636,6 +2989,11 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { case *map[int64]uint64: fastpathTV.EncMapInt64Uint64V(*v, fastpathCheckNilTrue, e) + case map[int64]uintptr: + fastpathTV.EncMapInt64UintptrV(v, fastpathCheckNilTrue, e) + case *map[int64]uintptr: + fastpathTV.EncMapInt64UintptrV(*v, fastpathCheckNilTrue, e) + case map[int64]int: fastpathTV.EncMapInt64IntV(v, fastpathCheckNilTrue, e) case *map[int64]int: @@ -2711,6 +3069,11 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { case *map[bool]uint64: fastpathTV.EncMapBoolUint64V(*v, fastpathCheckNilTrue, e) + case map[bool]uintptr: + fastpathTV.EncMapBoolUintptrV(v, fastpathCheckNilTrue, e) + case *map[bool]uintptr: + fastpathTV.EncMapBoolUintptrV(*v, fastpathCheckNilTrue, e) + case map[bool]int: fastpathTV.EncMapBoolIntV(v, fastpathCheckNilTrue, e) case *map[bool]int: @@ -2752,6 +3115,7 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { fastpathTV.EncMapBoolBoolV(*v, fastpathCheckNilTrue, e) default: + _ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release) return false } return true @@ -2759,7448 +3123,12830 @@ func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { // -- -- fast path functions -func (f encFnInfo) fastpathEncSliceIntfR(rv reflect.Value) { - fastpathTV.EncSliceIntfV(rv.Interface().([]interface{}), fastpathCheckNilFalse, f.e) +func (f *encFnInfo) fastpathEncSliceIntfR(rv reflect.Value) { + if f.ti.mbs { + fastpathTV.EncAsMapSliceIntfV(rv.Interface().([]interface{}), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceIntfV(rv.Interface().([]interface{}), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceIntfV(v []interface{}, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - e.encode(v2) + for _, v2 := range v { + if cr != nil { + cr.sendContainerState(containerArrayElem) } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - e.encode(v2) - } - ee.EncodeArrayEnd() + e.encode(v2) + } + if cr != nil { + cr.sendContainerState(containerArrayEnd) } } -func (f encFnInfo) fastpathEncSliceStringR(rv reflect.Value) { - fastpathTV.EncSliceStringV(rv.Interface().([]string), fastpathCheckNilFalse, f.e) +func (_ fastpathT) EncAsMapSliceIntfV(v []interface{}, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + e.encode(v2) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncSliceStringR(rv reflect.Value) { + if f.ti.mbs { + fastpathTV.EncAsMapSliceStringV(rv.Interface().([]string), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceStringV(rv.Interface().([]string), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceStringV(v []string, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - ee.EncodeString(c_UTF8, v2) + for _, v2 := range v { + if cr != nil { + cr.sendContainerState(containerArrayElem) } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - ee.EncodeString(c_UTF8, v2) - } - ee.EncodeArrayEnd() + ee.EncodeString(c_UTF8, v2) + } + if cr != nil { + cr.sendContainerState(containerArrayEnd) } } -func (f encFnInfo) fastpathEncSliceFloat32R(rv reflect.Value) { - fastpathTV.EncSliceFloat32V(rv.Interface().([]float32), fastpathCheckNilFalse, f.e) +func (_ fastpathT) EncAsMapSliceStringV(v []string, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + ee.EncodeString(c_UTF8, v2) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncSliceFloat32R(rv reflect.Value) { + if f.ti.mbs { + fastpathTV.EncAsMapSliceFloat32V(rv.Interface().([]float32), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceFloat32V(rv.Interface().([]float32), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceFloat32V(v []float32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - ee.EncodeFloat32(v2) + for _, v2 := range v { + if cr != nil { + cr.sendContainerState(containerArrayElem) } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - ee.EncodeFloat32(v2) - } - ee.EncodeArrayEnd() + ee.EncodeFloat32(v2) + } + if cr != nil { + cr.sendContainerState(containerArrayEnd) } } -func (f encFnInfo) fastpathEncSliceFloat64R(rv reflect.Value) { - fastpathTV.EncSliceFloat64V(rv.Interface().([]float64), fastpathCheckNilFalse, f.e) +func (_ fastpathT) EncAsMapSliceFloat32V(v []float32, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + ee.EncodeFloat32(v2) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncSliceFloat64R(rv reflect.Value) { + if f.ti.mbs { + fastpathTV.EncAsMapSliceFloat64V(rv.Interface().([]float64), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceFloat64V(rv.Interface().([]float64), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceFloat64V(v []float64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - ee.EncodeFloat64(v2) + for _, v2 := range v { + if cr != nil { + cr.sendContainerState(containerArrayElem) } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - ee.EncodeFloat64(v2) - } - ee.EncodeArrayEnd() + ee.EncodeFloat64(v2) + } + if cr != nil { + cr.sendContainerState(containerArrayEnd) } } -func (f encFnInfo) fastpathEncSliceUintR(rv reflect.Value) { - fastpathTV.EncSliceUintV(rv.Interface().([]uint), fastpathCheckNilFalse, f.e) +func (_ fastpathT) EncAsMapSliceFloat64V(v []float64, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + ee.EncodeFloat64(v2) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncSliceUintR(rv reflect.Value) { + if f.ti.mbs { + fastpathTV.EncAsMapSliceUintV(rv.Interface().([]uint), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceUintV(rv.Interface().([]uint), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceUintV(v []uint, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - ee.EncodeUint(uint64(v2)) + for _, v2 := range v { + if cr != nil { + cr.sendContainerState(containerArrayElem) } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - ee.EncodeUint(uint64(v2)) - } - ee.EncodeArrayEnd() + ee.EncodeUint(uint64(v2)) + } + if cr != nil { + cr.sendContainerState(containerArrayEnd) } } -func (f encFnInfo) fastpathEncSliceUint16R(rv reflect.Value) { - fastpathTV.EncSliceUint16V(rv.Interface().([]uint16), fastpathCheckNilFalse, f.e) +func (_ fastpathT) EncAsMapSliceUintV(v []uint, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + ee.EncodeUint(uint64(v2)) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncSliceUint16R(rv reflect.Value) { + if f.ti.mbs { + fastpathTV.EncAsMapSliceUint16V(rv.Interface().([]uint16), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceUint16V(rv.Interface().([]uint16), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceUint16V(v []uint16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - ee.EncodeUint(uint64(v2)) + for _, v2 := range v { + if cr != nil { + cr.sendContainerState(containerArrayElem) } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - ee.EncodeUint(uint64(v2)) - } - ee.EncodeArrayEnd() + ee.EncodeUint(uint64(v2)) + } + if cr != nil { + cr.sendContainerState(containerArrayEnd) } } -func (f encFnInfo) fastpathEncSliceUint32R(rv reflect.Value) { - fastpathTV.EncSliceUint32V(rv.Interface().([]uint32), fastpathCheckNilFalse, f.e) +func (_ fastpathT) EncAsMapSliceUint16V(v []uint16, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + ee.EncodeUint(uint64(v2)) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncSliceUint32R(rv reflect.Value) { + if f.ti.mbs { + fastpathTV.EncAsMapSliceUint32V(rv.Interface().([]uint32), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceUint32V(rv.Interface().([]uint32), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceUint32V(v []uint32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - ee.EncodeUint(uint64(v2)) + for _, v2 := range v { + if cr != nil { + cr.sendContainerState(containerArrayElem) } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - ee.EncodeUint(uint64(v2)) - } - ee.EncodeArrayEnd() + ee.EncodeUint(uint64(v2)) + } + if cr != nil { + cr.sendContainerState(containerArrayEnd) } } -func (f encFnInfo) fastpathEncSliceUint64R(rv reflect.Value) { - fastpathTV.EncSliceUint64V(rv.Interface().([]uint64), fastpathCheckNilFalse, f.e) +func (_ fastpathT) EncAsMapSliceUint32V(v []uint32, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + ee.EncodeUint(uint64(v2)) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncSliceUint64R(rv reflect.Value) { + if f.ti.mbs { + fastpathTV.EncAsMapSliceUint64V(rv.Interface().([]uint64), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceUint64V(rv.Interface().([]uint64), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceUint64V(v []uint64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - ee.EncodeUint(uint64(v2)) + for _, v2 := range v { + if cr != nil { + cr.sendContainerState(containerArrayElem) } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - ee.EncodeUint(uint64(v2)) - } - ee.EncodeArrayEnd() + ee.EncodeUint(uint64(v2)) + } + if cr != nil { + cr.sendContainerState(containerArrayEnd) } } -func (f encFnInfo) fastpathEncSliceIntR(rv reflect.Value) { - fastpathTV.EncSliceIntV(rv.Interface().([]int), fastpathCheckNilFalse, f.e) +func (_ fastpathT) EncAsMapSliceUint64V(v []uint64, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + ee.EncodeUint(uint64(v2)) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncSliceUintptrR(rv reflect.Value) { + if f.ti.mbs { + fastpathTV.EncAsMapSliceUintptrV(rv.Interface().([]uintptr), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceUintptrV(rv.Interface().([]uintptr), fastpathCheckNilFalse, f.e) + } +} +func (_ fastpathT) EncSliceUintptrV(v []uintptr, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeArrayStart(len(v)) + for _, v2 := range v { + if cr != nil { + cr.sendContainerState(containerArrayElem) + } + e.encode(v2) + } + if cr != nil { + cr.sendContainerState(containerArrayEnd) + } +} + +func (_ fastpathT) EncAsMapSliceUintptrV(v []uintptr, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + e.encode(v2) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncSliceIntR(rv reflect.Value) { + if f.ti.mbs { + fastpathTV.EncAsMapSliceIntV(rv.Interface().([]int), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceIntV(rv.Interface().([]int), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceIntV(v []int, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - ee.EncodeInt(int64(v2)) + for _, v2 := range v { + if cr != nil { + cr.sendContainerState(containerArrayElem) } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - ee.EncodeInt(int64(v2)) - } - ee.EncodeArrayEnd() + ee.EncodeInt(int64(v2)) + } + if cr != nil { + cr.sendContainerState(containerArrayEnd) } } -func (f encFnInfo) fastpathEncSliceInt8R(rv reflect.Value) { - fastpathTV.EncSliceInt8V(rv.Interface().([]int8), fastpathCheckNilFalse, f.e) +func (_ fastpathT) EncAsMapSliceIntV(v []int, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + ee.EncodeInt(int64(v2)) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncSliceInt8R(rv reflect.Value) { + if f.ti.mbs { + fastpathTV.EncAsMapSliceInt8V(rv.Interface().([]int8), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceInt8V(rv.Interface().([]int8), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceInt8V(v []int8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - ee.EncodeInt(int64(v2)) + for _, v2 := range v { + if cr != nil { + cr.sendContainerState(containerArrayElem) } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - ee.EncodeInt(int64(v2)) - } - ee.EncodeArrayEnd() + ee.EncodeInt(int64(v2)) + } + if cr != nil { + cr.sendContainerState(containerArrayEnd) } } -func (f encFnInfo) fastpathEncSliceInt16R(rv reflect.Value) { - fastpathTV.EncSliceInt16V(rv.Interface().([]int16), fastpathCheckNilFalse, f.e) +func (_ fastpathT) EncAsMapSliceInt8V(v []int8, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + ee.EncodeInt(int64(v2)) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncSliceInt16R(rv reflect.Value) { + if f.ti.mbs { + fastpathTV.EncAsMapSliceInt16V(rv.Interface().([]int16), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceInt16V(rv.Interface().([]int16), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceInt16V(v []int16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - ee.EncodeInt(int64(v2)) + for _, v2 := range v { + if cr != nil { + cr.sendContainerState(containerArrayElem) } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - ee.EncodeInt(int64(v2)) - } - ee.EncodeArrayEnd() + ee.EncodeInt(int64(v2)) + } + if cr != nil { + cr.sendContainerState(containerArrayEnd) } } -func (f encFnInfo) fastpathEncSliceInt32R(rv reflect.Value) { - fastpathTV.EncSliceInt32V(rv.Interface().([]int32), fastpathCheckNilFalse, f.e) +func (_ fastpathT) EncAsMapSliceInt16V(v []int16, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + ee.EncodeInt(int64(v2)) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncSliceInt32R(rv reflect.Value) { + if f.ti.mbs { + fastpathTV.EncAsMapSliceInt32V(rv.Interface().([]int32), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceInt32V(rv.Interface().([]int32), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceInt32V(v []int32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - ee.EncodeInt(int64(v2)) + for _, v2 := range v { + if cr != nil { + cr.sendContainerState(containerArrayElem) } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - ee.EncodeInt(int64(v2)) - } - ee.EncodeArrayEnd() + ee.EncodeInt(int64(v2)) + } + if cr != nil { + cr.sendContainerState(containerArrayEnd) } } -func (f encFnInfo) fastpathEncSliceInt64R(rv reflect.Value) { - fastpathTV.EncSliceInt64V(rv.Interface().([]int64), fastpathCheckNilFalse, f.e) +func (_ fastpathT) EncAsMapSliceInt32V(v []int32, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + ee.EncodeInt(int64(v2)) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncSliceInt64R(rv reflect.Value) { + if f.ti.mbs { + fastpathTV.EncAsMapSliceInt64V(rv.Interface().([]int64), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceInt64V(rv.Interface().([]int64), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceInt64V(v []int64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - ee.EncodeInt(int64(v2)) + for _, v2 := range v { + if cr != nil { + cr.sendContainerState(containerArrayElem) } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - ee.EncodeInt(int64(v2)) - } - ee.EncodeArrayEnd() + ee.EncodeInt(int64(v2)) + } + if cr != nil { + cr.sendContainerState(containerArrayEnd) } } -func (f encFnInfo) fastpathEncSliceBoolR(rv reflect.Value) { - fastpathTV.EncSliceBoolV(rv.Interface().([]bool), fastpathCheckNilFalse, f.e) +func (_ fastpathT) EncAsMapSliceInt64V(v []int64, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + ee.EncodeInt(int64(v2)) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncSliceBoolR(rv reflect.Value) { + if f.ti.mbs { + fastpathTV.EncAsMapSliceBoolV(rv.Interface().([]bool), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.EncSliceBoolV(rv.Interface().([]bool), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) EncSliceBoolV(v []bool, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - ee.EncodeBool(v2) + for _, v2 := range v { + if cr != nil { + cr.sendContainerState(containerArrayElem) } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - ee.EncodeBool(v2) - } - ee.EncodeArrayEnd() + ee.EncodeBool(v2) + } + if cr != nil { + cr.sendContainerState(containerArrayEnd) } } -func (f encFnInfo) fastpathEncMapIntfIntfR(rv reflect.Value) { +func (_ fastpathT) EncAsMapSliceBoolV(v []bool, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + ee.EncodeBool(v2) + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapIntfIntfR(rv reflect.Value) { fastpathTV.EncMapIntfIntfV(rv.Interface().(map[interface{}]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfIntfV(v map[interface{}]interface{}, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - e.encode(k2) - e.encode(v2) + if e.h.Canonical { + var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding + e2 := NewEncoderBytes(&mksv, e.hh) + v2 := make([]bytesI, len(v)) + var i, l int + var vp *bytesI + for k2, _ := range v { + l = len(mksv) + e2.MustEncode(k2) + vp = &v2[i] + vp.v = mksv[l:] + vp.i = k2 + i++ + } + sort.Sort(bytesISlice(v2)) + for j := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.asis(v2[j].v) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[v2[j].i]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } e.encode(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } e.encode(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntfStringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfStringR(rv reflect.Value) { fastpathTV.EncMapIntfStringV(rv.Interface().(map[interface{}]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfStringV(v map[interface{}]string, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeString(c_UTF8, v2) + if e.h.Canonical { + var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding + e2 := NewEncoderBytes(&mksv, e.hh) + v2 := make([]bytesI, len(v)) + var i, l int + var vp *bytesI + for k2, _ := range v { + l = len(mksv) + e2.MustEncode(k2) + vp = &v2[i] + vp.v = mksv[l:] + vp.i = k2 + i++ + } + sort.Sort(bytesISlice(v2)) + for j := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.asis(v2[j].v) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[v2[j].i]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } e.encode(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeString(c_UTF8, v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntfUintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfUintR(rv reflect.Value) { fastpathTV.EncMapIntfUintV(rv.Interface().(map[interface{}]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfUintV(v map[interface{}]uint, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding + e2 := NewEncoderBytes(&mksv, e.hh) + v2 := make([]bytesI, len(v)) + var i, l int + var vp *bytesI + for k2, _ := range v { + l = len(mksv) + e2.MustEncode(k2) + vp = &v2[i] + vp.v = mksv[l:] + vp.i = k2 + i++ + } + sort.Sort(bytesISlice(v2)) + for j := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.asis(v2[j].v) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[v2[j].i]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } e.encode(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntfUint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfUint8R(rv reflect.Value) { fastpathTV.EncMapIntfUint8V(rv.Interface().(map[interface{}]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfUint8V(v map[interface{}]uint8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding + e2 := NewEncoderBytes(&mksv, e.hh) + v2 := make([]bytesI, len(v)) + var i, l int + var vp *bytesI + for k2, _ := range v { + l = len(mksv) + e2.MustEncode(k2) + vp = &v2[i] + vp.v = mksv[l:] + vp.i = k2 + i++ + } + sort.Sort(bytesISlice(v2)) + for j := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.asis(v2[j].v) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[v2[j].i]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } e.encode(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntfUint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfUint16R(rv reflect.Value) { fastpathTV.EncMapIntfUint16V(rv.Interface().(map[interface{}]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfUint16V(v map[interface{}]uint16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding + e2 := NewEncoderBytes(&mksv, e.hh) + v2 := make([]bytesI, len(v)) + var i, l int + var vp *bytesI + for k2, _ := range v { + l = len(mksv) + e2.MustEncode(k2) + vp = &v2[i] + vp.v = mksv[l:] + vp.i = k2 + i++ + } + sort.Sort(bytesISlice(v2)) + for j := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.asis(v2[j].v) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[v2[j].i]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } e.encode(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntfUint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfUint32R(rv reflect.Value) { fastpathTV.EncMapIntfUint32V(rv.Interface().(map[interface{}]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfUint32V(v map[interface{}]uint32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding + e2 := NewEncoderBytes(&mksv, e.hh) + v2 := make([]bytesI, len(v)) + var i, l int + var vp *bytesI + for k2, _ := range v { + l = len(mksv) + e2.MustEncode(k2) + vp = &v2[i] + vp.v = mksv[l:] + vp.i = k2 + i++ + } + sort.Sort(bytesISlice(v2)) + for j := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.asis(v2[j].v) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[v2[j].i]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } e.encode(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntfUint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfUint64R(rv reflect.Value) { fastpathTV.EncMapIntfUint64V(rv.Interface().(map[interface{}]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfUint64V(v map[interface{}]uint64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding + e2 := NewEncoderBytes(&mksv, e.hh) + v2 := make([]bytesI, len(v)) + var i, l int + var vp *bytesI + for k2, _ := range v { + l = len(mksv) + e2.MustEncode(k2) + vp = &v2[i] + vp.v = mksv[l:] + vp.i = k2 + i++ + } + sort.Sort(bytesISlice(v2)) + for j := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.asis(v2[j].v) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[v2[j].i]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } e.encode(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntfIntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfUintptrR(rv reflect.Value) { + fastpathTV.EncMapIntfUintptrV(rv.Interface().(map[interface{}]uintptr), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapIntfUintptrV(v map[interface{}]uintptr, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding + e2 := NewEncoderBytes(&mksv, e.hh) + v2 := make([]bytesI, len(v)) + var i, l int + var vp *bytesI + for k2, _ := range v { + l = len(mksv) + e2.MustEncode(k2) + vp = &v2[i] + vp.v = mksv[l:] + vp.i = k2 + i++ + } + sort.Sort(bytesISlice(v2)) + for j := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.asis(v2[j].v) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[v2[j].i]) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(k2) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v2) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapIntfIntR(rv reflect.Value) { fastpathTV.EncMapIntfIntV(rv.Interface().(map[interface{}]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfIntV(v map[interface{}]int, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding + e2 := NewEncoderBytes(&mksv, e.hh) + v2 := make([]bytesI, len(v)) + var i, l int + var vp *bytesI + for k2, _ := range v { + l = len(mksv) + e2.MustEncode(k2) + vp = &v2[i] + vp.v = mksv[l:] + vp.i = k2 + i++ + } + sort.Sort(bytesISlice(v2)) + for j := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.asis(v2[j].v) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[v2[j].i]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } e.encode(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntfInt8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfInt8R(rv reflect.Value) { fastpathTV.EncMapIntfInt8V(rv.Interface().(map[interface{}]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfInt8V(v map[interface{}]int8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding + e2 := NewEncoderBytes(&mksv, e.hh) + v2 := make([]bytesI, len(v)) + var i, l int + var vp *bytesI + for k2, _ := range v { + l = len(mksv) + e2.MustEncode(k2) + vp = &v2[i] + vp.v = mksv[l:] + vp.i = k2 + i++ + } + sort.Sort(bytesISlice(v2)) + for j := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.asis(v2[j].v) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[v2[j].i]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } e.encode(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntfInt16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfInt16R(rv reflect.Value) { fastpathTV.EncMapIntfInt16V(rv.Interface().(map[interface{}]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfInt16V(v map[interface{}]int16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding + e2 := NewEncoderBytes(&mksv, e.hh) + v2 := make([]bytesI, len(v)) + var i, l int + var vp *bytesI + for k2, _ := range v { + l = len(mksv) + e2.MustEncode(k2) + vp = &v2[i] + vp.v = mksv[l:] + vp.i = k2 + i++ + } + sort.Sort(bytesISlice(v2)) + for j := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.asis(v2[j].v) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[v2[j].i]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } e.encode(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntfInt32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfInt32R(rv reflect.Value) { fastpathTV.EncMapIntfInt32V(rv.Interface().(map[interface{}]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfInt32V(v map[interface{}]int32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding + e2 := NewEncoderBytes(&mksv, e.hh) + v2 := make([]bytesI, len(v)) + var i, l int + var vp *bytesI + for k2, _ := range v { + l = len(mksv) + e2.MustEncode(k2) + vp = &v2[i] + vp.v = mksv[l:] + vp.i = k2 + i++ + } + sort.Sort(bytesISlice(v2)) + for j := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.asis(v2[j].v) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[v2[j].i]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } e.encode(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntfInt64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfInt64R(rv reflect.Value) { fastpathTV.EncMapIntfInt64V(rv.Interface().(map[interface{}]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfInt64V(v map[interface{}]int64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding + e2 := NewEncoderBytes(&mksv, e.hh) + v2 := make([]bytesI, len(v)) + var i, l int + var vp *bytesI + for k2, _ := range v { + l = len(mksv) + e2.MustEncode(k2) + vp = &v2[i] + vp.v = mksv[l:] + vp.i = k2 + i++ + } + sort.Sort(bytesISlice(v2)) + for j := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.asis(v2[j].v) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[v2[j].i]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } e.encode(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntfFloat32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfFloat32R(rv reflect.Value) { fastpathTV.EncMapIntfFloat32V(rv.Interface().(map[interface{}]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfFloat32V(v map[interface{}]float32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeFloat32(v2) + if e.h.Canonical { + var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding + e2 := NewEncoderBytes(&mksv, e.hh) + v2 := make([]bytesI, len(v)) + var i, l int + var vp *bytesI + for k2, _ := range v { + l = len(mksv) + e2.MustEncode(k2) + vp = &v2[i] + vp.v = mksv[l:] + vp.i = k2 + i++ + } + sort.Sort(bytesISlice(v2)) + for j := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.asis(v2[j].v) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[v2[j].i]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } e.encode(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat32(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntfFloat64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfFloat64R(rv reflect.Value) { fastpathTV.EncMapIntfFloat64V(rv.Interface().(map[interface{}]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfFloat64V(v map[interface{}]float64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeFloat64(v2) + if e.h.Canonical { + var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding + e2 := NewEncoderBytes(&mksv, e.hh) + v2 := make([]bytesI, len(v)) + var i, l int + var vp *bytesI + for k2, _ := range v { + l = len(mksv) + e2.MustEncode(k2) + vp = &v2[i] + vp.v = mksv[l:] + vp.i = k2 + i++ + } + sort.Sort(bytesISlice(v2)) + for j := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.asis(v2[j].v) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[v2[j].i]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } e.encode(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat64(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntfBoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntfBoolR(rv reflect.Value) { fastpathTV.EncMapIntfBoolV(rv.Interface().(map[interface{}]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntfBoolV(v map[interface{}]bool, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - e.encode(k2) - ee.EncodeBool(v2) + if e.h.Canonical { + var mksv []byte = make([]byte, 0, len(v)*16) // temporary byte slice for the encoding + e2 := NewEncoderBytes(&mksv, e.hh) + v2 := make([]bytesI, len(v)) + var i, l int + var vp *bytesI + for k2, _ := range v { + l = len(mksv) + e2.MustEncode(k2) + vp = &v2[i] + vp.v = mksv[l:] + vp.i = k2 + i++ + } + sort.Sort(bytesISlice(v2)) + for j := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.asis(v2[j].v) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[v2[j].i]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } e.encode(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeBool(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapStringIntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringIntfR(rv reflect.Value) { fastpathTV.EncMapStringIntfV(rv.Interface().(map[string]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringIntfV(v map[string]interface{}, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { + if e.h.Canonical { + v2 := make([]string, len(v)) + var i int + for k, _ := range v { + v2[i] = string(k) + i++ + } + sort.Sort(stringSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - e.encode(v2) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[string(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } e.encode(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapStringStringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringStringR(rv reflect.Value) { fastpathTV.EncMapStringStringV(rv.Interface().(map[string]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringStringV(v map[string]string, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { + if e.h.Canonical { + v2 := make([]string, len(v)) + var i int + for k, _ := range v { + v2[i] = string(k) + i++ + } + sort.Sort(stringSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeString(c_UTF8, v2) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeString(c_UTF8, v[string(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeString(c_UTF8, v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapStringUintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringUintR(rv reflect.Value) { fastpathTV.EncMapStringUintV(rv.Interface().(map[string]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringUintV(v map[string]uint, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { + if e.h.Canonical { + v2 := make([]string, len(v)) + var i int + for k, _ := range v { + v2[i] = string(k) + i++ + } + sort.Sort(stringSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeUint(uint64(v2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[string(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapStringUint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringUint8R(rv reflect.Value) { fastpathTV.EncMapStringUint8V(rv.Interface().(map[string]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringUint8V(v map[string]uint8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { + if e.h.Canonical { + v2 := make([]string, len(v)) + var i int + for k, _ := range v { + v2[i] = string(k) + i++ + } + sort.Sort(stringSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeUint(uint64(v2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[string(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapStringUint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringUint16R(rv reflect.Value) { fastpathTV.EncMapStringUint16V(rv.Interface().(map[string]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringUint16V(v map[string]uint16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { + if e.h.Canonical { + v2 := make([]string, len(v)) + var i int + for k, _ := range v { + v2[i] = string(k) + i++ + } + sort.Sort(stringSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeUint(uint64(v2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[string(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapStringUint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringUint32R(rv reflect.Value) { fastpathTV.EncMapStringUint32V(rv.Interface().(map[string]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringUint32V(v map[string]uint32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { + if e.h.Canonical { + v2 := make([]string, len(v)) + var i int + for k, _ := range v { + v2[i] = string(k) + i++ + } + sort.Sort(stringSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeUint(uint64(v2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[string(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapStringUint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringUint64R(rv reflect.Value) { fastpathTV.EncMapStringUint64V(rv.Interface().(map[string]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringUint64V(v map[string]uint64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { + if e.h.Canonical { + v2 := make([]string, len(v)) + var i int + for k, _ := range v { + v2[i] = string(k) + i++ + } + sort.Sort(stringSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeUint(uint64(v2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[string(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapStringIntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringUintptrR(rv reflect.Value) { + fastpathTV.EncMapStringUintptrV(rv.Interface().(map[string]uintptr), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapStringUintptrV(v map[string]uintptr, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 + if e.h.Canonical { + v2 := make([]string, len(v)) + var i int + for k, _ := range v { + v2[i] = string(k) + i++ + } + sort.Sort(stringSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + if asSymbols { + ee.EncodeSymbol(k2) + } else { + ee.EncodeString(c_UTF8, k2) + } + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[string(k2)]) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + if asSymbols { + ee.EncodeSymbol(k2) + } else { + ee.EncodeString(c_UTF8, k2) + } + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v2) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapStringIntR(rv reflect.Value) { fastpathTV.EncMapStringIntV(rv.Interface().(map[string]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringIntV(v map[string]int, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { + if e.h.Canonical { + v2 := make([]string, len(v)) + var i int + for k, _ := range v { + v2[i] = string(k) + i++ + } + sort.Sort(stringSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeInt(int64(v2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[string(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapStringInt8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringInt8R(rv reflect.Value) { fastpathTV.EncMapStringInt8V(rv.Interface().(map[string]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringInt8V(v map[string]int8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { + if e.h.Canonical { + v2 := make([]string, len(v)) + var i int + for k, _ := range v { + v2[i] = string(k) + i++ + } + sort.Sort(stringSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeInt(int64(v2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[string(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapStringInt16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringInt16R(rv reflect.Value) { fastpathTV.EncMapStringInt16V(rv.Interface().(map[string]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringInt16V(v map[string]int16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { + if e.h.Canonical { + v2 := make([]string, len(v)) + var i int + for k, _ := range v { + v2[i] = string(k) + i++ + } + sort.Sort(stringSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeInt(int64(v2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[string(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapStringInt32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringInt32R(rv reflect.Value) { fastpathTV.EncMapStringInt32V(rv.Interface().(map[string]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringInt32V(v map[string]int32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { + if e.h.Canonical { + v2 := make([]string, len(v)) + var i int + for k, _ := range v { + v2[i] = string(k) + i++ + } + sort.Sort(stringSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeInt(int64(v2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[string(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapStringInt64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringInt64R(rv reflect.Value) { fastpathTV.EncMapStringInt64V(rv.Interface().(map[string]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringInt64V(v map[string]int64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { + if e.h.Canonical { + v2 := make([]string, len(v)) + var i int + for k, _ := range v { + v2[i] = string(k) + i++ + } + sort.Sort(stringSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeInt(int64(v2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[string(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapStringFloat32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringFloat32R(rv reflect.Value) { fastpathTV.EncMapStringFloat32V(rv.Interface().(map[string]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringFloat32V(v map[string]float32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { + if e.h.Canonical { + v2 := make([]string, len(v)) + var i int + for k, _ := range v { + v2[i] = string(k) + i++ + } + sort.Sort(stringSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeFloat32(v2) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat32(v[string(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat32(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapStringFloat64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringFloat64R(rv reflect.Value) { fastpathTV.EncMapStringFloat64V(rv.Interface().(map[string]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringFloat64V(v map[string]float64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { + if e.h.Canonical { + v2 := make([]string, len(v)) + var i int + for k, _ := range v { + v2[i] = string(k) + i++ + } + sort.Sort(stringSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeFloat64(v2) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat64(v[string(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat64(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapStringBoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapStringBoolR(rv reflect.Value) { fastpathTV.EncMapStringBoolV(rv.Interface().(map[string]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapStringBoolV(v map[string]bool, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0 - if e.be { - for k2, v2 := range v { + if e.h.Canonical { + v2 := make([]string, len(v)) + var i int + for k, _ := range v { + v2[i] = string(k) + i++ + } + sort.Sort(stringSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeBool(v2) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeBool(v[string(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) } - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeBool(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat32IntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32IntfR(rv reflect.Value) { fastpathTV.EncMapFloat32IntfV(rv.Interface().(map[float32]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32IntfV(v map[float32]interface{}, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - e.encode(v2) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat32(float32(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[float32(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } e.encode(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat32StringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32StringR(rv reflect.Value) { fastpathTV.EncMapFloat32StringV(rv.Interface().(map[float32]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32StringV(v map[float32]string, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeString(c_UTF8, v2) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat32(float32(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeString(c_UTF8, v[float32(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeString(c_UTF8, v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat32UintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32UintR(rv reflect.Value) { fastpathTV.EncMapFloat32UintV(rv.Interface().(map[float32]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32UintV(v map[float32]uint, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat32(float32(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[float32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat32Uint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32Uint8R(rv reflect.Value) { fastpathTV.EncMapFloat32Uint8V(rv.Interface().(map[float32]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32Uint8V(v map[float32]uint8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat32(float32(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[float32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat32Uint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32Uint16R(rv reflect.Value) { fastpathTV.EncMapFloat32Uint16V(rv.Interface().(map[float32]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32Uint16V(v map[float32]uint16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat32(float32(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[float32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat32Uint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32Uint32R(rv reflect.Value) { fastpathTV.EncMapFloat32Uint32V(rv.Interface().(map[float32]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32Uint32V(v map[float32]uint32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat32(float32(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[float32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat32Uint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32Uint64R(rv reflect.Value) { fastpathTV.EncMapFloat32Uint64V(rv.Interface().(map[float32]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32Uint64V(v map[float32]uint64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat32(float32(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[float32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat32IntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32UintptrR(rv reflect.Value) { + fastpathTV.EncMapFloat32UintptrV(rv.Interface().(map[float32]uintptr), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapFloat32UintptrV(v map[float32]uintptr, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat32(float32(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[float32(k2)]) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat32(k2) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v2) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapFloat32IntR(rv reflect.Value) { fastpathTV.EncMapFloat32IntV(rv.Interface().(map[float32]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32IntV(v map[float32]int, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat32(float32(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[float32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat32Int8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32Int8R(rv reflect.Value) { fastpathTV.EncMapFloat32Int8V(rv.Interface().(map[float32]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32Int8V(v map[float32]int8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat32(float32(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[float32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat32Int16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32Int16R(rv reflect.Value) { fastpathTV.EncMapFloat32Int16V(rv.Interface().(map[float32]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32Int16V(v map[float32]int16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat32(float32(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[float32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat32Int32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32Int32R(rv reflect.Value) { fastpathTV.EncMapFloat32Int32V(rv.Interface().(map[float32]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32Int32V(v map[float32]int32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat32(float32(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[float32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat32Int64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32Int64R(rv reflect.Value) { fastpathTV.EncMapFloat32Int64V(rv.Interface().(map[float32]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32Int64V(v map[float32]int64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat32(float32(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[float32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat32Float32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32Float32R(rv reflect.Value) { fastpathTV.EncMapFloat32Float32V(rv.Interface().(map[float32]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32Float32V(v map[float32]float32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeFloat32(v2) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat32(float32(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat32(v[float32(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat32(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat32Float64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32Float64R(rv reflect.Value) { fastpathTV.EncMapFloat32Float64V(rv.Interface().(map[float32]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32Float64V(v map[float32]float64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeFloat64(v2) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat32(float32(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat64(v[float32(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat64(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat32BoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat32BoolR(rv reflect.Value) { fastpathTV.EncMapFloat32BoolV(rv.Interface().(map[float32]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat32BoolV(v map[float32]bool, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat32(k2) - ee.EncodeBool(v2) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat32(float32(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeBool(v[float32(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat32(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeBool(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat64IntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64IntfR(rv reflect.Value) { fastpathTV.EncMapFloat64IntfV(rv.Interface().(map[float64]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64IntfV(v map[float64]interface{}, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - e.encode(v2) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat64(float64(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[float64(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } e.encode(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat64StringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64StringR(rv reflect.Value) { fastpathTV.EncMapFloat64StringV(rv.Interface().(map[float64]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64StringV(v map[float64]string, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeString(c_UTF8, v2) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat64(float64(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeString(c_UTF8, v[float64(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeString(c_UTF8, v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat64UintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64UintR(rv reflect.Value) { fastpathTV.EncMapFloat64UintV(rv.Interface().(map[float64]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64UintV(v map[float64]uint, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat64(float64(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[float64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat64Uint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64Uint8R(rv reflect.Value) { fastpathTV.EncMapFloat64Uint8V(rv.Interface().(map[float64]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64Uint8V(v map[float64]uint8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat64(float64(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[float64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat64Uint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64Uint16R(rv reflect.Value) { fastpathTV.EncMapFloat64Uint16V(rv.Interface().(map[float64]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64Uint16V(v map[float64]uint16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat64(float64(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[float64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat64Uint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64Uint32R(rv reflect.Value) { fastpathTV.EncMapFloat64Uint32V(rv.Interface().(map[float64]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64Uint32V(v map[float64]uint32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat64(float64(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[float64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat64Uint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64Uint64R(rv reflect.Value) { fastpathTV.EncMapFloat64Uint64V(rv.Interface().(map[float64]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64Uint64V(v map[float64]uint64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat64(float64(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[float64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat64IntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64UintptrR(rv reflect.Value) { + fastpathTV.EncMapFloat64UintptrV(rv.Interface().(map[float64]uintptr), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapFloat64UintptrV(v map[float64]uintptr, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat64(float64(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[float64(k2)]) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat64(k2) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v2) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapFloat64IntR(rv reflect.Value) { fastpathTV.EncMapFloat64IntV(rv.Interface().(map[float64]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64IntV(v map[float64]int, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat64(float64(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[float64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat64Int8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64Int8R(rv reflect.Value) { fastpathTV.EncMapFloat64Int8V(rv.Interface().(map[float64]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64Int8V(v map[float64]int8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat64(float64(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[float64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat64Int16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64Int16R(rv reflect.Value) { fastpathTV.EncMapFloat64Int16V(rv.Interface().(map[float64]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64Int16V(v map[float64]int16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat64(float64(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[float64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat64Int32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64Int32R(rv reflect.Value) { fastpathTV.EncMapFloat64Int32V(rv.Interface().(map[float64]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64Int32V(v map[float64]int32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat64(float64(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[float64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat64Int64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64Int64R(rv reflect.Value) { fastpathTV.EncMapFloat64Int64V(rv.Interface().(map[float64]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64Int64V(v map[float64]int64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat64(float64(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[float64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat64Float32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64Float32R(rv reflect.Value) { fastpathTV.EncMapFloat64Float32V(rv.Interface().(map[float64]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64Float32V(v map[float64]float32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeFloat32(v2) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat64(float64(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat32(v[float64(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat32(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat64Float64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64Float64R(rv reflect.Value) { fastpathTV.EncMapFloat64Float64V(rv.Interface().(map[float64]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64Float64V(v map[float64]float64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeFloat64(v2) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat64(float64(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat64(v[float64(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat64(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapFloat64BoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapFloat64BoolR(rv reflect.Value) { fastpathTV.EncMapFloat64BoolV(rv.Interface().(map[float64]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapFloat64BoolV(v map[float64]bool, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeFloat64(k2) - ee.EncodeBool(v2) + if e.h.Canonical { + v2 := make([]float64, len(v)) + var i int + for k, _ := range v { + v2[i] = float64(k) + i++ + } + sort.Sort(floatSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeFloat64(float64(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeBool(v[float64(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeFloat64(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeBool(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUintIntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintIntfR(rv reflect.Value) { fastpathTV.EncMapUintIntfV(rv.Interface().(map[uint]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintIntfV(v map[uint]interface{}, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - e.encode(v2) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[uint(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } e.encode(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUintStringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintStringR(rv reflect.Value) { fastpathTV.EncMapUintStringV(rv.Interface().(map[uint]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintStringV(v map[uint]string, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeString(c_UTF8, v2) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeString(c_UTF8, v[uint(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeString(c_UTF8, v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUintUintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintUintR(rv reflect.Value) { fastpathTV.EncMapUintUintV(rv.Interface().(map[uint]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintUintV(v map[uint]uint, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uint(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUintUint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintUint8R(rv reflect.Value) { fastpathTV.EncMapUintUint8V(rv.Interface().(map[uint]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintUint8V(v map[uint]uint8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uint(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUintUint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintUint16R(rv reflect.Value) { fastpathTV.EncMapUintUint16V(rv.Interface().(map[uint]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintUint16V(v map[uint]uint16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uint(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUintUint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintUint32R(rv reflect.Value) { fastpathTV.EncMapUintUint32V(rv.Interface().(map[uint]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintUint32V(v map[uint]uint32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uint(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUintUint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintUint64R(rv reflect.Value) { fastpathTV.EncMapUintUint64V(rv.Interface().(map[uint]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintUint64V(v map[uint]uint64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uint(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUintIntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintUintptrR(rv reflect.Value) { + fastpathTV.EncMapUintUintptrV(rv.Interface().(map[uint]uintptr), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapUintUintptrV(v map[uint]uintptr, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[uint(k2)]) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v2) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapUintIntR(rv reflect.Value) { fastpathTV.EncMapUintIntV(rv.Interface().(map[uint]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintIntV(v map[uint]int, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uint(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUintInt8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintInt8R(rv reflect.Value) { fastpathTV.EncMapUintInt8V(rv.Interface().(map[uint]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintInt8V(v map[uint]int8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uint(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUintInt16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintInt16R(rv reflect.Value) { fastpathTV.EncMapUintInt16V(rv.Interface().(map[uint]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintInt16V(v map[uint]int16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uint(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUintInt32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintInt32R(rv reflect.Value) { fastpathTV.EncMapUintInt32V(rv.Interface().(map[uint]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintInt32V(v map[uint]int32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uint(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUintInt64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintInt64R(rv reflect.Value) { fastpathTV.EncMapUintInt64V(rv.Interface().(map[uint]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintInt64V(v map[uint]int64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uint(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUintFloat32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintFloat32R(rv reflect.Value) { fastpathTV.EncMapUintFloat32V(rv.Interface().(map[uint]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintFloat32V(v map[uint]float32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeFloat32(v2) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat32(v[uint(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat32(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUintFloat64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintFloat64R(rv reflect.Value) { fastpathTV.EncMapUintFloat64V(rv.Interface().(map[uint]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintFloat64V(v map[uint]float64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeFloat64(v2) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat64(v[uint(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat64(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUintBoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintBoolR(rv reflect.Value) { fastpathTV.EncMapUintBoolV(rv.Interface().(map[uint]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUintBoolV(v map[uint]bool, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeBool(v2) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeBool(v[uint(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeBool(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint8IntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8IntfR(rv reflect.Value) { fastpathTV.EncMapUint8IntfV(rv.Interface().(map[uint8]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8IntfV(v map[uint8]interface{}, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - e.encode(v2) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[uint8(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } e.encode(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint8StringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8StringR(rv reflect.Value) { fastpathTV.EncMapUint8StringV(rv.Interface().(map[uint8]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8StringV(v map[uint8]string, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeString(c_UTF8, v2) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeString(c_UTF8, v[uint8(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeString(c_UTF8, v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint8UintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8UintR(rv reflect.Value) { fastpathTV.EncMapUint8UintV(rv.Interface().(map[uint8]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8UintV(v map[uint8]uint, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uint8(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint8Uint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8Uint8R(rv reflect.Value) { fastpathTV.EncMapUint8Uint8V(rv.Interface().(map[uint8]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8Uint8V(v map[uint8]uint8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uint8(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint8Uint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8Uint16R(rv reflect.Value) { fastpathTV.EncMapUint8Uint16V(rv.Interface().(map[uint8]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8Uint16V(v map[uint8]uint16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uint8(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint8Uint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8Uint32R(rv reflect.Value) { fastpathTV.EncMapUint8Uint32V(rv.Interface().(map[uint8]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8Uint32V(v map[uint8]uint32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uint8(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint8Uint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8Uint64R(rv reflect.Value) { fastpathTV.EncMapUint8Uint64V(rv.Interface().(map[uint8]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8Uint64V(v map[uint8]uint64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uint8(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint8IntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8UintptrR(rv reflect.Value) { + fastpathTV.EncMapUint8UintptrV(rv.Interface().(map[uint8]uintptr), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapUint8UintptrV(v map[uint8]uintptr, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[uint8(k2)]) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v2) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapUint8IntR(rv reflect.Value) { fastpathTV.EncMapUint8IntV(rv.Interface().(map[uint8]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8IntV(v map[uint8]int, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uint8(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint8Int8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8Int8R(rv reflect.Value) { fastpathTV.EncMapUint8Int8V(rv.Interface().(map[uint8]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8Int8V(v map[uint8]int8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uint8(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint8Int16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8Int16R(rv reflect.Value) { fastpathTV.EncMapUint8Int16V(rv.Interface().(map[uint8]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8Int16V(v map[uint8]int16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uint8(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint8Int32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8Int32R(rv reflect.Value) { fastpathTV.EncMapUint8Int32V(rv.Interface().(map[uint8]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8Int32V(v map[uint8]int32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uint8(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint8Int64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8Int64R(rv reflect.Value) { fastpathTV.EncMapUint8Int64V(rv.Interface().(map[uint8]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8Int64V(v map[uint8]int64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uint8(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint8Float32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8Float32R(rv reflect.Value) { fastpathTV.EncMapUint8Float32V(rv.Interface().(map[uint8]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8Float32V(v map[uint8]float32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeFloat32(v2) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat32(v[uint8(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat32(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint8Float64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8Float64R(rv reflect.Value) { fastpathTV.EncMapUint8Float64V(rv.Interface().(map[uint8]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8Float64V(v map[uint8]float64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeFloat64(v2) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat64(v[uint8(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat64(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint8BoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint8BoolR(rv reflect.Value) { fastpathTV.EncMapUint8BoolV(rv.Interface().(map[uint8]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint8BoolV(v map[uint8]bool, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeBool(v2) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeBool(v[uint8(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeBool(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint16IntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16IntfR(rv reflect.Value) { fastpathTV.EncMapUint16IntfV(rv.Interface().(map[uint16]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16IntfV(v map[uint16]interface{}, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - e.encode(v2) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[uint16(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } e.encode(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint16StringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16StringR(rv reflect.Value) { fastpathTV.EncMapUint16StringV(rv.Interface().(map[uint16]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16StringV(v map[uint16]string, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeString(c_UTF8, v2) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeString(c_UTF8, v[uint16(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeString(c_UTF8, v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint16UintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16UintR(rv reflect.Value) { fastpathTV.EncMapUint16UintV(rv.Interface().(map[uint16]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16UintV(v map[uint16]uint, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uint16(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint16Uint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16Uint8R(rv reflect.Value) { fastpathTV.EncMapUint16Uint8V(rv.Interface().(map[uint16]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16Uint8V(v map[uint16]uint8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uint16(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint16Uint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16Uint16R(rv reflect.Value) { fastpathTV.EncMapUint16Uint16V(rv.Interface().(map[uint16]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16Uint16V(v map[uint16]uint16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uint16(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint16Uint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16Uint32R(rv reflect.Value) { fastpathTV.EncMapUint16Uint32V(rv.Interface().(map[uint16]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16Uint32V(v map[uint16]uint32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uint16(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint16Uint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16Uint64R(rv reflect.Value) { fastpathTV.EncMapUint16Uint64V(rv.Interface().(map[uint16]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16Uint64V(v map[uint16]uint64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uint16(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint16IntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16UintptrR(rv reflect.Value) { + fastpathTV.EncMapUint16UintptrV(rv.Interface().(map[uint16]uintptr), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapUint16UintptrV(v map[uint16]uintptr, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[uint16(k2)]) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v2) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapUint16IntR(rv reflect.Value) { fastpathTV.EncMapUint16IntV(rv.Interface().(map[uint16]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16IntV(v map[uint16]int, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uint16(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint16Int8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16Int8R(rv reflect.Value) { fastpathTV.EncMapUint16Int8V(rv.Interface().(map[uint16]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16Int8V(v map[uint16]int8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uint16(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint16Int16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16Int16R(rv reflect.Value) { fastpathTV.EncMapUint16Int16V(rv.Interface().(map[uint16]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16Int16V(v map[uint16]int16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uint16(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint16Int32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16Int32R(rv reflect.Value) { fastpathTV.EncMapUint16Int32V(rv.Interface().(map[uint16]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16Int32V(v map[uint16]int32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uint16(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint16Int64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16Int64R(rv reflect.Value) { fastpathTV.EncMapUint16Int64V(rv.Interface().(map[uint16]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16Int64V(v map[uint16]int64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uint16(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint16Float32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16Float32R(rv reflect.Value) { fastpathTV.EncMapUint16Float32V(rv.Interface().(map[uint16]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16Float32V(v map[uint16]float32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeFloat32(v2) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat32(v[uint16(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat32(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint16Float64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16Float64R(rv reflect.Value) { fastpathTV.EncMapUint16Float64V(rv.Interface().(map[uint16]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16Float64V(v map[uint16]float64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeFloat64(v2) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat64(v[uint16(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat64(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint16BoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint16BoolR(rv reflect.Value) { fastpathTV.EncMapUint16BoolV(rv.Interface().(map[uint16]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint16BoolV(v map[uint16]bool, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeBool(v2) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeBool(v[uint16(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeBool(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint32IntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32IntfR(rv reflect.Value) { fastpathTV.EncMapUint32IntfV(rv.Interface().(map[uint32]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32IntfV(v map[uint32]interface{}, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - e.encode(v2) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[uint32(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } e.encode(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint32StringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32StringR(rv reflect.Value) { fastpathTV.EncMapUint32StringV(rv.Interface().(map[uint32]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32StringV(v map[uint32]string, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeString(c_UTF8, v2) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeString(c_UTF8, v[uint32(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeString(c_UTF8, v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint32UintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32UintR(rv reflect.Value) { fastpathTV.EncMapUint32UintV(rv.Interface().(map[uint32]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32UintV(v map[uint32]uint, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uint32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint32Uint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32Uint8R(rv reflect.Value) { fastpathTV.EncMapUint32Uint8V(rv.Interface().(map[uint32]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32Uint8V(v map[uint32]uint8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uint32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint32Uint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32Uint16R(rv reflect.Value) { fastpathTV.EncMapUint32Uint16V(rv.Interface().(map[uint32]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32Uint16V(v map[uint32]uint16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uint32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint32Uint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32Uint32R(rv reflect.Value) { fastpathTV.EncMapUint32Uint32V(rv.Interface().(map[uint32]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32Uint32V(v map[uint32]uint32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uint32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint32Uint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32Uint64R(rv reflect.Value) { fastpathTV.EncMapUint32Uint64V(rv.Interface().(map[uint32]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32Uint64V(v map[uint32]uint64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uint32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint32IntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32UintptrR(rv reflect.Value) { + fastpathTV.EncMapUint32UintptrV(rv.Interface().(map[uint32]uintptr), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapUint32UintptrV(v map[uint32]uintptr, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[uint32(k2)]) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v2) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapUint32IntR(rv reflect.Value) { fastpathTV.EncMapUint32IntV(rv.Interface().(map[uint32]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32IntV(v map[uint32]int, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uint32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint32Int8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32Int8R(rv reflect.Value) { fastpathTV.EncMapUint32Int8V(rv.Interface().(map[uint32]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32Int8V(v map[uint32]int8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uint32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint32Int16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32Int16R(rv reflect.Value) { fastpathTV.EncMapUint32Int16V(rv.Interface().(map[uint32]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32Int16V(v map[uint32]int16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uint32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint32Int32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32Int32R(rv reflect.Value) { fastpathTV.EncMapUint32Int32V(rv.Interface().(map[uint32]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32Int32V(v map[uint32]int32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uint32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint32Int64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32Int64R(rv reflect.Value) { fastpathTV.EncMapUint32Int64V(rv.Interface().(map[uint32]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32Int64V(v map[uint32]int64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uint32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint32Float32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32Float32R(rv reflect.Value) { fastpathTV.EncMapUint32Float32V(rv.Interface().(map[uint32]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32Float32V(v map[uint32]float32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeFloat32(v2) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat32(v[uint32(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat32(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint32Float64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32Float64R(rv reflect.Value) { fastpathTV.EncMapUint32Float64V(rv.Interface().(map[uint32]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32Float64V(v map[uint32]float64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeFloat64(v2) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat64(v[uint32(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat64(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint32BoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint32BoolR(rv reflect.Value) { fastpathTV.EncMapUint32BoolV(rv.Interface().(map[uint32]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint32BoolV(v map[uint32]bool, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeBool(v2) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeBool(v[uint32(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeBool(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint64IntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64IntfR(rv reflect.Value) { fastpathTV.EncMapUint64IntfV(rv.Interface().(map[uint64]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64IntfV(v map[uint64]interface{}, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - e.encode(v2) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[uint64(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } e.encode(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint64StringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64StringR(rv reflect.Value) { fastpathTV.EncMapUint64StringV(rv.Interface().(map[uint64]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64StringV(v map[uint64]string, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeString(c_UTF8, v2) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeString(c_UTF8, v[uint64(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeString(c_UTF8, v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint64UintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64UintR(rv reflect.Value) { fastpathTV.EncMapUint64UintV(rv.Interface().(map[uint64]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64UintV(v map[uint64]uint, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uint64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint64Uint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64Uint8R(rv reflect.Value) { fastpathTV.EncMapUint64Uint8V(rv.Interface().(map[uint64]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64Uint8V(v map[uint64]uint8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uint64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint64Uint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64Uint16R(rv reflect.Value) { fastpathTV.EncMapUint64Uint16V(rv.Interface().(map[uint64]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64Uint16V(v map[uint64]uint16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uint64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint64Uint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64Uint32R(rv reflect.Value) { fastpathTV.EncMapUint64Uint32V(rv.Interface().(map[uint64]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64Uint32V(v map[uint64]uint32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uint64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint64Uint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64Uint64R(rv reflect.Value) { fastpathTV.EncMapUint64Uint64V(rv.Interface().(map[uint64]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64Uint64V(v map[uint64]uint64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uint64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint64IntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64UintptrR(rv reflect.Value) { + fastpathTV.EncMapUint64UintptrV(rv.Interface().(map[uint64]uintptr), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapUint64UintptrV(v map[uint64]uintptr, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[uint64(k2)]) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v2) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapUint64IntR(rv reflect.Value) { fastpathTV.EncMapUint64IntV(rv.Interface().(map[uint64]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64IntV(v map[uint64]int, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uint64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint64Int8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64Int8R(rv reflect.Value) { fastpathTV.EncMapUint64Int8V(rv.Interface().(map[uint64]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64Int8V(v map[uint64]int8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uint64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint64Int16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64Int16R(rv reflect.Value) { fastpathTV.EncMapUint64Int16V(rv.Interface().(map[uint64]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64Int16V(v map[uint64]int16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uint64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint64Int32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64Int32R(rv reflect.Value) { fastpathTV.EncMapUint64Int32V(rv.Interface().(map[uint64]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64Int32V(v map[uint64]int32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uint64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint64Int64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64Int64R(rv reflect.Value) { fastpathTV.EncMapUint64Int64V(rv.Interface().(map[uint64]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64Int64V(v map[uint64]int64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uint64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint64Float32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64Float32R(rv reflect.Value) { fastpathTV.EncMapUint64Float32V(rv.Interface().(map[uint64]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64Float32V(v map[uint64]float32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeFloat32(v2) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat32(v[uint64(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat32(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint64Float64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64Float64R(rv reflect.Value) { fastpathTV.EncMapUint64Float64V(rv.Interface().(map[uint64]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64Float64V(v map[uint64]float64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeFloat64(v2) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat64(v[uint64(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat64(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapUint64BoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUint64BoolR(rv reflect.Value) { fastpathTV.EncMapUint64BoolV(rv.Interface().(map[uint64]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapUint64BoolV(v map[uint64]bool, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeUint(uint64(k2)) - ee.EncodeBool(v2) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeUint(uint64(uint64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeBool(v[uint64(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeUint(uint64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeBool(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntIntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapUintptrIntfR(rv reflect.Value) { + fastpathTV.EncMapUintptrIntfV(rv.Interface().(map[uintptr]interface{}), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapUintptrIntfV(v map[uintptr]interface{}, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(uintptr(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[uintptr(k2)]) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(k2) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v2) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapUintptrStringR(rv reflect.Value) { + fastpathTV.EncMapUintptrStringV(rv.Interface().(map[uintptr]string), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapUintptrStringV(v map[uintptr]string, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(uintptr(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeString(c_UTF8, v[uintptr(k2)]) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(k2) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeString(c_UTF8, v2) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapUintptrUintR(rv reflect.Value) { + fastpathTV.EncMapUintptrUintV(rv.Interface().(map[uintptr]uint), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapUintptrUintV(v map[uintptr]uint, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(uintptr(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uintptr(k2)])) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(k2) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v2)) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapUintptrUint8R(rv reflect.Value) { + fastpathTV.EncMapUintptrUint8V(rv.Interface().(map[uintptr]uint8), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapUintptrUint8V(v map[uintptr]uint8, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(uintptr(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uintptr(k2)])) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(k2) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v2)) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapUintptrUint16R(rv reflect.Value) { + fastpathTV.EncMapUintptrUint16V(rv.Interface().(map[uintptr]uint16), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapUintptrUint16V(v map[uintptr]uint16, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(uintptr(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uintptr(k2)])) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(k2) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v2)) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapUintptrUint32R(rv reflect.Value) { + fastpathTV.EncMapUintptrUint32V(rv.Interface().(map[uintptr]uint32), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapUintptrUint32V(v map[uintptr]uint32, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(uintptr(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uintptr(k2)])) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(k2) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v2)) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapUintptrUint64R(rv reflect.Value) { + fastpathTV.EncMapUintptrUint64V(rv.Interface().(map[uintptr]uint64), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapUintptrUint64V(v map[uintptr]uint64, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(uintptr(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[uintptr(k2)])) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(k2) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v2)) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapUintptrUintptrR(rv reflect.Value) { + fastpathTV.EncMapUintptrUintptrV(rv.Interface().(map[uintptr]uintptr), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapUintptrUintptrV(v map[uintptr]uintptr, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(uintptr(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[uintptr(k2)]) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(k2) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v2) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapUintptrIntR(rv reflect.Value) { + fastpathTV.EncMapUintptrIntV(rv.Interface().(map[uintptr]int), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapUintptrIntV(v map[uintptr]int, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(uintptr(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uintptr(k2)])) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(k2) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v2)) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapUintptrInt8R(rv reflect.Value) { + fastpathTV.EncMapUintptrInt8V(rv.Interface().(map[uintptr]int8), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapUintptrInt8V(v map[uintptr]int8, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(uintptr(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uintptr(k2)])) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(k2) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v2)) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapUintptrInt16R(rv reflect.Value) { + fastpathTV.EncMapUintptrInt16V(rv.Interface().(map[uintptr]int16), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapUintptrInt16V(v map[uintptr]int16, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(uintptr(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uintptr(k2)])) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(k2) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v2)) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapUintptrInt32R(rv reflect.Value) { + fastpathTV.EncMapUintptrInt32V(rv.Interface().(map[uintptr]int32), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapUintptrInt32V(v map[uintptr]int32, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(uintptr(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uintptr(k2)])) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(k2) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v2)) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapUintptrInt64R(rv reflect.Value) { + fastpathTV.EncMapUintptrInt64V(rv.Interface().(map[uintptr]int64), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapUintptrInt64V(v map[uintptr]int64, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(uintptr(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[uintptr(k2)])) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(k2) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v2)) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapUintptrFloat32R(rv reflect.Value) { + fastpathTV.EncMapUintptrFloat32V(rv.Interface().(map[uintptr]float32), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapUintptrFloat32V(v map[uintptr]float32, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(uintptr(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat32(v[uintptr(k2)]) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(k2) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat32(v2) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapUintptrFloat64R(rv reflect.Value) { + fastpathTV.EncMapUintptrFloat64V(rv.Interface().(map[uintptr]float64), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapUintptrFloat64V(v map[uintptr]float64, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(uintptr(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat64(v[uintptr(k2)]) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(k2) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat64(v2) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapUintptrBoolR(rv reflect.Value) { + fastpathTV.EncMapUintptrBoolV(rv.Interface().(map[uintptr]bool), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapUintptrBoolV(v map[uintptr]bool, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]uint64, len(v)) + var i int + for k, _ := range v { + v2[i] = uint64(k) + i++ + } + sort.Sort(uintSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(uintptr(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeBool(v[uintptr(k2)]) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + e.encode(k2) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeBool(v2) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapIntIntfR(rv reflect.Value) { fastpathTV.EncMapIntIntfV(rv.Interface().(map[int]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntIntfV(v map[int]interface{}, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - e.encode(v2) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[int(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } e.encode(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntStringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntStringR(rv reflect.Value) { fastpathTV.EncMapIntStringV(rv.Interface().(map[int]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntStringV(v map[int]string, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeString(c_UTF8, v2) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeString(c_UTF8, v[int(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeString(c_UTF8, v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntUintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntUintR(rv reflect.Value) { fastpathTV.EncMapIntUintV(rv.Interface().(map[int]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntUintV(v map[int]uint, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[int(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntUint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntUint8R(rv reflect.Value) { fastpathTV.EncMapIntUint8V(rv.Interface().(map[int]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntUint8V(v map[int]uint8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[int(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntUint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntUint16R(rv reflect.Value) { fastpathTV.EncMapIntUint16V(rv.Interface().(map[int]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntUint16V(v map[int]uint16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[int(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntUint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntUint32R(rv reflect.Value) { fastpathTV.EncMapIntUint32V(rv.Interface().(map[int]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntUint32V(v map[int]uint32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[int(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntUint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntUint64R(rv reflect.Value) { fastpathTV.EncMapIntUint64V(rv.Interface().(map[int]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntUint64V(v map[int]uint64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[int(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntIntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntUintptrR(rv reflect.Value) { + fastpathTV.EncMapIntUintptrV(rv.Interface().(map[int]uintptr), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapIntUintptrV(v map[int]uintptr, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[int(k2)]) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v2) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapIntIntR(rv reflect.Value) { fastpathTV.EncMapIntIntV(rv.Interface().(map[int]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntIntV(v map[int]int, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[int(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntInt8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntInt8R(rv reflect.Value) { fastpathTV.EncMapIntInt8V(rv.Interface().(map[int]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntInt8V(v map[int]int8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[int(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntInt16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntInt16R(rv reflect.Value) { fastpathTV.EncMapIntInt16V(rv.Interface().(map[int]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntInt16V(v map[int]int16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[int(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntInt32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntInt32R(rv reflect.Value) { fastpathTV.EncMapIntInt32V(rv.Interface().(map[int]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntInt32V(v map[int]int32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[int(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntInt64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntInt64R(rv reflect.Value) { fastpathTV.EncMapIntInt64V(rv.Interface().(map[int]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntInt64V(v map[int]int64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[int(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntFloat32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntFloat32R(rv reflect.Value) { fastpathTV.EncMapIntFloat32V(rv.Interface().(map[int]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntFloat32V(v map[int]float32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeFloat32(v2) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat32(v[int(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat32(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntFloat64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntFloat64R(rv reflect.Value) { fastpathTV.EncMapIntFloat64V(rv.Interface().(map[int]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntFloat64V(v map[int]float64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeFloat64(v2) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat64(v[int(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat64(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapIntBoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapIntBoolR(rv reflect.Value) { fastpathTV.EncMapIntBoolV(rv.Interface().(map[int]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapIntBoolV(v map[int]bool, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeBool(v2) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeBool(v[int(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeBool(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt8IntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8IntfR(rv reflect.Value) { fastpathTV.EncMapInt8IntfV(rv.Interface().(map[int8]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8IntfV(v map[int8]interface{}, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - e.encode(v2) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[int8(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } e.encode(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt8StringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8StringR(rv reflect.Value) { fastpathTV.EncMapInt8StringV(rv.Interface().(map[int8]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8StringV(v map[int8]string, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeString(c_UTF8, v2) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeString(c_UTF8, v[int8(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeString(c_UTF8, v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt8UintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8UintR(rv reflect.Value) { fastpathTV.EncMapInt8UintV(rv.Interface().(map[int8]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8UintV(v map[int8]uint, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[int8(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt8Uint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8Uint8R(rv reflect.Value) { fastpathTV.EncMapInt8Uint8V(rv.Interface().(map[int8]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8Uint8V(v map[int8]uint8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[int8(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt8Uint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8Uint16R(rv reflect.Value) { fastpathTV.EncMapInt8Uint16V(rv.Interface().(map[int8]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8Uint16V(v map[int8]uint16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[int8(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt8Uint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8Uint32R(rv reflect.Value) { fastpathTV.EncMapInt8Uint32V(rv.Interface().(map[int8]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8Uint32V(v map[int8]uint32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[int8(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt8Uint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8Uint64R(rv reflect.Value) { fastpathTV.EncMapInt8Uint64V(rv.Interface().(map[int8]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8Uint64V(v map[int8]uint64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[int8(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt8IntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8UintptrR(rv reflect.Value) { + fastpathTV.EncMapInt8UintptrV(rv.Interface().(map[int8]uintptr), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapInt8UintptrV(v map[int8]uintptr, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[int8(k2)]) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v2) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapInt8IntR(rv reflect.Value) { fastpathTV.EncMapInt8IntV(rv.Interface().(map[int8]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8IntV(v map[int8]int, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[int8(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt8Int8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8Int8R(rv reflect.Value) { fastpathTV.EncMapInt8Int8V(rv.Interface().(map[int8]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8Int8V(v map[int8]int8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[int8(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt8Int16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8Int16R(rv reflect.Value) { fastpathTV.EncMapInt8Int16V(rv.Interface().(map[int8]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8Int16V(v map[int8]int16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[int8(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt8Int32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8Int32R(rv reflect.Value) { fastpathTV.EncMapInt8Int32V(rv.Interface().(map[int8]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8Int32V(v map[int8]int32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[int8(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt8Int64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8Int64R(rv reflect.Value) { fastpathTV.EncMapInt8Int64V(rv.Interface().(map[int8]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8Int64V(v map[int8]int64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[int8(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt8Float32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8Float32R(rv reflect.Value) { fastpathTV.EncMapInt8Float32V(rv.Interface().(map[int8]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8Float32V(v map[int8]float32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeFloat32(v2) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat32(v[int8(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat32(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt8Float64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8Float64R(rv reflect.Value) { fastpathTV.EncMapInt8Float64V(rv.Interface().(map[int8]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8Float64V(v map[int8]float64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeFloat64(v2) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat64(v[int8(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat64(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt8BoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt8BoolR(rv reflect.Value) { fastpathTV.EncMapInt8BoolV(rv.Interface().(map[int8]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt8BoolV(v map[int8]bool, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeBool(v2) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int8(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeBool(v[int8(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeBool(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt16IntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16IntfR(rv reflect.Value) { fastpathTV.EncMapInt16IntfV(rv.Interface().(map[int16]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16IntfV(v map[int16]interface{}, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - e.encode(v2) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[int16(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } e.encode(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt16StringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16StringR(rv reflect.Value) { fastpathTV.EncMapInt16StringV(rv.Interface().(map[int16]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16StringV(v map[int16]string, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeString(c_UTF8, v2) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeString(c_UTF8, v[int16(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeString(c_UTF8, v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt16UintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16UintR(rv reflect.Value) { fastpathTV.EncMapInt16UintV(rv.Interface().(map[int16]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16UintV(v map[int16]uint, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[int16(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt16Uint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16Uint8R(rv reflect.Value) { fastpathTV.EncMapInt16Uint8V(rv.Interface().(map[int16]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16Uint8V(v map[int16]uint8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[int16(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt16Uint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16Uint16R(rv reflect.Value) { fastpathTV.EncMapInt16Uint16V(rv.Interface().(map[int16]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16Uint16V(v map[int16]uint16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[int16(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt16Uint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16Uint32R(rv reflect.Value) { fastpathTV.EncMapInt16Uint32V(rv.Interface().(map[int16]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16Uint32V(v map[int16]uint32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[int16(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt16Uint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16Uint64R(rv reflect.Value) { fastpathTV.EncMapInt16Uint64V(rv.Interface().(map[int16]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16Uint64V(v map[int16]uint64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[int16(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt16IntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16UintptrR(rv reflect.Value) { + fastpathTV.EncMapInt16UintptrV(rv.Interface().(map[int16]uintptr), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapInt16UintptrV(v map[int16]uintptr, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[int16(k2)]) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v2) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapInt16IntR(rv reflect.Value) { fastpathTV.EncMapInt16IntV(rv.Interface().(map[int16]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16IntV(v map[int16]int, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[int16(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt16Int8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16Int8R(rv reflect.Value) { fastpathTV.EncMapInt16Int8V(rv.Interface().(map[int16]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16Int8V(v map[int16]int8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[int16(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt16Int16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16Int16R(rv reflect.Value) { fastpathTV.EncMapInt16Int16V(rv.Interface().(map[int16]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16Int16V(v map[int16]int16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[int16(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt16Int32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16Int32R(rv reflect.Value) { fastpathTV.EncMapInt16Int32V(rv.Interface().(map[int16]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16Int32V(v map[int16]int32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[int16(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt16Int64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16Int64R(rv reflect.Value) { fastpathTV.EncMapInt16Int64V(rv.Interface().(map[int16]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16Int64V(v map[int16]int64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[int16(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt16Float32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16Float32R(rv reflect.Value) { fastpathTV.EncMapInt16Float32V(rv.Interface().(map[int16]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16Float32V(v map[int16]float32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeFloat32(v2) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat32(v[int16(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat32(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt16Float64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16Float64R(rv reflect.Value) { fastpathTV.EncMapInt16Float64V(rv.Interface().(map[int16]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16Float64V(v map[int16]float64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeFloat64(v2) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat64(v[int16(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat64(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt16BoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt16BoolR(rv reflect.Value) { fastpathTV.EncMapInt16BoolV(rv.Interface().(map[int16]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt16BoolV(v map[int16]bool, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeBool(v2) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int16(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeBool(v[int16(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeBool(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt32IntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32IntfR(rv reflect.Value) { fastpathTV.EncMapInt32IntfV(rv.Interface().(map[int32]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32IntfV(v map[int32]interface{}, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - e.encode(v2) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[int32(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } e.encode(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt32StringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32StringR(rv reflect.Value) { fastpathTV.EncMapInt32StringV(rv.Interface().(map[int32]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32StringV(v map[int32]string, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeString(c_UTF8, v2) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeString(c_UTF8, v[int32(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeString(c_UTF8, v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt32UintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32UintR(rv reflect.Value) { fastpathTV.EncMapInt32UintV(rv.Interface().(map[int32]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32UintV(v map[int32]uint, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[int32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt32Uint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32Uint8R(rv reflect.Value) { fastpathTV.EncMapInt32Uint8V(rv.Interface().(map[int32]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32Uint8V(v map[int32]uint8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[int32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt32Uint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32Uint16R(rv reflect.Value) { fastpathTV.EncMapInt32Uint16V(rv.Interface().(map[int32]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32Uint16V(v map[int32]uint16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[int32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt32Uint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32Uint32R(rv reflect.Value) { fastpathTV.EncMapInt32Uint32V(rv.Interface().(map[int32]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32Uint32V(v map[int32]uint32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[int32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt32Uint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32Uint64R(rv reflect.Value) { fastpathTV.EncMapInt32Uint64V(rv.Interface().(map[int32]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32Uint64V(v map[int32]uint64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[int32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt32IntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32UintptrR(rv reflect.Value) { + fastpathTV.EncMapInt32UintptrV(rv.Interface().(map[int32]uintptr), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapInt32UintptrV(v map[int32]uintptr, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[int32(k2)]) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v2) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapInt32IntR(rv reflect.Value) { fastpathTV.EncMapInt32IntV(rv.Interface().(map[int32]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32IntV(v map[int32]int, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[int32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt32Int8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32Int8R(rv reflect.Value) { fastpathTV.EncMapInt32Int8V(rv.Interface().(map[int32]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32Int8V(v map[int32]int8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[int32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt32Int16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32Int16R(rv reflect.Value) { fastpathTV.EncMapInt32Int16V(rv.Interface().(map[int32]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32Int16V(v map[int32]int16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[int32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt32Int32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32Int32R(rv reflect.Value) { fastpathTV.EncMapInt32Int32V(rv.Interface().(map[int32]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32Int32V(v map[int32]int32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[int32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt32Int64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32Int64R(rv reflect.Value) { fastpathTV.EncMapInt32Int64V(rv.Interface().(map[int32]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32Int64V(v map[int32]int64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[int32(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt32Float32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32Float32R(rv reflect.Value) { fastpathTV.EncMapInt32Float32V(rv.Interface().(map[int32]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32Float32V(v map[int32]float32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeFloat32(v2) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat32(v[int32(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat32(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt32Float64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32Float64R(rv reflect.Value) { fastpathTV.EncMapInt32Float64V(rv.Interface().(map[int32]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32Float64V(v map[int32]float64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeFloat64(v2) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat64(v[int32(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat64(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt32BoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt32BoolR(rv reflect.Value) { fastpathTV.EncMapInt32BoolV(rv.Interface().(map[int32]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt32BoolV(v map[int32]bool, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeBool(v2) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int32(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeBool(v[int32(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeBool(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt64IntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64IntfR(rv reflect.Value) { fastpathTV.EncMapInt64IntfV(rv.Interface().(map[int64]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64IntfV(v map[int64]interface{}, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - e.encode(v2) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[int64(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } e.encode(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt64StringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64StringR(rv reflect.Value) { fastpathTV.EncMapInt64StringV(rv.Interface().(map[int64]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64StringV(v map[int64]string, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeString(c_UTF8, v2) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeString(c_UTF8, v[int64(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeString(c_UTF8, v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt64UintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64UintR(rv reflect.Value) { fastpathTV.EncMapInt64UintV(rv.Interface().(map[int64]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64UintV(v map[int64]uint, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[int64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt64Uint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64Uint8R(rv reflect.Value) { fastpathTV.EncMapInt64Uint8V(rv.Interface().(map[int64]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64Uint8V(v map[int64]uint8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[int64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt64Uint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64Uint16R(rv reflect.Value) { fastpathTV.EncMapInt64Uint16V(rv.Interface().(map[int64]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64Uint16V(v map[int64]uint16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[int64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt64Uint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64Uint32R(rv reflect.Value) { fastpathTV.EncMapInt64Uint32V(rv.Interface().(map[int64]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64Uint32V(v map[int64]uint32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[int64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt64Uint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64Uint64R(rv reflect.Value) { fastpathTV.EncMapInt64Uint64V(rv.Interface().(map[int64]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64Uint64V(v map[int64]uint64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[int64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt64IntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64UintptrR(rv reflect.Value) { + fastpathTV.EncMapInt64UintptrV(rv.Interface().(map[int64]uintptr), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapInt64UintptrV(v map[int64]uintptr, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[int64(k2)]) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v2) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapInt64IntR(rv reflect.Value) { fastpathTV.EncMapInt64IntV(rv.Interface().(map[int64]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64IntV(v map[int64]int, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[int64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt64Int8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64Int8R(rv reflect.Value) { fastpathTV.EncMapInt64Int8V(rv.Interface().(map[int64]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64Int8V(v map[int64]int8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[int64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt64Int16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64Int16R(rv reflect.Value) { fastpathTV.EncMapInt64Int16V(rv.Interface().(map[int64]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64Int16V(v map[int64]int16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[int64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt64Int32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64Int32R(rv reflect.Value) { fastpathTV.EncMapInt64Int32V(rv.Interface().(map[int64]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64Int32V(v map[int64]int32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[int64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt64Int64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64Int64R(rv reflect.Value) { fastpathTV.EncMapInt64Int64V(rv.Interface().(map[int64]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64Int64V(v map[int64]int64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[int64(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt64Float32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64Float32R(rv reflect.Value) { fastpathTV.EncMapInt64Float32V(rv.Interface().(map[int64]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64Float32V(v map[int64]float32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeFloat32(v2) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat32(v[int64(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat32(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt64Float64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64Float64R(rv reflect.Value) { fastpathTV.EncMapInt64Float64V(rv.Interface().(map[int64]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64Float64V(v map[int64]float64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeFloat64(v2) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat64(v[int64(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat64(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapInt64BoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapInt64BoolR(rv reflect.Value) { fastpathTV.EncMapInt64BoolV(rv.Interface().(map[int64]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapInt64BoolV(v map[int64]bool, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeInt(int64(k2)) - ee.EncodeBool(v2) + if e.h.Canonical { + v2 := make([]int64, len(v)) + var i int + for k, _ := range v { + v2[i] = int64(k) + i++ + } + sort.Sort(intSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeInt(int64(int64(k2))) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeBool(v[int64(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeInt(int64(k2)) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeBool(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapBoolIntfR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolIntfR(rv reflect.Value) { fastpathTV.EncMapBoolIntfV(rv.Interface().(map[bool]interface{}), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolIntfV(v map[bool]interface{}, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - e.encode(v2) + if e.h.Canonical { + v2 := make([]bool, len(v)) + var i int + for k, _ := range v { + v2[i] = bool(k) + i++ + } + sort.Sort(boolSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeBool(bool(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[bool(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } e.encode(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapBoolStringR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolStringR(rv reflect.Value) { fastpathTV.EncMapBoolStringV(rv.Interface().(map[bool]string), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolStringV(v map[bool]string, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeString(c_UTF8, v2) + if e.h.Canonical { + v2 := make([]bool, len(v)) + var i int + for k, _ := range v { + v2[i] = bool(k) + i++ + } + sort.Sort(boolSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeBool(bool(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeString(c_UTF8, v[bool(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeString(c_UTF8, v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapBoolUintR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolUintR(rv reflect.Value) { fastpathTV.EncMapBoolUintV(rv.Interface().(map[bool]uint), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolUintV(v map[bool]uint, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]bool, len(v)) + var i int + for k, _ := range v { + v2[i] = bool(k) + i++ + } + sort.Sort(boolSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeBool(bool(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[bool(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapBoolUint8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolUint8R(rv reflect.Value) { fastpathTV.EncMapBoolUint8V(rv.Interface().(map[bool]uint8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolUint8V(v map[bool]uint8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]bool, len(v)) + var i int + for k, _ := range v { + v2[i] = bool(k) + i++ + } + sort.Sort(boolSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeBool(bool(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[bool(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapBoolUint16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolUint16R(rv reflect.Value) { fastpathTV.EncMapBoolUint16V(rv.Interface().(map[bool]uint16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolUint16V(v map[bool]uint16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]bool, len(v)) + var i int + for k, _ := range v { + v2[i] = bool(k) + i++ + } + sort.Sort(boolSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeBool(bool(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[bool(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapBoolUint32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolUint32R(rv reflect.Value) { fastpathTV.EncMapBoolUint32V(rv.Interface().(map[bool]uint32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolUint32V(v map[bool]uint32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]bool, len(v)) + var i int + for k, _ := range v { + v2[i] = bool(k) + i++ + } + sort.Sort(boolSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeBool(bool(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[bool(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapBoolUint64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolUint64R(rv reflect.Value) { fastpathTV.EncMapBoolUint64V(rv.Interface().(map[bool]uint64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolUint64V(v map[bool]uint64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeUint(uint64(v2)) + if e.h.Canonical { + v2 := make([]bool, len(v)) + var i int + for k, _ := range v { + v2[i] = bool(k) + i++ + } + sort.Sort(boolSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeBool(bool(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeUint(uint64(v[bool(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeUint(uint64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapBoolIntR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolUintptrR(rv reflect.Value) { + fastpathTV.EncMapBoolUintptrV(rv.Interface().(map[bool]uintptr), fastpathCheckNilFalse, f.e) +} +func (_ fastpathT) EncMapBoolUintptrV(v map[bool]uintptr, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + ee.EncodeMapStart(len(v)) + if e.h.Canonical { + v2 := make([]bool, len(v)) + var i int + for k, _ := range v { + v2[i] = bool(k) + i++ + } + sort.Sort(boolSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeBool(bool(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v[bool(k2)]) + } + } else { + for k2, v2 := range v { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeBool(k2) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + e.encode(v2) + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } +} + +func (f *encFnInfo) fastpathEncMapBoolIntR(rv reflect.Value) { fastpathTV.EncMapBoolIntV(rv.Interface().(map[bool]int), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolIntV(v map[bool]int, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]bool, len(v)) + var i int + for k, _ := range v { + v2[i] = bool(k) + i++ + } + sort.Sort(boolSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeBool(bool(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[bool(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapBoolInt8R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolInt8R(rv reflect.Value) { fastpathTV.EncMapBoolInt8V(rv.Interface().(map[bool]int8), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolInt8V(v map[bool]int8, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]bool, len(v)) + var i int + for k, _ := range v { + v2[i] = bool(k) + i++ + } + sort.Sort(boolSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeBool(bool(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[bool(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapBoolInt16R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolInt16R(rv reflect.Value) { fastpathTV.EncMapBoolInt16V(rv.Interface().(map[bool]int16), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolInt16V(v map[bool]int16, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]bool, len(v)) + var i int + for k, _ := range v { + v2[i] = bool(k) + i++ + } + sort.Sort(boolSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeBool(bool(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[bool(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapBoolInt32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolInt32R(rv reflect.Value) { fastpathTV.EncMapBoolInt32V(rv.Interface().(map[bool]int32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolInt32V(v map[bool]int32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]bool, len(v)) + var i int + for k, _ := range v { + v2[i] = bool(k) + i++ + } + sort.Sort(boolSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeBool(bool(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[bool(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapBoolInt64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolInt64R(rv reflect.Value) { fastpathTV.EncMapBoolInt64V(rv.Interface().(map[bool]int64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolInt64V(v map[bool]int64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeInt(int64(v2)) + if e.h.Canonical { + v2 := make([]bool, len(v)) + var i int + for k, _ := range v { + v2[i] = bool(k) + i++ + } + sort.Sort(boolSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeBool(bool(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeInt(int64(v[bool(k2)])) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeInt(int64(v2)) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapBoolFloat32R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolFloat32R(rv reflect.Value) { fastpathTV.EncMapBoolFloat32V(rv.Interface().(map[bool]float32), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolFloat32V(v map[bool]float32, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeFloat32(v2) + if e.h.Canonical { + v2 := make([]bool, len(v)) + var i int + for k, _ := range v { + v2[i] = bool(k) + i++ + } + sort.Sort(boolSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeBool(bool(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat32(v[bool(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat32(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapBoolFloat64R(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolFloat64R(rv reflect.Value) { fastpathTV.EncMapBoolFloat64V(rv.Interface().(map[bool]float64), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolFloat64V(v map[bool]float64, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeFloat64(v2) + if e.h.Canonical { + v2 := make([]bool, len(v)) + var i int + for k, _ := range v { + v2[i] = bool(k) + i++ + } + sort.Sort(boolSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeBool(bool(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeFloat64(v[bool(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeFloat64(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } -func (f encFnInfo) fastpathEncMapBoolBoolR(rv reflect.Value) { +func (f *encFnInfo) fastpathEncMapBoolBoolR(rv reflect.Value) { fastpathTV.EncMapBoolBoolV(rv.Interface().(map[bool]bool), fastpathCheckNilFalse, f.e) } func (_ fastpathT) EncMapBoolBoolV(v map[bool]bool, checkNil bool, e *Encoder) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - - if e.be { - for k2, v2 := range v { - ee.EncodeBool(k2) - ee.EncodeBool(v2) + if e.h.Canonical { + v2 := make([]bool, len(v)) + var i int + for k, _ := range v { + v2[i] = bool(k) + i++ + } + sort.Sort(boolSlice(v2)) + for _, k2 := range v2 { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + ee.EncodeBool(bool(k2)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + ee.EncodeBool(v[bool(k2)]) } } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } ee.EncodeBool(k2) - ee.EncodeMapKVSeparator() + if cr != nil { + cr.sendContainerState(containerMapValue) + } ee.EncodeBool(v2) - j++ } - ee.EncodeMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } } @@ -10208,6 +15954,9 @@ func (_ fastpathT) EncMapBoolBoolV(v map[bool]bool, checkNil bool, e *Encoder) { // -- -- fast path type switch func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { + if !fastpathEnabled { + return false + } switch v := iv.(type) { case []interface{}: @@ -10274,6 +16023,14 @@ func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { *v = v2 } + case map[interface{}]uintptr: + fastpathTV.DecMapIntfUintptrV(v, fastpathCheckNilFalse, false, d) + case *map[interface{}]uintptr: + v2, changed2 := fastpathTV.DecMapIntfUintptrV(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + case map[interface{}]int: fastpathTV.DecMapIntfIntV(v, fastpathCheckNilFalse, false, d) case *map[interface{}]int: @@ -10402,6 +16159,14 @@ func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { *v = v2 } + case map[string]uintptr: + fastpathTV.DecMapStringUintptrV(v, fastpathCheckNilFalse, false, d) + case *map[string]uintptr: + v2, changed2 := fastpathTV.DecMapStringUintptrV(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + case map[string]int: fastpathTV.DecMapStringIntV(v, fastpathCheckNilFalse, false, d) case *map[string]int: @@ -10530,6 +16295,14 @@ func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { *v = v2 } + case map[float32]uintptr: + fastpathTV.DecMapFloat32UintptrV(v, fastpathCheckNilFalse, false, d) + case *map[float32]uintptr: + v2, changed2 := fastpathTV.DecMapFloat32UintptrV(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + case map[float32]int: fastpathTV.DecMapFloat32IntV(v, fastpathCheckNilFalse, false, d) case *map[float32]int: @@ -10658,6 +16431,14 @@ func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { *v = v2 } + case map[float64]uintptr: + fastpathTV.DecMapFloat64UintptrV(v, fastpathCheckNilFalse, false, d) + case *map[float64]uintptr: + v2, changed2 := fastpathTV.DecMapFloat64UintptrV(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + case map[float64]int: fastpathTV.DecMapFloat64IntV(v, fastpathCheckNilFalse, false, d) case *map[float64]int: @@ -10786,6 +16567,14 @@ func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { *v = v2 } + case map[uint]uintptr: + fastpathTV.DecMapUintUintptrV(v, fastpathCheckNilFalse, false, d) + case *map[uint]uintptr: + v2, changed2 := fastpathTV.DecMapUintUintptrV(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + case map[uint]int: fastpathTV.DecMapUintIntV(v, fastpathCheckNilFalse, false, d) case *map[uint]int: @@ -10906,6 +16695,14 @@ func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { *v = v2 } + case map[uint8]uintptr: + fastpathTV.DecMapUint8UintptrV(v, fastpathCheckNilFalse, false, d) + case *map[uint8]uintptr: + v2, changed2 := fastpathTV.DecMapUint8UintptrV(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + case map[uint8]int: fastpathTV.DecMapUint8IntV(v, fastpathCheckNilFalse, false, d) case *map[uint8]int: @@ -11034,6 +16831,14 @@ func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { *v = v2 } + case map[uint16]uintptr: + fastpathTV.DecMapUint16UintptrV(v, fastpathCheckNilFalse, false, d) + case *map[uint16]uintptr: + v2, changed2 := fastpathTV.DecMapUint16UintptrV(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + case map[uint16]int: fastpathTV.DecMapUint16IntV(v, fastpathCheckNilFalse, false, d) case *map[uint16]int: @@ -11162,6 +16967,14 @@ func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { *v = v2 } + case map[uint32]uintptr: + fastpathTV.DecMapUint32UintptrV(v, fastpathCheckNilFalse, false, d) + case *map[uint32]uintptr: + v2, changed2 := fastpathTV.DecMapUint32UintptrV(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + case map[uint32]int: fastpathTV.DecMapUint32IntV(v, fastpathCheckNilFalse, false, d) case *map[uint32]int: @@ -11290,6 +17103,14 @@ func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { *v = v2 } + case map[uint64]uintptr: + fastpathTV.DecMapUint64UintptrV(v, fastpathCheckNilFalse, false, d) + case *map[uint64]uintptr: + v2, changed2 := fastpathTV.DecMapUint64UintptrV(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + case map[uint64]int: fastpathTV.DecMapUint64IntV(v, fastpathCheckNilFalse, false, d) case *map[uint64]int: @@ -11354,6 +17175,142 @@ func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { *v = v2 } + case []uintptr: + fastpathTV.DecSliceUintptrV(v, fastpathCheckNilFalse, false, d) + case *[]uintptr: + v2, changed2 := fastpathTV.DecSliceUintptrV(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + + case map[uintptr]interface{}: + fastpathTV.DecMapUintptrIntfV(v, fastpathCheckNilFalse, false, d) + case *map[uintptr]interface{}: + v2, changed2 := fastpathTV.DecMapUintptrIntfV(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + + case map[uintptr]string: + fastpathTV.DecMapUintptrStringV(v, fastpathCheckNilFalse, false, d) + case *map[uintptr]string: + v2, changed2 := fastpathTV.DecMapUintptrStringV(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + + case map[uintptr]uint: + fastpathTV.DecMapUintptrUintV(v, fastpathCheckNilFalse, false, d) + case *map[uintptr]uint: + v2, changed2 := fastpathTV.DecMapUintptrUintV(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + + case map[uintptr]uint8: + fastpathTV.DecMapUintptrUint8V(v, fastpathCheckNilFalse, false, d) + case *map[uintptr]uint8: + v2, changed2 := fastpathTV.DecMapUintptrUint8V(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + + case map[uintptr]uint16: + fastpathTV.DecMapUintptrUint16V(v, fastpathCheckNilFalse, false, d) + case *map[uintptr]uint16: + v2, changed2 := fastpathTV.DecMapUintptrUint16V(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + + case map[uintptr]uint32: + fastpathTV.DecMapUintptrUint32V(v, fastpathCheckNilFalse, false, d) + case *map[uintptr]uint32: + v2, changed2 := fastpathTV.DecMapUintptrUint32V(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + + case map[uintptr]uint64: + fastpathTV.DecMapUintptrUint64V(v, fastpathCheckNilFalse, false, d) + case *map[uintptr]uint64: + v2, changed2 := fastpathTV.DecMapUintptrUint64V(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + + case map[uintptr]uintptr: + fastpathTV.DecMapUintptrUintptrV(v, fastpathCheckNilFalse, false, d) + case *map[uintptr]uintptr: + v2, changed2 := fastpathTV.DecMapUintptrUintptrV(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + + case map[uintptr]int: + fastpathTV.DecMapUintptrIntV(v, fastpathCheckNilFalse, false, d) + case *map[uintptr]int: + v2, changed2 := fastpathTV.DecMapUintptrIntV(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + + case map[uintptr]int8: + fastpathTV.DecMapUintptrInt8V(v, fastpathCheckNilFalse, false, d) + case *map[uintptr]int8: + v2, changed2 := fastpathTV.DecMapUintptrInt8V(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + + case map[uintptr]int16: + fastpathTV.DecMapUintptrInt16V(v, fastpathCheckNilFalse, false, d) + case *map[uintptr]int16: + v2, changed2 := fastpathTV.DecMapUintptrInt16V(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + + case map[uintptr]int32: + fastpathTV.DecMapUintptrInt32V(v, fastpathCheckNilFalse, false, d) + case *map[uintptr]int32: + v2, changed2 := fastpathTV.DecMapUintptrInt32V(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + + case map[uintptr]int64: + fastpathTV.DecMapUintptrInt64V(v, fastpathCheckNilFalse, false, d) + case *map[uintptr]int64: + v2, changed2 := fastpathTV.DecMapUintptrInt64V(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + + case map[uintptr]float32: + fastpathTV.DecMapUintptrFloat32V(v, fastpathCheckNilFalse, false, d) + case *map[uintptr]float32: + v2, changed2 := fastpathTV.DecMapUintptrFloat32V(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + + case map[uintptr]float64: + fastpathTV.DecMapUintptrFloat64V(v, fastpathCheckNilFalse, false, d) + case *map[uintptr]float64: + v2, changed2 := fastpathTV.DecMapUintptrFloat64V(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + + case map[uintptr]bool: + fastpathTV.DecMapUintptrBoolV(v, fastpathCheckNilFalse, false, d) + case *map[uintptr]bool: + v2, changed2 := fastpathTV.DecMapUintptrBoolV(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + case []int: fastpathTV.DecSliceIntV(v, fastpathCheckNilFalse, false, d) case *[]int: @@ -11418,6 +17375,14 @@ func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { *v = v2 } + case map[int]uintptr: + fastpathTV.DecMapIntUintptrV(v, fastpathCheckNilFalse, false, d) + case *map[int]uintptr: + v2, changed2 := fastpathTV.DecMapIntUintptrV(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + case map[int]int: fastpathTV.DecMapIntIntV(v, fastpathCheckNilFalse, false, d) case *map[int]int: @@ -11546,6 +17511,14 @@ func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { *v = v2 } + case map[int8]uintptr: + fastpathTV.DecMapInt8UintptrV(v, fastpathCheckNilFalse, false, d) + case *map[int8]uintptr: + v2, changed2 := fastpathTV.DecMapInt8UintptrV(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + case map[int8]int: fastpathTV.DecMapInt8IntV(v, fastpathCheckNilFalse, false, d) case *map[int8]int: @@ -11674,6 +17647,14 @@ func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { *v = v2 } + case map[int16]uintptr: + fastpathTV.DecMapInt16UintptrV(v, fastpathCheckNilFalse, false, d) + case *map[int16]uintptr: + v2, changed2 := fastpathTV.DecMapInt16UintptrV(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + case map[int16]int: fastpathTV.DecMapInt16IntV(v, fastpathCheckNilFalse, false, d) case *map[int16]int: @@ -11802,6 +17783,14 @@ func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { *v = v2 } + case map[int32]uintptr: + fastpathTV.DecMapInt32UintptrV(v, fastpathCheckNilFalse, false, d) + case *map[int32]uintptr: + v2, changed2 := fastpathTV.DecMapInt32UintptrV(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + case map[int32]int: fastpathTV.DecMapInt32IntV(v, fastpathCheckNilFalse, false, d) case *map[int32]int: @@ -11930,6 +17919,14 @@ func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { *v = v2 } + case map[int64]uintptr: + fastpathTV.DecMapInt64UintptrV(v, fastpathCheckNilFalse, false, d) + case *map[int64]uintptr: + v2, changed2 := fastpathTV.DecMapInt64UintptrV(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + case map[int64]int: fastpathTV.DecMapInt64IntV(v, fastpathCheckNilFalse, false, d) case *map[int64]int: @@ -12058,6 +18055,14 @@ func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { *v = v2 } + case map[bool]uintptr: + fastpathTV.DecMapBoolUintptrV(v, fastpathCheckNilFalse, false, d) + case *map[bool]uintptr: + v2, changed2 := fastpathTV.DecMapBoolUintptrV(*v, fastpathCheckNilFalse, true, d) + if changed2 { + *v = v2 + } + case map[bool]int: fastpathTV.DecMapBoolIntV(v, fastpathCheckNilFalse, false, d) case *map[bool]int: @@ -12123,6 +18128,7 @@ func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { } default: + _ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release) return false } return true @@ -12130,9 +18136,9 @@ func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { // -- -- fast path functions -func (f decFnInfo) fastpathDecSliceIntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceIntfR(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]interface{}) v, changed := fastpathTV.DecSliceIntfV(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -12150,10 +18156,9 @@ func (f fastpathT) DecSliceIntfX(vp *[]interface{}, checkNil bool, d *Decoder) { *vp = v } } -func (_ fastpathT) DecSliceIntfV(v []interface{}, checkNil bool, canChange bool, - d *Decoder) (_ []interface{}, changed bool) { +func (_ fastpathT) DecSliceIntfV(v []interface{}, checkNil bool, canChange bool, d *Decoder) (_ []interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -12162,52 +18167,83 @@ func (_ fastpathT) DecSliceIntfV(v []interface{}, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() - if canChange && v == nil { - if containerLenS <= 0 { - v = []interface{}{} - } else { - v = make([]interface{}, containerLenS, containerLenS) - } - changed = true - } if containerLenS == 0 { - if canChange && len(v) != 0 { - v = v[:0] + if canChange { + if v == nil { + v = []interface{}{} + } else if len(v) != 0 { + v = v[:0] + } changed = true } + slh.End() return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS + x2read := containerLenS + var xtrunc bool if containerLenS > cap(v) { if canChange { - s := make([]interface{}, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 16) + if xtrunc { + if xlen <= cap(v) { + v = v[:xlen] + } else { + v = make([]interface{}, xlen) + } + } else { + v = make([]interface{}, xlen) + } changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) } + x2read = len(v) } else if containerLenS != len(v) { - v = v[:containerLenS] - changed = true + if canChange { + v = v[:containerLenS] + changed = true + } } - // all checks done. cannot go past len. j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { + slh.ElemContainerState(j) d.decode(&v[j]) } - if !canChange { + if xtrunc { for ; j < containerLenS; j++ { + v = append(v, nil) + slh.ElemContainerState(j) + d.decode(&v[j]) + } + } else if !canChange { + for ; j < containerLenS; j++ { + slh.ElemContainerState(j) d.swallow() } } } else { + breakFound := dd.CheckBreak() + if breakFound { + if canChange { + if v == nil { + v = []interface{}{} + } else if len(v) != 0 { + v = v[:0] + } + changed = true + } + slh.End() + return v, changed + } + if cap(v) == 0 { + v = make([]interface{}, 1, 4) + changed = true + } j := 0 - for ; !dd.CheckBreak(); j++ { + for ; !breakFound; j++ { if j >= len(v) { if canChange { v = append(v, nil) @@ -12216,24 +18252,27 @@ func (_ fastpathT) DecSliceIntfV(v []interface{}, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + slh.ElemContainerState(j) + if j < len(v) { d.decode(&v[j]) } else { d.swallow() } + breakFound = dd.CheckBreak() + } + if canChange && j < len(v) { + v = v[:j] + changed = true } - slh.End() } + slh.End() return v, changed } -func (f decFnInfo) fastpathDecSliceStringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceStringR(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]string) v, changed := fastpathTV.DecSliceStringV(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -12251,10 +18290,9 @@ func (f fastpathT) DecSliceStringX(vp *[]string, checkNil bool, d *Decoder) { *vp = v } } -func (_ fastpathT) DecSliceStringV(v []string, checkNil bool, canChange bool, - d *Decoder) (_ []string, changed bool) { +func (_ fastpathT) DecSliceStringV(v []string, checkNil bool, canChange bool, d *Decoder) (_ []string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -12263,52 +18301,83 @@ func (_ fastpathT) DecSliceStringV(v []string, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() - if canChange && v == nil { - if containerLenS <= 0 { - v = []string{} - } else { - v = make([]string, containerLenS, containerLenS) - } - changed = true - } if containerLenS == 0 { - if canChange && len(v) != 0 { - v = v[:0] + if canChange { + if v == nil { + v = []string{} + } else if len(v) != 0 { + v = v[:0] + } changed = true } + slh.End() return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS + x2read := containerLenS + var xtrunc bool if containerLenS > cap(v) { if canChange { - s := make([]string, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 16) + if xtrunc { + if xlen <= cap(v) { + v = v[:xlen] + } else { + v = make([]string, xlen) + } + } else { + v = make([]string, xlen) + } changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) } + x2read = len(v) } else if containerLenS != len(v) { - v = v[:containerLenS] - changed = true + if canChange { + v = v[:containerLenS] + changed = true + } } - // all checks done. cannot go past len. j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { + slh.ElemContainerState(j) v[j] = dd.DecodeString() } - if !canChange { + if xtrunc { for ; j < containerLenS; j++ { + v = append(v, "") + slh.ElemContainerState(j) + v[j] = dd.DecodeString() + } + } else if !canChange { + for ; j < containerLenS; j++ { + slh.ElemContainerState(j) d.swallow() } } } else { + breakFound := dd.CheckBreak() + if breakFound { + if canChange { + if v == nil { + v = []string{} + } else if len(v) != 0 { + v = v[:0] + } + changed = true + } + slh.End() + return v, changed + } + if cap(v) == 0 { + v = make([]string, 1, 4) + changed = true + } j := 0 - for ; !dd.CheckBreak(); j++ { + for ; !breakFound; j++ { if j >= len(v) { if canChange { v = append(v, "") @@ -12317,23 +18386,26 @@ func (_ fastpathT) DecSliceStringV(v []string, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + slh.ElemContainerState(j) + if j < len(v) { v[j] = dd.DecodeString() } else { d.swallow() } + breakFound = dd.CheckBreak() + } + if canChange && j < len(v) { + v = v[:j] + changed = true } - slh.End() } + slh.End() return v, changed } -func (f decFnInfo) fastpathDecSliceFloat32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceFloat32R(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]float32) v, changed := fastpathTV.DecSliceFloat32V(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -12351,10 +18423,9 @@ func (f fastpathT) DecSliceFloat32X(vp *[]float32, checkNil bool, d *Decoder) { *vp = v } } -func (_ fastpathT) DecSliceFloat32V(v []float32, checkNil bool, canChange bool, - d *Decoder) (_ []float32, changed bool) { +func (_ fastpathT) DecSliceFloat32V(v []float32, checkNil bool, canChange bool, d *Decoder) (_ []float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -12363,52 +18434,83 @@ func (_ fastpathT) DecSliceFloat32V(v []float32, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() - if canChange && v == nil { - if containerLenS <= 0 { - v = []float32{} - } else { - v = make([]float32, containerLenS, containerLenS) - } - changed = true - } if containerLenS == 0 { - if canChange && len(v) != 0 { - v = v[:0] + if canChange { + if v == nil { + v = []float32{} + } else if len(v) != 0 { + v = v[:0] + } changed = true } + slh.End() return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS + x2read := containerLenS + var xtrunc bool if containerLenS > cap(v) { if canChange { - s := make([]float32, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 4) + if xtrunc { + if xlen <= cap(v) { + v = v[:xlen] + } else { + v = make([]float32, xlen) + } + } else { + v = make([]float32, xlen) + } changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) } + x2read = len(v) } else if containerLenS != len(v) { - v = v[:containerLenS] - changed = true + if canChange { + v = v[:containerLenS] + changed = true + } } - // all checks done. cannot go past len. j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { + slh.ElemContainerState(j) v[j] = float32(dd.DecodeFloat(true)) } - if !canChange { + if xtrunc { for ; j < containerLenS; j++ { + v = append(v, 0) + slh.ElemContainerState(j) + v[j] = float32(dd.DecodeFloat(true)) + } + } else if !canChange { + for ; j < containerLenS; j++ { + slh.ElemContainerState(j) d.swallow() } } } else { + breakFound := dd.CheckBreak() + if breakFound { + if canChange { + if v == nil { + v = []float32{} + } else if len(v) != 0 { + v = v[:0] + } + changed = true + } + slh.End() + return v, changed + } + if cap(v) == 0 { + v = make([]float32, 1, 4) + changed = true + } j := 0 - for ; !dd.CheckBreak(); j++ { + for ; !breakFound; j++ { if j >= len(v) { if canChange { v = append(v, 0) @@ -12417,23 +18519,26 @@ func (_ fastpathT) DecSliceFloat32V(v []float32, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + slh.ElemContainerState(j) + if j < len(v) { v[j] = float32(dd.DecodeFloat(true)) } else { d.swallow() } + breakFound = dd.CheckBreak() + } + if canChange && j < len(v) { + v = v[:j] + changed = true } - slh.End() } + slh.End() return v, changed } -func (f decFnInfo) fastpathDecSliceFloat64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceFloat64R(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]float64) v, changed := fastpathTV.DecSliceFloat64V(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -12451,10 +18556,9 @@ func (f fastpathT) DecSliceFloat64X(vp *[]float64, checkNil bool, d *Decoder) { *vp = v } } -func (_ fastpathT) DecSliceFloat64V(v []float64, checkNil bool, canChange bool, - d *Decoder) (_ []float64, changed bool) { +func (_ fastpathT) DecSliceFloat64V(v []float64, checkNil bool, canChange bool, d *Decoder) (_ []float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -12463,52 +18567,83 @@ func (_ fastpathT) DecSliceFloat64V(v []float64, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() - if canChange && v == nil { - if containerLenS <= 0 { - v = []float64{} - } else { - v = make([]float64, containerLenS, containerLenS) - } - changed = true - } if containerLenS == 0 { - if canChange && len(v) != 0 { - v = v[:0] + if canChange { + if v == nil { + v = []float64{} + } else if len(v) != 0 { + v = v[:0] + } changed = true } + slh.End() return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS + x2read := containerLenS + var xtrunc bool if containerLenS > cap(v) { if canChange { - s := make([]float64, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 8) + if xtrunc { + if xlen <= cap(v) { + v = v[:xlen] + } else { + v = make([]float64, xlen) + } + } else { + v = make([]float64, xlen) + } changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) } + x2read = len(v) } else if containerLenS != len(v) { - v = v[:containerLenS] - changed = true + if canChange { + v = v[:containerLenS] + changed = true + } } - // all checks done. cannot go past len. j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { + slh.ElemContainerState(j) v[j] = dd.DecodeFloat(false) } - if !canChange { + if xtrunc { for ; j < containerLenS; j++ { + v = append(v, 0) + slh.ElemContainerState(j) + v[j] = dd.DecodeFloat(false) + } + } else if !canChange { + for ; j < containerLenS; j++ { + slh.ElemContainerState(j) d.swallow() } } } else { + breakFound := dd.CheckBreak() + if breakFound { + if canChange { + if v == nil { + v = []float64{} + } else if len(v) != 0 { + v = v[:0] + } + changed = true + } + slh.End() + return v, changed + } + if cap(v) == 0 { + v = make([]float64, 1, 4) + changed = true + } j := 0 - for ; !dd.CheckBreak(); j++ { + for ; !breakFound; j++ { if j >= len(v) { if canChange { v = append(v, 0) @@ -12517,23 +18652,26 @@ func (_ fastpathT) DecSliceFloat64V(v []float64, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + slh.ElemContainerState(j) + if j < len(v) { v[j] = dd.DecodeFloat(false) } else { d.swallow() } + breakFound = dd.CheckBreak() + } + if canChange && j < len(v) { + v = v[:j] + changed = true } - slh.End() } + slh.End() return v, changed } -func (f decFnInfo) fastpathDecSliceUintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceUintR(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]uint) v, changed := fastpathTV.DecSliceUintV(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -12551,10 +18689,9 @@ func (f fastpathT) DecSliceUintX(vp *[]uint, checkNil bool, d *Decoder) { *vp = v } } -func (_ fastpathT) DecSliceUintV(v []uint, checkNil bool, canChange bool, - d *Decoder) (_ []uint, changed bool) { +func (_ fastpathT) DecSliceUintV(v []uint, checkNil bool, canChange bool, d *Decoder) (_ []uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -12563,52 +18700,83 @@ func (_ fastpathT) DecSliceUintV(v []uint, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() - if canChange && v == nil { - if containerLenS <= 0 { - v = []uint{} - } else { - v = make([]uint, containerLenS, containerLenS) - } - changed = true - } if containerLenS == 0 { - if canChange && len(v) != 0 { - v = v[:0] + if canChange { + if v == nil { + v = []uint{} + } else if len(v) != 0 { + v = v[:0] + } changed = true } + slh.End() return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS + x2read := containerLenS + var xtrunc bool if containerLenS > cap(v) { if canChange { - s := make([]uint, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 8) + if xtrunc { + if xlen <= cap(v) { + v = v[:xlen] + } else { + v = make([]uint, xlen) + } + } else { + v = make([]uint, xlen) + } changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) } + x2read = len(v) } else if containerLenS != len(v) { - v = v[:containerLenS] - changed = true + if canChange { + v = v[:containerLenS] + changed = true + } } - // all checks done. cannot go past len. j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { + slh.ElemContainerState(j) v[j] = uint(dd.DecodeUint(uintBitsize)) } - if !canChange { + if xtrunc { for ; j < containerLenS; j++ { + v = append(v, 0) + slh.ElemContainerState(j) + v[j] = uint(dd.DecodeUint(uintBitsize)) + } + } else if !canChange { + for ; j < containerLenS; j++ { + slh.ElemContainerState(j) d.swallow() } } } else { + breakFound := dd.CheckBreak() + if breakFound { + if canChange { + if v == nil { + v = []uint{} + } else if len(v) != 0 { + v = v[:0] + } + changed = true + } + slh.End() + return v, changed + } + if cap(v) == 0 { + v = make([]uint, 1, 4) + changed = true + } j := 0 - for ; !dd.CheckBreak(); j++ { + for ; !breakFound; j++ { if j >= len(v) { if canChange { v = append(v, 0) @@ -12617,23 +18785,26 @@ func (_ fastpathT) DecSliceUintV(v []uint, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + slh.ElemContainerState(j) + if j < len(v) { v[j] = uint(dd.DecodeUint(uintBitsize)) } else { d.swallow() } + breakFound = dd.CheckBreak() + } + if canChange && j < len(v) { + v = v[:j] + changed = true } - slh.End() } + slh.End() return v, changed } -func (f decFnInfo) fastpathDecSliceUint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceUint16R(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]uint16) v, changed := fastpathTV.DecSliceUint16V(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -12651,10 +18822,9 @@ func (f fastpathT) DecSliceUint16X(vp *[]uint16, checkNil bool, d *Decoder) { *vp = v } } -func (_ fastpathT) DecSliceUint16V(v []uint16, checkNil bool, canChange bool, - d *Decoder) (_ []uint16, changed bool) { +func (_ fastpathT) DecSliceUint16V(v []uint16, checkNil bool, canChange bool, d *Decoder) (_ []uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -12663,52 +18833,83 @@ func (_ fastpathT) DecSliceUint16V(v []uint16, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() - if canChange && v == nil { - if containerLenS <= 0 { - v = []uint16{} - } else { - v = make([]uint16, containerLenS, containerLenS) - } - changed = true - } if containerLenS == 0 { - if canChange && len(v) != 0 { - v = v[:0] + if canChange { + if v == nil { + v = []uint16{} + } else if len(v) != 0 { + v = v[:0] + } changed = true } + slh.End() return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS + x2read := containerLenS + var xtrunc bool if containerLenS > cap(v) { if canChange { - s := make([]uint16, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 2) + if xtrunc { + if xlen <= cap(v) { + v = v[:xlen] + } else { + v = make([]uint16, xlen) + } + } else { + v = make([]uint16, xlen) + } changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) } + x2read = len(v) } else if containerLenS != len(v) { - v = v[:containerLenS] - changed = true + if canChange { + v = v[:containerLenS] + changed = true + } } - // all checks done. cannot go past len. j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { + slh.ElemContainerState(j) v[j] = uint16(dd.DecodeUint(16)) } - if !canChange { + if xtrunc { for ; j < containerLenS; j++ { + v = append(v, 0) + slh.ElemContainerState(j) + v[j] = uint16(dd.DecodeUint(16)) + } + } else if !canChange { + for ; j < containerLenS; j++ { + slh.ElemContainerState(j) d.swallow() } } } else { + breakFound := dd.CheckBreak() + if breakFound { + if canChange { + if v == nil { + v = []uint16{} + } else if len(v) != 0 { + v = v[:0] + } + changed = true + } + slh.End() + return v, changed + } + if cap(v) == 0 { + v = make([]uint16, 1, 4) + changed = true + } j := 0 - for ; !dd.CheckBreak(); j++ { + for ; !breakFound; j++ { if j >= len(v) { if canChange { v = append(v, 0) @@ -12717,23 +18918,26 @@ func (_ fastpathT) DecSliceUint16V(v []uint16, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + slh.ElemContainerState(j) + if j < len(v) { v[j] = uint16(dd.DecodeUint(16)) } else { d.swallow() } + breakFound = dd.CheckBreak() + } + if canChange && j < len(v) { + v = v[:j] + changed = true } - slh.End() } + slh.End() return v, changed } -func (f decFnInfo) fastpathDecSliceUint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceUint32R(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]uint32) v, changed := fastpathTV.DecSliceUint32V(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -12751,10 +18955,9 @@ func (f fastpathT) DecSliceUint32X(vp *[]uint32, checkNil bool, d *Decoder) { *vp = v } } -func (_ fastpathT) DecSliceUint32V(v []uint32, checkNil bool, canChange bool, - d *Decoder) (_ []uint32, changed bool) { +func (_ fastpathT) DecSliceUint32V(v []uint32, checkNil bool, canChange bool, d *Decoder) (_ []uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -12763,52 +18966,83 @@ func (_ fastpathT) DecSliceUint32V(v []uint32, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() - if canChange && v == nil { - if containerLenS <= 0 { - v = []uint32{} - } else { - v = make([]uint32, containerLenS, containerLenS) - } - changed = true - } if containerLenS == 0 { - if canChange && len(v) != 0 { - v = v[:0] + if canChange { + if v == nil { + v = []uint32{} + } else if len(v) != 0 { + v = v[:0] + } changed = true } + slh.End() return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS + x2read := containerLenS + var xtrunc bool if containerLenS > cap(v) { if canChange { - s := make([]uint32, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 4) + if xtrunc { + if xlen <= cap(v) { + v = v[:xlen] + } else { + v = make([]uint32, xlen) + } + } else { + v = make([]uint32, xlen) + } changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) } + x2read = len(v) } else if containerLenS != len(v) { - v = v[:containerLenS] - changed = true + if canChange { + v = v[:containerLenS] + changed = true + } } - // all checks done. cannot go past len. j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { + slh.ElemContainerState(j) v[j] = uint32(dd.DecodeUint(32)) } - if !canChange { + if xtrunc { for ; j < containerLenS; j++ { + v = append(v, 0) + slh.ElemContainerState(j) + v[j] = uint32(dd.DecodeUint(32)) + } + } else if !canChange { + for ; j < containerLenS; j++ { + slh.ElemContainerState(j) d.swallow() } } } else { + breakFound := dd.CheckBreak() + if breakFound { + if canChange { + if v == nil { + v = []uint32{} + } else if len(v) != 0 { + v = v[:0] + } + changed = true + } + slh.End() + return v, changed + } + if cap(v) == 0 { + v = make([]uint32, 1, 4) + changed = true + } j := 0 - for ; !dd.CheckBreak(); j++ { + for ; !breakFound; j++ { if j >= len(v) { if canChange { v = append(v, 0) @@ -12817,23 +19051,26 @@ func (_ fastpathT) DecSliceUint32V(v []uint32, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + slh.ElemContainerState(j) + if j < len(v) { v[j] = uint32(dd.DecodeUint(32)) } else { d.swallow() } + breakFound = dd.CheckBreak() + } + if canChange && j < len(v) { + v = v[:j] + changed = true } - slh.End() } + slh.End() return v, changed } -func (f decFnInfo) fastpathDecSliceUint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceUint64R(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]uint64) v, changed := fastpathTV.DecSliceUint64V(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -12851,10 +19088,9 @@ func (f fastpathT) DecSliceUint64X(vp *[]uint64, checkNil bool, d *Decoder) { *vp = v } } -func (_ fastpathT) DecSliceUint64V(v []uint64, checkNil bool, canChange bool, - d *Decoder) (_ []uint64, changed bool) { +func (_ fastpathT) DecSliceUint64V(v []uint64, checkNil bool, canChange bool, d *Decoder) (_ []uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -12863,52 +19099,83 @@ func (_ fastpathT) DecSliceUint64V(v []uint64, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() - if canChange && v == nil { - if containerLenS <= 0 { - v = []uint64{} - } else { - v = make([]uint64, containerLenS, containerLenS) - } - changed = true - } if containerLenS == 0 { - if canChange && len(v) != 0 { - v = v[:0] + if canChange { + if v == nil { + v = []uint64{} + } else if len(v) != 0 { + v = v[:0] + } changed = true } + slh.End() return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS + x2read := containerLenS + var xtrunc bool if containerLenS > cap(v) { if canChange { - s := make([]uint64, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 8) + if xtrunc { + if xlen <= cap(v) { + v = v[:xlen] + } else { + v = make([]uint64, xlen) + } + } else { + v = make([]uint64, xlen) + } changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) } + x2read = len(v) } else if containerLenS != len(v) { - v = v[:containerLenS] - changed = true + if canChange { + v = v[:containerLenS] + changed = true + } } - // all checks done. cannot go past len. j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { + slh.ElemContainerState(j) v[j] = dd.DecodeUint(64) } - if !canChange { + if xtrunc { for ; j < containerLenS; j++ { + v = append(v, 0) + slh.ElemContainerState(j) + v[j] = dd.DecodeUint(64) + } + } else if !canChange { + for ; j < containerLenS; j++ { + slh.ElemContainerState(j) d.swallow() } } } else { + breakFound := dd.CheckBreak() + if breakFound { + if canChange { + if v == nil { + v = []uint64{} + } else if len(v) != 0 { + v = v[:0] + } + changed = true + } + slh.End() + return v, changed + } + if cap(v) == 0 { + v = make([]uint64, 1, 4) + changed = true + } j := 0 - for ; !dd.CheckBreak(); j++ { + for ; !breakFound; j++ { if j >= len(v) { if canChange { v = append(v, 0) @@ -12917,23 +19184,159 @@ func (_ fastpathT) DecSliceUint64V(v []uint64, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + slh.ElemContainerState(j) + if j < len(v) { v[j] = dd.DecodeUint(64) } else { d.swallow() } + breakFound = dd.CheckBreak() + } + if canChange && j < len(v) { + v = v[:j] + changed = true } - slh.End() } + slh.End() return v, changed } -func (f decFnInfo) fastpathDecSliceIntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceUintptrR(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { + vp := rv.Addr().Interface().(*[]uintptr) + v, changed := fastpathTV.DecSliceUintptrV(*vp, fastpathCheckNilFalse, !array, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().([]uintptr) + fastpathTV.DecSliceUintptrV(v, fastpathCheckNilFalse, false, f.d) + } +} + +func (f fastpathT) DecSliceUintptrX(vp *[]uintptr, checkNil bool, d *Decoder) { + v, changed := f.DecSliceUintptrV(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecSliceUintptrV(v []uintptr, checkNil bool, canChange bool, d *Decoder) (_ []uintptr, changed bool) { + dd := d.d + + if checkNil && dd.TryDecodeAsNil() { + if v != nil { + changed = true + } + return nil, changed + } + + slh, containerLenS := d.decSliceHelperStart() + if containerLenS == 0 { + if canChange { + if v == nil { + v = []uintptr{} + } else if len(v) != 0 { + v = v[:0] + } + changed = true + } + slh.End() + return v, changed + } + + if containerLenS > 0 { + x2read := containerLenS + var xtrunc bool + if containerLenS > cap(v) { + if canChange { + var xlen int + xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 8) + if xtrunc { + if xlen <= cap(v) { + v = v[:xlen] + } else { + v = make([]uintptr, xlen) + } + } else { + v = make([]uintptr, xlen) + } + changed = true + } else { + d.arrayCannotExpand(len(v), containerLenS) + } + x2read = len(v) + } else if containerLenS != len(v) { + if canChange { + v = v[:containerLenS] + changed = true + } + } + j := 0 + for ; j < x2read; j++ { + slh.ElemContainerState(j) + v[j] = uintptr(dd.DecodeUint(uintBitsize)) + } + if xtrunc { + for ; j < containerLenS; j++ { + v = append(v, 0) + slh.ElemContainerState(j) + v[j] = uintptr(dd.DecodeUint(uintBitsize)) + } + } else if !canChange { + for ; j < containerLenS; j++ { + slh.ElemContainerState(j) + d.swallow() + } + } + } else { + breakFound := dd.CheckBreak() + if breakFound { + if canChange { + if v == nil { + v = []uintptr{} + } else if len(v) != 0 { + v = v[:0] + } + changed = true + } + slh.End() + return v, changed + } + if cap(v) == 0 { + v = make([]uintptr, 1, 4) + changed = true + } + j := 0 + for ; !breakFound; j++ { + if j >= len(v) { + if canChange { + v = append(v, 0) + changed = true + } else { + d.arrayCannotExpand(len(v), j+1) + } + } + slh.ElemContainerState(j) + if j < len(v) { + v[j] = uintptr(dd.DecodeUint(uintBitsize)) + } else { + d.swallow() + } + breakFound = dd.CheckBreak() + } + if canChange && j < len(v) { + v = v[:j] + changed = true + } + } + slh.End() + return v, changed +} + +func (f *decFnInfo) fastpathDecSliceIntR(rv reflect.Value) { + array := f.seq == seqTypeArray + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]int) v, changed := fastpathTV.DecSliceIntV(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -12951,10 +19354,9 @@ func (f fastpathT) DecSliceIntX(vp *[]int, checkNil bool, d *Decoder) { *vp = v } } -func (_ fastpathT) DecSliceIntV(v []int, checkNil bool, canChange bool, - d *Decoder) (_ []int, changed bool) { +func (_ fastpathT) DecSliceIntV(v []int, checkNil bool, canChange bool, d *Decoder) (_ []int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -12963,52 +19365,83 @@ func (_ fastpathT) DecSliceIntV(v []int, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() - if canChange && v == nil { - if containerLenS <= 0 { - v = []int{} - } else { - v = make([]int, containerLenS, containerLenS) - } - changed = true - } if containerLenS == 0 { - if canChange && len(v) != 0 { - v = v[:0] + if canChange { + if v == nil { + v = []int{} + } else if len(v) != 0 { + v = v[:0] + } changed = true } + slh.End() return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS + x2read := containerLenS + var xtrunc bool if containerLenS > cap(v) { if canChange { - s := make([]int, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 8) + if xtrunc { + if xlen <= cap(v) { + v = v[:xlen] + } else { + v = make([]int, xlen) + } + } else { + v = make([]int, xlen) + } changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) } + x2read = len(v) } else if containerLenS != len(v) { - v = v[:containerLenS] - changed = true + if canChange { + v = v[:containerLenS] + changed = true + } } - // all checks done. cannot go past len. j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { + slh.ElemContainerState(j) v[j] = int(dd.DecodeInt(intBitsize)) } - if !canChange { + if xtrunc { for ; j < containerLenS; j++ { + v = append(v, 0) + slh.ElemContainerState(j) + v[j] = int(dd.DecodeInt(intBitsize)) + } + } else if !canChange { + for ; j < containerLenS; j++ { + slh.ElemContainerState(j) d.swallow() } } } else { + breakFound := dd.CheckBreak() + if breakFound { + if canChange { + if v == nil { + v = []int{} + } else if len(v) != 0 { + v = v[:0] + } + changed = true + } + slh.End() + return v, changed + } + if cap(v) == 0 { + v = make([]int, 1, 4) + changed = true + } j := 0 - for ; !dd.CheckBreak(); j++ { + for ; !breakFound; j++ { if j >= len(v) { if canChange { v = append(v, 0) @@ -13017,23 +19450,26 @@ func (_ fastpathT) DecSliceIntV(v []int, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + slh.ElemContainerState(j) + if j < len(v) { v[j] = int(dd.DecodeInt(intBitsize)) } else { d.swallow() } + breakFound = dd.CheckBreak() + } + if canChange && j < len(v) { + v = v[:j] + changed = true } - slh.End() } + slh.End() return v, changed } -func (f decFnInfo) fastpathDecSliceInt8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceInt8R(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]int8) v, changed := fastpathTV.DecSliceInt8V(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -13051,10 +19487,9 @@ func (f fastpathT) DecSliceInt8X(vp *[]int8, checkNil bool, d *Decoder) { *vp = v } } -func (_ fastpathT) DecSliceInt8V(v []int8, checkNil bool, canChange bool, - d *Decoder) (_ []int8, changed bool) { +func (_ fastpathT) DecSliceInt8V(v []int8, checkNil bool, canChange bool, d *Decoder) (_ []int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -13063,52 +19498,83 @@ func (_ fastpathT) DecSliceInt8V(v []int8, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() - if canChange && v == nil { - if containerLenS <= 0 { - v = []int8{} - } else { - v = make([]int8, containerLenS, containerLenS) - } - changed = true - } if containerLenS == 0 { - if canChange && len(v) != 0 { - v = v[:0] + if canChange { + if v == nil { + v = []int8{} + } else if len(v) != 0 { + v = v[:0] + } changed = true } + slh.End() return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS + x2read := containerLenS + var xtrunc bool if containerLenS > cap(v) { if canChange { - s := make([]int8, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 1) + if xtrunc { + if xlen <= cap(v) { + v = v[:xlen] + } else { + v = make([]int8, xlen) + } + } else { + v = make([]int8, xlen) + } changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) } + x2read = len(v) } else if containerLenS != len(v) { - v = v[:containerLenS] - changed = true + if canChange { + v = v[:containerLenS] + changed = true + } } - // all checks done. cannot go past len. j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { + slh.ElemContainerState(j) v[j] = int8(dd.DecodeInt(8)) } - if !canChange { + if xtrunc { for ; j < containerLenS; j++ { + v = append(v, 0) + slh.ElemContainerState(j) + v[j] = int8(dd.DecodeInt(8)) + } + } else if !canChange { + for ; j < containerLenS; j++ { + slh.ElemContainerState(j) d.swallow() } } } else { + breakFound := dd.CheckBreak() + if breakFound { + if canChange { + if v == nil { + v = []int8{} + } else if len(v) != 0 { + v = v[:0] + } + changed = true + } + slh.End() + return v, changed + } + if cap(v) == 0 { + v = make([]int8, 1, 4) + changed = true + } j := 0 - for ; !dd.CheckBreak(); j++ { + for ; !breakFound; j++ { if j >= len(v) { if canChange { v = append(v, 0) @@ -13117,23 +19583,26 @@ func (_ fastpathT) DecSliceInt8V(v []int8, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + slh.ElemContainerState(j) + if j < len(v) { v[j] = int8(dd.DecodeInt(8)) } else { d.swallow() } + breakFound = dd.CheckBreak() + } + if canChange && j < len(v) { + v = v[:j] + changed = true } - slh.End() } + slh.End() return v, changed } -func (f decFnInfo) fastpathDecSliceInt16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceInt16R(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]int16) v, changed := fastpathTV.DecSliceInt16V(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -13151,10 +19620,9 @@ func (f fastpathT) DecSliceInt16X(vp *[]int16, checkNil bool, d *Decoder) { *vp = v } } -func (_ fastpathT) DecSliceInt16V(v []int16, checkNil bool, canChange bool, - d *Decoder) (_ []int16, changed bool) { +func (_ fastpathT) DecSliceInt16V(v []int16, checkNil bool, canChange bool, d *Decoder) (_ []int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -13163,52 +19631,83 @@ func (_ fastpathT) DecSliceInt16V(v []int16, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() - if canChange && v == nil { - if containerLenS <= 0 { - v = []int16{} - } else { - v = make([]int16, containerLenS, containerLenS) - } - changed = true - } if containerLenS == 0 { - if canChange && len(v) != 0 { - v = v[:0] + if canChange { + if v == nil { + v = []int16{} + } else if len(v) != 0 { + v = v[:0] + } changed = true } + slh.End() return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS + x2read := containerLenS + var xtrunc bool if containerLenS > cap(v) { if canChange { - s := make([]int16, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 2) + if xtrunc { + if xlen <= cap(v) { + v = v[:xlen] + } else { + v = make([]int16, xlen) + } + } else { + v = make([]int16, xlen) + } changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) } + x2read = len(v) } else if containerLenS != len(v) { - v = v[:containerLenS] - changed = true + if canChange { + v = v[:containerLenS] + changed = true + } } - // all checks done. cannot go past len. j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { + slh.ElemContainerState(j) v[j] = int16(dd.DecodeInt(16)) } - if !canChange { + if xtrunc { for ; j < containerLenS; j++ { + v = append(v, 0) + slh.ElemContainerState(j) + v[j] = int16(dd.DecodeInt(16)) + } + } else if !canChange { + for ; j < containerLenS; j++ { + slh.ElemContainerState(j) d.swallow() } } } else { + breakFound := dd.CheckBreak() + if breakFound { + if canChange { + if v == nil { + v = []int16{} + } else if len(v) != 0 { + v = v[:0] + } + changed = true + } + slh.End() + return v, changed + } + if cap(v) == 0 { + v = make([]int16, 1, 4) + changed = true + } j := 0 - for ; !dd.CheckBreak(); j++ { + for ; !breakFound; j++ { if j >= len(v) { if canChange { v = append(v, 0) @@ -13217,23 +19716,26 @@ func (_ fastpathT) DecSliceInt16V(v []int16, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + slh.ElemContainerState(j) + if j < len(v) { v[j] = int16(dd.DecodeInt(16)) } else { d.swallow() } + breakFound = dd.CheckBreak() + } + if canChange && j < len(v) { + v = v[:j] + changed = true } - slh.End() } + slh.End() return v, changed } -func (f decFnInfo) fastpathDecSliceInt32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceInt32R(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]int32) v, changed := fastpathTV.DecSliceInt32V(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -13251,10 +19753,9 @@ func (f fastpathT) DecSliceInt32X(vp *[]int32, checkNil bool, d *Decoder) { *vp = v } } -func (_ fastpathT) DecSliceInt32V(v []int32, checkNil bool, canChange bool, - d *Decoder) (_ []int32, changed bool) { +func (_ fastpathT) DecSliceInt32V(v []int32, checkNil bool, canChange bool, d *Decoder) (_ []int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -13263,52 +19764,83 @@ func (_ fastpathT) DecSliceInt32V(v []int32, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() - if canChange && v == nil { - if containerLenS <= 0 { - v = []int32{} - } else { - v = make([]int32, containerLenS, containerLenS) - } - changed = true - } if containerLenS == 0 { - if canChange && len(v) != 0 { - v = v[:0] + if canChange { + if v == nil { + v = []int32{} + } else if len(v) != 0 { + v = v[:0] + } changed = true } + slh.End() return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS + x2read := containerLenS + var xtrunc bool if containerLenS > cap(v) { if canChange { - s := make([]int32, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 4) + if xtrunc { + if xlen <= cap(v) { + v = v[:xlen] + } else { + v = make([]int32, xlen) + } + } else { + v = make([]int32, xlen) + } changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) } + x2read = len(v) } else if containerLenS != len(v) { - v = v[:containerLenS] - changed = true + if canChange { + v = v[:containerLenS] + changed = true + } } - // all checks done. cannot go past len. j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { + slh.ElemContainerState(j) v[j] = int32(dd.DecodeInt(32)) } - if !canChange { + if xtrunc { for ; j < containerLenS; j++ { + v = append(v, 0) + slh.ElemContainerState(j) + v[j] = int32(dd.DecodeInt(32)) + } + } else if !canChange { + for ; j < containerLenS; j++ { + slh.ElemContainerState(j) d.swallow() } } } else { + breakFound := dd.CheckBreak() + if breakFound { + if canChange { + if v == nil { + v = []int32{} + } else if len(v) != 0 { + v = v[:0] + } + changed = true + } + slh.End() + return v, changed + } + if cap(v) == 0 { + v = make([]int32, 1, 4) + changed = true + } j := 0 - for ; !dd.CheckBreak(); j++ { + for ; !breakFound; j++ { if j >= len(v) { if canChange { v = append(v, 0) @@ -13317,23 +19849,26 @@ func (_ fastpathT) DecSliceInt32V(v []int32, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + slh.ElemContainerState(j) + if j < len(v) { v[j] = int32(dd.DecodeInt(32)) } else { d.swallow() } + breakFound = dd.CheckBreak() + } + if canChange && j < len(v) { + v = v[:j] + changed = true } - slh.End() } + slh.End() return v, changed } -func (f decFnInfo) fastpathDecSliceInt64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceInt64R(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]int64) v, changed := fastpathTV.DecSliceInt64V(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -13351,10 +19886,9 @@ func (f fastpathT) DecSliceInt64X(vp *[]int64, checkNil bool, d *Decoder) { *vp = v } } -func (_ fastpathT) DecSliceInt64V(v []int64, checkNil bool, canChange bool, - d *Decoder) (_ []int64, changed bool) { +func (_ fastpathT) DecSliceInt64V(v []int64, checkNil bool, canChange bool, d *Decoder) (_ []int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -13363,52 +19897,83 @@ func (_ fastpathT) DecSliceInt64V(v []int64, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() - if canChange && v == nil { - if containerLenS <= 0 { - v = []int64{} - } else { - v = make([]int64, containerLenS, containerLenS) - } - changed = true - } if containerLenS == 0 { - if canChange && len(v) != 0 { - v = v[:0] + if canChange { + if v == nil { + v = []int64{} + } else if len(v) != 0 { + v = v[:0] + } changed = true } + slh.End() return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS + x2read := containerLenS + var xtrunc bool if containerLenS > cap(v) { if canChange { - s := make([]int64, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 8) + if xtrunc { + if xlen <= cap(v) { + v = v[:xlen] + } else { + v = make([]int64, xlen) + } + } else { + v = make([]int64, xlen) + } changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) } + x2read = len(v) } else if containerLenS != len(v) { - v = v[:containerLenS] - changed = true + if canChange { + v = v[:containerLenS] + changed = true + } } - // all checks done. cannot go past len. j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { + slh.ElemContainerState(j) v[j] = dd.DecodeInt(64) } - if !canChange { + if xtrunc { for ; j < containerLenS; j++ { + v = append(v, 0) + slh.ElemContainerState(j) + v[j] = dd.DecodeInt(64) + } + } else if !canChange { + for ; j < containerLenS; j++ { + slh.ElemContainerState(j) d.swallow() } } } else { + breakFound := dd.CheckBreak() + if breakFound { + if canChange { + if v == nil { + v = []int64{} + } else if len(v) != 0 { + v = v[:0] + } + changed = true + } + slh.End() + return v, changed + } + if cap(v) == 0 { + v = make([]int64, 1, 4) + changed = true + } j := 0 - for ; !dd.CheckBreak(); j++ { + for ; !breakFound; j++ { if j >= len(v) { if canChange { v = append(v, 0) @@ -13417,23 +19982,26 @@ func (_ fastpathT) DecSliceInt64V(v []int64, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + slh.ElemContainerState(j) + if j < len(v) { v[j] = dd.DecodeInt(64) } else { d.swallow() } + breakFound = dd.CheckBreak() + } + if canChange && j < len(v) { + v = v[:j] + changed = true } - slh.End() } + slh.End() return v, changed } -func (f decFnInfo) fastpathDecSliceBoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecSliceBoolR(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { vp := rv.Addr().Interface().(*[]bool) v, changed := fastpathTV.DecSliceBoolV(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -13451,10 +20019,9 @@ func (f fastpathT) DecSliceBoolX(vp *[]bool, checkNil bool, d *Decoder) { *vp = v } } -func (_ fastpathT) DecSliceBoolV(v []bool, checkNil bool, canChange bool, - d *Decoder) (_ []bool, changed bool) { +func (_ fastpathT) DecSliceBoolV(v []bool, checkNil bool, canChange bool, d *Decoder) (_ []bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -13463,52 +20030,83 @@ func (_ fastpathT) DecSliceBoolV(v []bool, checkNil bool, canChange bool, } slh, containerLenS := d.decSliceHelperStart() - if canChange && v == nil { - if containerLenS <= 0 { - v = []bool{} - } else { - v = make([]bool, containerLenS, containerLenS) - } - changed = true - } if containerLenS == 0 { - if canChange && len(v) != 0 { - v = v[:0] + if canChange { + if v == nil { + v = []bool{} + } else if len(v) != 0 { + v = v[:0] + } changed = true } + slh.End() return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS + x2read := containerLenS + var xtrunc bool if containerLenS > cap(v) { if canChange { - s := make([]bool, containerLenS, containerLenS) - // copy(s, v[:cap(v)]) - v = s + var xlen int + xlen, xtrunc = decInferLen(containerLenS, d.h.MaxInitLen, 1) + if xtrunc { + if xlen <= cap(v) { + v = v[:xlen] + } else { + v = make([]bool, xlen) + } + } else { + v = make([]bool, xlen) + } changed = true } else { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) } + x2read = len(v) } else if containerLenS != len(v) { - v = v[:containerLenS] - changed = true + if canChange { + v = v[:containerLenS] + changed = true + } } - // all checks done. cannot go past len. j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { + slh.ElemContainerState(j) v[j] = dd.DecodeBool() } - if !canChange { + if xtrunc { for ; j < containerLenS; j++ { + v = append(v, false) + slh.ElemContainerState(j) + v[j] = dd.DecodeBool() + } + } else if !canChange { + for ; j < containerLenS; j++ { + slh.ElemContainerState(j) d.swallow() } } } else { + breakFound := dd.CheckBreak() + if breakFound { + if canChange { + if v == nil { + v = []bool{} + } else if len(v) != 0 { + v = v[:0] + } + changed = true + } + slh.End() + return v, changed + } + if cap(v) == 0 { + v = make([]bool, 1, 4) + changed = true + } j := 0 - for ; !dd.CheckBreak(); j++ { + for ; !breakFound; j++ { if j >= len(v) { if canChange { v = append(v, false) @@ -13517,21 +20115,24 @@ func (_ fastpathT) DecSliceBoolV(v []bool, checkNil bool, canChange bool, d.arrayCannotExpand(len(v), j+1) } } - if j > 0 { - slh.Sep(j) - } - if j < len(v) { // all checks done. cannot go past len. + slh.ElemContainerState(j) + if j < len(v) { v[j] = dd.DecodeBool() } else { d.swallow() } + breakFound = dd.CheckBreak() + } + if canChange && j < len(v) { + v = v[:j] + changed = true } - slh.End() } + slh.End() return v, changed } -func (f decFnInfo) fastpathDecMapIntfIntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfIntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]interface{}) v, changed := fastpathTV.DecMapIntfIntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -13552,7 +20153,8 @@ func (f fastpathT) DecMapIntfIntfX(vp *map[interface{}]interface{}, checkNil boo func (_ fastpathT) DecMapIntfIntfV(v map[interface{}]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -13562,51 +20164,67 @@ func (_ fastpathT) DecMapIntfIntfV(v map[interface{}]interface{}, checkNil bool, containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]interface{}, containerLen) - } else { - v = make(map[interface{}]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 32) + v = make(map[interface{}]interface{}, xlen) changed = true } + mapGet := !d.h.MapValueReset && !d.h.InterfaceReset + var mk interface{} + var mv interface{} if containerLen > 0 { for j := 0; j < containerLen; j++ { - var mk interface{} + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil } - mv := v[mk] d.decode(&mv) - if v != nil { v[mk] = mv } } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } - var mk interface{} + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil } - dd.ReadMapKVSeparator() - mv := v[mk] d.decode(&mv) - if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntfStringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfStringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]string) v, changed := fastpathTV.DecMapIntfStringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -13627,7 +20245,8 @@ func (f fastpathT) DecMapIntfStringX(vp *map[interface{}]string, checkNil bool, func (_ fastpathT) DecMapIntfStringV(v map[interface{}]string, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -13637,21 +20256,26 @@ func (_ fastpathT) DecMapIntfStringV(v map[interface{}]string, checkNil bool, ca containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]string, containerLen) - } else { - v = make(map[interface{}]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 32) + v = make(map[interface{}]string, xlen) changed = true } + + var mk interface{} + var mv string if containerLen > 0 { for j := 0; j < containerLen; j++ { - var mk interface{} + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv @@ -13659,27 +20283,30 @@ func (_ fastpathT) DecMapIntfStringV(v map[interface{}]string, checkNil bool, ca } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } - var mk interface{} + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntfUintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfUintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]uint) v, changed := fastpathTV.DecMapIntfUintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -13700,7 +20327,8 @@ func (f fastpathT) DecMapIntfUintX(vp *map[interface{}]uint, checkNil bool, d *D func (_ fastpathT) DecMapIntfUintV(v map[interface{}]uint, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -13710,21 +20338,26 @@ func (_ fastpathT) DecMapIntfUintV(v map[interface{}]uint, checkNil bool, canCha containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]uint, containerLen) - } else { - v = make(map[interface{}]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[interface{}]uint, xlen) changed = true } + + var mk interface{} + var mv uint if containerLen > 0 { for j := 0; j < containerLen; j++ { - var mk interface{} + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv @@ -13732,27 +20365,30 @@ func (_ fastpathT) DecMapIntfUintV(v map[interface{}]uint, checkNil bool, canCha } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } - var mk interface{} + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntfUint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfUint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]uint8) v, changed := fastpathTV.DecMapIntfUint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -13773,7 +20409,8 @@ func (f fastpathT) DecMapIntfUint8X(vp *map[interface{}]uint8, checkNil bool, d func (_ fastpathT) DecMapIntfUint8V(v map[interface{}]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -13783,21 +20420,26 @@ func (_ fastpathT) DecMapIntfUint8V(v map[interface{}]uint8, checkNil bool, canC containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]uint8, containerLen) - } else { - v = make(map[interface{}]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17) + v = make(map[interface{}]uint8, xlen) changed = true } + + var mk interface{} + var mv uint8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - var mk interface{} + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv @@ -13805,27 +20447,30 @@ func (_ fastpathT) DecMapIntfUint8V(v map[interface{}]uint8, checkNil bool, canC } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } - var mk interface{} + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntfUint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfUint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]uint16) v, changed := fastpathTV.DecMapIntfUint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -13846,7 +20491,8 @@ func (f fastpathT) DecMapIntfUint16X(vp *map[interface{}]uint16, checkNil bool, func (_ fastpathT) DecMapIntfUint16V(v map[interface{}]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -13856,21 +20502,26 @@ func (_ fastpathT) DecMapIntfUint16V(v map[interface{}]uint16, checkNil bool, ca containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]uint16, containerLen) - } else { - v = make(map[interface{}]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 18) + v = make(map[interface{}]uint16, xlen) changed = true } + + var mk interface{} + var mv uint16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - var mk interface{} + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv @@ -13878,27 +20529,30 @@ func (_ fastpathT) DecMapIntfUint16V(v map[interface{}]uint16, checkNil bool, ca } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } - var mk interface{} + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntfUint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfUint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]uint32) v, changed := fastpathTV.DecMapIntfUint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -13919,7 +20573,8 @@ func (f fastpathT) DecMapIntfUint32X(vp *map[interface{}]uint32, checkNil bool, func (_ fastpathT) DecMapIntfUint32V(v map[interface{}]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -13929,21 +20584,26 @@ func (_ fastpathT) DecMapIntfUint32V(v map[interface{}]uint32, checkNil bool, ca containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]uint32, containerLen) - } else { - v = make(map[interface{}]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20) + v = make(map[interface{}]uint32, xlen) changed = true } + + var mk interface{} + var mv uint32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - var mk interface{} + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv @@ -13951,27 +20611,30 @@ func (_ fastpathT) DecMapIntfUint32V(v map[interface{}]uint32, checkNil bool, ca } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } - var mk interface{} + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntfUint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfUint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]uint64) v, changed := fastpathTV.DecMapIntfUint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -13992,7 +20655,8 @@ func (f fastpathT) DecMapIntfUint64X(vp *map[interface{}]uint64, checkNil bool, func (_ fastpathT) DecMapIntfUint64V(v map[interface{}]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14002,21 +20666,26 @@ func (_ fastpathT) DecMapIntfUint64V(v map[interface{}]uint64, checkNil bool, ca containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]uint64, containerLen) - } else { - v = make(map[interface{}]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[interface{}]uint64, xlen) changed = true } + + var mk interface{} + var mv uint64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - var mk interface{} + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv @@ -14024,27 +20693,112 @@ func (_ fastpathT) DecMapIntfUint64V(v map[interface{}]uint64, checkNil bool, ca } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } - var mk interface{} + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntfIntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfUintptrR(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[interface{}]uintptr) + v, changed := fastpathTV.DecMapIntfUintptrV(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[interface{}]uintptr) + fastpathTV.DecMapIntfUintptrV(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapIntfUintptrX(vp *map[interface{}]uintptr, checkNil bool, d *Decoder) { + v, changed := f.DecMapIntfUintptrV(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapIntfUintptrV(v map[interface{}]uintptr, checkNil bool, canChange bool, + d *Decoder) (_ map[interface{}]uintptr, changed bool) { + dd := d.d + cr := d.cr + + 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, 24) + v = make(map[interface{}]uintptr, xlen) + changed = true + } + + var mk interface{} + var mv uintptr + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = nil + d.decode(&mk) + if bv, bok := mk.([]byte); bok { + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = nil + d.decode(&mk) + if bv, bok := mk.([]byte); bok { + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapIntfIntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]int) v, changed := fastpathTV.DecMapIntfIntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -14065,7 +20819,8 @@ func (f fastpathT) DecMapIntfIntX(vp *map[interface{}]int, checkNil bool, d *Dec func (_ fastpathT) DecMapIntfIntV(v map[interface{}]int, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14075,21 +20830,26 @@ func (_ fastpathT) DecMapIntfIntV(v map[interface{}]int, checkNil bool, canChang containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]int, containerLen) - } else { - v = make(map[interface{}]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[interface{}]int, xlen) changed = true } + + var mk interface{} + var mv int if containerLen > 0 { for j := 0; j < containerLen; j++ { - var mk interface{} + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv @@ -14097,27 +20857,30 @@ func (_ fastpathT) DecMapIntfIntV(v map[interface{}]int, checkNil bool, canChang } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } - var mk interface{} + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - dd.ReadMapKVSeparator() - mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntfInt8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfInt8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]int8) v, changed := fastpathTV.DecMapIntfInt8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -14138,7 +20901,8 @@ func (f fastpathT) DecMapIntfInt8X(vp *map[interface{}]int8, checkNil bool, d *D func (_ fastpathT) DecMapIntfInt8V(v map[interface{}]int8, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14148,21 +20912,26 @@ func (_ fastpathT) DecMapIntfInt8V(v map[interface{}]int8, checkNil bool, canCha containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]int8, containerLen) - } else { - v = make(map[interface{}]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17) + v = make(map[interface{}]int8, xlen) changed = true } + + var mk interface{} + var mv int8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - var mk interface{} + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv @@ -14170,27 +20939,30 @@ func (_ fastpathT) DecMapIntfInt8V(v map[interface{}]int8, checkNil bool, canCha } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } - var mk interface{} + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - dd.ReadMapKVSeparator() - mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntfInt16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfInt16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]int16) v, changed := fastpathTV.DecMapIntfInt16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -14211,7 +20983,8 @@ func (f fastpathT) DecMapIntfInt16X(vp *map[interface{}]int16, checkNil bool, d func (_ fastpathT) DecMapIntfInt16V(v map[interface{}]int16, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14221,21 +20994,26 @@ func (_ fastpathT) DecMapIntfInt16V(v map[interface{}]int16, checkNil bool, canC containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]int16, containerLen) - } else { - v = make(map[interface{}]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 18) + v = make(map[interface{}]int16, xlen) changed = true } + + var mk interface{} + var mv int16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - var mk interface{} + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv @@ -14243,27 +21021,30 @@ func (_ fastpathT) DecMapIntfInt16V(v map[interface{}]int16, checkNil bool, canC } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } - var mk interface{} + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - dd.ReadMapKVSeparator() - mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntfInt32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfInt32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]int32) v, changed := fastpathTV.DecMapIntfInt32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -14284,7 +21065,8 @@ func (f fastpathT) DecMapIntfInt32X(vp *map[interface{}]int32, checkNil bool, d func (_ fastpathT) DecMapIntfInt32V(v map[interface{}]int32, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14294,21 +21076,26 @@ func (_ fastpathT) DecMapIntfInt32V(v map[interface{}]int32, checkNil bool, canC containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]int32, containerLen) - } else { - v = make(map[interface{}]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20) + v = make(map[interface{}]int32, xlen) changed = true } + + var mk interface{} + var mv int32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - var mk interface{} + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv @@ -14316,27 +21103,30 @@ func (_ fastpathT) DecMapIntfInt32V(v map[interface{}]int32, checkNil bool, canC } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } - var mk interface{} + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - dd.ReadMapKVSeparator() - mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntfInt64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfInt64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]int64) v, changed := fastpathTV.DecMapIntfInt64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -14357,7 +21147,8 @@ func (f fastpathT) DecMapIntfInt64X(vp *map[interface{}]int64, checkNil bool, d func (_ fastpathT) DecMapIntfInt64V(v map[interface{}]int64, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14367,21 +21158,26 @@ func (_ fastpathT) DecMapIntfInt64V(v map[interface{}]int64, checkNil bool, canC containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]int64, containerLen) - } else { - v = make(map[interface{}]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[interface{}]int64, xlen) changed = true } + + var mk interface{} + var mv int64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - var mk interface{} + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv @@ -14389,27 +21185,30 @@ func (_ fastpathT) DecMapIntfInt64V(v map[interface{}]int64, checkNil bool, canC } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } - var mk interface{} + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntfFloat32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfFloat32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]float32) v, changed := fastpathTV.DecMapIntfFloat32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -14430,7 +21229,8 @@ func (f fastpathT) DecMapIntfFloat32X(vp *map[interface{}]float32, checkNil bool func (_ fastpathT) DecMapIntfFloat32V(v map[interface{}]float32, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14440,21 +21240,26 @@ func (_ fastpathT) DecMapIntfFloat32V(v map[interface{}]float32, checkNil bool, containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]float32, containerLen) - } else { - v = make(map[interface{}]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20) + v = make(map[interface{}]float32, xlen) changed = true } + + var mk interface{} + var mv float32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - var mk interface{} + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv @@ -14462,27 +21267,30 @@ func (_ fastpathT) DecMapIntfFloat32V(v map[interface{}]float32, checkNil bool, } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } - var mk interface{} + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - dd.ReadMapKVSeparator() - mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntfFloat64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfFloat64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]float64) v, changed := fastpathTV.DecMapIntfFloat64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -14503,7 +21311,8 @@ func (f fastpathT) DecMapIntfFloat64X(vp *map[interface{}]float64, checkNil bool func (_ fastpathT) DecMapIntfFloat64V(v map[interface{}]float64, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14513,21 +21322,26 @@ func (_ fastpathT) DecMapIntfFloat64V(v map[interface{}]float64, checkNil bool, containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]float64, containerLen) - } else { - v = make(map[interface{}]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[interface{}]float64, xlen) changed = true } + + var mk interface{} + var mv float64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - var mk interface{} + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv @@ -14535,27 +21349,30 @@ func (_ fastpathT) DecMapIntfFloat64V(v map[interface{}]float64, checkNil bool, } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } - var mk interface{} + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntfBoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntfBoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[interface{}]bool) v, changed := fastpathTV.DecMapIntfBoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -14576,7 +21393,8 @@ func (f fastpathT) DecMapIntfBoolX(vp *map[interface{}]bool, checkNil bool, d *D func (_ fastpathT) DecMapIntfBoolV(v map[interface{}]bool, checkNil bool, canChange bool, d *Decoder) (_ map[interface{}]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14586,21 +21404,26 @@ func (_ fastpathT) DecMapIntfBoolV(v map[interface{}]bool, checkNil bool, canCha containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[interface{}]bool, containerLen) - } else { - v = make(map[interface{}]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17) + v = make(map[interface{}]bool, xlen) changed = true } + + var mk interface{} + var mv bool if containerLen > 0 { for j := 0; j < containerLen; j++ { - var mk interface{} + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv @@ -14608,27 +21431,30 @@ func (_ fastpathT) DecMapIntfBoolV(v map[interface{}]bool, checkNil bool, canCha } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) } - var mk interface{} + mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. + mk = d.string(bv) + } + if cr != nil { + cr.sendContainerState(containerMapValue) } - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapStringIntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringIntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]interface{}) v, changed := fastpathTV.DecMapStringIntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -14649,7 +21475,8 @@ func (f fastpathT) DecMapStringIntfX(vp *map[string]interface{}, checkNil bool, func (_ fastpathT) DecMapStringIntfV(v map[string]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[string]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14659,43 +21486,59 @@ func (_ fastpathT) DecMapStringIntfV(v map[string]interface{}, checkNil bool, ca containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]interface{}, containerLen) - } else { - v = make(map[string]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 32) + v = make(map[string]interface{}, xlen) changed = true } + mapGet := !d.h.MapValueReset && !d.h.InterfaceReset + var mk string + var mv interface{} if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeString() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil + } d.decode(&mv) - if v != nil { v[mk] = mv } } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil } - mk := dd.DecodeString() - dd.ReadMapKVSeparator() - mv := v[mk] d.decode(&mv) - if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapStringStringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringStringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]string) v, changed := fastpathTV.DecMapStringStringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -14716,7 +21559,8 @@ func (f fastpathT) DecMapStringStringX(vp *map[string]string, checkNil bool, d * func (_ fastpathT) DecMapStringStringV(v map[string]string, checkNil bool, canChange bool, d *Decoder) (_ map[string]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14726,17 +21570,22 @@ func (_ fastpathT) DecMapStringStringV(v map[string]string, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]string, containerLen) - } else { - v = make(map[string]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 32) + v = make(map[string]string, xlen) changed = true } + + var mk string + var mv string if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeString() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeString() if v != nil { v[mk] = mv @@ -14744,23 +21593,26 @@ func (_ fastpathT) DecMapStringStringV(v map[string]string, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeString() - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapStringUintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringUintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]uint) v, changed := fastpathTV.DecMapStringUintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -14781,7 +21633,8 @@ func (f fastpathT) DecMapStringUintX(vp *map[string]uint, checkNil bool, d *Deco func (_ fastpathT) DecMapStringUintV(v map[string]uint, checkNil bool, canChange bool, d *Decoder) (_ map[string]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14791,17 +21644,22 @@ func (_ fastpathT) DecMapStringUintV(v map[string]uint, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]uint, containerLen) - } else { - v = make(map[string]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[string]uint, xlen) changed = true } + + var mk string + var mv uint if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeString() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv @@ -14809,23 +21667,26 @@ func (_ fastpathT) DecMapStringUintV(v map[string]uint, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeString() - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapStringUint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringUint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]uint8) v, changed := fastpathTV.DecMapStringUint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -14846,7 +21707,8 @@ func (f fastpathT) DecMapStringUint8X(vp *map[string]uint8, checkNil bool, d *De func (_ fastpathT) DecMapStringUint8V(v map[string]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[string]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14856,17 +21718,22 @@ func (_ fastpathT) DecMapStringUint8V(v map[string]uint8, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]uint8, containerLen) - } else { - v = make(map[string]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17) + v = make(map[string]uint8, xlen) changed = true } + + var mk string + var mv uint8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeString() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv @@ -14874,23 +21741,26 @@ func (_ fastpathT) DecMapStringUint8V(v map[string]uint8, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeString() - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapStringUint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringUint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]uint16) v, changed := fastpathTV.DecMapStringUint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -14911,7 +21781,8 @@ func (f fastpathT) DecMapStringUint16X(vp *map[string]uint16, checkNil bool, d * func (_ fastpathT) DecMapStringUint16V(v map[string]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[string]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14921,17 +21792,22 @@ func (_ fastpathT) DecMapStringUint16V(v map[string]uint16, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]uint16, containerLen) - } else { - v = make(map[string]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 18) + v = make(map[string]uint16, xlen) changed = true } + + var mk string + var mv uint16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeString() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv @@ -14939,23 +21815,26 @@ func (_ fastpathT) DecMapStringUint16V(v map[string]uint16, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeString() - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapStringUint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringUint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]uint32) v, changed := fastpathTV.DecMapStringUint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -14976,7 +21855,8 @@ func (f fastpathT) DecMapStringUint32X(vp *map[string]uint32, checkNil bool, d * func (_ fastpathT) DecMapStringUint32V(v map[string]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[string]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -14986,17 +21866,22 @@ func (_ fastpathT) DecMapStringUint32V(v map[string]uint32, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]uint32, containerLen) - } else { - v = make(map[string]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20) + v = make(map[string]uint32, xlen) changed = true } + + var mk string + var mv uint32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeString() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv @@ -15004,23 +21889,26 @@ func (_ fastpathT) DecMapStringUint32V(v map[string]uint32, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeString() - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapStringUint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringUint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]uint64) v, changed := fastpathTV.DecMapStringUint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -15041,7 +21929,8 @@ func (f fastpathT) DecMapStringUint64X(vp *map[string]uint64, checkNil bool, d * func (_ fastpathT) DecMapStringUint64V(v map[string]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[string]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15051,17 +21940,22 @@ func (_ fastpathT) DecMapStringUint64V(v map[string]uint64, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]uint64, containerLen) - } else { - v = make(map[string]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[string]uint64, xlen) changed = true } + + var mk string + var mv uint64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeString() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeUint(64) if v != nil { v[mk] = mv @@ -15069,23 +21963,100 @@ func (_ fastpathT) DecMapStringUint64V(v map[string]uint64, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeString() - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapStringIntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringUintptrR(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[string]uintptr) + v, changed := fastpathTV.DecMapStringUintptrV(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[string]uintptr) + fastpathTV.DecMapStringUintptrV(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapStringUintptrX(vp *map[string]uintptr, checkNil bool, d *Decoder) { + v, changed := f.DecMapStringUintptrV(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapStringUintptrV(v map[string]uintptr, checkNil bool, canChange bool, + d *Decoder) (_ map[string]uintptr, changed bool) { + dd := d.d + cr := d.cr + + 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, 24) + v = make(map[string]uintptr, xlen) + changed = true + } + + var mk string + var mv uintptr + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapStringIntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]int) v, changed := fastpathTV.DecMapStringIntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -15106,7 +22077,8 @@ func (f fastpathT) DecMapStringIntX(vp *map[string]int, checkNil bool, d *Decode func (_ fastpathT) DecMapStringIntV(v map[string]int, checkNil bool, canChange bool, d *Decoder) (_ map[string]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15116,17 +22088,22 @@ func (_ fastpathT) DecMapStringIntV(v map[string]int, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]int, containerLen) - } else { - v = make(map[string]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[string]int, xlen) changed = true } + + var mk string + var mv int if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeString() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv @@ -15134,23 +22111,26 @@ func (_ fastpathT) DecMapStringIntV(v map[string]int, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeString() - dd.ReadMapKVSeparator() - mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapStringInt8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringInt8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]int8) v, changed := fastpathTV.DecMapStringInt8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -15171,7 +22151,8 @@ func (f fastpathT) DecMapStringInt8X(vp *map[string]int8, checkNil bool, d *Deco func (_ fastpathT) DecMapStringInt8V(v map[string]int8, checkNil bool, canChange bool, d *Decoder) (_ map[string]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15181,17 +22162,22 @@ func (_ fastpathT) DecMapStringInt8V(v map[string]int8, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]int8, containerLen) - } else { - v = make(map[string]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17) + v = make(map[string]int8, xlen) changed = true } + + var mk string + var mv int8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeString() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv @@ -15199,23 +22185,26 @@ func (_ fastpathT) DecMapStringInt8V(v map[string]int8, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeString() - dd.ReadMapKVSeparator() - mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapStringInt16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringInt16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]int16) v, changed := fastpathTV.DecMapStringInt16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -15236,7 +22225,8 @@ func (f fastpathT) DecMapStringInt16X(vp *map[string]int16, checkNil bool, d *De func (_ fastpathT) DecMapStringInt16V(v map[string]int16, checkNil bool, canChange bool, d *Decoder) (_ map[string]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15246,17 +22236,22 @@ func (_ fastpathT) DecMapStringInt16V(v map[string]int16, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]int16, containerLen) - } else { - v = make(map[string]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 18) + v = make(map[string]int16, xlen) changed = true } + + var mk string + var mv int16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeString() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv @@ -15264,23 +22259,26 @@ func (_ fastpathT) DecMapStringInt16V(v map[string]int16, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeString() - dd.ReadMapKVSeparator() - mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapStringInt32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringInt32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]int32) v, changed := fastpathTV.DecMapStringInt32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -15301,7 +22299,8 @@ func (f fastpathT) DecMapStringInt32X(vp *map[string]int32, checkNil bool, d *De func (_ fastpathT) DecMapStringInt32V(v map[string]int32, checkNil bool, canChange bool, d *Decoder) (_ map[string]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15311,17 +22310,22 @@ func (_ fastpathT) DecMapStringInt32V(v map[string]int32, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]int32, containerLen) - } else { - v = make(map[string]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20) + v = make(map[string]int32, xlen) changed = true } + + var mk string + var mv int32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeString() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv @@ -15329,23 +22333,26 @@ func (_ fastpathT) DecMapStringInt32V(v map[string]int32, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeString() - dd.ReadMapKVSeparator() - mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapStringInt64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringInt64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]int64) v, changed := fastpathTV.DecMapStringInt64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -15366,7 +22373,8 @@ func (f fastpathT) DecMapStringInt64X(vp *map[string]int64, checkNil bool, d *De func (_ fastpathT) DecMapStringInt64V(v map[string]int64, checkNil bool, canChange bool, d *Decoder) (_ map[string]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15376,17 +22384,22 @@ func (_ fastpathT) DecMapStringInt64V(v map[string]int64, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]int64, containerLen) - } else { - v = make(map[string]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[string]int64, xlen) changed = true } + + var mk string + var mv int64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeString() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeInt(64) if v != nil { v[mk] = mv @@ -15394,23 +22407,26 @@ func (_ fastpathT) DecMapStringInt64V(v map[string]int64, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeString() - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapStringFloat32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringFloat32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]float32) v, changed := fastpathTV.DecMapStringFloat32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -15431,7 +22447,8 @@ func (f fastpathT) DecMapStringFloat32X(vp *map[string]float32, checkNil bool, d func (_ fastpathT) DecMapStringFloat32V(v map[string]float32, checkNil bool, canChange bool, d *Decoder) (_ map[string]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15441,17 +22458,22 @@ func (_ fastpathT) DecMapStringFloat32V(v map[string]float32, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]float32, containerLen) - } else { - v = make(map[string]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20) + v = make(map[string]float32, xlen) changed = true } + + var mk string + var mv float32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeString() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv @@ -15459,23 +22481,26 @@ func (_ fastpathT) DecMapStringFloat32V(v map[string]float32, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeString() - dd.ReadMapKVSeparator() - mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapStringFloat64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringFloat64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]float64) v, changed := fastpathTV.DecMapStringFloat64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -15496,7 +22521,8 @@ func (f fastpathT) DecMapStringFloat64X(vp *map[string]float64, checkNil bool, d func (_ fastpathT) DecMapStringFloat64V(v map[string]float64, checkNil bool, canChange bool, d *Decoder) (_ map[string]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15506,17 +22532,22 @@ func (_ fastpathT) DecMapStringFloat64V(v map[string]float64, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]float64, containerLen) - } else { - v = make(map[string]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[string]float64, xlen) changed = true } + + var mk string + var mv float64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeString() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv @@ -15524,23 +22555,26 @@ func (_ fastpathT) DecMapStringFloat64V(v map[string]float64, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeString() - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapStringBoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapStringBoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[string]bool) v, changed := fastpathTV.DecMapStringBoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -15561,7 +22595,8 @@ func (f fastpathT) DecMapStringBoolX(vp *map[string]bool, checkNil bool, d *Deco func (_ fastpathT) DecMapStringBoolV(v map[string]bool, checkNil bool, canChange bool, d *Decoder) (_ map[string]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15571,17 +22606,22 @@ func (_ fastpathT) DecMapStringBoolV(v map[string]bool, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[string]bool, containerLen) - } else { - v = make(map[string]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17) + v = make(map[string]bool, xlen) changed = true } + + var mk string + var mv bool if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeString() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeBool() if v != nil { v[mk] = mv @@ -15589,23 +22629,26 @@ func (_ fastpathT) DecMapStringBoolV(v map[string]bool, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeString() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeString() - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32IntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32IntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]interface{}) v, changed := fastpathTV.DecMapFloat32IntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -15626,7 +22669,8 @@ func (f fastpathT) DecMapFloat32IntfX(vp *map[float32]interface{}, checkNil bool func (_ fastpathT) DecMapFloat32IntfV(v map[float32]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[float32]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15636,43 +22680,59 @@ func (_ fastpathT) DecMapFloat32IntfV(v map[float32]interface{}, checkNil bool, containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]interface{}, containerLen) - } else { - v = make(map[float32]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20) + v = make(map[float32]interface{}, xlen) changed = true } + mapGet := !d.h.MapValueReset && !d.h.InterfaceReset + var mk float32 + var mv interface{} if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := float32(dd.DecodeFloat(true)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil + } d.decode(&mv) - if v != nil { v[mk] = mv } } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil } - mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() - mv := v[mk] d.decode(&mv) - if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32StringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32StringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]string) v, changed := fastpathTV.DecMapFloat32StringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -15693,7 +22753,8 @@ func (f fastpathT) DecMapFloat32StringX(vp *map[float32]string, checkNil bool, d func (_ fastpathT) DecMapFloat32StringV(v map[float32]string, checkNil bool, canChange bool, d *Decoder) (_ map[float32]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15703,17 +22764,22 @@ func (_ fastpathT) DecMapFloat32StringV(v map[float32]string, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]string, containerLen) - } else { - v = make(map[float32]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20) + v = make(map[float32]string, xlen) changed = true } + + var mk float32 + var mv string if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := float32(dd.DecodeFloat(true)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeString() if v != nil { v[mk] = mv @@ -15721,23 +22787,26 @@ func (_ fastpathT) DecMapFloat32StringV(v map[float32]string, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32UintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32UintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]uint) v, changed := fastpathTV.DecMapFloat32UintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -15758,7 +22827,8 @@ func (f fastpathT) DecMapFloat32UintX(vp *map[float32]uint, checkNil bool, d *De func (_ fastpathT) DecMapFloat32UintV(v map[float32]uint, checkNil bool, canChange bool, d *Decoder) (_ map[float32]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15768,17 +22838,22 @@ func (_ fastpathT) DecMapFloat32UintV(v map[float32]uint, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]uint, containerLen) - } else { - v = make(map[float32]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[float32]uint, xlen) changed = true } + + var mk float32 + var mv uint if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := float32(dd.DecodeFloat(true)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv @@ -15786,23 +22861,26 @@ func (_ fastpathT) DecMapFloat32UintV(v map[float32]uint, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32Uint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32Uint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]uint8) v, changed := fastpathTV.DecMapFloat32Uint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -15823,7 +22901,8 @@ func (f fastpathT) DecMapFloat32Uint8X(vp *map[float32]uint8, checkNil bool, d * func (_ fastpathT) DecMapFloat32Uint8V(v map[float32]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[float32]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15833,17 +22912,22 @@ func (_ fastpathT) DecMapFloat32Uint8V(v map[float32]uint8, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]uint8, containerLen) - } else { - v = make(map[float32]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[float32]uint8, xlen) changed = true } + + var mk float32 + var mv uint8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := float32(dd.DecodeFloat(true)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv @@ -15851,23 +22935,26 @@ func (_ fastpathT) DecMapFloat32Uint8V(v map[float32]uint8, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32Uint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32Uint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]uint16) v, changed := fastpathTV.DecMapFloat32Uint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -15888,7 +22975,8 @@ func (f fastpathT) DecMapFloat32Uint16X(vp *map[float32]uint16, checkNil bool, d func (_ fastpathT) DecMapFloat32Uint16V(v map[float32]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[float32]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15898,17 +22986,22 @@ func (_ fastpathT) DecMapFloat32Uint16V(v map[float32]uint16, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]uint16, containerLen) - } else { - v = make(map[float32]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6) + v = make(map[float32]uint16, xlen) changed = true } + + var mk float32 + var mv uint16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := float32(dd.DecodeFloat(true)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv @@ -15916,23 +23009,26 @@ func (_ fastpathT) DecMapFloat32Uint16V(v map[float32]uint16, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32Uint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32Uint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]uint32) v, changed := fastpathTV.DecMapFloat32Uint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -15953,7 +23049,8 @@ func (f fastpathT) DecMapFloat32Uint32X(vp *map[float32]uint32, checkNil bool, d func (_ fastpathT) DecMapFloat32Uint32V(v map[float32]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[float32]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -15963,17 +23060,22 @@ func (_ fastpathT) DecMapFloat32Uint32V(v map[float32]uint32, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]uint32, containerLen) - } else { - v = make(map[float32]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8) + v = make(map[float32]uint32, xlen) changed = true } + + var mk float32 + var mv uint32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := float32(dd.DecodeFloat(true)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv @@ -15981,23 +23083,26 @@ func (_ fastpathT) DecMapFloat32Uint32V(v map[float32]uint32, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32Uint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32Uint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]uint64) v, changed := fastpathTV.DecMapFloat32Uint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -16018,7 +23123,8 @@ func (f fastpathT) DecMapFloat32Uint64X(vp *map[float32]uint64, checkNil bool, d func (_ fastpathT) DecMapFloat32Uint64V(v map[float32]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[float32]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16028,17 +23134,22 @@ func (_ fastpathT) DecMapFloat32Uint64V(v map[float32]uint64, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]uint64, containerLen) - } else { - v = make(map[float32]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[float32]uint64, xlen) changed = true } + + var mk float32 + var mv uint64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := float32(dd.DecodeFloat(true)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeUint(64) if v != nil { v[mk] = mv @@ -16046,23 +23157,100 @@ func (_ fastpathT) DecMapFloat32Uint64V(v map[float32]uint64, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32IntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32UintptrR(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[float32]uintptr) + v, changed := fastpathTV.DecMapFloat32UintptrV(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[float32]uintptr) + fastpathTV.DecMapFloat32UintptrV(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapFloat32UintptrX(vp *map[float32]uintptr, checkNil bool, d *Decoder) { + v, changed := f.DecMapFloat32UintptrV(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapFloat32UintptrV(v map[float32]uintptr, checkNil bool, canChange bool, + d *Decoder) (_ map[float32]uintptr, changed bool) { + dd := d.d + cr := d.cr + + 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, 12) + v = make(map[float32]uintptr, xlen) + changed = true + } + + var mk float32 + var mv uintptr + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapFloat32IntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]int) v, changed := fastpathTV.DecMapFloat32IntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -16083,7 +23271,8 @@ func (f fastpathT) DecMapFloat32IntX(vp *map[float32]int, checkNil bool, d *Deco func (_ fastpathT) DecMapFloat32IntV(v map[float32]int, checkNil bool, canChange bool, d *Decoder) (_ map[float32]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16093,17 +23282,22 @@ func (_ fastpathT) DecMapFloat32IntV(v map[float32]int, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]int, containerLen) - } else { - v = make(map[float32]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[float32]int, xlen) changed = true } + + var mk float32 + var mv int if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := float32(dd.DecodeFloat(true)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv @@ -16111,23 +23305,26 @@ func (_ fastpathT) DecMapFloat32IntV(v map[float32]int, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32Int8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32Int8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]int8) v, changed := fastpathTV.DecMapFloat32Int8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -16148,7 +23345,8 @@ func (f fastpathT) DecMapFloat32Int8X(vp *map[float32]int8, checkNil bool, d *De func (_ fastpathT) DecMapFloat32Int8V(v map[float32]int8, checkNil bool, canChange bool, d *Decoder) (_ map[float32]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16158,17 +23356,22 @@ func (_ fastpathT) DecMapFloat32Int8V(v map[float32]int8, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]int8, containerLen) - } else { - v = make(map[float32]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[float32]int8, xlen) changed = true } + + var mk float32 + var mv int8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := float32(dd.DecodeFloat(true)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv @@ -16176,23 +23379,26 @@ func (_ fastpathT) DecMapFloat32Int8V(v map[float32]int8, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32Int16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32Int16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]int16) v, changed := fastpathTV.DecMapFloat32Int16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -16213,7 +23419,8 @@ func (f fastpathT) DecMapFloat32Int16X(vp *map[float32]int16, checkNil bool, d * func (_ fastpathT) DecMapFloat32Int16V(v map[float32]int16, checkNil bool, canChange bool, d *Decoder) (_ map[float32]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16223,17 +23430,22 @@ func (_ fastpathT) DecMapFloat32Int16V(v map[float32]int16, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]int16, containerLen) - } else { - v = make(map[float32]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6) + v = make(map[float32]int16, xlen) changed = true } + + var mk float32 + var mv int16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := float32(dd.DecodeFloat(true)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv @@ -16241,23 +23453,26 @@ func (_ fastpathT) DecMapFloat32Int16V(v map[float32]int16, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32Int32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32Int32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]int32) v, changed := fastpathTV.DecMapFloat32Int32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -16278,7 +23493,8 @@ func (f fastpathT) DecMapFloat32Int32X(vp *map[float32]int32, checkNil bool, d * func (_ fastpathT) DecMapFloat32Int32V(v map[float32]int32, checkNil bool, canChange bool, d *Decoder) (_ map[float32]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16288,17 +23504,22 @@ func (_ fastpathT) DecMapFloat32Int32V(v map[float32]int32, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]int32, containerLen) - } else { - v = make(map[float32]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8) + v = make(map[float32]int32, xlen) changed = true } + + var mk float32 + var mv int32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := float32(dd.DecodeFloat(true)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv @@ -16306,23 +23527,26 @@ func (_ fastpathT) DecMapFloat32Int32V(v map[float32]int32, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32Int64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32Int64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]int64) v, changed := fastpathTV.DecMapFloat32Int64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -16343,7 +23567,8 @@ func (f fastpathT) DecMapFloat32Int64X(vp *map[float32]int64, checkNil bool, d * func (_ fastpathT) DecMapFloat32Int64V(v map[float32]int64, checkNil bool, canChange bool, d *Decoder) (_ map[float32]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16353,17 +23578,22 @@ func (_ fastpathT) DecMapFloat32Int64V(v map[float32]int64, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]int64, containerLen) - } else { - v = make(map[float32]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[float32]int64, xlen) changed = true } + + var mk float32 + var mv int64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := float32(dd.DecodeFloat(true)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeInt(64) if v != nil { v[mk] = mv @@ -16371,23 +23601,26 @@ func (_ fastpathT) DecMapFloat32Int64V(v map[float32]int64, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32Float32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32Float32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]float32) v, changed := fastpathTV.DecMapFloat32Float32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -16408,7 +23641,8 @@ func (f fastpathT) DecMapFloat32Float32X(vp *map[float32]float32, checkNil bool, func (_ fastpathT) DecMapFloat32Float32V(v map[float32]float32, checkNil bool, canChange bool, d *Decoder) (_ map[float32]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16418,17 +23652,22 @@ func (_ fastpathT) DecMapFloat32Float32V(v map[float32]float32, checkNil bool, c containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]float32, containerLen) - } else { - v = make(map[float32]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8) + v = make(map[float32]float32, xlen) changed = true } + + var mk float32 + var mv float32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := float32(dd.DecodeFloat(true)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv @@ -16436,23 +23675,26 @@ func (_ fastpathT) DecMapFloat32Float32V(v map[float32]float32, checkNil bool, c } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32Float64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32Float64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]float64) v, changed := fastpathTV.DecMapFloat32Float64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -16473,7 +23715,8 @@ func (f fastpathT) DecMapFloat32Float64X(vp *map[float32]float64, checkNil bool, func (_ fastpathT) DecMapFloat32Float64V(v map[float32]float64, checkNil bool, canChange bool, d *Decoder) (_ map[float32]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16483,17 +23726,22 @@ func (_ fastpathT) DecMapFloat32Float64V(v map[float32]float64, checkNil bool, c containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]float64, containerLen) - } else { - v = make(map[float32]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[float32]float64, xlen) changed = true } + + var mk float32 + var mv float64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := float32(dd.DecodeFloat(true)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv @@ -16501,23 +23749,26 @@ func (_ fastpathT) DecMapFloat32Float64V(v map[float32]float64, checkNil bool, c } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat32BoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat32BoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float32]bool) v, changed := fastpathTV.DecMapFloat32BoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -16538,7 +23789,8 @@ func (f fastpathT) DecMapFloat32BoolX(vp *map[float32]bool, checkNil bool, d *De func (_ fastpathT) DecMapFloat32BoolV(v map[float32]bool, checkNil bool, canChange bool, d *Decoder) (_ map[float32]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16548,17 +23800,22 @@ func (_ fastpathT) DecMapFloat32BoolV(v map[float32]bool, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float32]bool, containerLen) - } else { - v = make(map[float32]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[float32]bool, xlen) changed = true } + + var mk float32 + var mv bool if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := float32(dd.DecodeFloat(true)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeBool() if v != nil { v[mk] = mv @@ -16566,23 +23823,26 @@ func (_ fastpathT) DecMapFloat32BoolV(v map[float32]bool, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = float32(dd.DecodeFloat(true)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := float32(dd.DecodeFloat(true)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64IntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64IntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]interface{}) v, changed := fastpathTV.DecMapFloat64IntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -16603,7 +23863,8 @@ func (f fastpathT) DecMapFloat64IntfX(vp *map[float64]interface{}, checkNil bool func (_ fastpathT) DecMapFloat64IntfV(v map[float64]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[float64]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16613,43 +23874,59 @@ func (_ fastpathT) DecMapFloat64IntfV(v map[float64]interface{}, checkNil bool, containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]interface{}, containerLen) - } else { - v = make(map[float64]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[float64]interface{}, xlen) changed = true } + mapGet := !d.h.MapValueReset && !d.h.InterfaceReset + var mk float64 + var mv interface{} if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeFloat(false) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil + } d.decode(&mv) - if v != nil { v[mk] = mv } } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil } - mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() - mv := v[mk] d.decode(&mv) - if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64StringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64StringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]string) v, changed := fastpathTV.DecMapFloat64StringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -16670,7 +23947,8 @@ func (f fastpathT) DecMapFloat64StringX(vp *map[float64]string, checkNil bool, d func (_ fastpathT) DecMapFloat64StringV(v map[float64]string, checkNil bool, canChange bool, d *Decoder) (_ map[float64]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16680,17 +23958,22 @@ func (_ fastpathT) DecMapFloat64StringV(v map[float64]string, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]string, containerLen) - } else { - v = make(map[float64]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[float64]string, xlen) changed = true } + + var mk float64 + var mv string if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeFloat(false) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeString() if v != nil { v[mk] = mv @@ -16698,23 +23981,26 @@ func (_ fastpathT) DecMapFloat64StringV(v map[float64]string, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64UintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64UintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]uint) v, changed := fastpathTV.DecMapFloat64UintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -16735,7 +24021,8 @@ func (f fastpathT) DecMapFloat64UintX(vp *map[float64]uint, checkNil bool, d *De func (_ fastpathT) DecMapFloat64UintV(v map[float64]uint, checkNil bool, canChange bool, d *Decoder) (_ map[float64]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16745,17 +24032,22 @@ func (_ fastpathT) DecMapFloat64UintV(v map[float64]uint, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]uint, containerLen) - } else { - v = make(map[float64]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[float64]uint, xlen) changed = true } + + var mk float64 + var mv uint if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeFloat(false) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv @@ -16763,23 +24055,26 @@ func (_ fastpathT) DecMapFloat64UintV(v map[float64]uint, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64Uint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64Uint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]uint8) v, changed := fastpathTV.DecMapFloat64Uint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -16800,7 +24095,8 @@ func (f fastpathT) DecMapFloat64Uint8X(vp *map[float64]uint8, checkNil bool, d * func (_ fastpathT) DecMapFloat64Uint8V(v map[float64]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[float64]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16810,17 +24106,22 @@ func (_ fastpathT) DecMapFloat64Uint8V(v map[float64]uint8, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]uint8, containerLen) - } else { - v = make(map[float64]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[float64]uint8, xlen) changed = true } + + var mk float64 + var mv uint8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeFloat(false) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv @@ -16828,23 +24129,26 @@ func (_ fastpathT) DecMapFloat64Uint8V(v map[float64]uint8, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64Uint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64Uint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]uint16) v, changed := fastpathTV.DecMapFloat64Uint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -16865,7 +24169,8 @@ func (f fastpathT) DecMapFloat64Uint16X(vp *map[float64]uint16, checkNil bool, d func (_ fastpathT) DecMapFloat64Uint16V(v map[float64]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[float64]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16875,17 +24180,22 @@ func (_ fastpathT) DecMapFloat64Uint16V(v map[float64]uint16, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]uint16, containerLen) - } else { - v = make(map[float64]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[float64]uint16, xlen) changed = true } + + var mk float64 + var mv uint16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeFloat(false) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv @@ -16893,23 +24203,26 @@ func (_ fastpathT) DecMapFloat64Uint16V(v map[float64]uint16, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64Uint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64Uint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]uint32) v, changed := fastpathTV.DecMapFloat64Uint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -16930,7 +24243,8 @@ func (f fastpathT) DecMapFloat64Uint32X(vp *map[float64]uint32, checkNil bool, d func (_ fastpathT) DecMapFloat64Uint32V(v map[float64]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[float64]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -16940,17 +24254,22 @@ func (_ fastpathT) DecMapFloat64Uint32V(v map[float64]uint32, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]uint32, containerLen) - } else { - v = make(map[float64]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[float64]uint32, xlen) changed = true } + + var mk float64 + var mv uint32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeFloat(false) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv @@ -16958,23 +24277,26 @@ func (_ fastpathT) DecMapFloat64Uint32V(v map[float64]uint32, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64Uint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64Uint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]uint64) v, changed := fastpathTV.DecMapFloat64Uint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -16995,7 +24317,8 @@ func (f fastpathT) DecMapFloat64Uint64X(vp *map[float64]uint64, checkNil bool, d func (_ fastpathT) DecMapFloat64Uint64V(v map[float64]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[float64]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17005,17 +24328,22 @@ func (_ fastpathT) DecMapFloat64Uint64V(v map[float64]uint64, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]uint64, containerLen) - } else { - v = make(map[float64]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[float64]uint64, xlen) changed = true } + + var mk float64 + var mv uint64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeFloat(false) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeUint(64) if v != nil { v[mk] = mv @@ -17023,23 +24351,100 @@ func (_ fastpathT) DecMapFloat64Uint64V(v map[float64]uint64, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64IntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64UintptrR(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[float64]uintptr) + v, changed := fastpathTV.DecMapFloat64UintptrV(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[float64]uintptr) + fastpathTV.DecMapFloat64UintptrV(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapFloat64UintptrX(vp *map[float64]uintptr, checkNil bool, d *Decoder) { + v, changed := f.DecMapFloat64UintptrV(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapFloat64UintptrV(v map[float64]uintptr, checkNil bool, canChange bool, + d *Decoder) (_ map[float64]uintptr, changed bool) { + dd := d.d + cr := d.cr + + 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, 16) + v = make(map[float64]uintptr, xlen) + changed = true + } + + var mk float64 + var mv uintptr + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapFloat64IntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]int) v, changed := fastpathTV.DecMapFloat64IntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -17060,7 +24465,8 @@ func (f fastpathT) DecMapFloat64IntX(vp *map[float64]int, checkNil bool, d *Deco func (_ fastpathT) DecMapFloat64IntV(v map[float64]int, checkNil bool, canChange bool, d *Decoder) (_ map[float64]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17070,17 +24476,22 @@ func (_ fastpathT) DecMapFloat64IntV(v map[float64]int, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]int, containerLen) - } else { - v = make(map[float64]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[float64]int, xlen) changed = true } + + var mk float64 + var mv int if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeFloat(false) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv @@ -17088,23 +24499,26 @@ func (_ fastpathT) DecMapFloat64IntV(v map[float64]int, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64Int8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64Int8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]int8) v, changed := fastpathTV.DecMapFloat64Int8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -17125,7 +24539,8 @@ func (f fastpathT) DecMapFloat64Int8X(vp *map[float64]int8, checkNil bool, d *De func (_ fastpathT) DecMapFloat64Int8V(v map[float64]int8, checkNil bool, canChange bool, d *Decoder) (_ map[float64]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17135,17 +24550,22 @@ func (_ fastpathT) DecMapFloat64Int8V(v map[float64]int8, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]int8, containerLen) - } else { - v = make(map[float64]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[float64]int8, xlen) changed = true } + + var mk float64 + var mv int8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeFloat(false) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv @@ -17153,23 +24573,26 @@ func (_ fastpathT) DecMapFloat64Int8V(v map[float64]int8, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64Int16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64Int16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]int16) v, changed := fastpathTV.DecMapFloat64Int16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -17190,7 +24613,8 @@ func (f fastpathT) DecMapFloat64Int16X(vp *map[float64]int16, checkNil bool, d * func (_ fastpathT) DecMapFloat64Int16V(v map[float64]int16, checkNil bool, canChange bool, d *Decoder) (_ map[float64]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17200,17 +24624,22 @@ func (_ fastpathT) DecMapFloat64Int16V(v map[float64]int16, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]int16, containerLen) - } else { - v = make(map[float64]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[float64]int16, xlen) changed = true } + + var mk float64 + var mv int16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeFloat(false) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv @@ -17218,23 +24647,26 @@ func (_ fastpathT) DecMapFloat64Int16V(v map[float64]int16, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64Int32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64Int32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]int32) v, changed := fastpathTV.DecMapFloat64Int32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -17255,7 +24687,8 @@ func (f fastpathT) DecMapFloat64Int32X(vp *map[float64]int32, checkNil bool, d * func (_ fastpathT) DecMapFloat64Int32V(v map[float64]int32, checkNil bool, canChange bool, d *Decoder) (_ map[float64]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17265,17 +24698,22 @@ func (_ fastpathT) DecMapFloat64Int32V(v map[float64]int32, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]int32, containerLen) - } else { - v = make(map[float64]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[float64]int32, xlen) changed = true } + + var mk float64 + var mv int32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeFloat(false) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv @@ -17283,23 +24721,26 @@ func (_ fastpathT) DecMapFloat64Int32V(v map[float64]int32, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64Int64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64Int64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]int64) v, changed := fastpathTV.DecMapFloat64Int64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -17320,7 +24761,8 @@ func (f fastpathT) DecMapFloat64Int64X(vp *map[float64]int64, checkNil bool, d * func (_ fastpathT) DecMapFloat64Int64V(v map[float64]int64, checkNil bool, canChange bool, d *Decoder) (_ map[float64]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17330,17 +24772,22 @@ func (_ fastpathT) DecMapFloat64Int64V(v map[float64]int64, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]int64, containerLen) - } else { - v = make(map[float64]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[float64]int64, xlen) changed = true } + + var mk float64 + var mv int64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeFloat(false) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeInt(64) if v != nil { v[mk] = mv @@ -17348,23 +24795,26 @@ func (_ fastpathT) DecMapFloat64Int64V(v map[float64]int64, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64Float32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64Float32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]float32) v, changed := fastpathTV.DecMapFloat64Float32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -17385,7 +24835,8 @@ func (f fastpathT) DecMapFloat64Float32X(vp *map[float64]float32, checkNil bool, func (_ fastpathT) DecMapFloat64Float32V(v map[float64]float32, checkNil bool, canChange bool, d *Decoder) (_ map[float64]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17395,17 +24846,22 @@ func (_ fastpathT) DecMapFloat64Float32V(v map[float64]float32, checkNil bool, c containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]float32, containerLen) - } else { - v = make(map[float64]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[float64]float32, xlen) changed = true } + + var mk float64 + var mv float32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeFloat(false) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv @@ -17413,23 +24869,26 @@ func (_ fastpathT) DecMapFloat64Float32V(v map[float64]float32, checkNil bool, c } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() - mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64Float64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64Float64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]float64) v, changed := fastpathTV.DecMapFloat64Float64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -17450,7 +24909,8 @@ func (f fastpathT) DecMapFloat64Float64X(vp *map[float64]float64, checkNil bool, func (_ fastpathT) DecMapFloat64Float64V(v map[float64]float64, checkNil bool, canChange bool, d *Decoder) (_ map[float64]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17460,17 +24920,22 @@ func (_ fastpathT) DecMapFloat64Float64V(v map[float64]float64, checkNil bool, c containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]float64, containerLen) - } else { - v = make(map[float64]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[float64]float64, xlen) changed = true } + + var mk float64 + var mv float64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeFloat(false) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv @@ -17478,23 +24943,26 @@ func (_ fastpathT) DecMapFloat64Float64V(v map[float64]float64, checkNil bool, c } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapFloat64BoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapFloat64BoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[float64]bool) v, changed := fastpathTV.DecMapFloat64BoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -17515,7 +24983,8 @@ func (f fastpathT) DecMapFloat64BoolX(vp *map[float64]bool, checkNil bool, d *De func (_ fastpathT) DecMapFloat64BoolV(v map[float64]bool, checkNil bool, canChange bool, d *Decoder) (_ map[float64]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17525,17 +24994,22 @@ func (_ fastpathT) DecMapFloat64BoolV(v map[float64]bool, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[float64]bool, containerLen) - } else { - v = make(map[float64]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[float64]bool, xlen) changed = true } + + var mk float64 + var mv bool if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeFloat(false) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeBool() if v != nil { v[mk] = mv @@ -17543,23 +25017,26 @@ func (_ fastpathT) DecMapFloat64BoolV(v map[float64]bool, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeFloat(false) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeFloat(false) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUintIntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintIntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]interface{}) v, changed := fastpathTV.DecMapUintIntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -17580,7 +25057,8 @@ func (f fastpathT) DecMapUintIntfX(vp *map[uint]interface{}, checkNil bool, d *D func (_ fastpathT) DecMapUintIntfV(v map[uint]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[uint]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17590,43 +25068,59 @@ func (_ fastpathT) DecMapUintIntfV(v map[uint]interface{}, checkNil bool, canCha containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]interface{}, containerLen) - } else { - v = make(map[uint]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[uint]interface{}, xlen) changed = true } + mapGet := !d.h.MapValueReset && !d.h.InterfaceReset + var mk uint + var mv interface{} if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint(dd.DecodeUint(uintBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil + } d.decode(&mv) - if v != nil { v[mk] = mv } } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil } - mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] d.decode(&mv) - if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUintStringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintStringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]string) v, changed := fastpathTV.DecMapUintStringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -17647,7 +25141,8 @@ func (f fastpathT) DecMapUintStringX(vp *map[uint]string, checkNil bool, d *Deco func (_ fastpathT) DecMapUintStringV(v map[uint]string, checkNil bool, canChange bool, d *Decoder) (_ map[uint]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17657,17 +25152,22 @@ func (_ fastpathT) DecMapUintStringV(v map[uint]string, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]string, containerLen) - } else { - v = make(map[uint]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[uint]string, xlen) changed = true } + + var mk uint + var mv string if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint(dd.DecodeUint(uintBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeString() if v != nil { v[mk] = mv @@ -17675,23 +25175,26 @@ func (_ fastpathT) DecMapUintStringV(v map[uint]string, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUintUintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintUintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]uint) v, changed := fastpathTV.DecMapUintUintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -17712,7 +25215,8 @@ func (f fastpathT) DecMapUintUintX(vp *map[uint]uint, checkNil bool, d *Decoder) func (_ fastpathT) DecMapUintUintV(v map[uint]uint, checkNil bool, canChange bool, d *Decoder) (_ map[uint]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17722,17 +25226,22 @@ func (_ fastpathT) DecMapUintUintV(v map[uint]uint, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]uint, containerLen) - } else { - v = make(map[uint]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[uint]uint, xlen) changed = true } + + var mk uint + var mv uint if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint(dd.DecodeUint(uintBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv @@ -17740,23 +25249,26 @@ func (_ fastpathT) DecMapUintUintV(v map[uint]uint, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUintUint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintUint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]uint8) v, changed := fastpathTV.DecMapUintUint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -17777,7 +25289,8 @@ func (f fastpathT) DecMapUintUint8X(vp *map[uint]uint8, checkNil bool, d *Decode func (_ fastpathT) DecMapUintUint8V(v map[uint]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[uint]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17787,17 +25300,22 @@ func (_ fastpathT) DecMapUintUint8V(v map[uint]uint8, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]uint8, containerLen) - } else { - v = make(map[uint]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[uint]uint8, xlen) changed = true } + + var mk uint + var mv uint8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint(dd.DecodeUint(uintBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv @@ -17805,23 +25323,26 @@ func (_ fastpathT) DecMapUintUint8V(v map[uint]uint8, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUintUint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintUint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]uint16) v, changed := fastpathTV.DecMapUintUint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -17842,7 +25363,8 @@ func (f fastpathT) DecMapUintUint16X(vp *map[uint]uint16, checkNil bool, d *Deco func (_ fastpathT) DecMapUintUint16V(v map[uint]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[uint]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17852,17 +25374,22 @@ func (_ fastpathT) DecMapUintUint16V(v map[uint]uint16, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]uint16, containerLen) - } else { - v = make(map[uint]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[uint]uint16, xlen) changed = true } + + var mk uint + var mv uint16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint(dd.DecodeUint(uintBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv @@ -17870,23 +25397,26 @@ func (_ fastpathT) DecMapUintUint16V(v map[uint]uint16, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUintUint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintUint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]uint32) v, changed := fastpathTV.DecMapUintUint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -17907,7 +25437,8 @@ func (f fastpathT) DecMapUintUint32X(vp *map[uint]uint32, checkNil bool, d *Deco func (_ fastpathT) DecMapUintUint32V(v map[uint]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[uint]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17917,17 +25448,22 @@ func (_ fastpathT) DecMapUintUint32V(v map[uint]uint32, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]uint32, containerLen) - } else { - v = make(map[uint]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[uint]uint32, xlen) changed = true } + + var mk uint + var mv uint32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint(dd.DecodeUint(uintBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv @@ -17935,23 +25471,26 @@ func (_ fastpathT) DecMapUintUint32V(v map[uint]uint32, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUintUint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintUint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]uint64) v, changed := fastpathTV.DecMapUintUint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -17972,7 +25511,8 @@ func (f fastpathT) DecMapUintUint64X(vp *map[uint]uint64, checkNil bool, d *Deco func (_ fastpathT) DecMapUintUint64V(v map[uint]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[uint]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -17982,17 +25522,22 @@ func (_ fastpathT) DecMapUintUint64V(v map[uint]uint64, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]uint64, containerLen) - } else { - v = make(map[uint]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[uint]uint64, xlen) changed = true } + + var mk uint + var mv uint64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint(dd.DecodeUint(uintBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeUint(64) if v != nil { v[mk] = mv @@ -18000,23 +25545,100 @@ func (_ fastpathT) DecMapUintUint64V(v map[uint]uint64, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUintIntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintUintptrR(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[uint]uintptr) + v, changed := fastpathTV.DecMapUintUintptrV(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[uint]uintptr) + fastpathTV.DecMapUintUintptrV(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapUintUintptrX(vp *map[uint]uintptr, checkNil bool, d *Decoder) { + v, changed := f.DecMapUintUintptrV(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapUintUintptrV(v map[uint]uintptr, checkNil bool, canChange bool, + d *Decoder) (_ map[uint]uintptr, changed bool) { + dd := d.d + cr := d.cr + + 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, 16) + v = make(map[uint]uintptr, xlen) + changed = true + } + + var mk uint + var mv uintptr + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapUintIntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]int) v, changed := fastpathTV.DecMapUintIntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -18037,7 +25659,8 @@ func (f fastpathT) DecMapUintIntX(vp *map[uint]int, checkNil bool, d *Decoder) { func (_ fastpathT) DecMapUintIntV(v map[uint]int, checkNil bool, canChange bool, d *Decoder) (_ map[uint]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18047,17 +25670,22 @@ func (_ fastpathT) DecMapUintIntV(v map[uint]int, checkNil bool, canChange bool, containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]int, containerLen) - } else { - v = make(map[uint]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[uint]int, xlen) changed = true } + + var mk uint + var mv int if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint(dd.DecodeUint(uintBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv @@ -18065,23 +25693,26 @@ func (_ fastpathT) DecMapUintIntV(v map[uint]int, checkNil bool, canChange bool, } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUintInt8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintInt8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]int8) v, changed := fastpathTV.DecMapUintInt8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -18102,7 +25733,8 @@ func (f fastpathT) DecMapUintInt8X(vp *map[uint]int8, checkNil bool, d *Decoder) func (_ fastpathT) DecMapUintInt8V(v map[uint]int8, checkNil bool, canChange bool, d *Decoder) (_ map[uint]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18112,17 +25744,22 @@ func (_ fastpathT) DecMapUintInt8V(v map[uint]int8, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]int8, containerLen) - } else { - v = make(map[uint]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[uint]int8, xlen) changed = true } + + var mk uint + var mv int8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint(dd.DecodeUint(uintBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv @@ -18130,23 +25767,26 @@ func (_ fastpathT) DecMapUintInt8V(v map[uint]int8, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUintInt16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintInt16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]int16) v, changed := fastpathTV.DecMapUintInt16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -18167,7 +25807,8 @@ func (f fastpathT) DecMapUintInt16X(vp *map[uint]int16, checkNil bool, d *Decode func (_ fastpathT) DecMapUintInt16V(v map[uint]int16, checkNil bool, canChange bool, d *Decoder) (_ map[uint]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18177,17 +25818,22 @@ func (_ fastpathT) DecMapUintInt16V(v map[uint]int16, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]int16, containerLen) - } else { - v = make(map[uint]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[uint]int16, xlen) changed = true } + + var mk uint + var mv int16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint(dd.DecodeUint(uintBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv @@ -18195,23 +25841,26 @@ func (_ fastpathT) DecMapUintInt16V(v map[uint]int16, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUintInt32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintInt32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]int32) v, changed := fastpathTV.DecMapUintInt32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -18232,7 +25881,8 @@ func (f fastpathT) DecMapUintInt32X(vp *map[uint]int32, checkNil bool, d *Decode func (_ fastpathT) DecMapUintInt32V(v map[uint]int32, checkNil bool, canChange bool, d *Decoder) (_ map[uint]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18242,17 +25892,22 @@ func (_ fastpathT) DecMapUintInt32V(v map[uint]int32, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]int32, containerLen) - } else { - v = make(map[uint]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[uint]int32, xlen) changed = true } + + var mk uint + var mv int32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint(dd.DecodeUint(uintBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv @@ -18260,23 +25915,26 @@ func (_ fastpathT) DecMapUintInt32V(v map[uint]int32, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUintInt64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintInt64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]int64) v, changed := fastpathTV.DecMapUintInt64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -18297,7 +25955,8 @@ func (f fastpathT) DecMapUintInt64X(vp *map[uint]int64, checkNil bool, d *Decode func (_ fastpathT) DecMapUintInt64V(v map[uint]int64, checkNil bool, canChange bool, d *Decoder) (_ map[uint]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18307,17 +25966,22 @@ func (_ fastpathT) DecMapUintInt64V(v map[uint]int64, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]int64, containerLen) - } else { - v = make(map[uint]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[uint]int64, xlen) changed = true } + + var mk uint + var mv int64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint(dd.DecodeUint(uintBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeInt(64) if v != nil { v[mk] = mv @@ -18325,23 +25989,26 @@ func (_ fastpathT) DecMapUintInt64V(v map[uint]int64, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUintFloat32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintFloat32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]float32) v, changed := fastpathTV.DecMapUintFloat32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -18362,7 +26029,8 @@ func (f fastpathT) DecMapUintFloat32X(vp *map[uint]float32, checkNil bool, d *De func (_ fastpathT) DecMapUintFloat32V(v map[uint]float32, checkNil bool, canChange bool, d *Decoder) (_ map[uint]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18372,17 +26040,22 @@ func (_ fastpathT) DecMapUintFloat32V(v map[uint]float32, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]float32, containerLen) - } else { - v = make(map[uint]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[uint]float32, xlen) changed = true } + + var mk uint + var mv float32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint(dd.DecodeUint(uintBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv @@ -18390,23 +26063,26 @@ func (_ fastpathT) DecMapUintFloat32V(v map[uint]float32, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUintFloat64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintFloat64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]float64) v, changed := fastpathTV.DecMapUintFloat64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -18427,7 +26103,8 @@ func (f fastpathT) DecMapUintFloat64X(vp *map[uint]float64, checkNil bool, d *De func (_ fastpathT) DecMapUintFloat64V(v map[uint]float64, checkNil bool, canChange bool, d *Decoder) (_ map[uint]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18437,17 +26114,22 @@ func (_ fastpathT) DecMapUintFloat64V(v map[uint]float64, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]float64, containerLen) - } else { - v = make(map[uint]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[uint]float64, xlen) changed = true } + + var mk uint + var mv float64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint(dd.DecodeUint(uintBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv @@ -18455,23 +26137,26 @@ func (_ fastpathT) DecMapUintFloat64V(v map[uint]float64, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUintBoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintBoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint]bool) v, changed := fastpathTV.DecMapUintBoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -18492,7 +26177,8 @@ func (f fastpathT) DecMapUintBoolX(vp *map[uint]bool, checkNil bool, d *Decoder) func (_ fastpathT) DecMapUintBoolV(v map[uint]bool, checkNil bool, canChange bool, d *Decoder) (_ map[uint]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18502,17 +26188,22 @@ func (_ fastpathT) DecMapUintBoolV(v map[uint]bool, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint]bool, containerLen) - } else { - v = make(map[uint]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[uint]bool, xlen) changed = true } + + var mk uint + var mv bool if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint(dd.DecodeUint(uintBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeBool() if v != nil { v[mk] = mv @@ -18520,23 +26211,26 @@ func (_ fastpathT) DecMapUintBoolV(v map[uint]bool, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint(dd.DecodeUint(uintBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint8IntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8IntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]interface{}) v, changed := fastpathTV.DecMapUint8IntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -18557,7 +26251,8 @@ func (f fastpathT) DecMapUint8IntfX(vp *map[uint8]interface{}, checkNil bool, d func (_ fastpathT) DecMapUint8IntfV(v map[uint8]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18567,43 +26262,59 @@ func (_ fastpathT) DecMapUint8IntfV(v map[uint8]interface{}, checkNil bool, canC containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]interface{}, containerLen) - } else { - v = make(map[uint8]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17) + v = make(map[uint8]interface{}, xlen) changed = true } + mapGet := !d.h.MapValueReset && !d.h.InterfaceReset + var mk uint8 + var mv interface{} if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint8(dd.DecodeUint(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil + } d.decode(&mv) - if v != nil { v[mk] = mv } } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil } - mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() - mv := v[mk] d.decode(&mv) - if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint8StringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8StringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]string) v, changed := fastpathTV.DecMapUint8StringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -18624,7 +26335,8 @@ func (f fastpathT) DecMapUint8StringX(vp *map[uint8]string, checkNil bool, d *De func (_ fastpathT) DecMapUint8StringV(v map[uint8]string, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18634,17 +26346,22 @@ func (_ fastpathT) DecMapUint8StringV(v map[uint8]string, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]string, containerLen) - } else { - v = make(map[uint8]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17) + v = make(map[uint8]string, xlen) changed = true } + + var mk uint8 + var mv string if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint8(dd.DecodeUint(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeString() if v != nil { v[mk] = mv @@ -18652,23 +26369,26 @@ func (_ fastpathT) DecMapUint8StringV(v map[uint8]string, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint8UintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8UintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]uint) v, changed := fastpathTV.DecMapUint8UintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -18689,7 +26409,8 @@ func (f fastpathT) DecMapUint8UintX(vp *map[uint8]uint, checkNil bool, d *Decode func (_ fastpathT) DecMapUint8UintV(v map[uint8]uint, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18699,17 +26420,22 @@ func (_ fastpathT) DecMapUint8UintV(v map[uint8]uint, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]uint, containerLen) - } else { - v = make(map[uint8]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[uint8]uint, xlen) changed = true } + + var mk uint8 + var mv uint if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint8(dd.DecodeUint(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv @@ -18717,23 +26443,26 @@ func (_ fastpathT) DecMapUint8UintV(v map[uint8]uint, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint8Uint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8Uint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]uint8) v, changed := fastpathTV.DecMapUint8Uint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -18754,7 +26483,8 @@ func (f fastpathT) DecMapUint8Uint8X(vp *map[uint8]uint8, checkNil bool, d *Deco func (_ fastpathT) DecMapUint8Uint8V(v map[uint8]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18764,17 +26494,22 @@ func (_ fastpathT) DecMapUint8Uint8V(v map[uint8]uint8, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]uint8, containerLen) - } else { - v = make(map[uint8]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2) + v = make(map[uint8]uint8, xlen) changed = true } + + var mk uint8 + var mv uint8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint8(dd.DecodeUint(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv @@ -18782,23 +26517,26 @@ func (_ fastpathT) DecMapUint8Uint8V(v map[uint8]uint8, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint8Uint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8Uint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]uint16) v, changed := fastpathTV.DecMapUint8Uint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -18819,7 +26557,8 @@ func (f fastpathT) DecMapUint8Uint16X(vp *map[uint8]uint16, checkNil bool, d *De func (_ fastpathT) DecMapUint8Uint16V(v map[uint8]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18829,17 +26568,22 @@ func (_ fastpathT) DecMapUint8Uint16V(v map[uint8]uint16, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]uint16, containerLen) - } else { - v = make(map[uint8]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3) + v = make(map[uint8]uint16, xlen) changed = true } + + var mk uint8 + var mv uint16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint8(dd.DecodeUint(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv @@ -18847,23 +26591,26 @@ func (_ fastpathT) DecMapUint8Uint16V(v map[uint8]uint16, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint8Uint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8Uint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]uint32) v, changed := fastpathTV.DecMapUint8Uint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -18884,7 +26631,8 @@ func (f fastpathT) DecMapUint8Uint32X(vp *map[uint8]uint32, checkNil bool, d *De func (_ fastpathT) DecMapUint8Uint32V(v map[uint8]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18894,17 +26642,22 @@ func (_ fastpathT) DecMapUint8Uint32V(v map[uint8]uint32, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]uint32, containerLen) - } else { - v = make(map[uint8]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[uint8]uint32, xlen) changed = true } + + var mk uint8 + var mv uint32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint8(dd.DecodeUint(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv @@ -18912,23 +26665,26 @@ func (_ fastpathT) DecMapUint8Uint32V(v map[uint8]uint32, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint8Uint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8Uint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]uint64) v, changed := fastpathTV.DecMapUint8Uint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -18949,7 +26705,8 @@ func (f fastpathT) DecMapUint8Uint64X(vp *map[uint8]uint64, checkNil bool, d *De func (_ fastpathT) DecMapUint8Uint64V(v map[uint8]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -18959,17 +26716,22 @@ func (_ fastpathT) DecMapUint8Uint64V(v map[uint8]uint64, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]uint64, containerLen) - } else { - v = make(map[uint8]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[uint8]uint64, xlen) changed = true } + + var mk uint8 + var mv uint64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint8(dd.DecodeUint(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeUint(64) if v != nil { v[mk] = mv @@ -18977,23 +26739,100 @@ func (_ fastpathT) DecMapUint8Uint64V(v map[uint8]uint64, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint8IntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8UintptrR(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[uint8]uintptr) + v, changed := fastpathTV.DecMapUint8UintptrV(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[uint8]uintptr) + fastpathTV.DecMapUint8UintptrV(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapUint8UintptrX(vp *map[uint8]uintptr, checkNil bool, d *Decoder) { + v, changed := f.DecMapUint8UintptrV(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapUint8UintptrV(v map[uint8]uintptr, checkNil bool, canChange bool, + d *Decoder) (_ map[uint8]uintptr, changed bool) { + dd := d.d + cr := d.cr + + 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, 9) + v = make(map[uint8]uintptr, xlen) + changed = true + } + + var mk uint8 + var mv uintptr + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapUint8IntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]int) v, changed := fastpathTV.DecMapUint8IntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -19014,7 +26853,8 @@ func (f fastpathT) DecMapUint8IntX(vp *map[uint8]int, checkNil bool, d *Decoder) func (_ fastpathT) DecMapUint8IntV(v map[uint8]int, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19024,17 +26864,22 @@ func (_ fastpathT) DecMapUint8IntV(v map[uint8]int, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]int, containerLen) - } else { - v = make(map[uint8]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[uint8]int, xlen) changed = true } + + var mk uint8 + var mv int if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint8(dd.DecodeUint(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv @@ -19042,23 +26887,26 @@ func (_ fastpathT) DecMapUint8IntV(v map[uint8]int, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint8Int8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8Int8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]int8) v, changed := fastpathTV.DecMapUint8Int8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -19079,7 +26927,8 @@ func (f fastpathT) DecMapUint8Int8X(vp *map[uint8]int8, checkNil bool, d *Decode func (_ fastpathT) DecMapUint8Int8V(v map[uint8]int8, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19089,17 +26938,22 @@ func (_ fastpathT) DecMapUint8Int8V(v map[uint8]int8, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]int8, containerLen) - } else { - v = make(map[uint8]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2) + v = make(map[uint8]int8, xlen) changed = true } + + var mk uint8 + var mv int8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint8(dd.DecodeUint(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv @@ -19107,23 +26961,26 @@ func (_ fastpathT) DecMapUint8Int8V(v map[uint8]int8, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint8Int16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8Int16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]int16) v, changed := fastpathTV.DecMapUint8Int16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -19144,7 +27001,8 @@ func (f fastpathT) DecMapUint8Int16X(vp *map[uint8]int16, checkNil bool, d *Deco func (_ fastpathT) DecMapUint8Int16V(v map[uint8]int16, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19154,17 +27012,22 @@ func (_ fastpathT) DecMapUint8Int16V(v map[uint8]int16, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]int16, containerLen) - } else { - v = make(map[uint8]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3) + v = make(map[uint8]int16, xlen) changed = true } + + var mk uint8 + var mv int16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint8(dd.DecodeUint(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv @@ -19172,23 +27035,26 @@ func (_ fastpathT) DecMapUint8Int16V(v map[uint8]int16, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint8Int32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8Int32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]int32) v, changed := fastpathTV.DecMapUint8Int32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -19209,7 +27075,8 @@ func (f fastpathT) DecMapUint8Int32X(vp *map[uint8]int32, checkNil bool, d *Deco func (_ fastpathT) DecMapUint8Int32V(v map[uint8]int32, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19219,17 +27086,22 @@ func (_ fastpathT) DecMapUint8Int32V(v map[uint8]int32, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]int32, containerLen) - } else { - v = make(map[uint8]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[uint8]int32, xlen) changed = true } + + var mk uint8 + var mv int32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint8(dd.DecodeUint(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv @@ -19237,23 +27109,26 @@ func (_ fastpathT) DecMapUint8Int32V(v map[uint8]int32, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint8Int64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8Int64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]int64) v, changed := fastpathTV.DecMapUint8Int64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -19274,7 +27149,8 @@ func (f fastpathT) DecMapUint8Int64X(vp *map[uint8]int64, checkNil bool, d *Deco func (_ fastpathT) DecMapUint8Int64V(v map[uint8]int64, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19284,17 +27160,22 @@ func (_ fastpathT) DecMapUint8Int64V(v map[uint8]int64, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]int64, containerLen) - } else { - v = make(map[uint8]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[uint8]int64, xlen) changed = true } + + var mk uint8 + var mv int64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint8(dd.DecodeUint(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeInt(64) if v != nil { v[mk] = mv @@ -19302,23 +27183,26 @@ func (_ fastpathT) DecMapUint8Int64V(v map[uint8]int64, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint8Float32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8Float32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]float32) v, changed := fastpathTV.DecMapUint8Float32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -19339,7 +27223,8 @@ func (f fastpathT) DecMapUint8Float32X(vp *map[uint8]float32, checkNil bool, d * func (_ fastpathT) DecMapUint8Float32V(v map[uint8]float32, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19349,17 +27234,22 @@ func (_ fastpathT) DecMapUint8Float32V(v map[uint8]float32, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]float32, containerLen) - } else { - v = make(map[uint8]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[uint8]float32, xlen) changed = true } + + var mk uint8 + var mv float32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint8(dd.DecodeUint(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv @@ -19367,23 +27257,26 @@ func (_ fastpathT) DecMapUint8Float32V(v map[uint8]float32, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint8Float64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8Float64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]float64) v, changed := fastpathTV.DecMapUint8Float64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -19404,7 +27297,8 @@ func (f fastpathT) DecMapUint8Float64X(vp *map[uint8]float64, checkNil bool, d * func (_ fastpathT) DecMapUint8Float64V(v map[uint8]float64, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19414,17 +27308,22 @@ func (_ fastpathT) DecMapUint8Float64V(v map[uint8]float64, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]float64, containerLen) - } else { - v = make(map[uint8]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[uint8]float64, xlen) changed = true } + + var mk uint8 + var mv float64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint8(dd.DecodeUint(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv @@ -19432,23 +27331,26 @@ func (_ fastpathT) DecMapUint8Float64V(v map[uint8]float64, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint8BoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint8BoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint8]bool) v, changed := fastpathTV.DecMapUint8BoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -19469,7 +27371,8 @@ func (f fastpathT) DecMapUint8BoolX(vp *map[uint8]bool, checkNil bool, d *Decode func (_ fastpathT) DecMapUint8BoolV(v map[uint8]bool, checkNil bool, canChange bool, d *Decoder) (_ map[uint8]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19479,17 +27382,22 @@ func (_ fastpathT) DecMapUint8BoolV(v map[uint8]bool, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint8]bool, containerLen) - } else { - v = make(map[uint8]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2) + v = make(map[uint8]bool, xlen) changed = true } + + var mk uint8 + var mv bool if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint8(dd.DecodeUint(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeBool() if v != nil { v[mk] = mv @@ -19497,23 +27405,26 @@ func (_ fastpathT) DecMapUint8BoolV(v map[uint8]bool, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint8(dd.DecodeUint(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint8(dd.DecodeUint(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint16IntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16IntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]interface{}) v, changed := fastpathTV.DecMapUint16IntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -19534,7 +27445,8 @@ func (f fastpathT) DecMapUint16IntfX(vp *map[uint16]interface{}, checkNil bool, func (_ fastpathT) DecMapUint16IntfV(v map[uint16]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19544,43 +27456,59 @@ func (_ fastpathT) DecMapUint16IntfV(v map[uint16]interface{}, checkNil bool, ca containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]interface{}, containerLen) - } else { - v = make(map[uint16]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 18) + v = make(map[uint16]interface{}, xlen) changed = true } + mapGet := !d.h.MapValueReset && !d.h.InterfaceReset + var mk uint16 + var mv interface{} if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint16(dd.DecodeUint(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil + } d.decode(&mv) - if v != nil { v[mk] = mv } } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil } - mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() - mv := v[mk] d.decode(&mv) - if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint16StringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16StringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]string) v, changed := fastpathTV.DecMapUint16StringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -19601,7 +27529,8 @@ func (f fastpathT) DecMapUint16StringX(vp *map[uint16]string, checkNil bool, d * func (_ fastpathT) DecMapUint16StringV(v map[uint16]string, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19611,17 +27540,22 @@ func (_ fastpathT) DecMapUint16StringV(v map[uint16]string, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]string, containerLen) - } else { - v = make(map[uint16]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 18) + v = make(map[uint16]string, xlen) changed = true } + + var mk uint16 + var mv string if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint16(dd.DecodeUint(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeString() if v != nil { v[mk] = mv @@ -19629,23 +27563,26 @@ func (_ fastpathT) DecMapUint16StringV(v map[uint16]string, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint16UintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16UintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]uint) v, changed := fastpathTV.DecMapUint16UintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -19666,7 +27603,8 @@ func (f fastpathT) DecMapUint16UintX(vp *map[uint16]uint, checkNil bool, d *Deco func (_ fastpathT) DecMapUint16UintV(v map[uint16]uint, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19676,17 +27614,22 @@ func (_ fastpathT) DecMapUint16UintV(v map[uint16]uint, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]uint, containerLen) - } else { - v = make(map[uint16]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[uint16]uint, xlen) changed = true } + + var mk uint16 + var mv uint if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint16(dd.DecodeUint(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv @@ -19694,23 +27637,26 @@ func (_ fastpathT) DecMapUint16UintV(v map[uint16]uint, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint16Uint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16Uint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]uint8) v, changed := fastpathTV.DecMapUint16Uint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -19731,7 +27677,8 @@ func (f fastpathT) DecMapUint16Uint8X(vp *map[uint16]uint8, checkNil bool, d *De func (_ fastpathT) DecMapUint16Uint8V(v map[uint16]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19741,17 +27688,22 @@ func (_ fastpathT) DecMapUint16Uint8V(v map[uint16]uint8, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]uint8, containerLen) - } else { - v = make(map[uint16]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3) + v = make(map[uint16]uint8, xlen) changed = true } + + var mk uint16 + var mv uint8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint16(dd.DecodeUint(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv @@ -19759,23 +27711,26 @@ func (_ fastpathT) DecMapUint16Uint8V(v map[uint16]uint8, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint16Uint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16Uint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]uint16) v, changed := fastpathTV.DecMapUint16Uint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -19796,7 +27751,8 @@ func (f fastpathT) DecMapUint16Uint16X(vp *map[uint16]uint16, checkNil bool, d * func (_ fastpathT) DecMapUint16Uint16V(v map[uint16]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19806,17 +27762,22 @@ func (_ fastpathT) DecMapUint16Uint16V(v map[uint16]uint16, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]uint16, containerLen) - } else { - v = make(map[uint16]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 4) + v = make(map[uint16]uint16, xlen) changed = true } + + var mk uint16 + var mv uint16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint16(dd.DecodeUint(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv @@ -19824,23 +27785,26 @@ func (_ fastpathT) DecMapUint16Uint16V(v map[uint16]uint16, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint16Uint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16Uint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]uint32) v, changed := fastpathTV.DecMapUint16Uint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -19861,7 +27825,8 @@ func (f fastpathT) DecMapUint16Uint32X(vp *map[uint16]uint32, checkNil bool, d * func (_ fastpathT) DecMapUint16Uint32V(v map[uint16]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19871,17 +27836,22 @@ func (_ fastpathT) DecMapUint16Uint32V(v map[uint16]uint32, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]uint32, containerLen) - } else { - v = make(map[uint16]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6) + v = make(map[uint16]uint32, xlen) changed = true } + + var mk uint16 + var mv uint32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint16(dd.DecodeUint(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv @@ -19889,23 +27859,26 @@ func (_ fastpathT) DecMapUint16Uint32V(v map[uint16]uint32, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint16Uint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16Uint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]uint64) v, changed := fastpathTV.DecMapUint16Uint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -19926,7 +27899,8 @@ func (f fastpathT) DecMapUint16Uint64X(vp *map[uint16]uint64, checkNil bool, d * func (_ fastpathT) DecMapUint16Uint64V(v map[uint16]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -19936,17 +27910,22 @@ func (_ fastpathT) DecMapUint16Uint64V(v map[uint16]uint64, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]uint64, containerLen) - } else { - v = make(map[uint16]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[uint16]uint64, xlen) changed = true } + + var mk uint16 + var mv uint64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint16(dd.DecodeUint(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeUint(64) if v != nil { v[mk] = mv @@ -19954,23 +27933,100 @@ func (_ fastpathT) DecMapUint16Uint64V(v map[uint16]uint64, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint16IntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16UintptrR(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[uint16]uintptr) + v, changed := fastpathTV.DecMapUint16UintptrV(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[uint16]uintptr) + fastpathTV.DecMapUint16UintptrV(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapUint16UintptrX(vp *map[uint16]uintptr, checkNil bool, d *Decoder) { + v, changed := f.DecMapUint16UintptrV(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapUint16UintptrV(v map[uint16]uintptr, checkNil bool, canChange bool, + d *Decoder) (_ map[uint16]uintptr, changed bool) { + dd := d.d + cr := d.cr + + 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, 10) + v = make(map[uint16]uintptr, xlen) + changed = true + } + + var mk uint16 + var mv uintptr + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapUint16IntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]int) v, changed := fastpathTV.DecMapUint16IntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -19991,7 +28047,8 @@ func (f fastpathT) DecMapUint16IntX(vp *map[uint16]int, checkNil bool, d *Decode func (_ fastpathT) DecMapUint16IntV(v map[uint16]int, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20001,17 +28058,22 @@ func (_ fastpathT) DecMapUint16IntV(v map[uint16]int, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]int, containerLen) - } else { - v = make(map[uint16]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[uint16]int, xlen) changed = true } + + var mk uint16 + var mv int if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint16(dd.DecodeUint(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv @@ -20019,23 +28081,26 @@ func (_ fastpathT) DecMapUint16IntV(v map[uint16]int, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint16Int8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16Int8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]int8) v, changed := fastpathTV.DecMapUint16Int8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -20056,7 +28121,8 @@ func (f fastpathT) DecMapUint16Int8X(vp *map[uint16]int8, checkNil bool, d *Deco func (_ fastpathT) DecMapUint16Int8V(v map[uint16]int8, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20066,17 +28132,22 @@ func (_ fastpathT) DecMapUint16Int8V(v map[uint16]int8, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]int8, containerLen) - } else { - v = make(map[uint16]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3) + v = make(map[uint16]int8, xlen) changed = true } + + var mk uint16 + var mv int8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint16(dd.DecodeUint(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv @@ -20084,23 +28155,26 @@ func (_ fastpathT) DecMapUint16Int8V(v map[uint16]int8, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint16Int16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16Int16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]int16) v, changed := fastpathTV.DecMapUint16Int16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -20121,7 +28195,8 @@ func (f fastpathT) DecMapUint16Int16X(vp *map[uint16]int16, checkNil bool, d *De func (_ fastpathT) DecMapUint16Int16V(v map[uint16]int16, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20131,17 +28206,22 @@ func (_ fastpathT) DecMapUint16Int16V(v map[uint16]int16, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]int16, containerLen) - } else { - v = make(map[uint16]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 4) + v = make(map[uint16]int16, xlen) changed = true } + + var mk uint16 + var mv int16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint16(dd.DecodeUint(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv @@ -20149,23 +28229,26 @@ func (_ fastpathT) DecMapUint16Int16V(v map[uint16]int16, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint16Int32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16Int32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]int32) v, changed := fastpathTV.DecMapUint16Int32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -20186,7 +28269,8 @@ func (f fastpathT) DecMapUint16Int32X(vp *map[uint16]int32, checkNil bool, d *De func (_ fastpathT) DecMapUint16Int32V(v map[uint16]int32, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20196,17 +28280,22 @@ func (_ fastpathT) DecMapUint16Int32V(v map[uint16]int32, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]int32, containerLen) - } else { - v = make(map[uint16]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6) + v = make(map[uint16]int32, xlen) changed = true } + + var mk uint16 + var mv int32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint16(dd.DecodeUint(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv @@ -20214,23 +28303,26 @@ func (_ fastpathT) DecMapUint16Int32V(v map[uint16]int32, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint16Int64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16Int64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]int64) v, changed := fastpathTV.DecMapUint16Int64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -20251,7 +28343,8 @@ func (f fastpathT) DecMapUint16Int64X(vp *map[uint16]int64, checkNil bool, d *De func (_ fastpathT) DecMapUint16Int64V(v map[uint16]int64, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20261,17 +28354,22 @@ func (_ fastpathT) DecMapUint16Int64V(v map[uint16]int64, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]int64, containerLen) - } else { - v = make(map[uint16]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[uint16]int64, xlen) changed = true } + + var mk uint16 + var mv int64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint16(dd.DecodeUint(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeInt(64) if v != nil { v[mk] = mv @@ -20279,23 +28377,26 @@ func (_ fastpathT) DecMapUint16Int64V(v map[uint16]int64, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint16Float32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16Float32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]float32) v, changed := fastpathTV.DecMapUint16Float32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -20316,7 +28417,8 @@ func (f fastpathT) DecMapUint16Float32X(vp *map[uint16]float32, checkNil bool, d func (_ fastpathT) DecMapUint16Float32V(v map[uint16]float32, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20326,17 +28428,22 @@ func (_ fastpathT) DecMapUint16Float32V(v map[uint16]float32, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]float32, containerLen) - } else { - v = make(map[uint16]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6) + v = make(map[uint16]float32, xlen) changed = true } + + var mk uint16 + var mv float32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint16(dd.DecodeUint(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv @@ -20344,23 +28451,26 @@ func (_ fastpathT) DecMapUint16Float32V(v map[uint16]float32, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint16Float64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16Float64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]float64) v, changed := fastpathTV.DecMapUint16Float64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -20381,7 +28491,8 @@ func (f fastpathT) DecMapUint16Float64X(vp *map[uint16]float64, checkNil bool, d func (_ fastpathT) DecMapUint16Float64V(v map[uint16]float64, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20391,17 +28502,22 @@ func (_ fastpathT) DecMapUint16Float64V(v map[uint16]float64, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]float64, containerLen) - } else { - v = make(map[uint16]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[uint16]float64, xlen) changed = true } + + var mk uint16 + var mv float64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint16(dd.DecodeUint(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv @@ -20409,23 +28525,26 @@ func (_ fastpathT) DecMapUint16Float64V(v map[uint16]float64, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint16BoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint16BoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint16]bool) v, changed := fastpathTV.DecMapUint16BoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -20446,7 +28565,8 @@ func (f fastpathT) DecMapUint16BoolX(vp *map[uint16]bool, checkNil bool, d *Deco func (_ fastpathT) DecMapUint16BoolV(v map[uint16]bool, checkNil bool, canChange bool, d *Decoder) (_ map[uint16]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20456,17 +28576,22 @@ func (_ fastpathT) DecMapUint16BoolV(v map[uint16]bool, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint16]bool, containerLen) - } else { - v = make(map[uint16]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3) + v = make(map[uint16]bool, xlen) changed = true } + + var mk uint16 + var mv bool if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint16(dd.DecodeUint(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeBool() if v != nil { v[mk] = mv @@ -20474,23 +28599,26 @@ func (_ fastpathT) DecMapUint16BoolV(v map[uint16]bool, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint16(dd.DecodeUint(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint16(dd.DecodeUint(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint32IntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32IntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]interface{}) v, changed := fastpathTV.DecMapUint32IntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -20511,7 +28639,8 @@ func (f fastpathT) DecMapUint32IntfX(vp *map[uint32]interface{}, checkNil bool, func (_ fastpathT) DecMapUint32IntfV(v map[uint32]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20521,43 +28650,59 @@ func (_ fastpathT) DecMapUint32IntfV(v map[uint32]interface{}, checkNil bool, ca containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]interface{}, containerLen) - } else { - v = make(map[uint32]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20) + v = make(map[uint32]interface{}, xlen) changed = true } + mapGet := !d.h.MapValueReset && !d.h.InterfaceReset + var mk uint32 + var mv interface{} if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint32(dd.DecodeUint(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil + } d.decode(&mv) - if v != nil { v[mk] = mv } } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil } - mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() - mv := v[mk] d.decode(&mv) - if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint32StringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32StringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]string) v, changed := fastpathTV.DecMapUint32StringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -20578,7 +28723,8 @@ func (f fastpathT) DecMapUint32StringX(vp *map[uint32]string, checkNil bool, d * func (_ fastpathT) DecMapUint32StringV(v map[uint32]string, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20588,17 +28734,22 @@ func (_ fastpathT) DecMapUint32StringV(v map[uint32]string, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]string, containerLen) - } else { - v = make(map[uint32]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20) + v = make(map[uint32]string, xlen) changed = true } + + var mk uint32 + var mv string if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint32(dd.DecodeUint(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeString() if v != nil { v[mk] = mv @@ -20606,23 +28757,26 @@ func (_ fastpathT) DecMapUint32StringV(v map[uint32]string, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint32UintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32UintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]uint) v, changed := fastpathTV.DecMapUint32UintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -20643,7 +28797,8 @@ func (f fastpathT) DecMapUint32UintX(vp *map[uint32]uint, checkNil bool, d *Deco func (_ fastpathT) DecMapUint32UintV(v map[uint32]uint, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20653,17 +28808,22 @@ func (_ fastpathT) DecMapUint32UintV(v map[uint32]uint, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]uint, containerLen) - } else { - v = make(map[uint32]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[uint32]uint, xlen) changed = true } + + var mk uint32 + var mv uint if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint32(dd.DecodeUint(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv @@ -20671,23 +28831,26 @@ func (_ fastpathT) DecMapUint32UintV(v map[uint32]uint, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint32Uint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32Uint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]uint8) v, changed := fastpathTV.DecMapUint32Uint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -20708,7 +28871,8 @@ func (f fastpathT) DecMapUint32Uint8X(vp *map[uint32]uint8, checkNil bool, d *De func (_ fastpathT) DecMapUint32Uint8V(v map[uint32]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20718,17 +28882,22 @@ func (_ fastpathT) DecMapUint32Uint8V(v map[uint32]uint8, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]uint8, containerLen) - } else { - v = make(map[uint32]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[uint32]uint8, xlen) changed = true } + + var mk uint32 + var mv uint8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint32(dd.DecodeUint(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv @@ -20736,23 +28905,26 @@ func (_ fastpathT) DecMapUint32Uint8V(v map[uint32]uint8, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint32Uint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32Uint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]uint16) v, changed := fastpathTV.DecMapUint32Uint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -20773,7 +28945,8 @@ func (f fastpathT) DecMapUint32Uint16X(vp *map[uint32]uint16, checkNil bool, d * func (_ fastpathT) DecMapUint32Uint16V(v map[uint32]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20783,17 +28956,22 @@ func (_ fastpathT) DecMapUint32Uint16V(v map[uint32]uint16, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]uint16, containerLen) - } else { - v = make(map[uint32]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6) + v = make(map[uint32]uint16, xlen) changed = true } + + var mk uint32 + var mv uint16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint32(dd.DecodeUint(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv @@ -20801,23 +28979,26 @@ func (_ fastpathT) DecMapUint32Uint16V(v map[uint32]uint16, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint32Uint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32Uint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]uint32) v, changed := fastpathTV.DecMapUint32Uint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -20838,7 +29019,8 @@ func (f fastpathT) DecMapUint32Uint32X(vp *map[uint32]uint32, checkNil bool, d * func (_ fastpathT) DecMapUint32Uint32V(v map[uint32]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20848,17 +29030,22 @@ func (_ fastpathT) DecMapUint32Uint32V(v map[uint32]uint32, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]uint32, containerLen) - } else { - v = make(map[uint32]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8) + v = make(map[uint32]uint32, xlen) changed = true } + + var mk uint32 + var mv uint32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint32(dd.DecodeUint(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv @@ -20866,23 +29053,26 @@ func (_ fastpathT) DecMapUint32Uint32V(v map[uint32]uint32, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint32Uint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32Uint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]uint64) v, changed := fastpathTV.DecMapUint32Uint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -20903,7 +29093,8 @@ func (f fastpathT) DecMapUint32Uint64X(vp *map[uint32]uint64, checkNil bool, d * func (_ fastpathT) DecMapUint32Uint64V(v map[uint32]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20913,17 +29104,22 @@ func (_ fastpathT) DecMapUint32Uint64V(v map[uint32]uint64, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]uint64, containerLen) - } else { - v = make(map[uint32]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[uint32]uint64, xlen) changed = true } + + var mk uint32 + var mv uint64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint32(dd.DecodeUint(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeUint(64) if v != nil { v[mk] = mv @@ -20931,23 +29127,100 @@ func (_ fastpathT) DecMapUint32Uint64V(v map[uint32]uint64, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint32IntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32UintptrR(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[uint32]uintptr) + v, changed := fastpathTV.DecMapUint32UintptrV(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[uint32]uintptr) + fastpathTV.DecMapUint32UintptrV(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapUint32UintptrX(vp *map[uint32]uintptr, checkNil bool, d *Decoder) { + v, changed := f.DecMapUint32UintptrV(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapUint32UintptrV(v map[uint32]uintptr, checkNil bool, canChange bool, + d *Decoder) (_ map[uint32]uintptr, changed bool) { + dd := d.d + cr := d.cr + + 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, 12) + v = make(map[uint32]uintptr, xlen) + changed = true + } + + var mk uint32 + var mv uintptr + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapUint32IntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]int) v, changed := fastpathTV.DecMapUint32IntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -20968,7 +29241,8 @@ func (f fastpathT) DecMapUint32IntX(vp *map[uint32]int, checkNil bool, d *Decode func (_ fastpathT) DecMapUint32IntV(v map[uint32]int, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -20978,17 +29252,22 @@ func (_ fastpathT) DecMapUint32IntV(v map[uint32]int, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]int, containerLen) - } else { - v = make(map[uint32]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[uint32]int, xlen) changed = true } + + var mk uint32 + var mv int if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint32(dd.DecodeUint(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv @@ -20996,23 +29275,26 @@ func (_ fastpathT) DecMapUint32IntV(v map[uint32]int, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint32Int8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32Int8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]int8) v, changed := fastpathTV.DecMapUint32Int8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -21033,7 +29315,8 @@ func (f fastpathT) DecMapUint32Int8X(vp *map[uint32]int8, checkNil bool, d *Deco func (_ fastpathT) DecMapUint32Int8V(v map[uint32]int8, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21043,17 +29326,22 @@ func (_ fastpathT) DecMapUint32Int8V(v map[uint32]int8, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]int8, containerLen) - } else { - v = make(map[uint32]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[uint32]int8, xlen) changed = true } + + var mk uint32 + var mv int8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint32(dd.DecodeUint(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv @@ -21061,23 +29349,26 @@ func (_ fastpathT) DecMapUint32Int8V(v map[uint32]int8, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint32Int16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32Int16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]int16) v, changed := fastpathTV.DecMapUint32Int16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -21098,7 +29389,8 @@ func (f fastpathT) DecMapUint32Int16X(vp *map[uint32]int16, checkNil bool, d *De func (_ fastpathT) DecMapUint32Int16V(v map[uint32]int16, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21108,17 +29400,22 @@ func (_ fastpathT) DecMapUint32Int16V(v map[uint32]int16, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]int16, containerLen) - } else { - v = make(map[uint32]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6) + v = make(map[uint32]int16, xlen) changed = true } + + var mk uint32 + var mv int16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint32(dd.DecodeUint(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv @@ -21126,23 +29423,26 @@ func (_ fastpathT) DecMapUint32Int16V(v map[uint32]int16, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint32Int32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32Int32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]int32) v, changed := fastpathTV.DecMapUint32Int32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -21163,7 +29463,8 @@ func (f fastpathT) DecMapUint32Int32X(vp *map[uint32]int32, checkNil bool, d *De func (_ fastpathT) DecMapUint32Int32V(v map[uint32]int32, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21173,17 +29474,22 @@ func (_ fastpathT) DecMapUint32Int32V(v map[uint32]int32, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]int32, containerLen) - } else { - v = make(map[uint32]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8) + v = make(map[uint32]int32, xlen) changed = true } + + var mk uint32 + var mv int32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint32(dd.DecodeUint(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv @@ -21191,23 +29497,26 @@ func (_ fastpathT) DecMapUint32Int32V(v map[uint32]int32, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint32Int64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32Int64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]int64) v, changed := fastpathTV.DecMapUint32Int64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -21228,7 +29537,8 @@ func (f fastpathT) DecMapUint32Int64X(vp *map[uint32]int64, checkNil bool, d *De func (_ fastpathT) DecMapUint32Int64V(v map[uint32]int64, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21238,17 +29548,22 @@ func (_ fastpathT) DecMapUint32Int64V(v map[uint32]int64, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]int64, containerLen) - } else { - v = make(map[uint32]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[uint32]int64, xlen) changed = true } + + var mk uint32 + var mv int64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint32(dd.DecodeUint(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeInt(64) if v != nil { v[mk] = mv @@ -21256,23 +29571,26 @@ func (_ fastpathT) DecMapUint32Int64V(v map[uint32]int64, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint32Float32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32Float32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]float32) v, changed := fastpathTV.DecMapUint32Float32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -21293,7 +29611,8 @@ func (f fastpathT) DecMapUint32Float32X(vp *map[uint32]float32, checkNil bool, d func (_ fastpathT) DecMapUint32Float32V(v map[uint32]float32, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21303,17 +29622,22 @@ func (_ fastpathT) DecMapUint32Float32V(v map[uint32]float32, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]float32, containerLen) - } else { - v = make(map[uint32]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8) + v = make(map[uint32]float32, xlen) changed = true } + + var mk uint32 + var mv float32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint32(dd.DecodeUint(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv @@ -21321,23 +29645,26 @@ func (_ fastpathT) DecMapUint32Float32V(v map[uint32]float32, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint32Float64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32Float64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]float64) v, changed := fastpathTV.DecMapUint32Float64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -21358,7 +29685,8 @@ func (f fastpathT) DecMapUint32Float64X(vp *map[uint32]float64, checkNil bool, d func (_ fastpathT) DecMapUint32Float64V(v map[uint32]float64, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21368,17 +29696,22 @@ func (_ fastpathT) DecMapUint32Float64V(v map[uint32]float64, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]float64, containerLen) - } else { - v = make(map[uint32]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[uint32]float64, xlen) changed = true } + + var mk uint32 + var mv float64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint32(dd.DecodeUint(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv @@ -21386,23 +29719,26 @@ func (_ fastpathT) DecMapUint32Float64V(v map[uint32]float64, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint32BoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint32BoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint32]bool) v, changed := fastpathTV.DecMapUint32BoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -21423,7 +29759,8 @@ func (f fastpathT) DecMapUint32BoolX(vp *map[uint32]bool, checkNil bool, d *Deco func (_ fastpathT) DecMapUint32BoolV(v map[uint32]bool, checkNil bool, canChange bool, d *Decoder) (_ map[uint32]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21433,17 +29770,22 @@ func (_ fastpathT) DecMapUint32BoolV(v map[uint32]bool, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint32]bool, containerLen) - } else { - v = make(map[uint32]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[uint32]bool, xlen) changed = true } + + var mk uint32 + var mv bool if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := uint32(dd.DecodeUint(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeBool() if v != nil { v[mk] = mv @@ -21451,23 +29793,26 @@ func (_ fastpathT) DecMapUint32BoolV(v map[uint32]bool, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uint32(dd.DecodeUint(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := uint32(dd.DecodeUint(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint64IntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64IntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]interface{}) v, changed := fastpathTV.DecMapUint64IntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -21488,7 +29833,8 @@ func (f fastpathT) DecMapUint64IntfX(vp *map[uint64]interface{}, checkNil bool, func (_ fastpathT) DecMapUint64IntfV(v map[uint64]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21498,43 +29844,59 @@ func (_ fastpathT) DecMapUint64IntfV(v map[uint64]interface{}, checkNil bool, ca containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]interface{}, containerLen) - } else { - v = make(map[uint64]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[uint64]interface{}, xlen) changed = true } + mapGet := !d.h.MapValueReset && !d.h.InterfaceReset + var mk uint64 + var mv interface{} if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeUint(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil + } d.decode(&mv) - if v != nil { v[mk] = mv } } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil } - mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() - mv := v[mk] d.decode(&mv) - if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint64StringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64StringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]string) v, changed := fastpathTV.DecMapUint64StringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -21555,7 +29917,8 @@ func (f fastpathT) DecMapUint64StringX(vp *map[uint64]string, checkNil bool, d * func (_ fastpathT) DecMapUint64StringV(v map[uint64]string, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21565,17 +29928,22 @@ func (_ fastpathT) DecMapUint64StringV(v map[uint64]string, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]string, containerLen) - } else { - v = make(map[uint64]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[uint64]string, xlen) changed = true } + + var mk uint64 + var mv string if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeUint(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeString() if v != nil { v[mk] = mv @@ -21583,23 +29951,26 @@ func (_ fastpathT) DecMapUint64StringV(v map[uint64]string, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint64UintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64UintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]uint) v, changed := fastpathTV.DecMapUint64UintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -21620,7 +29991,8 @@ func (f fastpathT) DecMapUint64UintX(vp *map[uint64]uint, checkNil bool, d *Deco func (_ fastpathT) DecMapUint64UintV(v map[uint64]uint, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21630,17 +30002,22 @@ func (_ fastpathT) DecMapUint64UintV(v map[uint64]uint, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]uint, containerLen) - } else { - v = make(map[uint64]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[uint64]uint, xlen) changed = true } + + var mk uint64 + var mv uint if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeUint(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv @@ -21648,23 +30025,26 @@ func (_ fastpathT) DecMapUint64UintV(v map[uint64]uint, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint64Uint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64Uint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]uint8) v, changed := fastpathTV.DecMapUint64Uint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -21685,7 +30065,8 @@ func (f fastpathT) DecMapUint64Uint8X(vp *map[uint64]uint8, checkNil bool, d *De func (_ fastpathT) DecMapUint64Uint8V(v map[uint64]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21695,17 +30076,22 @@ func (_ fastpathT) DecMapUint64Uint8V(v map[uint64]uint8, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]uint8, containerLen) - } else { - v = make(map[uint64]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[uint64]uint8, xlen) changed = true } + + var mk uint64 + var mv uint8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeUint(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv @@ -21713,23 +30099,26 @@ func (_ fastpathT) DecMapUint64Uint8V(v map[uint64]uint8, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint64Uint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64Uint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]uint16) v, changed := fastpathTV.DecMapUint64Uint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -21750,7 +30139,8 @@ func (f fastpathT) DecMapUint64Uint16X(vp *map[uint64]uint16, checkNil bool, d * func (_ fastpathT) DecMapUint64Uint16V(v map[uint64]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21760,17 +30150,22 @@ func (_ fastpathT) DecMapUint64Uint16V(v map[uint64]uint16, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]uint16, containerLen) - } else { - v = make(map[uint64]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[uint64]uint16, xlen) changed = true } + + var mk uint64 + var mv uint16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeUint(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv @@ -21778,23 +30173,26 @@ func (_ fastpathT) DecMapUint64Uint16V(v map[uint64]uint16, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint64Uint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64Uint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]uint32) v, changed := fastpathTV.DecMapUint64Uint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -21815,7 +30213,8 @@ func (f fastpathT) DecMapUint64Uint32X(vp *map[uint64]uint32, checkNil bool, d * func (_ fastpathT) DecMapUint64Uint32V(v map[uint64]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21825,17 +30224,22 @@ func (_ fastpathT) DecMapUint64Uint32V(v map[uint64]uint32, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]uint32, containerLen) - } else { - v = make(map[uint64]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[uint64]uint32, xlen) changed = true } + + var mk uint64 + var mv uint32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeUint(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv @@ -21843,23 +30247,26 @@ func (_ fastpathT) DecMapUint64Uint32V(v map[uint64]uint32, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint64Uint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64Uint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]uint64) v, changed := fastpathTV.DecMapUint64Uint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -21880,7 +30287,8 @@ func (f fastpathT) DecMapUint64Uint64X(vp *map[uint64]uint64, checkNil bool, d * func (_ fastpathT) DecMapUint64Uint64V(v map[uint64]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21890,17 +30298,22 @@ func (_ fastpathT) DecMapUint64Uint64V(v map[uint64]uint64, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]uint64, containerLen) - } else { - v = make(map[uint64]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[uint64]uint64, xlen) changed = true } + + var mk uint64 + var mv uint64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeUint(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeUint(64) if v != nil { v[mk] = mv @@ -21908,23 +30321,100 @@ func (_ fastpathT) DecMapUint64Uint64V(v map[uint64]uint64, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint64IntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64UintptrR(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[uint64]uintptr) + v, changed := fastpathTV.DecMapUint64UintptrV(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[uint64]uintptr) + fastpathTV.DecMapUint64UintptrV(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapUint64UintptrX(vp *map[uint64]uintptr, checkNil bool, d *Decoder) { + v, changed := f.DecMapUint64UintptrV(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapUint64UintptrV(v map[uint64]uintptr, checkNil bool, canChange bool, + d *Decoder) (_ map[uint64]uintptr, changed bool) { + dd := d.d + cr := d.cr + + 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, 16) + v = make(map[uint64]uintptr, xlen) + changed = true + } + + var mk uint64 + var mv uintptr + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapUint64IntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]int) v, changed := fastpathTV.DecMapUint64IntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -21945,7 +30435,8 @@ func (f fastpathT) DecMapUint64IntX(vp *map[uint64]int, checkNil bool, d *Decode func (_ fastpathT) DecMapUint64IntV(v map[uint64]int, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -21955,17 +30446,22 @@ func (_ fastpathT) DecMapUint64IntV(v map[uint64]int, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]int, containerLen) - } else { - v = make(map[uint64]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[uint64]int, xlen) changed = true } + + var mk uint64 + var mv int if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeUint(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv @@ -21973,23 +30469,26 @@ func (_ fastpathT) DecMapUint64IntV(v map[uint64]int, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint64Int8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64Int8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]int8) v, changed := fastpathTV.DecMapUint64Int8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -22010,7 +30509,8 @@ func (f fastpathT) DecMapUint64Int8X(vp *map[uint64]int8, checkNil bool, d *Deco func (_ fastpathT) DecMapUint64Int8V(v map[uint64]int8, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22020,17 +30520,22 @@ func (_ fastpathT) DecMapUint64Int8V(v map[uint64]int8, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]int8, containerLen) - } else { - v = make(map[uint64]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[uint64]int8, xlen) changed = true } + + var mk uint64 + var mv int8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeUint(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv @@ -22038,23 +30543,26 @@ func (_ fastpathT) DecMapUint64Int8V(v map[uint64]int8, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint64Int16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64Int16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]int16) v, changed := fastpathTV.DecMapUint64Int16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -22075,7 +30583,8 @@ func (f fastpathT) DecMapUint64Int16X(vp *map[uint64]int16, checkNil bool, d *De func (_ fastpathT) DecMapUint64Int16V(v map[uint64]int16, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22085,17 +30594,22 @@ func (_ fastpathT) DecMapUint64Int16V(v map[uint64]int16, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]int16, containerLen) - } else { - v = make(map[uint64]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[uint64]int16, xlen) changed = true } + + var mk uint64 + var mv int16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeUint(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv @@ -22103,23 +30617,26 @@ func (_ fastpathT) DecMapUint64Int16V(v map[uint64]int16, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint64Int32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64Int32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]int32) v, changed := fastpathTV.DecMapUint64Int32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -22140,7 +30657,8 @@ func (f fastpathT) DecMapUint64Int32X(vp *map[uint64]int32, checkNil bool, d *De func (_ fastpathT) DecMapUint64Int32V(v map[uint64]int32, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22150,17 +30668,22 @@ func (_ fastpathT) DecMapUint64Int32V(v map[uint64]int32, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]int32, containerLen) - } else { - v = make(map[uint64]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[uint64]int32, xlen) changed = true } + + var mk uint64 + var mv int32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeUint(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv @@ -22168,23 +30691,26 @@ func (_ fastpathT) DecMapUint64Int32V(v map[uint64]int32, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint64Int64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64Int64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]int64) v, changed := fastpathTV.DecMapUint64Int64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -22205,7 +30731,8 @@ func (f fastpathT) DecMapUint64Int64X(vp *map[uint64]int64, checkNil bool, d *De func (_ fastpathT) DecMapUint64Int64V(v map[uint64]int64, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22215,17 +30742,22 @@ func (_ fastpathT) DecMapUint64Int64V(v map[uint64]int64, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]int64, containerLen) - } else { - v = make(map[uint64]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[uint64]int64, xlen) changed = true } + + var mk uint64 + var mv int64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeUint(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeInt(64) if v != nil { v[mk] = mv @@ -22233,23 +30765,26 @@ func (_ fastpathT) DecMapUint64Int64V(v map[uint64]int64, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint64Float32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64Float32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]float32) v, changed := fastpathTV.DecMapUint64Float32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -22270,7 +30805,8 @@ func (f fastpathT) DecMapUint64Float32X(vp *map[uint64]float32, checkNil bool, d func (_ fastpathT) DecMapUint64Float32V(v map[uint64]float32, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22280,17 +30816,22 @@ func (_ fastpathT) DecMapUint64Float32V(v map[uint64]float32, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]float32, containerLen) - } else { - v = make(map[uint64]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[uint64]float32, xlen) changed = true } + + var mk uint64 + var mv float32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeUint(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv @@ -22298,23 +30839,26 @@ func (_ fastpathT) DecMapUint64Float32V(v map[uint64]float32, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint64Float64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64Float64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]float64) v, changed := fastpathTV.DecMapUint64Float64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -22335,7 +30879,8 @@ func (f fastpathT) DecMapUint64Float64X(vp *map[uint64]float64, checkNil bool, d func (_ fastpathT) DecMapUint64Float64V(v map[uint64]float64, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22345,17 +30890,22 @@ func (_ fastpathT) DecMapUint64Float64V(v map[uint64]float64, checkNil bool, can containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]float64, containerLen) - } else { - v = make(map[uint64]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[uint64]float64, xlen) changed = true } + + var mk uint64 + var mv float64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeUint(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv @@ -22363,23 +30913,26 @@ func (_ fastpathT) DecMapUint64Float64V(v map[uint64]float64, checkNil bool, can } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapUint64BoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUint64BoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[uint64]bool) v, changed := fastpathTV.DecMapUint64BoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -22400,7 +30953,8 @@ func (f fastpathT) DecMapUint64BoolX(vp *map[uint64]bool, checkNil bool, d *Deco func (_ fastpathT) DecMapUint64BoolV(v map[uint64]bool, checkNil bool, canChange bool, d *Decoder) (_ map[uint64]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22410,17 +30964,22 @@ func (_ fastpathT) DecMapUint64BoolV(v map[uint64]bool, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[uint64]bool, containerLen) - } else { - v = make(map[uint64]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[uint64]bool, xlen) changed = true } + + var mk uint64 + var mv bool if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeUint(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeBool() if v != nil { v[mk] = mv @@ -22428,23 +30987,1220 @@ func (_ fastpathT) DecMapUint64BoolV(v map[uint64]bool, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeUint(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeUint(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntIntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapUintptrIntfR(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[uintptr]interface{}) + v, changed := fastpathTV.DecMapUintptrIntfV(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[uintptr]interface{}) + fastpathTV.DecMapUintptrIntfV(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapUintptrIntfX(vp *map[uintptr]interface{}, checkNil bool, d *Decoder) { + v, changed := f.DecMapUintptrIntfV(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapUintptrIntfV(v map[uintptr]interface{}, checkNil bool, canChange bool, + d *Decoder) (_ map[uintptr]interface{}, changed bool) { + dd := d.d + cr := d.cr + + 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, 24) + v = make(map[uintptr]interface{}, xlen) + changed = true + } + mapGet := !d.h.MapValueReset && !d.h.InterfaceReset + var mk uintptr + var mv interface{} + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil + } + d.decode(&mv) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil + } + d.decode(&mv) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapUintptrStringR(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[uintptr]string) + v, changed := fastpathTV.DecMapUintptrStringV(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[uintptr]string) + fastpathTV.DecMapUintptrStringV(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapUintptrStringX(vp *map[uintptr]string, checkNil bool, d *Decoder) { + v, changed := f.DecMapUintptrStringV(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapUintptrStringV(v map[uintptr]string, checkNil bool, canChange bool, + d *Decoder) (_ map[uintptr]string, changed bool) { + dd := d.d + cr := d.cr + + 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, 24) + v = make(map[uintptr]string, xlen) + changed = true + } + + var mk uintptr + var mv string + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = dd.DecodeString() + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = dd.DecodeString() + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapUintptrUintR(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[uintptr]uint) + v, changed := fastpathTV.DecMapUintptrUintV(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[uintptr]uint) + fastpathTV.DecMapUintptrUintV(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapUintptrUintX(vp *map[uintptr]uint, checkNil bool, d *Decoder) { + v, changed := f.DecMapUintptrUintV(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapUintptrUintV(v map[uintptr]uint, checkNil bool, canChange bool, + d *Decoder) (_ map[uintptr]uint, changed bool) { + dd := d.d + cr := d.cr + + 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, 16) + v = make(map[uintptr]uint, xlen) + changed = true + } + + var mk uintptr + var mv uint + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uint(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uint(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapUintptrUint8R(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[uintptr]uint8) + v, changed := fastpathTV.DecMapUintptrUint8V(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[uintptr]uint8) + fastpathTV.DecMapUintptrUint8V(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapUintptrUint8X(vp *map[uintptr]uint8, checkNil bool, d *Decoder) { + v, changed := f.DecMapUintptrUint8V(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapUintptrUint8V(v map[uintptr]uint8, checkNil bool, canChange bool, + d *Decoder) (_ map[uintptr]uint8, changed bool) { + dd := d.d + cr := d.cr + + 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, 9) + v = make(map[uintptr]uint8, xlen) + changed = true + } + + var mk uintptr + var mv uint8 + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uint8(dd.DecodeUint(8)) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uint8(dd.DecodeUint(8)) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapUintptrUint16R(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[uintptr]uint16) + v, changed := fastpathTV.DecMapUintptrUint16V(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[uintptr]uint16) + fastpathTV.DecMapUintptrUint16V(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapUintptrUint16X(vp *map[uintptr]uint16, checkNil bool, d *Decoder) { + v, changed := f.DecMapUintptrUint16V(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapUintptrUint16V(v map[uintptr]uint16, checkNil bool, canChange bool, + d *Decoder) (_ map[uintptr]uint16, changed bool) { + dd := d.d + cr := d.cr + + 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, 10) + v = make(map[uintptr]uint16, xlen) + changed = true + } + + var mk uintptr + var mv uint16 + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uint16(dd.DecodeUint(16)) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uint16(dd.DecodeUint(16)) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapUintptrUint32R(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[uintptr]uint32) + v, changed := fastpathTV.DecMapUintptrUint32V(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[uintptr]uint32) + fastpathTV.DecMapUintptrUint32V(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapUintptrUint32X(vp *map[uintptr]uint32, checkNil bool, d *Decoder) { + v, changed := f.DecMapUintptrUint32V(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapUintptrUint32V(v map[uintptr]uint32, checkNil bool, canChange bool, + d *Decoder) (_ map[uintptr]uint32, changed bool) { + dd := d.d + cr := d.cr + + 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, 12) + v = make(map[uintptr]uint32, xlen) + changed = true + } + + var mk uintptr + var mv uint32 + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uint32(dd.DecodeUint(32)) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uint32(dd.DecodeUint(32)) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapUintptrUint64R(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[uintptr]uint64) + v, changed := fastpathTV.DecMapUintptrUint64V(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[uintptr]uint64) + fastpathTV.DecMapUintptrUint64V(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapUintptrUint64X(vp *map[uintptr]uint64, checkNil bool, d *Decoder) { + v, changed := f.DecMapUintptrUint64V(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapUintptrUint64V(v map[uintptr]uint64, checkNil bool, canChange bool, + d *Decoder) (_ map[uintptr]uint64, changed bool) { + dd := d.d + cr := d.cr + + 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, 16) + v = make(map[uintptr]uint64, xlen) + changed = true + } + + var mk uintptr + var mv uint64 + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = dd.DecodeUint(64) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = dd.DecodeUint(64) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapUintptrUintptrR(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[uintptr]uintptr) + v, changed := fastpathTV.DecMapUintptrUintptrV(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[uintptr]uintptr) + fastpathTV.DecMapUintptrUintptrV(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapUintptrUintptrX(vp *map[uintptr]uintptr, checkNil bool, d *Decoder) { + v, changed := f.DecMapUintptrUintptrV(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapUintptrUintptrV(v map[uintptr]uintptr, checkNil bool, canChange bool, + d *Decoder) (_ map[uintptr]uintptr, changed bool) { + dd := d.d + cr := d.cr + + 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, 16) + v = make(map[uintptr]uintptr, xlen) + changed = true + } + + var mk uintptr + var mv uintptr + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapUintptrIntR(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[uintptr]int) + v, changed := fastpathTV.DecMapUintptrIntV(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[uintptr]int) + fastpathTV.DecMapUintptrIntV(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapUintptrIntX(vp *map[uintptr]int, checkNil bool, d *Decoder) { + v, changed := f.DecMapUintptrIntV(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapUintptrIntV(v map[uintptr]int, checkNil bool, canChange bool, + d *Decoder) (_ map[uintptr]int, changed bool) { + dd := d.d + cr := d.cr + + 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, 16) + v = make(map[uintptr]int, xlen) + changed = true + } + + var mk uintptr + var mv int + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = int(dd.DecodeInt(intBitsize)) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = int(dd.DecodeInt(intBitsize)) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapUintptrInt8R(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[uintptr]int8) + v, changed := fastpathTV.DecMapUintptrInt8V(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[uintptr]int8) + fastpathTV.DecMapUintptrInt8V(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapUintptrInt8X(vp *map[uintptr]int8, checkNil bool, d *Decoder) { + v, changed := f.DecMapUintptrInt8V(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapUintptrInt8V(v map[uintptr]int8, checkNil bool, canChange bool, + d *Decoder) (_ map[uintptr]int8, changed bool) { + dd := d.d + cr := d.cr + + 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, 9) + v = make(map[uintptr]int8, xlen) + changed = true + } + + var mk uintptr + var mv int8 + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = int8(dd.DecodeInt(8)) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = int8(dd.DecodeInt(8)) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapUintptrInt16R(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[uintptr]int16) + v, changed := fastpathTV.DecMapUintptrInt16V(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[uintptr]int16) + fastpathTV.DecMapUintptrInt16V(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapUintptrInt16X(vp *map[uintptr]int16, checkNil bool, d *Decoder) { + v, changed := f.DecMapUintptrInt16V(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapUintptrInt16V(v map[uintptr]int16, checkNil bool, canChange bool, + d *Decoder) (_ map[uintptr]int16, changed bool) { + dd := d.d + cr := d.cr + + 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, 10) + v = make(map[uintptr]int16, xlen) + changed = true + } + + var mk uintptr + var mv int16 + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = int16(dd.DecodeInt(16)) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = int16(dd.DecodeInt(16)) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapUintptrInt32R(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[uintptr]int32) + v, changed := fastpathTV.DecMapUintptrInt32V(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[uintptr]int32) + fastpathTV.DecMapUintptrInt32V(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapUintptrInt32X(vp *map[uintptr]int32, checkNil bool, d *Decoder) { + v, changed := f.DecMapUintptrInt32V(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapUintptrInt32V(v map[uintptr]int32, checkNil bool, canChange bool, + d *Decoder) (_ map[uintptr]int32, changed bool) { + dd := d.d + cr := d.cr + + 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, 12) + v = make(map[uintptr]int32, xlen) + changed = true + } + + var mk uintptr + var mv int32 + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = int32(dd.DecodeInt(32)) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = int32(dd.DecodeInt(32)) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapUintptrInt64R(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[uintptr]int64) + v, changed := fastpathTV.DecMapUintptrInt64V(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[uintptr]int64) + fastpathTV.DecMapUintptrInt64V(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapUintptrInt64X(vp *map[uintptr]int64, checkNil bool, d *Decoder) { + v, changed := f.DecMapUintptrInt64V(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapUintptrInt64V(v map[uintptr]int64, checkNil bool, canChange bool, + d *Decoder) (_ map[uintptr]int64, changed bool) { + dd := d.d + cr := d.cr + + 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, 16) + v = make(map[uintptr]int64, xlen) + changed = true + } + + var mk uintptr + var mv int64 + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = dd.DecodeInt(64) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = dd.DecodeInt(64) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapUintptrFloat32R(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[uintptr]float32) + v, changed := fastpathTV.DecMapUintptrFloat32V(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[uintptr]float32) + fastpathTV.DecMapUintptrFloat32V(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapUintptrFloat32X(vp *map[uintptr]float32, checkNil bool, d *Decoder) { + v, changed := f.DecMapUintptrFloat32V(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapUintptrFloat32V(v map[uintptr]float32, checkNil bool, canChange bool, + d *Decoder) (_ map[uintptr]float32, changed bool) { + dd := d.d + cr := d.cr + + 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, 12) + v = make(map[uintptr]float32, xlen) + changed = true + } + + var mk uintptr + var mv float32 + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = float32(dd.DecodeFloat(true)) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = float32(dd.DecodeFloat(true)) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapUintptrFloat64R(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[uintptr]float64) + v, changed := fastpathTV.DecMapUintptrFloat64V(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[uintptr]float64) + fastpathTV.DecMapUintptrFloat64V(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapUintptrFloat64X(vp *map[uintptr]float64, checkNil bool, d *Decoder) { + v, changed := f.DecMapUintptrFloat64V(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapUintptrFloat64V(v map[uintptr]float64, checkNil bool, canChange bool, + d *Decoder) (_ map[uintptr]float64, changed bool) { + dd := d.d + cr := d.cr + + 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, 16) + v = make(map[uintptr]float64, xlen) + changed = true + } + + var mk uintptr + var mv float64 + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = dd.DecodeFloat(false) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = dd.DecodeFloat(false) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapUintptrBoolR(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[uintptr]bool) + v, changed := fastpathTV.DecMapUintptrBoolV(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[uintptr]bool) + fastpathTV.DecMapUintptrBoolV(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapUintptrBoolX(vp *map[uintptr]bool, checkNil bool, d *Decoder) { + v, changed := f.DecMapUintptrBoolV(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapUintptrBoolV(v map[uintptr]bool, checkNil bool, canChange bool, + d *Decoder) (_ map[uintptr]bool, changed bool) { + dd := d.d + cr := d.cr + + 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, 9) + v = make(map[uintptr]bool, xlen) + changed = true + } + + var mk uintptr + var mv bool + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = dd.DecodeBool() + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = uintptr(dd.DecodeUint(uintBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = dd.DecodeBool() + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapIntIntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]interface{}) v, changed := fastpathTV.DecMapIntIntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -22465,7 +32221,8 @@ func (f fastpathT) DecMapIntIntfX(vp *map[int]interface{}, checkNil bool, d *Dec func (_ fastpathT) DecMapIntIntfV(v map[int]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[int]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22475,43 +32232,59 @@ func (_ fastpathT) DecMapIntIntfV(v map[int]interface{}, checkNil bool, canChang containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]interface{}, containerLen) - } else { - v = make(map[int]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[int]interface{}, xlen) changed = true } + mapGet := !d.h.MapValueReset && !d.h.InterfaceReset + var mk int + var mv interface{} if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int(dd.DecodeInt(intBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil + } d.decode(&mv) - if v != nil { v[mk] = mv } } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil } - mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] d.decode(&mv) - if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntStringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntStringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]string) v, changed := fastpathTV.DecMapIntStringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -22532,7 +32305,8 @@ func (f fastpathT) DecMapIntStringX(vp *map[int]string, checkNil bool, d *Decode func (_ fastpathT) DecMapIntStringV(v map[int]string, checkNil bool, canChange bool, d *Decoder) (_ map[int]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22542,17 +32316,22 @@ func (_ fastpathT) DecMapIntStringV(v map[int]string, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]string, containerLen) - } else { - v = make(map[int]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[int]string, xlen) changed = true } + + var mk int + var mv string if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int(dd.DecodeInt(intBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeString() if v != nil { v[mk] = mv @@ -22560,23 +32339,26 @@ func (_ fastpathT) DecMapIntStringV(v map[int]string, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntUintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntUintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]uint) v, changed := fastpathTV.DecMapIntUintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -22597,7 +32379,8 @@ func (f fastpathT) DecMapIntUintX(vp *map[int]uint, checkNil bool, d *Decoder) { func (_ fastpathT) DecMapIntUintV(v map[int]uint, checkNil bool, canChange bool, d *Decoder) (_ map[int]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22607,17 +32390,22 @@ func (_ fastpathT) DecMapIntUintV(v map[int]uint, checkNil bool, canChange bool, containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]uint, containerLen) - } else { - v = make(map[int]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[int]uint, xlen) changed = true } + + var mk int + var mv uint if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int(dd.DecodeInt(intBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv @@ -22625,23 +32413,26 @@ func (_ fastpathT) DecMapIntUintV(v map[int]uint, checkNil bool, canChange bool, } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntUint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntUint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]uint8) v, changed := fastpathTV.DecMapIntUint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -22662,7 +32453,8 @@ func (f fastpathT) DecMapIntUint8X(vp *map[int]uint8, checkNil bool, d *Decoder) func (_ fastpathT) DecMapIntUint8V(v map[int]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[int]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22672,17 +32464,22 @@ func (_ fastpathT) DecMapIntUint8V(v map[int]uint8, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]uint8, containerLen) - } else { - v = make(map[int]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[int]uint8, xlen) changed = true } + + var mk int + var mv uint8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int(dd.DecodeInt(intBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv @@ -22690,23 +32487,26 @@ func (_ fastpathT) DecMapIntUint8V(v map[int]uint8, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntUint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntUint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]uint16) v, changed := fastpathTV.DecMapIntUint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -22727,7 +32527,8 @@ func (f fastpathT) DecMapIntUint16X(vp *map[int]uint16, checkNil bool, d *Decode func (_ fastpathT) DecMapIntUint16V(v map[int]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[int]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22737,17 +32538,22 @@ func (_ fastpathT) DecMapIntUint16V(v map[int]uint16, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]uint16, containerLen) - } else { - v = make(map[int]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[int]uint16, xlen) changed = true } + + var mk int + var mv uint16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int(dd.DecodeInt(intBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv @@ -22755,23 +32561,26 @@ func (_ fastpathT) DecMapIntUint16V(v map[int]uint16, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntUint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntUint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]uint32) v, changed := fastpathTV.DecMapIntUint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -22792,7 +32601,8 @@ func (f fastpathT) DecMapIntUint32X(vp *map[int]uint32, checkNil bool, d *Decode func (_ fastpathT) DecMapIntUint32V(v map[int]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[int]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22802,17 +32612,22 @@ func (_ fastpathT) DecMapIntUint32V(v map[int]uint32, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]uint32, containerLen) - } else { - v = make(map[int]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[int]uint32, xlen) changed = true } + + var mk int + var mv uint32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int(dd.DecodeInt(intBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv @@ -22820,23 +32635,26 @@ func (_ fastpathT) DecMapIntUint32V(v map[int]uint32, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntUint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntUint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]uint64) v, changed := fastpathTV.DecMapIntUint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -22857,7 +32675,8 @@ func (f fastpathT) DecMapIntUint64X(vp *map[int]uint64, checkNil bool, d *Decode func (_ fastpathT) DecMapIntUint64V(v map[int]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[int]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22867,17 +32686,22 @@ func (_ fastpathT) DecMapIntUint64V(v map[int]uint64, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]uint64, containerLen) - } else { - v = make(map[int]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[int]uint64, xlen) changed = true } + + var mk int + var mv uint64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int(dd.DecodeInt(intBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeUint(64) if v != nil { v[mk] = mv @@ -22885,23 +32709,100 @@ func (_ fastpathT) DecMapIntUint64V(v map[int]uint64, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntIntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntUintptrR(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[int]uintptr) + v, changed := fastpathTV.DecMapIntUintptrV(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[int]uintptr) + fastpathTV.DecMapIntUintptrV(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapIntUintptrX(vp *map[int]uintptr, checkNil bool, d *Decoder) { + v, changed := f.DecMapIntUintptrV(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapIntUintptrV(v map[int]uintptr, checkNil bool, canChange bool, + d *Decoder) (_ map[int]uintptr, changed bool) { + dd := d.d + cr := d.cr + + 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, 16) + v = make(map[int]uintptr, xlen) + changed = true + } + + var mk int + var mv uintptr + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapIntIntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]int) v, changed := fastpathTV.DecMapIntIntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -22922,7 +32823,8 @@ func (f fastpathT) DecMapIntIntX(vp *map[int]int, checkNil bool, d *Decoder) { func (_ fastpathT) DecMapIntIntV(v map[int]int, checkNil bool, canChange bool, d *Decoder) (_ map[int]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22932,17 +32834,22 @@ func (_ fastpathT) DecMapIntIntV(v map[int]int, checkNil bool, canChange bool, containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]int, containerLen) - } else { - v = make(map[int]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[int]int, xlen) changed = true } + + var mk int + var mv int if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int(dd.DecodeInt(intBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv @@ -22950,23 +32857,26 @@ func (_ fastpathT) DecMapIntIntV(v map[int]int, checkNil bool, canChange bool, } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntInt8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntInt8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]int8) v, changed := fastpathTV.DecMapIntInt8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -22987,7 +32897,8 @@ func (f fastpathT) DecMapIntInt8X(vp *map[int]int8, checkNil bool, d *Decoder) { func (_ fastpathT) DecMapIntInt8V(v map[int]int8, checkNil bool, canChange bool, d *Decoder) (_ map[int]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -22997,17 +32908,22 @@ func (_ fastpathT) DecMapIntInt8V(v map[int]int8, checkNil bool, canChange bool, containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]int8, containerLen) - } else { - v = make(map[int]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[int]int8, xlen) changed = true } + + var mk int + var mv int8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int(dd.DecodeInt(intBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv @@ -23015,23 +32931,26 @@ func (_ fastpathT) DecMapIntInt8V(v map[int]int8, checkNil bool, canChange bool, } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntInt16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntInt16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]int16) v, changed := fastpathTV.DecMapIntInt16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -23052,7 +32971,8 @@ func (f fastpathT) DecMapIntInt16X(vp *map[int]int16, checkNil bool, d *Decoder) func (_ fastpathT) DecMapIntInt16V(v map[int]int16, checkNil bool, canChange bool, d *Decoder) (_ map[int]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23062,17 +32982,22 @@ func (_ fastpathT) DecMapIntInt16V(v map[int]int16, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]int16, containerLen) - } else { - v = make(map[int]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[int]int16, xlen) changed = true } + + var mk int + var mv int16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int(dd.DecodeInt(intBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv @@ -23080,23 +33005,26 @@ func (_ fastpathT) DecMapIntInt16V(v map[int]int16, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntInt32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntInt32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]int32) v, changed := fastpathTV.DecMapIntInt32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -23117,7 +33045,8 @@ func (f fastpathT) DecMapIntInt32X(vp *map[int]int32, checkNil bool, d *Decoder) func (_ fastpathT) DecMapIntInt32V(v map[int]int32, checkNil bool, canChange bool, d *Decoder) (_ map[int]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23127,17 +33056,22 @@ func (_ fastpathT) DecMapIntInt32V(v map[int]int32, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]int32, containerLen) - } else { - v = make(map[int]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[int]int32, xlen) changed = true } + + var mk int + var mv int32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int(dd.DecodeInt(intBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv @@ -23145,23 +33079,26 @@ func (_ fastpathT) DecMapIntInt32V(v map[int]int32, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntInt64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntInt64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]int64) v, changed := fastpathTV.DecMapIntInt64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -23182,7 +33119,8 @@ func (f fastpathT) DecMapIntInt64X(vp *map[int]int64, checkNil bool, d *Decoder) func (_ fastpathT) DecMapIntInt64V(v map[int]int64, checkNil bool, canChange bool, d *Decoder) (_ map[int]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23192,17 +33130,22 @@ func (_ fastpathT) DecMapIntInt64V(v map[int]int64, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]int64, containerLen) - } else { - v = make(map[int]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[int]int64, xlen) changed = true } + + var mk int + var mv int64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int(dd.DecodeInt(intBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeInt(64) if v != nil { v[mk] = mv @@ -23210,23 +33153,26 @@ func (_ fastpathT) DecMapIntInt64V(v map[int]int64, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntFloat32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntFloat32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]float32) v, changed := fastpathTV.DecMapIntFloat32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -23247,7 +33193,8 @@ func (f fastpathT) DecMapIntFloat32X(vp *map[int]float32, checkNil bool, d *Deco func (_ fastpathT) DecMapIntFloat32V(v map[int]float32, checkNil bool, canChange bool, d *Decoder) (_ map[int]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23257,17 +33204,22 @@ func (_ fastpathT) DecMapIntFloat32V(v map[int]float32, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]float32, containerLen) - } else { - v = make(map[int]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[int]float32, xlen) changed = true } + + var mk int + var mv float32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int(dd.DecodeInt(intBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv @@ -23275,23 +33227,26 @@ func (_ fastpathT) DecMapIntFloat32V(v map[int]float32, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntFloat64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntFloat64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]float64) v, changed := fastpathTV.DecMapIntFloat64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -23312,7 +33267,8 @@ func (f fastpathT) DecMapIntFloat64X(vp *map[int]float64, checkNil bool, d *Deco func (_ fastpathT) DecMapIntFloat64V(v map[int]float64, checkNil bool, canChange bool, d *Decoder) (_ map[int]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23322,17 +33278,22 @@ func (_ fastpathT) DecMapIntFloat64V(v map[int]float64, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]float64, containerLen) - } else { - v = make(map[int]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[int]float64, xlen) changed = true } + + var mk int + var mv float64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int(dd.DecodeInt(intBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv @@ -23340,23 +33301,26 @@ func (_ fastpathT) DecMapIntFloat64V(v map[int]float64, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapIntBoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapIntBoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int]bool) v, changed := fastpathTV.DecMapIntBoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -23377,7 +33341,8 @@ func (f fastpathT) DecMapIntBoolX(vp *map[int]bool, checkNil bool, d *Decoder) { func (_ fastpathT) DecMapIntBoolV(v map[int]bool, checkNil bool, canChange bool, d *Decoder) (_ map[int]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23387,17 +33352,22 @@ func (_ fastpathT) DecMapIntBoolV(v map[int]bool, checkNil bool, canChange bool, containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int]bool, containerLen) - } else { - v = make(map[int]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[int]bool, xlen) changed = true } + + var mk int + var mv bool if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int(dd.DecodeInt(intBitsize)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeBool() if v != nil { v[mk] = mv @@ -23405,23 +33375,26 @@ func (_ fastpathT) DecMapIntBoolV(v map[int]bool, checkNil bool, canChange bool, } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int(dd.DecodeInt(intBitsize)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int(dd.DecodeInt(intBitsize)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt8IntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8IntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]interface{}) v, changed := fastpathTV.DecMapInt8IntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -23442,7 +33415,8 @@ func (f fastpathT) DecMapInt8IntfX(vp *map[int8]interface{}, checkNil bool, d *D func (_ fastpathT) DecMapInt8IntfV(v map[int8]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[int8]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23452,43 +33426,59 @@ func (_ fastpathT) DecMapInt8IntfV(v map[int8]interface{}, checkNil bool, canCha containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]interface{}, containerLen) - } else { - v = make(map[int8]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17) + v = make(map[int8]interface{}, xlen) changed = true } + mapGet := !d.h.MapValueReset && !d.h.InterfaceReset + var mk int8 + var mv interface{} if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int8(dd.DecodeInt(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil + } d.decode(&mv) - if v != nil { v[mk] = mv } } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil } - mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() - mv := v[mk] d.decode(&mv) - if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt8StringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8StringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]string) v, changed := fastpathTV.DecMapInt8StringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -23509,7 +33499,8 @@ func (f fastpathT) DecMapInt8StringX(vp *map[int8]string, checkNil bool, d *Deco func (_ fastpathT) DecMapInt8StringV(v map[int8]string, checkNil bool, canChange bool, d *Decoder) (_ map[int8]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23519,17 +33510,22 @@ func (_ fastpathT) DecMapInt8StringV(v map[int8]string, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]string, containerLen) - } else { - v = make(map[int8]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17) + v = make(map[int8]string, xlen) changed = true } + + var mk int8 + var mv string if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int8(dd.DecodeInt(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeString() if v != nil { v[mk] = mv @@ -23537,23 +33533,26 @@ func (_ fastpathT) DecMapInt8StringV(v map[int8]string, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt8UintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8UintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]uint) v, changed := fastpathTV.DecMapInt8UintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -23574,7 +33573,8 @@ func (f fastpathT) DecMapInt8UintX(vp *map[int8]uint, checkNil bool, d *Decoder) func (_ fastpathT) DecMapInt8UintV(v map[int8]uint, checkNil bool, canChange bool, d *Decoder) (_ map[int8]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23584,17 +33584,22 @@ func (_ fastpathT) DecMapInt8UintV(v map[int8]uint, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]uint, containerLen) - } else { - v = make(map[int8]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[int8]uint, xlen) changed = true } + + var mk int8 + var mv uint if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int8(dd.DecodeInt(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv @@ -23602,23 +33607,26 @@ func (_ fastpathT) DecMapInt8UintV(v map[int8]uint, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt8Uint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8Uint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]uint8) v, changed := fastpathTV.DecMapInt8Uint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -23639,7 +33647,8 @@ func (f fastpathT) DecMapInt8Uint8X(vp *map[int8]uint8, checkNil bool, d *Decode func (_ fastpathT) DecMapInt8Uint8V(v map[int8]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[int8]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23649,17 +33658,22 @@ func (_ fastpathT) DecMapInt8Uint8V(v map[int8]uint8, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]uint8, containerLen) - } else { - v = make(map[int8]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2) + v = make(map[int8]uint8, xlen) changed = true } + + var mk int8 + var mv uint8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int8(dd.DecodeInt(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv @@ -23667,23 +33681,26 @@ func (_ fastpathT) DecMapInt8Uint8V(v map[int8]uint8, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt8Uint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8Uint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]uint16) v, changed := fastpathTV.DecMapInt8Uint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -23704,7 +33721,8 @@ func (f fastpathT) DecMapInt8Uint16X(vp *map[int8]uint16, checkNil bool, d *Deco func (_ fastpathT) DecMapInt8Uint16V(v map[int8]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[int8]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23714,17 +33732,22 @@ func (_ fastpathT) DecMapInt8Uint16V(v map[int8]uint16, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]uint16, containerLen) - } else { - v = make(map[int8]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3) + v = make(map[int8]uint16, xlen) changed = true } + + var mk int8 + var mv uint16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int8(dd.DecodeInt(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv @@ -23732,23 +33755,26 @@ func (_ fastpathT) DecMapInt8Uint16V(v map[int8]uint16, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt8Uint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8Uint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]uint32) v, changed := fastpathTV.DecMapInt8Uint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -23769,7 +33795,8 @@ func (f fastpathT) DecMapInt8Uint32X(vp *map[int8]uint32, checkNil bool, d *Deco func (_ fastpathT) DecMapInt8Uint32V(v map[int8]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[int8]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23779,17 +33806,22 @@ func (_ fastpathT) DecMapInt8Uint32V(v map[int8]uint32, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]uint32, containerLen) - } else { - v = make(map[int8]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[int8]uint32, xlen) changed = true } + + var mk int8 + var mv uint32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int8(dd.DecodeInt(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv @@ -23797,23 +33829,26 @@ func (_ fastpathT) DecMapInt8Uint32V(v map[int8]uint32, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt8Uint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8Uint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]uint64) v, changed := fastpathTV.DecMapInt8Uint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -23834,7 +33869,8 @@ func (f fastpathT) DecMapInt8Uint64X(vp *map[int8]uint64, checkNil bool, d *Deco func (_ fastpathT) DecMapInt8Uint64V(v map[int8]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[int8]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23844,17 +33880,22 @@ func (_ fastpathT) DecMapInt8Uint64V(v map[int8]uint64, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]uint64, containerLen) - } else { - v = make(map[int8]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[int8]uint64, xlen) changed = true } + + var mk int8 + var mv uint64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int8(dd.DecodeInt(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeUint(64) if v != nil { v[mk] = mv @@ -23862,23 +33903,100 @@ func (_ fastpathT) DecMapInt8Uint64V(v map[int8]uint64, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt8IntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8UintptrR(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[int8]uintptr) + v, changed := fastpathTV.DecMapInt8UintptrV(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[int8]uintptr) + fastpathTV.DecMapInt8UintptrV(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapInt8UintptrX(vp *map[int8]uintptr, checkNil bool, d *Decoder) { + v, changed := f.DecMapInt8UintptrV(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapInt8UintptrV(v map[int8]uintptr, checkNil bool, canChange bool, + d *Decoder) (_ map[int8]uintptr, changed bool) { + dd := d.d + cr := d.cr + + 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, 9) + v = make(map[int8]uintptr, xlen) + changed = true + } + + var mk int8 + var mv uintptr + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapInt8IntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]int) v, changed := fastpathTV.DecMapInt8IntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -23899,7 +34017,8 @@ func (f fastpathT) DecMapInt8IntX(vp *map[int8]int, checkNil bool, d *Decoder) { func (_ fastpathT) DecMapInt8IntV(v map[int8]int, checkNil bool, canChange bool, d *Decoder) (_ map[int8]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23909,17 +34028,22 @@ func (_ fastpathT) DecMapInt8IntV(v map[int8]int, checkNil bool, canChange bool, containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]int, containerLen) - } else { - v = make(map[int8]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[int8]int, xlen) changed = true } + + var mk int8 + var mv int if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int8(dd.DecodeInt(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv @@ -23927,23 +34051,26 @@ func (_ fastpathT) DecMapInt8IntV(v map[int8]int, checkNil bool, canChange bool, } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt8Int8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8Int8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]int8) v, changed := fastpathTV.DecMapInt8Int8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -23964,7 +34091,8 @@ func (f fastpathT) DecMapInt8Int8X(vp *map[int8]int8, checkNil bool, d *Decoder) func (_ fastpathT) DecMapInt8Int8V(v map[int8]int8, checkNil bool, canChange bool, d *Decoder) (_ map[int8]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -23974,17 +34102,22 @@ func (_ fastpathT) DecMapInt8Int8V(v map[int8]int8, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]int8, containerLen) - } else { - v = make(map[int8]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2) + v = make(map[int8]int8, xlen) changed = true } + + var mk int8 + var mv int8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int8(dd.DecodeInt(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv @@ -23992,23 +34125,26 @@ func (_ fastpathT) DecMapInt8Int8V(v map[int8]int8, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt8Int16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8Int16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]int16) v, changed := fastpathTV.DecMapInt8Int16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -24029,7 +34165,8 @@ func (f fastpathT) DecMapInt8Int16X(vp *map[int8]int16, checkNil bool, d *Decode func (_ fastpathT) DecMapInt8Int16V(v map[int8]int16, checkNil bool, canChange bool, d *Decoder) (_ map[int8]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24039,17 +34176,22 @@ func (_ fastpathT) DecMapInt8Int16V(v map[int8]int16, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]int16, containerLen) - } else { - v = make(map[int8]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3) + v = make(map[int8]int16, xlen) changed = true } + + var mk int8 + var mv int16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int8(dd.DecodeInt(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv @@ -24057,23 +34199,26 @@ func (_ fastpathT) DecMapInt8Int16V(v map[int8]int16, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt8Int32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8Int32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]int32) v, changed := fastpathTV.DecMapInt8Int32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -24094,7 +34239,8 @@ func (f fastpathT) DecMapInt8Int32X(vp *map[int8]int32, checkNil bool, d *Decode func (_ fastpathT) DecMapInt8Int32V(v map[int8]int32, checkNil bool, canChange bool, d *Decoder) (_ map[int8]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24104,17 +34250,22 @@ func (_ fastpathT) DecMapInt8Int32V(v map[int8]int32, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]int32, containerLen) - } else { - v = make(map[int8]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[int8]int32, xlen) changed = true } + + var mk int8 + var mv int32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int8(dd.DecodeInt(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv @@ -24122,23 +34273,26 @@ func (_ fastpathT) DecMapInt8Int32V(v map[int8]int32, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt8Int64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8Int64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]int64) v, changed := fastpathTV.DecMapInt8Int64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -24159,7 +34313,8 @@ func (f fastpathT) DecMapInt8Int64X(vp *map[int8]int64, checkNil bool, d *Decode func (_ fastpathT) DecMapInt8Int64V(v map[int8]int64, checkNil bool, canChange bool, d *Decoder) (_ map[int8]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24169,17 +34324,22 @@ func (_ fastpathT) DecMapInt8Int64V(v map[int8]int64, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]int64, containerLen) - } else { - v = make(map[int8]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[int8]int64, xlen) changed = true } + + var mk int8 + var mv int64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int8(dd.DecodeInt(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeInt(64) if v != nil { v[mk] = mv @@ -24187,23 +34347,26 @@ func (_ fastpathT) DecMapInt8Int64V(v map[int8]int64, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt8Float32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8Float32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]float32) v, changed := fastpathTV.DecMapInt8Float32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -24224,7 +34387,8 @@ func (f fastpathT) DecMapInt8Float32X(vp *map[int8]float32, checkNil bool, d *De func (_ fastpathT) DecMapInt8Float32V(v map[int8]float32, checkNil bool, canChange bool, d *Decoder) (_ map[int8]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24234,17 +34398,22 @@ func (_ fastpathT) DecMapInt8Float32V(v map[int8]float32, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]float32, containerLen) - } else { - v = make(map[int8]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[int8]float32, xlen) changed = true } + + var mk int8 + var mv float32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int8(dd.DecodeInt(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv @@ -24252,23 +34421,26 @@ func (_ fastpathT) DecMapInt8Float32V(v map[int8]float32, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt8Float64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8Float64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]float64) v, changed := fastpathTV.DecMapInt8Float64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -24289,7 +34461,8 @@ func (f fastpathT) DecMapInt8Float64X(vp *map[int8]float64, checkNil bool, d *De func (_ fastpathT) DecMapInt8Float64V(v map[int8]float64, checkNil bool, canChange bool, d *Decoder) (_ map[int8]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24299,17 +34472,22 @@ func (_ fastpathT) DecMapInt8Float64V(v map[int8]float64, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]float64, containerLen) - } else { - v = make(map[int8]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[int8]float64, xlen) changed = true } + + var mk int8 + var mv float64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int8(dd.DecodeInt(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv @@ -24317,23 +34495,26 @@ func (_ fastpathT) DecMapInt8Float64V(v map[int8]float64, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt8BoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt8BoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int8]bool) v, changed := fastpathTV.DecMapInt8BoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -24354,7 +34535,8 @@ func (f fastpathT) DecMapInt8BoolX(vp *map[int8]bool, checkNil bool, d *Decoder) func (_ fastpathT) DecMapInt8BoolV(v map[int8]bool, checkNil bool, canChange bool, d *Decoder) (_ map[int8]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24364,17 +34546,22 @@ func (_ fastpathT) DecMapInt8BoolV(v map[int8]bool, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int8]bool, containerLen) - } else { - v = make(map[int8]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2) + v = make(map[int8]bool, xlen) changed = true } + + var mk int8 + var mv bool if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int8(dd.DecodeInt(8)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeBool() if v != nil { v[mk] = mv @@ -24382,23 +34569,26 @@ func (_ fastpathT) DecMapInt8BoolV(v map[int8]bool, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int8(dd.DecodeInt(8)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int8(dd.DecodeInt(8)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt16IntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16IntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]interface{}) v, changed := fastpathTV.DecMapInt16IntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -24419,7 +34609,8 @@ func (f fastpathT) DecMapInt16IntfX(vp *map[int16]interface{}, checkNil bool, d func (_ fastpathT) DecMapInt16IntfV(v map[int16]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[int16]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24429,43 +34620,59 @@ func (_ fastpathT) DecMapInt16IntfV(v map[int16]interface{}, checkNil bool, canC containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]interface{}, containerLen) - } else { - v = make(map[int16]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 18) + v = make(map[int16]interface{}, xlen) changed = true } + mapGet := !d.h.MapValueReset && !d.h.InterfaceReset + var mk int16 + var mv interface{} if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int16(dd.DecodeInt(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil + } d.decode(&mv) - if v != nil { v[mk] = mv } } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil } - mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() - mv := v[mk] d.decode(&mv) - if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt16StringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16StringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]string) v, changed := fastpathTV.DecMapInt16StringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -24486,7 +34693,8 @@ func (f fastpathT) DecMapInt16StringX(vp *map[int16]string, checkNil bool, d *De func (_ fastpathT) DecMapInt16StringV(v map[int16]string, checkNil bool, canChange bool, d *Decoder) (_ map[int16]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24496,17 +34704,22 @@ func (_ fastpathT) DecMapInt16StringV(v map[int16]string, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]string, containerLen) - } else { - v = make(map[int16]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 18) + v = make(map[int16]string, xlen) changed = true } + + var mk int16 + var mv string if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int16(dd.DecodeInt(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeString() if v != nil { v[mk] = mv @@ -24514,23 +34727,26 @@ func (_ fastpathT) DecMapInt16StringV(v map[int16]string, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt16UintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16UintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]uint) v, changed := fastpathTV.DecMapInt16UintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -24551,7 +34767,8 @@ func (f fastpathT) DecMapInt16UintX(vp *map[int16]uint, checkNil bool, d *Decode func (_ fastpathT) DecMapInt16UintV(v map[int16]uint, checkNil bool, canChange bool, d *Decoder) (_ map[int16]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24561,17 +34778,22 @@ func (_ fastpathT) DecMapInt16UintV(v map[int16]uint, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]uint, containerLen) - } else { - v = make(map[int16]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[int16]uint, xlen) changed = true } + + var mk int16 + var mv uint if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int16(dd.DecodeInt(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv @@ -24579,23 +34801,26 @@ func (_ fastpathT) DecMapInt16UintV(v map[int16]uint, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt16Uint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16Uint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]uint8) v, changed := fastpathTV.DecMapInt16Uint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -24616,7 +34841,8 @@ func (f fastpathT) DecMapInt16Uint8X(vp *map[int16]uint8, checkNil bool, d *Deco func (_ fastpathT) DecMapInt16Uint8V(v map[int16]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[int16]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24626,17 +34852,22 @@ func (_ fastpathT) DecMapInt16Uint8V(v map[int16]uint8, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]uint8, containerLen) - } else { - v = make(map[int16]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3) + v = make(map[int16]uint8, xlen) changed = true } + + var mk int16 + var mv uint8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int16(dd.DecodeInt(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv @@ -24644,23 +34875,26 @@ func (_ fastpathT) DecMapInt16Uint8V(v map[int16]uint8, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt16Uint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16Uint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]uint16) v, changed := fastpathTV.DecMapInt16Uint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -24681,7 +34915,8 @@ func (f fastpathT) DecMapInt16Uint16X(vp *map[int16]uint16, checkNil bool, d *De func (_ fastpathT) DecMapInt16Uint16V(v map[int16]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[int16]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24691,17 +34926,22 @@ func (_ fastpathT) DecMapInt16Uint16V(v map[int16]uint16, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]uint16, containerLen) - } else { - v = make(map[int16]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 4) + v = make(map[int16]uint16, xlen) changed = true } + + var mk int16 + var mv uint16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int16(dd.DecodeInt(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv @@ -24709,23 +34949,26 @@ func (_ fastpathT) DecMapInt16Uint16V(v map[int16]uint16, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt16Uint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16Uint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]uint32) v, changed := fastpathTV.DecMapInt16Uint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -24746,7 +34989,8 @@ func (f fastpathT) DecMapInt16Uint32X(vp *map[int16]uint32, checkNil bool, d *De func (_ fastpathT) DecMapInt16Uint32V(v map[int16]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[int16]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24756,17 +35000,22 @@ func (_ fastpathT) DecMapInt16Uint32V(v map[int16]uint32, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]uint32, containerLen) - } else { - v = make(map[int16]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6) + v = make(map[int16]uint32, xlen) changed = true } + + var mk int16 + var mv uint32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int16(dd.DecodeInt(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv @@ -24774,23 +35023,26 @@ func (_ fastpathT) DecMapInt16Uint32V(v map[int16]uint32, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt16Uint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16Uint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]uint64) v, changed := fastpathTV.DecMapInt16Uint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -24811,7 +35063,8 @@ func (f fastpathT) DecMapInt16Uint64X(vp *map[int16]uint64, checkNil bool, d *De func (_ fastpathT) DecMapInt16Uint64V(v map[int16]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[int16]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24821,17 +35074,22 @@ func (_ fastpathT) DecMapInt16Uint64V(v map[int16]uint64, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]uint64, containerLen) - } else { - v = make(map[int16]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[int16]uint64, xlen) changed = true } + + var mk int16 + var mv uint64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int16(dd.DecodeInt(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeUint(64) if v != nil { v[mk] = mv @@ -24839,23 +35097,100 @@ func (_ fastpathT) DecMapInt16Uint64V(v map[int16]uint64, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt16IntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16UintptrR(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[int16]uintptr) + v, changed := fastpathTV.DecMapInt16UintptrV(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[int16]uintptr) + fastpathTV.DecMapInt16UintptrV(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapInt16UintptrX(vp *map[int16]uintptr, checkNil bool, d *Decoder) { + v, changed := f.DecMapInt16UintptrV(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapInt16UintptrV(v map[int16]uintptr, checkNil bool, canChange bool, + d *Decoder) (_ map[int16]uintptr, changed bool) { + dd := d.d + cr := d.cr + + 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, 10) + v = make(map[int16]uintptr, xlen) + changed = true + } + + var mk int16 + var mv uintptr + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapInt16IntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]int) v, changed := fastpathTV.DecMapInt16IntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -24876,7 +35211,8 @@ func (f fastpathT) DecMapInt16IntX(vp *map[int16]int, checkNil bool, d *Decoder) func (_ fastpathT) DecMapInt16IntV(v map[int16]int, checkNil bool, canChange bool, d *Decoder) (_ map[int16]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24886,17 +35222,22 @@ func (_ fastpathT) DecMapInt16IntV(v map[int16]int, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]int, containerLen) - } else { - v = make(map[int16]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[int16]int, xlen) changed = true } + + var mk int16 + var mv int if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int16(dd.DecodeInt(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv @@ -24904,23 +35245,26 @@ func (_ fastpathT) DecMapInt16IntV(v map[int16]int, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt16Int8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16Int8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]int8) v, changed := fastpathTV.DecMapInt16Int8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -24941,7 +35285,8 @@ func (f fastpathT) DecMapInt16Int8X(vp *map[int16]int8, checkNil bool, d *Decode func (_ fastpathT) DecMapInt16Int8V(v map[int16]int8, checkNil bool, canChange bool, d *Decoder) (_ map[int16]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -24951,17 +35296,22 @@ func (_ fastpathT) DecMapInt16Int8V(v map[int16]int8, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]int8, containerLen) - } else { - v = make(map[int16]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3) + v = make(map[int16]int8, xlen) changed = true } + + var mk int16 + var mv int8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int16(dd.DecodeInt(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv @@ -24969,23 +35319,26 @@ func (_ fastpathT) DecMapInt16Int8V(v map[int16]int8, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt16Int16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16Int16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]int16) v, changed := fastpathTV.DecMapInt16Int16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -25006,7 +35359,8 @@ func (f fastpathT) DecMapInt16Int16X(vp *map[int16]int16, checkNil bool, d *Deco func (_ fastpathT) DecMapInt16Int16V(v map[int16]int16, checkNil bool, canChange bool, d *Decoder) (_ map[int16]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25016,17 +35370,22 @@ func (_ fastpathT) DecMapInt16Int16V(v map[int16]int16, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]int16, containerLen) - } else { - v = make(map[int16]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 4) + v = make(map[int16]int16, xlen) changed = true } + + var mk int16 + var mv int16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int16(dd.DecodeInt(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv @@ -25034,23 +35393,26 @@ func (_ fastpathT) DecMapInt16Int16V(v map[int16]int16, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt16Int32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16Int32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]int32) v, changed := fastpathTV.DecMapInt16Int32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -25071,7 +35433,8 @@ func (f fastpathT) DecMapInt16Int32X(vp *map[int16]int32, checkNil bool, d *Deco func (_ fastpathT) DecMapInt16Int32V(v map[int16]int32, checkNil bool, canChange bool, d *Decoder) (_ map[int16]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25081,17 +35444,22 @@ func (_ fastpathT) DecMapInt16Int32V(v map[int16]int32, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]int32, containerLen) - } else { - v = make(map[int16]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6) + v = make(map[int16]int32, xlen) changed = true } + + var mk int16 + var mv int32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int16(dd.DecodeInt(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv @@ -25099,23 +35467,26 @@ func (_ fastpathT) DecMapInt16Int32V(v map[int16]int32, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt16Int64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16Int64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]int64) v, changed := fastpathTV.DecMapInt16Int64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -25136,7 +35507,8 @@ func (f fastpathT) DecMapInt16Int64X(vp *map[int16]int64, checkNil bool, d *Deco func (_ fastpathT) DecMapInt16Int64V(v map[int16]int64, checkNil bool, canChange bool, d *Decoder) (_ map[int16]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25146,17 +35518,22 @@ func (_ fastpathT) DecMapInt16Int64V(v map[int16]int64, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]int64, containerLen) - } else { - v = make(map[int16]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[int16]int64, xlen) changed = true } + + var mk int16 + var mv int64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int16(dd.DecodeInt(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeInt(64) if v != nil { v[mk] = mv @@ -25164,23 +35541,26 @@ func (_ fastpathT) DecMapInt16Int64V(v map[int16]int64, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt16Float32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16Float32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]float32) v, changed := fastpathTV.DecMapInt16Float32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -25201,7 +35581,8 @@ func (f fastpathT) DecMapInt16Float32X(vp *map[int16]float32, checkNil bool, d * func (_ fastpathT) DecMapInt16Float32V(v map[int16]float32, checkNil bool, canChange bool, d *Decoder) (_ map[int16]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25211,17 +35592,22 @@ func (_ fastpathT) DecMapInt16Float32V(v map[int16]float32, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]float32, containerLen) - } else { - v = make(map[int16]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6) + v = make(map[int16]float32, xlen) changed = true } + + var mk int16 + var mv float32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int16(dd.DecodeInt(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv @@ -25229,23 +35615,26 @@ func (_ fastpathT) DecMapInt16Float32V(v map[int16]float32, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt16Float64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16Float64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]float64) v, changed := fastpathTV.DecMapInt16Float64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -25266,7 +35655,8 @@ func (f fastpathT) DecMapInt16Float64X(vp *map[int16]float64, checkNil bool, d * func (_ fastpathT) DecMapInt16Float64V(v map[int16]float64, checkNil bool, canChange bool, d *Decoder) (_ map[int16]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25276,17 +35666,22 @@ func (_ fastpathT) DecMapInt16Float64V(v map[int16]float64, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]float64, containerLen) - } else { - v = make(map[int16]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[int16]float64, xlen) changed = true } + + var mk int16 + var mv float64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int16(dd.DecodeInt(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv @@ -25294,23 +35689,26 @@ func (_ fastpathT) DecMapInt16Float64V(v map[int16]float64, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt16BoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt16BoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int16]bool) v, changed := fastpathTV.DecMapInt16BoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -25331,7 +35729,8 @@ func (f fastpathT) DecMapInt16BoolX(vp *map[int16]bool, checkNil bool, d *Decode func (_ fastpathT) DecMapInt16BoolV(v map[int16]bool, checkNil bool, canChange bool, d *Decoder) (_ map[int16]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25341,17 +35740,22 @@ func (_ fastpathT) DecMapInt16BoolV(v map[int16]bool, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int16]bool, containerLen) - } else { - v = make(map[int16]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3) + v = make(map[int16]bool, xlen) changed = true } + + var mk int16 + var mv bool if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int16(dd.DecodeInt(16)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeBool() if v != nil { v[mk] = mv @@ -25359,23 +35763,26 @@ func (_ fastpathT) DecMapInt16BoolV(v map[int16]bool, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int16(dd.DecodeInt(16)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int16(dd.DecodeInt(16)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt32IntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32IntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]interface{}) v, changed := fastpathTV.DecMapInt32IntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -25396,7 +35803,8 @@ func (f fastpathT) DecMapInt32IntfX(vp *map[int32]interface{}, checkNil bool, d func (_ fastpathT) DecMapInt32IntfV(v map[int32]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[int32]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25406,43 +35814,59 @@ func (_ fastpathT) DecMapInt32IntfV(v map[int32]interface{}, checkNil bool, canC containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]interface{}, containerLen) - } else { - v = make(map[int32]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20) + v = make(map[int32]interface{}, xlen) changed = true } + mapGet := !d.h.MapValueReset && !d.h.InterfaceReset + var mk int32 + var mv interface{} if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int32(dd.DecodeInt(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil + } d.decode(&mv) - if v != nil { v[mk] = mv } } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil } - mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() - mv := v[mk] d.decode(&mv) - if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt32StringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32StringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]string) v, changed := fastpathTV.DecMapInt32StringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -25463,7 +35887,8 @@ func (f fastpathT) DecMapInt32StringX(vp *map[int32]string, checkNil bool, d *De func (_ fastpathT) DecMapInt32StringV(v map[int32]string, checkNil bool, canChange bool, d *Decoder) (_ map[int32]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25473,17 +35898,22 @@ func (_ fastpathT) DecMapInt32StringV(v map[int32]string, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]string, containerLen) - } else { - v = make(map[int32]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 20) + v = make(map[int32]string, xlen) changed = true } + + var mk int32 + var mv string if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int32(dd.DecodeInt(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeString() if v != nil { v[mk] = mv @@ -25491,23 +35921,26 @@ func (_ fastpathT) DecMapInt32StringV(v map[int32]string, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt32UintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32UintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]uint) v, changed := fastpathTV.DecMapInt32UintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -25528,7 +35961,8 @@ func (f fastpathT) DecMapInt32UintX(vp *map[int32]uint, checkNil bool, d *Decode func (_ fastpathT) DecMapInt32UintV(v map[int32]uint, checkNil bool, canChange bool, d *Decoder) (_ map[int32]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25538,17 +35972,22 @@ func (_ fastpathT) DecMapInt32UintV(v map[int32]uint, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]uint, containerLen) - } else { - v = make(map[int32]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[int32]uint, xlen) changed = true } + + var mk int32 + var mv uint if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int32(dd.DecodeInt(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv @@ -25556,23 +35995,26 @@ func (_ fastpathT) DecMapInt32UintV(v map[int32]uint, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt32Uint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32Uint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]uint8) v, changed := fastpathTV.DecMapInt32Uint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -25593,7 +36035,8 @@ func (f fastpathT) DecMapInt32Uint8X(vp *map[int32]uint8, checkNil bool, d *Deco func (_ fastpathT) DecMapInt32Uint8V(v map[int32]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[int32]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25603,17 +36046,22 @@ func (_ fastpathT) DecMapInt32Uint8V(v map[int32]uint8, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]uint8, containerLen) - } else { - v = make(map[int32]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[int32]uint8, xlen) changed = true } + + var mk int32 + var mv uint8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int32(dd.DecodeInt(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv @@ -25621,23 +36069,26 @@ func (_ fastpathT) DecMapInt32Uint8V(v map[int32]uint8, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt32Uint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32Uint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]uint16) v, changed := fastpathTV.DecMapInt32Uint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -25658,7 +36109,8 @@ func (f fastpathT) DecMapInt32Uint16X(vp *map[int32]uint16, checkNil bool, d *De func (_ fastpathT) DecMapInt32Uint16V(v map[int32]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[int32]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25668,17 +36120,22 @@ func (_ fastpathT) DecMapInt32Uint16V(v map[int32]uint16, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]uint16, containerLen) - } else { - v = make(map[int32]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6) + v = make(map[int32]uint16, xlen) changed = true } + + var mk int32 + var mv uint16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int32(dd.DecodeInt(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv @@ -25686,23 +36143,26 @@ func (_ fastpathT) DecMapInt32Uint16V(v map[int32]uint16, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt32Uint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32Uint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]uint32) v, changed := fastpathTV.DecMapInt32Uint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -25723,7 +36183,8 @@ func (f fastpathT) DecMapInt32Uint32X(vp *map[int32]uint32, checkNil bool, d *De func (_ fastpathT) DecMapInt32Uint32V(v map[int32]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[int32]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25733,17 +36194,22 @@ func (_ fastpathT) DecMapInt32Uint32V(v map[int32]uint32, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]uint32, containerLen) - } else { - v = make(map[int32]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8) + v = make(map[int32]uint32, xlen) changed = true } + + var mk int32 + var mv uint32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int32(dd.DecodeInt(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv @@ -25751,23 +36217,26 @@ func (_ fastpathT) DecMapInt32Uint32V(v map[int32]uint32, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt32Uint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32Uint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]uint64) v, changed := fastpathTV.DecMapInt32Uint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -25788,7 +36257,8 @@ func (f fastpathT) DecMapInt32Uint64X(vp *map[int32]uint64, checkNil bool, d *De func (_ fastpathT) DecMapInt32Uint64V(v map[int32]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[int32]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25798,17 +36268,22 @@ func (_ fastpathT) DecMapInt32Uint64V(v map[int32]uint64, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]uint64, containerLen) - } else { - v = make(map[int32]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[int32]uint64, xlen) changed = true } + + var mk int32 + var mv uint64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int32(dd.DecodeInt(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeUint(64) if v != nil { v[mk] = mv @@ -25816,23 +36291,100 @@ func (_ fastpathT) DecMapInt32Uint64V(v map[int32]uint64, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt32IntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32UintptrR(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[int32]uintptr) + v, changed := fastpathTV.DecMapInt32UintptrV(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[int32]uintptr) + fastpathTV.DecMapInt32UintptrV(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapInt32UintptrX(vp *map[int32]uintptr, checkNil bool, d *Decoder) { + v, changed := f.DecMapInt32UintptrV(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapInt32UintptrV(v map[int32]uintptr, checkNil bool, canChange bool, + d *Decoder) (_ map[int32]uintptr, changed bool) { + dd := d.d + cr := d.cr + + 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, 12) + v = make(map[int32]uintptr, xlen) + changed = true + } + + var mk int32 + var mv uintptr + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapInt32IntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]int) v, changed := fastpathTV.DecMapInt32IntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -25853,7 +36405,8 @@ func (f fastpathT) DecMapInt32IntX(vp *map[int32]int, checkNil bool, d *Decoder) func (_ fastpathT) DecMapInt32IntV(v map[int32]int, checkNil bool, canChange bool, d *Decoder) (_ map[int32]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25863,17 +36416,22 @@ func (_ fastpathT) DecMapInt32IntV(v map[int32]int, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]int, containerLen) - } else { - v = make(map[int32]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[int32]int, xlen) changed = true } + + var mk int32 + var mv int if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int32(dd.DecodeInt(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv @@ -25881,23 +36439,26 @@ func (_ fastpathT) DecMapInt32IntV(v map[int32]int, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt32Int8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32Int8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]int8) v, changed := fastpathTV.DecMapInt32Int8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -25918,7 +36479,8 @@ func (f fastpathT) DecMapInt32Int8X(vp *map[int32]int8, checkNil bool, d *Decode func (_ fastpathT) DecMapInt32Int8V(v map[int32]int8, checkNil bool, canChange bool, d *Decoder) (_ map[int32]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25928,17 +36490,22 @@ func (_ fastpathT) DecMapInt32Int8V(v map[int32]int8, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]int8, containerLen) - } else { - v = make(map[int32]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[int32]int8, xlen) changed = true } + + var mk int32 + var mv int8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int32(dd.DecodeInt(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv @@ -25946,23 +36513,26 @@ func (_ fastpathT) DecMapInt32Int8V(v map[int32]int8, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt32Int16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32Int16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]int16) v, changed := fastpathTV.DecMapInt32Int16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -25983,7 +36553,8 @@ func (f fastpathT) DecMapInt32Int16X(vp *map[int32]int16, checkNil bool, d *Deco func (_ fastpathT) DecMapInt32Int16V(v map[int32]int16, checkNil bool, canChange bool, d *Decoder) (_ map[int32]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -25993,17 +36564,22 @@ func (_ fastpathT) DecMapInt32Int16V(v map[int32]int16, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]int16, containerLen) - } else { - v = make(map[int32]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 6) + v = make(map[int32]int16, xlen) changed = true } + + var mk int32 + var mv int16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int32(dd.DecodeInt(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv @@ -26011,23 +36587,26 @@ func (_ fastpathT) DecMapInt32Int16V(v map[int32]int16, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt32Int32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32Int32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]int32) v, changed := fastpathTV.DecMapInt32Int32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -26048,7 +36627,8 @@ func (f fastpathT) DecMapInt32Int32X(vp *map[int32]int32, checkNil bool, d *Deco func (_ fastpathT) DecMapInt32Int32V(v map[int32]int32, checkNil bool, canChange bool, d *Decoder) (_ map[int32]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26058,17 +36638,22 @@ func (_ fastpathT) DecMapInt32Int32V(v map[int32]int32, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]int32, containerLen) - } else { - v = make(map[int32]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8) + v = make(map[int32]int32, xlen) changed = true } + + var mk int32 + var mv int32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int32(dd.DecodeInt(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv @@ -26076,23 +36661,26 @@ func (_ fastpathT) DecMapInt32Int32V(v map[int32]int32, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt32Int64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32Int64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]int64) v, changed := fastpathTV.DecMapInt32Int64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -26113,7 +36701,8 @@ func (f fastpathT) DecMapInt32Int64X(vp *map[int32]int64, checkNil bool, d *Deco func (_ fastpathT) DecMapInt32Int64V(v map[int32]int64, checkNil bool, canChange bool, d *Decoder) (_ map[int32]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26123,17 +36712,22 @@ func (_ fastpathT) DecMapInt32Int64V(v map[int32]int64, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]int64, containerLen) - } else { - v = make(map[int32]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[int32]int64, xlen) changed = true } + + var mk int32 + var mv int64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int32(dd.DecodeInt(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeInt(64) if v != nil { v[mk] = mv @@ -26141,23 +36735,26 @@ func (_ fastpathT) DecMapInt32Int64V(v map[int32]int64, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt32Float32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32Float32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]float32) v, changed := fastpathTV.DecMapInt32Float32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -26178,7 +36775,8 @@ func (f fastpathT) DecMapInt32Float32X(vp *map[int32]float32, checkNil bool, d * func (_ fastpathT) DecMapInt32Float32V(v map[int32]float32, checkNil bool, canChange bool, d *Decoder) (_ map[int32]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26188,17 +36786,22 @@ func (_ fastpathT) DecMapInt32Float32V(v map[int32]float32, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]float32, containerLen) - } else { - v = make(map[int32]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 8) + v = make(map[int32]float32, xlen) changed = true } + + var mk int32 + var mv float32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int32(dd.DecodeInt(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv @@ -26206,23 +36809,26 @@ func (_ fastpathT) DecMapInt32Float32V(v map[int32]float32, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt32Float64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32Float64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]float64) v, changed := fastpathTV.DecMapInt32Float64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -26243,7 +36849,8 @@ func (f fastpathT) DecMapInt32Float64X(vp *map[int32]float64, checkNil bool, d * func (_ fastpathT) DecMapInt32Float64V(v map[int32]float64, checkNil bool, canChange bool, d *Decoder) (_ map[int32]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26253,17 +36860,22 @@ func (_ fastpathT) DecMapInt32Float64V(v map[int32]float64, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]float64, containerLen) - } else { - v = make(map[int32]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[int32]float64, xlen) changed = true } + + var mk int32 + var mv float64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int32(dd.DecodeInt(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv @@ -26271,23 +36883,26 @@ func (_ fastpathT) DecMapInt32Float64V(v map[int32]float64, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt32BoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt32BoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int32]bool) v, changed := fastpathTV.DecMapInt32BoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -26308,7 +36923,8 @@ func (f fastpathT) DecMapInt32BoolX(vp *map[int32]bool, checkNil bool, d *Decode func (_ fastpathT) DecMapInt32BoolV(v map[int32]bool, checkNil bool, canChange bool, d *Decoder) (_ map[int32]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26318,17 +36934,22 @@ func (_ fastpathT) DecMapInt32BoolV(v map[int32]bool, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int32]bool, containerLen) - } else { - v = make(map[int32]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[int32]bool, xlen) changed = true } + + var mk int32 + var mv bool if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := int32(dd.DecodeInt(32)) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeBool() if v != nil { v[mk] = mv @@ -26336,23 +36957,26 @@ func (_ fastpathT) DecMapInt32BoolV(v map[int32]bool, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = int32(dd.DecodeInt(32)) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := int32(dd.DecodeInt(32)) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt64IntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64IntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]interface{}) v, changed := fastpathTV.DecMapInt64IntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -26373,7 +36997,8 @@ func (f fastpathT) DecMapInt64IntfX(vp *map[int64]interface{}, checkNil bool, d func (_ fastpathT) DecMapInt64IntfV(v map[int64]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[int64]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26383,43 +37008,59 @@ func (_ fastpathT) DecMapInt64IntfV(v map[int64]interface{}, checkNil bool, canC containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]interface{}, containerLen) - } else { - v = make(map[int64]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[int64]interface{}, xlen) changed = true } + mapGet := !d.h.MapValueReset && !d.h.InterfaceReset + var mk int64 + var mv interface{} if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeInt(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil + } d.decode(&mv) - if v != nil { v[mk] = mv } } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil } - mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() - mv := v[mk] d.decode(&mv) - if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt64StringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64StringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]string) v, changed := fastpathTV.DecMapInt64StringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -26440,7 +37081,8 @@ func (f fastpathT) DecMapInt64StringX(vp *map[int64]string, checkNil bool, d *De func (_ fastpathT) DecMapInt64StringV(v map[int64]string, checkNil bool, canChange bool, d *Decoder) (_ map[int64]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26450,17 +37092,22 @@ func (_ fastpathT) DecMapInt64StringV(v map[int64]string, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]string, containerLen) - } else { - v = make(map[int64]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 24) + v = make(map[int64]string, xlen) changed = true } + + var mk int64 + var mv string if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeInt(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeString() if v != nil { v[mk] = mv @@ -26468,23 +37115,26 @@ func (_ fastpathT) DecMapInt64StringV(v map[int64]string, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt64UintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64UintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]uint) v, changed := fastpathTV.DecMapInt64UintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -26505,7 +37155,8 @@ func (f fastpathT) DecMapInt64UintX(vp *map[int64]uint, checkNil bool, d *Decode func (_ fastpathT) DecMapInt64UintV(v map[int64]uint, checkNil bool, canChange bool, d *Decoder) (_ map[int64]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26515,17 +37166,22 @@ func (_ fastpathT) DecMapInt64UintV(v map[int64]uint, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]uint, containerLen) - } else { - v = make(map[int64]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[int64]uint, xlen) changed = true } + + var mk int64 + var mv uint if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeInt(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv @@ -26533,23 +37189,26 @@ func (_ fastpathT) DecMapInt64UintV(v map[int64]uint, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt64Uint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64Uint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]uint8) v, changed := fastpathTV.DecMapInt64Uint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -26570,7 +37229,8 @@ func (f fastpathT) DecMapInt64Uint8X(vp *map[int64]uint8, checkNil bool, d *Deco func (_ fastpathT) DecMapInt64Uint8V(v map[int64]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[int64]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26580,17 +37240,22 @@ func (_ fastpathT) DecMapInt64Uint8V(v map[int64]uint8, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]uint8, containerLen) - } else { - v = make(map[int64]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[int64]uint8, xlen) changed = true } + + var mk int64 + var mv uint8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeInt(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv @@ -26598,23 +37263,26 @@ func (_ fastpathT) DecMapInt64Uint8V(v map[int64]uint8, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt64Uint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64Uint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]uint16) v, changed := fastpathTV.DecMapInt64Uint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -26635,7 +37303,8 @@ func (f fastpathT) DecMapInt64Uint16X(vp *map[int64]uint16, checkNil bool, d *De func (_ fastpathT) DecMapInt64Uint16V(v map[int64]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[int64]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26645,17 +37314,22 @@ func (_ fastpathT) DecMapInt64Uint16V(v map[int64]uint16, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]uint16, containerLen) - } else { - v = make(map[int64]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[int64]uint16, xlen) changed = true } + + var mk int64 + var mv uint16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeInt(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv @@ -26663,23 +37337,26 @@ func (_ fastpathT) DecMapInt64Uint16V(v map[int64]uint16, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt64Uint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64Uint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]uint32) v, changed := fastpathTV.DecMapInt64Uint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -26700,7 +37377,8 @@ func (f fastpathT) DecMapInt64Uint32X(vp *map[int64]uint32, checkNil bool, d *De func (_ fastpathT) DecMapInt64Uint32V(v map[int64]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[int64]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26710,17 +37388,22 @@ func (_ fastpathT) DecMapInt64Uint32V(v map[int64]uint32, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]uint32, containerLen) - } else { - v = make(map[int64]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[int64]uint32, xlen) changed = true } + + var mk int64 + var mv uint32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeInt(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv @@ -26728,23 +37411,26 @@ func (_ fastpathT) DecMapInt64Uint32V(v map[int64]uint32, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt64Uint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64Uint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]uint64) v, changed := fastpathTV.DecMapInt64Uint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -26765,7 +37451,8 @@ func (f fastpathT) DecMapInt64Uint64X(vp *map[int64]uint64, checkNil bool, d *De func (_ fastpathT) DecMapInt64Uint64V(v map[int64]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[int64]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26775,17 +37462,22 @@ func (_ fastpathT) DecMapInt64Uint64V(v map[int64]uint64, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]uint64, containerLen) - } else { - v = make(map[int64]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[int64]uint64, xlen) changed = true } + + var mk int64 + var mv uint64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeInt(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeUint(64) if v != nil { v[mk] = mv @@ -26793,23 +37485,100 @@ func (_ fastpathT) DecMapInt64Uint64V(v map[int64]uint64, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt64IntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64UintptrR(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[int64]uintptr) + v, changed := fastpathTV.DecMapInt64UintptrV(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[int64]uintptr) + fastpathTV.DecMapInt64UintptrV(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapInt64UintptrX(vp *map[int64]uintptr, checkNil bool, d *Decoder) { + v, changed := f.DecMapInt64UintptrV(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapInt64UintptrV(v map[int64]uintptr, checkNil bool, canChange bool, + d *Decoder) (_ map[int64]uintptr, changed bool) { + dd := d.d + cr := d.cr + + 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, 16) + v = make(map[int64]uintptr, xlen) + changed = true + } + + var mk int64 + var mv uintptr + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapInt64IntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]int) v, changed := fastpathTV.DecMapInt64IntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -26830,7 +37599,8 @@ func (f fastpathT) DecMapInt64IntX(vp *map[int64]int, checkNil bool, d *Decoder) func (_ fastpathT) DecMapInt64IntV(v map[int64]int, checkNil bool, canChange bool, d *Decoder) (_ map[int64]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26840,17 +37610,22 @@ func (_ fastpathT) DecMapInt64IntV(v map[int64]int, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]int, containerLen) - } else { - v = make(map[int64]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[int64]int, xlen) changed = true } + + var mk int64 + var mv int if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeInt(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv @@ -26858,23 +37633,26 @@ func (_ fastpathT) DecMapInt64IntV(v map[int64]int, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt64Int8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64Int8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]int8) v, changed := fastpathTV.DecMapInt64Int8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -26895,7 +37673,8 @@ func (f fastpathT) DecMapInt64Int8X(vp *map[int64]int8, checkNil bool, d *Decode func (_ fastpathT) DecMapInt64Int8V(v map[int64]int8, checkNil bool, canChange bool, d *Decoder) (_ map[int64]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26905,17 +37684,22 @@ func (_ fastpathT) DecMapInt64Int8V(v map[int64]int8, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]int8, containerLen) - } else { - v = make(map[int64]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[int64]int8, xlen) changed = true } + + var mk int64 + var mv int8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeInt(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv @@ -26923,23 +37707,26 @@ func (_ fastpathT) DecMapInt64Int8V(v map[int64]int8, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt64Int16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64Int16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]int16) v, changed := fastpathTV.DecMapInt64Int16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -26960,7 +37747,8 @@ func (f fastpathT) DecMapInt64Int16X(vp *map[int64]int16, checkNil bool, d *Deco func (_ fastpathT) DecMapInt64Int16V(v map[int64]int16, checkNil bool, canChange bool, d *Decoder) (_ map[int64]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -26970,17 +37758,22 @@ func (_ fastpathT) DecMapInt64Int16V(v map[int64]int16, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]int16, containerLen) - } else { - v = make(map[int64]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 10) + v = make(map[int64]int16, xlen) changed = true } + + var mk int64 + var mv int16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeInt(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv @@ -26988,23 +37781,26 @@ func (_ fastpathT) DecMapInt64Int16V(v map[int64]int16, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt64Int32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64Int32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]int32) v, changed := fastpathTV.DecMapInt64Int32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -27025,7 +37821,8 @@ func (f fastpathT) DecMapInt64Int32X(vp *map[int64]int32, checkNil bool, d *Deco func (_ fastpathT) DecMapInt64Int32V(v map[int64]int32, checkNil bool, canChange bool, d *Decoder) (_ map[int64]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27035,17 +37832,22 @@ func (_ fastpathT) DecMapInt64Int32V(v map[int64]int32, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]int32, containerLen) - } else { - v = make(map[int64]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[int64]int32, xlen) changed = true } + + var mk int64 + var mv int32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeInt(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv @@ -27053,23 +37855,26 @@ func (_ fastpathT) DecMapInt64Int32V(v map[int64]int32, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt64Int64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64Int64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]int64) v, changed := fastpathTV.DecMapInt64Int64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -27090,7 +37895,8 @@ func (f fastpathT) DecMapInt64Int64X(vp *map[int64]int64, checkNil bool, d *Deco func (_ fastpathT) DecMapInt64Int64V(v map[int64]int64, checkNil bool, canChange bool, d *Decoder) (_ map[int64]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27100,17 +37906,22 @@ func (_ fastpathT) DecMapInt64Int64V(v map[int64]int64, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]int64, containerLen) - } else { - v = make(map[int64]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[int64]int64, xlen) changed = true } + + var mk int64 + var mv int64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeInt(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeInt(64) if v != nil { v[mk] = mv @@ -27118,23 +37929,26 @@ func (_ fastpathT) DecMapInt64Int64V(v map[int64]int64, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt64Float32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64Float32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]float32) v, changed := fastpathTV.DecMapInt64Float32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -27155,7 +37969,8 @@ func (f fastpathT) DecMapInt64Float32X(vp *map[int64]float32, checkNil bool, d * func (_ fastpathT) DecMapInt64Float32V(v map[int64]float32, checkNil bool, canChange bool, d *Decoder) (_ map[int64]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27165,17 +37980,22 @@ func (_ fastpathT) DecMapInt64Float32V(v map[int64]float32, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]float32, containerLen) - } else { - v = make(map[int64]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 12) + v = make(map[int64]float32, xlen) changed = true } + + var mk int64 + var mv float32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeInt(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv @@ -27183,23 +38003,26 @@ func (_ fastpathT) DecMapInt64Float32V(v map[int64]float32, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt64Float64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64Float64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]float64) v, changed := fastpathTV.DecMapInt64Float64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -27220,7 +38043,8 @@ func (f fastpathT) DecMapInt64Float64X(vp *map[int64]float64, checkNil bool, d * func (_ fastpathT) DecMapInt64Float64V(v map[int64]float64, checkNil bool, canChange bool, d *Decoder) (_ map[int64]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27230,17 +38054,22 @@ func (_ fastpathT) DecMapInt64Float64V(v map[int64]float64, checkNil bool, canCh containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]float64, containerLen) - } else { - v = make(map[int64]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 16) + v = make(map[int64]float64, xlen) changed = true } + + var mk int64 + var mv float64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeInt(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv @@ -27248,23 +38077,26 @@ func (_ fastpathT) DecMapInt64Float64V(v map[int64]float64, checkNil bool, canCh } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapInt64BoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapInt64BoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[int64]bool) v, changed := fastpathTV.DecMapInt64BoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -27285,7 +38117,8 @@ func (f fastpathT) DecMapInt64BoolX(vp *map[int64]bool, checkNil bool, d *Decode func (_ fastpathT) DecMapInt64BoolV(v map[int64]bool, checkNil bool, canChange bool, d *Decoder) (_ map[int64]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27295,17 +38128,22 @@ func (_ fastpathT) DecMapInt64BoolV(v map[int64]bool, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[int64]bool, containerLen) - } else { - v = make(map[int64]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[int64]bool, xlen) changed = true } + + var mk int64 + var mv bool if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeInt(64) - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeBool() if v != nil { v[mk] = mv @@ -27313,23 +38151,26 @@ func (_ fastpathT) DecMapInt64BoolV(v map[int64]bool, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeInt(64) + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeInt(64) - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapBoolIntfR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolIntfR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]interface{}) v, changed := fastpathTV.DecMapBoolIntfV(*vp, fastpathCheckNilFalse, true, f.d) @@ -27350,7 +38191,8 @@ func (f fastpathT) DecMapBoolIntfX(vp *map[bool]interface{}, checkNil bool, d *D func (_ fastpathT) DecMapBoolIntfV(v map[bool]interface{}, checkNil bool, canChange bool, d *Decoder) (_ map[bool]interface{}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27360,43 +38202,59 @@ func (_ fastpathT) DecMapBoolIntfV(v map[bool]interface{}, checkNil bool, canCha containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]interface{}, containerLen) - } else { - v = make(map[bool]interface{}) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17) + v = make(map[bool]interface{}, xlen) changed = true } + mapGet := !d.h.MapValueReset && !d.h.InterfaceReset + var mk bool + var mv interface{} if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeBool() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil + } d.decode(&mv) - if v != nil { v[mk] = mv } } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) + } + if mapGet { + mv = v[mk] + } else { + mv = nil } - mk := dd.DecodeBool() - dd.ReadMapKVSeparator() - mv := v[mk] d.decode(&mv) - if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapBoolStringR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolStringR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]string) v, changed := fastpathTV.DecMapBoolStringV(*vp, fastpathCheckNilFalse, true, f.d) @@ -27417,7 +38275,8 @@ func (f fastpathT) DecMapBoolStringX(vp *map[bool]string, checkNil bool, d *Deco func (_ fastpathT) DecMapBoolStringV(v map[bool]string, checkNil bool, canChange bool, d *Decoder) (_ map[bool]string, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27427,17 +38286,22 @@ func (_ fastpathT) DecMapBoolStringV(v map[bool]string, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]string, containerLen) - } else { - v = make(map[bool]string) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 17) + v = make(map[bool]string, xlen) changed = true } + + var mk bool + var mv string if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeBool() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeString() if v != nil { v[mk] = mv @@ -27445,23 +38309,26 @@ func (_ fastpathT) DecMapBoolStringV(v map[bool]string, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeBool() - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeString() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapBoolUintR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolUintR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]uint) v, changed := fastpathTV.DecMapBoolUintV(*vp, fastpathCheckNilFalse, true, f.d) @@ -27482,7 +38349,8 @@ func (f fastpathT) DecMapBoolUintX(vp *map[bool]uint, checkNil bool, d *Decoder) func (_ fastpathT) DecMapBoolUintV(v map[bool]uint, checkNil bool, canChange bool, d *Decoder) (_ map[bool]uint, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27492,17 +38360,22 @@ func (_ fastpathT) DecMapBoolUintV(v map[bool]uint, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]uint, containerLen) - } else { - v = make(map[bool]uint) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[bool]uint, xlen) changed = true } + + var mk bool + var mv uint if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeBool() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv @@ -27510,23 +38383,26 @@ func (_ fastpathT) DecMapBoolUintV(v map[bool]uint, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeBool() - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint(dd.DecodeUint(uintBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapBoolUint8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolUint8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]uint8) v, changed := fastpathTV.DecMapBoolUint8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -27547,7 +38423,8 @@ func (f fastpathT) DecMapBoolUint8X(vp *map[bool]uint8, checkNil bool, d *Decode func (_ fastpathT) DecMapBoolUint8V(v map[bool]uint8, checkNil bool, canChange bool, d *Decoder) (_ map[bool]uint8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27557,17 +38434,22 @@ func (_ fastpathT) DecMapBoolUint8V(v map[bool]uint8, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]uint8, containerLen) - } else { - v = make(map[bool]uint8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2) + v = make(map[bool]uint8, xlen) changed = true } + + var mk bool + var mv uint8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeBool() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv @@ -27575,23 +38457,26 @@ func (_ fastpathT) DecMapBoolUint8V(v map[bool]uint8, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeBool() - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint8(dd.DecodeUint(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapBoolUint16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolUint16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]uint16) v, changed := fastpathTV.DecMapBoolUint16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -27612,7 +38497,8 @@ func (f fastpathT) DecMapBoolUint16X(vp *map[bool]uint16, checkNil bool, d *Deco func (_ fastpathT) DecMapBoolUint16V(v map[bool]uint16, checkNil bool, canChange bool, d *Decoder) (_ map[bool]uint16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27622,17 +38508,22 @@ func (_ fastpathT) DecMapBoolUint16V(v map[bool]uint16, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]uint16, containerLen) - } else { - v = make(map[bool]uint16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3) + v = make(map[bool]uint16, xlen) changed = true } + + var mk bool + var mv uint16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeBool() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv @@ -27640,23 +38531,26 @@ func (_ fastpathT) DecMapBoolUint16V(v map[bool]uint16, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeBool() - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint16(dd.DecodeUint(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapBoolUint32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolUint32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]uint32) v, changed := fastpathTV.DecMapBoolUint32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -27677,7 +38571,8 @@ func (f fastpathT) DecMapBoolUint32X(vp *map[bool]uint32, checkNil bool, d *Deco func (_ fastpathT) DecMapBoolUint32V(v map[bool]uint32, checkNil bool, canChange bool, d *Decoder) (_ map[bool]uint32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27687,17 +38582,22 @@ func (_ fastpathT) DecMapBoolUint32V(v map[bool]uint32, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]uint32, containerLen) - } else { - v = make(map[bool]uint32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[bool]uint32, xlen) changed = true } + + var mk bool + var mv uint32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeBool() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv @@ -27705,23 +38605,26 @@ func (_ fastpathT) DecMapBoolUint32V(v map[bool]uint32, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeBool() - dd.ReadMapKVSeparator() - mv := v[mk] mv = uint32(dd.DecodeUint(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapBoolUint64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolUint64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]uint64) v, changed := fastpathTV.DecMapBoolUint64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -27742,7 +38645,8 @@ func (f fastpathT) DecMapBoolUint64X(vp *map[bool]uint64, checkNil bool, d *Deco func (_ fastpathT) DecMapBoolUint64V(v map[bool]uint64, checkNil bool, canChange bool, d *Decoder) (_ map[bool]uint64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27752,17 +38656,22 @@ func (_ fastpathT) DecMapBoolUint64V(v map[bool]uint64, checkNil bool, canChange containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]uint64, containerLen) - } else { - v = make(map[bool]uint64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[bool]uint64, xlen) changed = true } + + var mk bool + var mv uint64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeBool() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeUint(64) if v != nil { v[mk] = mv @@ -27770,23 +38679,100 @@ func (_ fastpathT) DecMapBoolUint64V(v map[bool]uint64, checkNil bool, canChange } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeBool() - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeUint(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapBoolIntR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolUintptrR(rv reflect.Value) { + if rv.CanAddr() { + vp := rv.Addr().Interface().(*map[bool]uintptr) + v, changed := fastpathTV.DecMapBoolUintptrV(*vp, fastpathCheckNilFalse, true, f.d) + if changed { + *vp = v + } + } else { + v := rv.Interface().(map[bool]uintptr) + fastpathTV.DecMapBoolUintptrV(v, fastpathCheckNilFalse, false, f.d) + } +} +func (f fastpathT) DecMapBoolUintptrX(vp *map[bool]uintptr, checkNil bool, d *Decoder) { + v, changed := f.DecMapBoolUintptrV(*vp, checkNil, true, d) + if changed { + *vp = v + } +} +func (_ fastpathT) DecMapBoolUintptrV(v map[bool]uintptr, checkNil bool, canChange bool, + d *Decoder) (_ map[bool]uintptr, changed bool) { + dd := d.d + cr := d.cr + + 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, 9) + v = make(map[bool]uintptr, xlen) + changed = true + } + + var mk bool + var mv uintptr + if containerLen > 0 { + for j := 0; j < containerLen; j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } else if containerLen < 0 { + for j := 0; !dd.CheckBreak(); j++ { + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) + } + mv = uintptr(dd.DecodeUint(uintBitsize)) + if v != nil { + v[mk] = mv + } + } + } + if cr != nil { + cr.sendContainerState(containerMapEnd) + } + return v, changed +} + +func (f *decFnInfo) fastpathDecMapBoolIntR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]int) v, changed := fastpathTV.DecMapBoolIntV(*vp, fastpathCheckNilFalse, true, f.d) @@ -27807,7 +38793,8 @@ func (f fastpathT) DecMapBoolIntX(vp *map[bool]int, checkNil bool, d *Decoder) { func (_ fastpathT) DecMapBoolIntV(v map[bool]int, checkNil bool, canChange bool, d *Decoder) (_ map[bool]int, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27817,17 +38804,22 @@ func (_ fastpathT) DecMapBoolIntV(v map[bool]int, checkNil bool, canChange bool, containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]int, containerLen) - } else { - v = make(map[bool]int) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[bool]int, xlen) changed = true } + + var mk bool + var mv int if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeBool() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv @@ -27835,23 +38827,26 @@ func (_ fastpathT) DecMapBoolIntV(v map[bool]int, checkNil bool, canChange bool, } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeBool() - dd.ReadMapKVSeparator() - mv := v[mk] mv = int(dd.DecodeInt(intBitsize)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapBoolInt8R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolInt8R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]int8) v, changed := fastpathTV.DecMapBoolInt8V(*vp, fastpathCheckNilFalse, true, f.d) @@ -27872,7 +38867,8 @@ func (f fastpathT) DecMapBoolInt8X(vp *map[bool]int8, checkNil bool, d *Decoder) func (_ fastpathT) DecMapBoolInt8V(v map[bool]int8, checkNil bool, canChange bool, d *Decoder) (_ map[bool]int8, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27882,17 +38878,22 @@ func (_ fastpathT) DecMapBoolInt8V(v map[bool]int8, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]int8, containerLen) - } else { - v = make(map[bool]int8) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2) + v = make(map[bool]int8, xlen) changed = true } + + var mk bool + var mv int8 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeBool() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv @@ -27900,23 +38901,26 @@ func (_ fastpathT) DecMapBoolInt8V(v map[bool]int8, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeBool() - dd.ReadMapKVSeparator() - mv := v[mk] mv = int8(dd.DecodeInt(8)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapBoolInt16R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolInt16R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]int16) v, changed := fastpathTV.DecMapBoolInt16V(*vp, fastpathCheckNilFalse, true, f.d) @@ -27937,7 +38941,8 @@ func (f fastpathT) DecMapBoolInt16X(vp *map[bool]int16, checkNil bool, d *Decode func (_ fastpathT) DecMapBoolInt16V(v map[bool]int16, checkNil bool, canChange bool, d *Decoder) (_ map[bool]int16, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -27947,17 +38952,22 @@ func (_ fastpathT) DecMapBoolInt16V(v map[bool]int16, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]int16, containerLen) - } else { - v = make(map[bool]int16) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 3) + v = make(map[bool]int16, xlen) changed = true } + + var mk bool + var mv int16 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeBool() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv @@ -27965,23 +38975,26 @@ func (_ fastpathT) DecMapBoolInt16V(v map[bool]int16, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeBool() - dd.ReadMapKVSeparator() - mv := v[mk] mv = int16(dd.DecodeInt(16)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapBoolInt32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolInt32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]int32) v, changed := fastpathTV.DecMapBoolInt32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -28002,7 +39015,8 @@ func (f fastpathT) DecMapBoolInt32X(vp *map[bool]int32, checkNil bool, d *Decode func (_ fastpathT) DecMapBoolInt32V(v map[bool]int32, checkNil bool, canChange bool, d *Decoder) (_ map[bool]int32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -28012,17 +39026,22 @@ func (_ fastpathT) DecMapBoolInt32V(v map[bool]int32, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]int32, containerLen) - } else { - v = make(map[bool]int32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[bool]int32, xlen) changed = true } + + var mk bool + var mv int32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeBool() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv @@ -28030,23 +39049,26 @@ func (_ fastpathT) DecMapBoolInt32V(v map[bool]int32, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeBool() - dd.ReadMapKVSeparator() - mv := v[mk] mv = int32(dd.DecodeInt(32)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapBoolInt64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolInt64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]int64) v, changed := fastpathTV.DecMapBoolInt64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -28067,7 +39089,8 @@ func (f fastpathT) DecMapBoolInt64X(vp *map[bool]int64, checkNil bool, d *Decode func (_ fastpathT) DecMapBoolInt64V(v map[bool]int64, checkNil bool, canChange bool, d *Decoder) (_ map[bool]int64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -28077,17 +39100,22 @@ func (_ fastpathT) DecMapBoolInt64V(v map[bool]int64, checkNil bool, canChange b containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]int64, containerLen) - } else { - v = make(map[bool]int64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[bool]int64, xlen) changed = true } + + var mk bool + var mv int64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeBool() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeInt(64) if v != nil { v[mk] = mv @@ -28095,23 +39123,26 @@ func (_ fastpathT) DecMapBoolInt64V(v map[bool]int64, checkNil bool, canChange b } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeBool() - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeInt(64) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapBoolFloat32R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolFloat32R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]float32) v, changed := fastpathTV.DecMapBoolFloat32V(*vp, fastpathCheckNilFalse, true, f.d) @@ -28132,7 +39163,8 @@ func (f fastpathT) DecMapBoolFloat32X(vp *map[bool]float32, checkNil bool, d *De func (_ fastpathT) DecMapBoolFloat32V(v map[bool]float32, checkNil bool, canChange bool, d *Decoder) (_ map[bool]float32, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -28142,17 +39174,22 @@ func (_ fastpathT) DecMapBoolFloat32V(v map[bool]float32, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]float32, containerLen) - } else { - v = make(map[bool]float32) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 5) + v = make(map[bool]float32, xlen) changed = true } + + var mk bool + var mv float32 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeBool() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv @@ -28160,23 +39197,26 @@ func (_ fastpathT) DecMapBoolFloat32V(v map[bool]float32, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeBool() - dd.ReadMapKVSeparator() - mv := v[mk] mv = float32(dd.DecodeFloat(true)) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapBoolFloat64R(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolFloat64R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]float64) v, changed := fastpathTV.DecMapBoolFloat64V(*vp, fastpathCheckNilFalse, true, f.d) @@ -28197,7 +39237,8 @@ func (f fastpathT) DecMapBoolFloat64X(vp *map[bool]float64, checkNil bool, d *De func (_ fastpathT) DecMapBoolFloat64V(v map[bool]float64, checkNil bool, canChange bool, d *Decoder) (_ map[bool]float64, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -28207,17 +39248,22 @@ func (_ fastpathT) DecMapBoolFloat64V(v map[bool]float64, checkNil bool, canChan containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]float64, containerLen) - } else { - v = make(map[bool]float64) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 9) + v = make(map[bool]float64, xlen) changed = true } + + var mk bool + var mv float64 if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeBool() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv @@ -28225,23 +39271,26 @@ func (_ fastpathT) DecMapBoolFloat64V(v map[bool]float64, checkNil bool, canChan } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeBool() - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeFloat(false) if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } -func (f decFnInfo) fastpathDecMapBoolBoolR(rv reflect.Value) { +func (f *decFnInfo) fastpathDecMapBoolBoolR(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[bool]bool) v, changed := fastpathTV.DecMapBoolBoolV(*vp, fastpathCheckNilFalse, true, f.d) @@ -28262,7 +39311,8 @@ func (f fastpathT) DecMapBoolBoolX(vp *map[bool]bool, checkNil bool, d *Decoder) func (_ fastpathT) DecMapBoolBoolV(v map[bool]bool, checkNil bool, canChange bool, d *Decoder) (_ map[bool]bool, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -28272,17 +39322,22 @@ func (_ fastpathT) DecMapBoolBoolV(v map[bool]bool, checkNil bool, canChange boo containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[bool]bool, containerLen) - } else { - v = make(map[bool]bool) // supports indefinite-length, etc - } + xlen, _ := decInferLen(containerLen, d.h.MaxInitLen, 2) + v = make(map[bool]bool, xlen) changed = true } + + var mk bool + var mv bool if containerLen > 0 { for j := 0; j < containerLen; j++ { - mk := dd.DecodeBool() - mv := v[mk] + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) + } mv = dd.DecodeBool() if v != nil { v[mk] = mv @@ -28290,18 +39345,21 @@ func (_ fastpathT) DecMapBoolBoolV(v map[bool]bool, checkNil bool, canChange boo } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() + if cr != nil { + cr.sendContainerState(containerMapKey) + } + mk = dd.DecodeBool() + if cr != nil { + cr.sendContainerState(containerMapValue) } - mk := dd.DecodeBool() - dd.ReadMapKVSeparator() - mv := v[mk] mv = dd.DecodeBool() if v != nil { v[mk] = mv } } - dd.ReadMapEnd() + } + if cr != nil { + cr.sendContainerState(containerMapEnd) } return v, changed } diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/fast-path.go.tmpl b/Godeps/_workspace/src/github.com/ugorji/go/codec/fast-path.go.tmpl index 9f0adcc..04c173f 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/fast-path.go.tmpl +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/fast-path.go.tmpl @@ -1,4 +1,4 @@ -// //+build ignore +// +build !notfastpath // Copyright (c) 2012-2015 Ugorji Nwoke. All rights reserved. // Use of this source code is governed by a MIT license found in the LICENSE file. @@ -48,8 +48,8 @@ var fastpathTV fastpathT type fastpathE struct { rtid uintptr rt reflect.Type - encfn func(encFnInfo, reflect.Value) - decfn func(decFnInfo, reflect.Value) + encfn func(*encFnInfo, reflect.Value) + decfn func(*decFnInfo, reflect.Value) } type fastpathA [{{ .FastpathLen }}]fastpathE @@ -85,7 +85,7 @@ func init() { return } i := 0 - fn := func(v interface{}, fe func(encFnInfo, reflect.Value), fd func(decFnInfo, reflect.Value)) (f fastpathE) { + fn := func(v interface{}, fe func(*encFnInfo, reflect.Value), fd func(*decFnInfo, reflect.Value)) (f fastpathE) { xrt := reflect.TypeOf(v) xptr := reflect.ValueOf(xrt).Pointer() fastpathAV[i] = fastpathE{xptr, xrt, fe, fd} @@ -93,11 +93,11 @@ func init() { return } - {{range .Values}}{{if not .Primitive}}{{if .Slice }} - fn([]{{ .Elem }}(nil), (encFnInfo).{{ .MethodNamePfx "fastpathEnc" false }}R, (decFnInfo).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}} + {{range .Values}}{{if not .Primitive}}{{if not .MapKey }} + fn([]{{ .Elem }}(nil), (*encFnInfo).{{ .MethodNamePfx "fastpathEnc" false }}R, (*decFnInfo).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}} - {{range .Values}}{{if not .Primitive}}{{if not .Slice }} - fn(map[{{ .MapKey }}]{{ .Elem }}(nil), (encFnInfo).{{ .MethodNamePfx "fastpathEnc" false }}R, (decFnInfo).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}} + {{range .Values}}{{if not .Primitive}}{{if .MapKey }} + fn(map[{{ .MapKey }}]{{ .Elem }}(nil), (*encFnInfo).{{ .MethodNamePfx "fastpathEnc" false }}R, (*decFnInfo).{{ .MethodNamePfx "fastpathDec" false }}R){{end}}{{end}}{{end}} sort.Sort(fastpathAslice(fastpathAV[:])) } @@ -106,118 +106,178 @@ func init() { // -- -- fast path type switch func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { + if !fastpathEnabled { + return false + } switch v := iv.(type) { -{{range .Values}}{{if not .Primitive}}{{if .Slice }} +{{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 .Slice }} + 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 .Slice }} +{{range .Values}}{{if not .Primitive}}{{if not .MapKey }} case []{{ .Elem }}: fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, fastpathCheckNilTrue, e) case *[]{{ .Elem }}: fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, fastpathCheckNilTrue, e) {{end}}{{end}}{{end}} default: + _ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release) return false } return true } func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { + if !fastpathEnabled { + return false + } switch v := iv.(type) { -{{range .Values}}{{if not .Primitive}}{{if not .Slice }} +{{range .Values}}{{if not .Primitive}}{{if .MapKey }} case map[{{ .MapKey }}]{{ .Elem }}: fastpathTV.{{ .MethodNamePfx "Enc" false }}V(v, fastpathCheckNilTrue, e) case *map[{{ .MapKey }}]{{ .Elem }}: fastpathTV.{{ .MethodNamePfx "Enc" false }}V(*v, fastpathCheckNilTrue, e) {{end}}{{end}}{{end}} default: + _ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release) return false } return true } // -- -- fast path functions -{{range .Values}}{{if not .Primitive}}{{if .Slice }} +{{range .Values}}{{if not .Primitive}}{{if not .MapKey }} -func (f encFnInfo) {{ .MethodNamePfx "fastpathEnc" false }}R(rv reflect.Value) { - fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv.Interface().([]{{ .Elem }}), fastpathCheckNilFalse, f.e) +func (f *encFnInfo) {{ .MethodNamePfx "fastpathEnc" false }}R(rv reflect.Value) { + if f.ti.mbs { + fastpathTV.{{ .MethodNamePfx "EncAsMap" false }}V(rv.Interface().([]{{ .Elem }}), fastpathCheckNilFalse, f.e) + } else { + fastpathTV.{{ .MethodNamePfx "Enc" false }}V(rv.Interface().([]{{ .Elem }}), fastpathCheckNilFalse, f.e) + } } func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v []{{ .Elem }}, checkNil bool, e *Encoder) { - ee := e.e + ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeArrayStart(len(v)) - if e.be { - for _, v2 := range v { - {{ encmd .Elem "v2"}} - } - } else { - for j, v2 := range v { - if j > 0 { - ee.EncodeArrayEntrySeparator() - } - {{ encmd .Elem "v2"}} - } - ee.EncodeArrayEnd() + for _, v2 := range v { + if cr != nil { cr.sendContainerState(containerArrayElem) } + {{ encmd .Elem "v2"}} } + if cr != nil { cr.sendContainerState(containerArrayEnd) }{{/* ee.EncodeEnd() */}} +} + +func (_ fastpathT) {{ .MethodNamePfx "EncAsMap" false }}V(v []{{ .Elem }}, checkNil bool, e *Encoder) { + ee := e.e + cr := e.cr + if checkNil && v == nil { + ee.EncodeNil() + return + } + if len(v)%2 == 1 { + e.errorf("mapBySlice requires even slice length, but got %v", len(v)) + return + } + ee.EncodeMapStart(len(v) / 2) + for j, v2 := range v { + if cr != nil { + if j%2 == 0 { + cr.sendContainerState(containerMapKey) + } else { + cr.sendContainerState(containerMapValue) + } + } + {{ encmd .Elem "v2"}} + } + if cr != nil { cr.sendContainerState(containerMapEnd) } } {{end}}{{end}}{{end}} -{{range .Values}}{{if not .Primitive}}{{if not .Slice }} +{{range .Values}}{{if not .Primitive}}{{if .MapKey }} -func (f encFnInfo) {{ .MethodNamePfx "fastpathEnc" false }}R(rv reflect.Value) { +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) { ee := e.e + cr := e.cr if checkNil && v == nil { ee.EncodeNil() return } ee.EncodeMapStart(len(v)) - {{if eq .MapKey "string"}}asSymbols := e.h.AsSymbols&AsSymbolMapStringKeysFlag != 0{{end}} - if e.be { - for k2, v2 := range 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) + v2 := make([]bytesI, len(v)) + var i, l int + var vp *bytesI {{/* put loop variables outside. seems currently needed for better perf */}} + for k2, _ := range v { + l = len(mksv) + e2.MustEncode(k2) + vp = &v2[i] + vp.v = mksv[l:] + vp.i = k2 + i++ + } + sort.Sort(bytesISlice(v2)) + for j := range v2 { + if cr != nil { cr.sendContainerState(containerMapKey) } + e.asis(v2[j].v) + if cr != nil { cr.sendContainerState(containerMapValue) } + e.encode(v[v2[j].i]) + } {{else}}{{ $x := sorttype .MapKey true}}v2 := make([]{{ $x }}, len(v)) + var i int + for k, _ := range v { + v2[i] = {{ $x }}(k) + i++ + } + sort.Sort({{ sorttype .MapKey false}}(v2)) + for _, k2 := range v2 { + if cr != nil { cr.sendContainerState(containerMapKey) } {{if eq .MapKey "string"}}if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) - }{{else}}{{ encmd .MapKey "k2"}}{{end}} - {{ encmd .Elem "v2"}} - } + }{{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}} } else { - j := 0 for k2, v2 := range v { - if j > 0 { - ee.EncodeMapEntrySeparator() - } + if cr != nil { cr.sendContainerState(containerMapKey) } {{if eq .MapKey "string"}}if asSymbols { ee.EncodeSymbol(k2) } else { ee.EncodeString(c_UTF8, k2) }{{else}}{{ encmd .MapKey "k2"}}{{end}} - ee.EncodeMapKVSeparator() + if cr != nil { cr.sendContainerState(containerMapValue) } {{ encmd .Elem "v2"}} - j++ } - ee.EncodeMapEnd() } + if cr != nil { cr.sendContainerState(containerMapEnd) }{{/* ee.EncodeEnd() */}} } {{end}}{{end}}{{end}} @@ -226,11 +286,14 @@ func (_ fastpathT) {{ .MethodNamePfx "Enc" false }}V(v map[{{ .MapKey }}]{{ .Ele // -- -- fast path type switch func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { + if !fastpathEnabled { + return false + } switch v := iv.(type) { -{{range .Values}}{{if not .Primitive}}{{if .Slice }} +{{range .Values}}{{if not .Primitive}}{{if not .MapKey }} case []{{ .Elem }}:{{else}} case map[{{ .MapKey }}]{{ .Elem }}:{{end}} - fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, fastpathCheckNilFalse, false, d){{if .Slice }} + fastpathTV.{{ .MethodNamePfx "Dec" false }}V(v, fastpathCheckNilFalse, false, d){{if not .MapKey }} case *[]{{ .Elem }}:{{else}} case *map[{{ .MapKey }}]{{ .Elem }}:{{end}} v2, changed2 := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*v, fastpathCheckNilFalse, true, d) @@ -239,22 +302,23 @@ func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { } {{end}}{{end}} default: + _ = v // TODO: workaround https://github.com/golang/go/issues/12927 (remove after go 1.6 release) return false } return true } // -- -- fast path functions -{{range .Values}}{{if not .Primitive}}{{if .Slice }} +{{range .Values}}{{if not .Primitive}}{{if not .MapKey }} {{/* Slices can change if they - did not come from an array - are addressable (from a ptr) - are settable (e.g. contained in an interface{}) */}} -func (f decFnInfo) {{ .MethodNamePfx "fastpathDec" false }}R(rv reflect.Value) { +func (f *decFnInfo) {{ .MethodNamePfx "fastpathDec" false }}R(rv reflect.Value) { array := f.seq == seqTypeArray - if !array && rv.CanAddr() { // CanSet => CanAddr + Exported + if !array && rv.CanAddr() { {{/* // CanSet => CanAddr + Exported */}} vp := rv.Addr().Interface().(*[]{{ .Elem }}) v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, fastpathCheckNilFalse, !array, f.d) if changed { @@ -272,10 +336,9 @@ func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *[]{{ .Elem }}, checkNil *vp = v } } -func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, checkNil bool, canChange bool, - d *Decoder) (_ []{{ .Elem }}, changed bool) { +func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, checkNil bool, canChange bool, d *Decoder) (_ []{{ .Elem }}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() + {{/* // if dd.isContainerType(valueTypeNil) { dd.TryDecodeAsNil() */}} if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -284,54 +347,87 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, checkNil b } slh, containerLenS := d.decSliceHelperStart() - if canChange && v == nil { - if containerLenS <= 0 { - v = []{{ .Elem }}{} - } else { - v = make([]{{ .Elem }}, containerLenS, containerLenS) - } - changed = true - } if containerLenS == 0 { - if canChange && len(v) != 0 { - v = v[:0] - changed = true - }{{/* - // slh.End() // dd.ReadArrayEnd() - */}} - return v, changed + if canChange { + if v == nil { + v = []{{ .Elem }}{} + } else if len(v) != 0 { + v = v[:0] + } + changed = true + } + slh.End() + return v, changed } - // for j := 0; j < containerLenS; j++ { if containerLenS > 0 { - decLen := containerLenS + x2read := containerLenS + var xtrunc bool if containerLenS > cap(v) { - if canChange { - s := make([]{{ .Elem }}, containerLenS, containerLenS) + if canChange { {{/* + // fast-path is for "basic" immutable types, so no need to copy them over + // s := make([]{{ .Elem }}, decInferLen(containerLenS, d.h.MaxInitLen)) // copy(s, v[:cap(v)]) - v = s + // 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 { d.arrayCannotExpand(len(v), containerLenS) - decLen = len(v) } + x2read = len(v) } else if containerLenS != len(v) { - v = v[:containerLenS] - changed = true - } - // all checks done. cannot go past len. + if canChange { + v = v[:containerLenS] + changed = true + } + } {{/* // all checks done. cannot go past len. */}} j := 0 - for ; j < decLen; j++ { + for ; j < x2read; j++ { + slh.ElemContainerState(j) {{ if eq .Elem "interface{}" }}d.decode(&v[j]){{ else }}v[j] = {{ decmd .Elem }}{{ end }} } - if !canChange { - for ; j < containerLenS; j++ { + 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 { - j := 0 - for ; !dd.CheckBreak(); j++ { + 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 }}) @@ -339,32 +435,35 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v []{{ .Elem }}, checkNil b } else { d.arrayCannotExpand(len(v), j+1) } - } - if j > 0 { - slh.Sep(j) } - if j < len(v) { // all checks done. cannot go past len. + 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 } - slh.End() } + slh.End() return v, changed } {{end}}{{end}}{{end}} -{{range .Values}}{{if not .Primitive}}{{if not .Slice }} +{{range .Values}}{{if not .Primitive}}{{if .MapKey }} {{/* Maps can change if they are - addressable (from a ptr) - settable (e.g. contained in an interface{}) */}} -func (f decFnInfo) {{ .MethodNamePfx "fastpathDec" false }}R(rv reflect.Value) { +func (f *decFnInfo) {{ .MethodNamePfx "fastpathDec" false }}R(rv reflect.Value) { if rv.CanAddr() { vp := rv.Addr().Interface().(*map[{{ .MapKey }}]{{ .Elem }}) v, changed := fastpathTV.{{ .MethodNamePfx "Dec" false }}V(*vp, fastpathCheckNilFalse, true, f.d) @@ -385,7 +484,8 @@ func (f fastpathT) {{ .MethodNamePfx "Dec" false }}X(vp *map[{{ .MapKey }}]{{ .E func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v map[{{ .MapKey }}]{{ .Elem }}, checkNil bool, canChange bool, d *Decoder) (_ map[{{ .MapKey }}]{{ .Elem }}, changed bool) { dd := d.d - // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() + cr := d.cr + {{/* // if dd.isContainerType(valueTypeNil) {dd.TryDecodeAsNil() */}} if checkNil && dd.TryDecodeAsNil() { if v != nil { changed = true @@ -395,47 +495,45 @@ func (_ fastpathT) {{ .MethodNamePfx "Dec" false }}V(v map[{{ .MapKey }}]{{ .Ele containerLen := dd.ReadMapStart() if canChange && v == nil { - if containerLen > 0 { - v = make(map[{{ .MapKey }}]{{ .Elem }}, containerLen) - } else { - v = make(map[{{ .MapKey }}]{{ .Elem }}) // supports indefinite-length, etc - } + 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 }} if containerLen > 0 { for j := 0; j < containerLen; j++ { - {{ if eq .MapKey "interface{}" }}var mk interface{} + if cr != nil { cr.sendContainerState(containerMapKey) } + {{ if eq .MapKey "interface{}" }}mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. - }{{ else }}mk := {{ decmd .MapKey }}{{ end }} - mv := v[mk] - {{ if eq .Elem "interface{}" }}d.decode(&mv) - {{ else }}mv = {{ decmd .Elem }}{{ end }} + 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 } } } else if containerLen < 0 { for j := 0; !dd.CheckBreak(); j++ { - if j > 0 { - dd.ReadMapEntrySeparator() - } - {{ if eq .MapKey "interface{}" }}var mk interface{} + if cr != nil { cr.sendContainerState(containerMapKey) } + {{ if eq .MapKey "interface{}" }}mk = nil d.decode(&mk) if bv, bok := mk.([]byte); bok { - mk = string(bv) // maps cannot have []byte as key. switch to string. - }{{ else }}mk := {{ decmd .MapKey }}{{ end }} - dd.ReadMapKVSeparator() - mv := v[mk] - {{ if eq .Elem "interface{}" }}d.decode(&mv) - {{ else }}mv = {{ decmd .Elem }}{{ end }} + 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 } } - dd.ReadMapEnd() } + if cr != nil { cr.sendContainerState(containerMapEnd) } return v, changed } diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/fast-path.not.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/fast-path.not.go new file mode 100644 index 0000000..d6f5f0c --- /dev/null +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/fast-path.not.go @@ -0,0 +1,32 @@ +// +build notfastpath + +package codec + +import "reflect" + +// The generated fast-path code is very large, and adds a few seconds to the build time. +// This causes test execution, execution of small tools which use codec, etc +// to take a long time. +// +// To mitigate, we now support the notfastpath tag. +// This tag disables fastpath during build, allowing for faster build, test execution, +// short-program runs, etc. + +func fastpathDecodeTypeSwitch(iv interface{}, d *Decoder) bool { return false } +func fastpathEncodeTypeSwitch(iv interface{}, e *Encoder) bool { return false } +func fastpathEncodeTypeSwitchSlice(iv interface{}, e *Encoder) bool { return false } +func fastpathEncodeTypeSwitchMap(iv interface{}, e *Encoder) bool { return false } + +type fastpathT struct{} +type fastpathE struct { + rtid uintptr + rt reflect.Type + encfn func(*encFnInfo, reflect.Value) + decfn func(*decFnInfo, reflect.Value) +} +type fastpathA [0]fastpathE + +func (x fastpathA) index(rtid uintptr) int { return -1 } + +var fastpathAV fastpathA +var fastpathTV fastpathT diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-dec-array.go.tmpl b/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-dec-array.go.tmpl index 0f4ea91..32df541 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-dec-array.go.tmpl +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-dec-array.go.tmpl @@ -1,80 +1,104 @@ -{{var "v"}} := {{ if not isArray}}*{{ end }}{{ .Varname }} -{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() - -var {{var "c"}} bool -_ = {{var "c"}} - -{{ if not isArray }}if {{var "v"}} == nil { - if {{var "l"}} <= 0 { - {{var "v"}} = make({{ .CTyp }}, 0) - } else { - {{var "v"}} = make({{ .CTyp }}, {{var "l"}}) - } - {{var "c"}} = true -} -{{ end }} -if {{var "l"}} == 0 { {{ if isSlice }} - if len({{var "v"}}) != 0 { - {{var "v"}} = {{var "v"}}[:0] - {{var "c"}} = true - } {{ end }} +{{var "v"}} := {{if not isArray}}*{{end}}{{ .Varname }} +{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}{{if not isArray}} +var {{var "c"}} bool {{/* // changed */}} +_ = {{var "c"}}{{end}} +if {{var "l"}} == 0 { + {{if isSlice }}if {{var "v"}} == nil { + {{var "v"}} = []{{ .Typ }}{} + {{var "c"}} = true + } else if len({{var "v"}}) != 0 { + {{var "v"}} = {{var "v"}}[:0] + {{var "c"}} = true + } {{end}} {{if isChan }}if {{var "v"}} == nil { + {{var "v"}} = make({{ .CTyp }}, 0) + {{var "c"}} = true + } {{end}} } else if {{var "l"}} > 0 { - {{ if isChan }} + {{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"}}++ { + {{var "h"}}.ElemContainerState({{var "r"}}) var {{var "t"}} {{ .Typ }} {{ $x := printf "%st%s" .TempVar .Rand }}{{ decLineVar $x }} - {{var "v"}} <- {{var "t"}} - {{ else }} - {{var "n"}} := {{var "l"}} - if {{var "l"}} > cap({{var "v"}}) { - {{ if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "l"}}) - {{var "n"}} = len({{var "v"}}) - {{ else }}{{ if .Immutable }} - {{var "v2"}} := {{var "v"}} - {{var "v"}} = make([]{{ .Typ }}, {{var "l"}}, {{var "l"}}) - if len({{var "v"}}) > 0 { - copy({{var "v"}}, {{var "v2"}}[:cap({{var "v2"}})]) - } - {{ else }}{{var "v"}} = make([]{{ .Typ }}, {{var "l"}}, {{var "l"}}) - {{ end }}{{var "c"}} = true - {{ end }} - } else if {{var "l"}} != len({{var "v"}}) { - {{ if isSlice }}{{var "v"}} = {{var "v"}}[:{{var "l"}}] - {{var "c"}} = true {{ end }} + {{var "v"}} <- {{var "t"}} } + {{ 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 isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "l"}}) + {{ else }}{{if not .Immutable }} + {{var "rg"}} := len({{var "v"}}) > 0 + {{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 { + {{var "v"}} = make([]{{ .Typ }}, {{var "rl"}}) + } + {{var "c"}} = true + {{var "rr"}} = len({{var "v"}}) {{if not .Immutable }} + 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 "c"}} = true + } {{end}} {{/* end isSlice:47 */}} {{var "j"}} := 0 - for ; {{var "j"}} < {{var "n"}} ; {{var "j"}}++ { + 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"}}++ { + } + {{if isArray }}for ; {{var "j"}} < {{var "l"}} ; {{var "j"}}++ { + {{var "h"}}.ElemContainerState({{var "j"}}) z.DecSwallow() - }{{ end }} - {{ end }}{{/* closing if not chan */}} -} else { - for {{var "j"}} := 0; !r.CheckBreak(); {{var "j"}}++ { - if {{var "j"}} >= len({{var "v"}}) { - {{ if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "j"}}+1) - {{ else if isSlice}}{{var "v"}} = append({{var "v"}}, {{zero}})// var {{var "z"}} {{ .Typ }} - {{var "c"}} = true {{ end }} + } + {{ else }}if {{var "rt"}} { + for ; {{var "j"}} < {{var "l"}} ; {{var "j"}}++ { + {{var "v"}} = append({{var "v"}}, {{ zero}}) + {{var "h"}}.ElemContainerState({{var "j"}}) + {{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x }} } - if {{var "j"}} > 0 { - {{var "h"}}.Sep({{var "j"}}) - } - {{ if isChan}} + } {{end}} {{/* end isArray:56 */}} + {{end}} {{/* end isChan:16 */}} +} else { {{/* len < 0 */}} + {{var "j"}} := 0 + for ; !r.CheckBreak(); {{var "j"}}++ { + {{if isChan }} + {{var "h"}}.ElemContainerState({{var "j"}}) var {{var "t"}} {{ .Typ }} {{ $x := printf "%st%s" .TempVar .Rand }}{{ decLineVar $x }} {{var "v"}} <- {{var "t"}} {{ else }} + if {{var "j"}} >= len({{var "v"}}) { + {{if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "j"}}+1) + {{ else }}{{var "v"}} = append({{var "v"}}, {{zero}})// var {{var "z"}} {{ .Typ }} + {{var "c"}} = true {{end}} + } + {{var "h"}}.ElemContainerState({{var "j"}}) if {{var "j"}} < len({{var "v"}}) { {{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x }} } else { z.DecSwallow() } - {{ end }} + {{end}} } - {{var "h"}}.End() + {{if isSlice }}if {{var "j"}} < len({{var "v"}}) { + {{var "v"}} = {{var "v"}}[:{{var "j"}}] + {{var "c"}} = true + } else if {{var "j"}} == 0 && {{var "v"}} == nil { + {{var "v"}} = []{{ .Typ }}{} + {{var "c"}} = true + }{{end}} } -{{ if not isArray }}if {{var "c"}} { +{{var "h"}}.End() +{{if not isArray }}if {{var "c"}} { *{{ .Varname }} = {{var "v"}} -}{{ end }} - +}{{end}} diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-dec-map.go.tmpl b/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-dec-map.go.tmpl index 9f8dafa..77400e0 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-dec-map.go.tmpl +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-dec-map.go.tmpl @@ -1,46 +1,58 @@ {{var "v"}} := *{{ .Varname }} {{var "l"}} := r.ReadMapStart() +{{var "bh"}} := z.DecBasicHandle() if {{var "v"}} == nil { - if {{var "l"}} > 0 { - {{var "v"}} = make(map[{{ .KTyp }}]{{ .Typ }}, {{var "l"}}) - } else { - {{var "v"}} = make(map[{{ .KTyp }}]{{ .Typ }}) // supports indefinite-length, etc - } + {{var "rl"}}, _ := z.DecInferLen({{var "l"}}, {{var "bh"}}.MaxInitLen, {{ .Size }}) + {{var "v"}} = make(map[{{ .KTyp }}]{{ .Typ }}, {{var "rl"}}) *{{ .Varname }} = {{var "v"}} } +var {{var "mk"}} {{ .KTyp }} +var {{var "mv"}} {{ .Typ }} +var {{var "mg"}} {{if decElemKindPtr}}, {{var "ms"}}, {{var "mok"}}{{end}} bool +if {{var "bh"}}.MapValueReset { + {{if decElemKindPtr}}{{var "mg"}} = true + {{else if decElemKindIntf}}if !{{var "bh"}}.InterfaceReset { {{var "mg"}} = true } + {{else if not decElemKindImmutable}}{{var "mg"}} = true + {{end}} } if {{var "l"}} > 0 { for {{var "j"}} := 0; {{var "j"}} < {{var "l"}}; {{var "j"}}++ { - var {{var "mk"}} {{ .KTyp }} + 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"}} { +{{ 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 }} - {{var "mv"}} := {{var "v"}}[{{var "mk"}}] + }{{ 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 {{var "v"}} != nil { + if {{if decElemKindPtr}} {{var "ms"}} && {{end}} {{var "v"}} != nil { {{var "v"}}[{{var "mk"}}] = {{var "mv"}} } } } else if {{var "l"}} < 0 { for {{var "j"}} := 0; !r.CheckBreak(); {{var "j"}}++ { - if {{var "j"}} > 0 { - r.ReadMapEntrySeparator() - } - var {{var "mk"}} {{ .KTyp }} + 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"}} { +{{ 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 }} - r.ReadMapKVSeparator() - {{var "mv"}} := {{var "v"}}[{{var "mk"}}] + }{{ 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 {{var "v"}} != nil { + if {{if decElemKindPtr}} {{var "ms"}} && {{end}} {{var "v"}} != nil { {{var "v"}}[{{var "mk"}}] = {{var "mv"}} } } -r.ReadMapEnd() } // else len==0: TODO: Should we clear map entries? +z.DecSendContainerState(codecSelfer_containerMapEnd{{ .Sfx }}) diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-helper.generated.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-helper.generated.go index ecf3ee5..22bce77 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-helper.generated.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-helper.generated.go @@ -10,6 +10,11 @@ package codec +import ( + "encoding" + "reflect" +) + // This file is used to generate helper code for codecgen. // The values here i.e. genHelper(En|De)coder are not to be used directly by // library users. They WILL change continously and without notice. @@ -60,6 +65,65 @@ func (f genHelperEncoder) EncFallback(iv interface{}) { 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 { + return f.e.js +} + +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperEncoder) HasExtensions() bool { + return len(f.e.h.extHandle) != 0 +} + +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperEncoder) EncExt(v interface{}) (r bool) { + rt := reflect.TypeOf(v) + if rt.Kind() == reflect.Ptr { + 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* +func (f genHelperEncoder) EncSendContainerState(c containerState) { + if f.e.cr != nil { + f.e.cr.sendContainerState(c) + } +} + +// ---------------- DECODER FOLLOWS ----------------- + // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* func (f genHelperDecoder) DecBasicHandle() *BasicHandle { return f.d.h @@ -100,3 +164,70 @@ func (f genHelperDecoder) DecStructFieldNotFound(index int, name string) { func (f genHelperDecoder) DecArrayCannotExpand(sliceLen, streamLen int) { f.d.arrayCannotExpand(sliceLen, streamLen) } + +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) DecTextUnmarshal(tm encoding.TextUnmarshaler) { + fnerr := tm.UnmarshalText(f.d.d.DecodeBytes(f.d.b[:], true, true)) + if fnerr != nil { + panic(fnerr) + } +} + +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) DecJSONUnmarshal(tm jsonUnmarshaler) { + // bs := f.dd.DecodeBytes(f.d.b[:], true, true) + // grab the bytes to be read, as UnmarshalJSON needs the full JSON so as to unmarshal it itself. + fnerr := tm.UnmarshalJSON(f.d.nextValueBytes()) + if fnerr != nil { + panic(fnerr) + } +} + +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) DecBinaryUnmarshal(bm encoding.BinaryUnmarshaler) { + fnerr := bm.UnmarshalBinary(f.d.d.DecodeBytes(nil, false, true)) + if fnerr != nil { + panic(fnerr) + } +} + +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) TimeRtidIfBinc() uintptr { + if _, ok := f.d.hh.(*BincHandle); ok { + return timeTypId + } + return 0 +} + +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) IsJSONHandle() bool { + return f.d.js +} + +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) HasExtensions() bool { + return len(f.d.h.extHandle) != 0 +} + +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) DecExt(v interface{}) (r bool) { + rt := reflect.TypeOf(v).Elem() + 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* +func (f genHelperDecoder) DecInferLen(clen, maxlen, unit int) (rvlen int, truncated bool) { + 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) + } +} diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-helper.go.tmpl b/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-helper.go.tmpl index 89d7518..3195857 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-helper.go.tmpl +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/gen-helper.go.tmpl @@ -10,6 +10,11 @@ package codec +import ( + "encoding" + "reflect" +) + // This file is used to generate helper code for codecgen. // The values here i.e. genHelper(En|De)coder are not to be used directly by // library users. They WILL change continously and without notice. @@ -48,6 +53,7 @@ type genHelperDecoder struct { func (f genHelperEncoder) EncBasicHandle() *BasicHandle { return f.e.h } + // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* func (f genHelperEncoder) EncBinary() bool { return f.e.be // f.e.hh.isBinaryEncoding() @@ -57,6 +63,57 @@ 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 { + return f.e.js +} +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperEncoder) HasExtensions() bool { + return len(f.e.h.extHandle) != 0 +} +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperEncoder) EncExt(v interface{}) (r bool) { + rt := reflect.TypeOf(v) + if rt.Kind() == reflect.Ptr { + 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* +func (f genHelperEncoder) EncSendContainerState(c containerState) { + if f.e.cr != nil { + f.e.cr.sendContainerState(c) + } +} + +// ---------------- DECODER FOLLOWS ----------------- // FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* func (f genHelperDecoder) DecBasicHandle() *BasicHandle { @@ -91,7 +148,64 @@ func (f genHelperDecoder) DecStructFieldNotFound(index int, name string) { func (f genHelperDecoder) DecArrayCannotExpand(sliceLen, streamLen int) { f.d.arrayCannotExpand(sliceLen, streamLen) } - +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) DecTextUnmarshal(tm encoding.TextUnmarshaler) { + fnerr := tm.UnmarshalText(f.d.d.DecodeBytes(f.d.b[:], true, true)) + if fnerr != nil { + panic(fnerr) + } +} +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) DecJSONUnmarshal(tm jsonUnmarshaler) { + // bs := f.dd.DecodeBytes(f.d.b[:], true, true) + // grab the bytes to be read, as UnmarshalJSON needs the full JSON so as to unmarshal it itself. + fnerr := tm.UnmarshalJSON(f.d.nextValueBytes()) + if fnerr != nil { + panic(fnerr) + } +} +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) DecBinaryUnmarshal(bm encoding.BinaryUnmarshaler) { + fnerr := bm.UnmarshalBinary(f.d.d.DecodeBytes(nil, false, true)) + if fnerr != nil { + panic(fnerr) + } +} +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) TimeRtidIfBinc() uintptr { + if _, ok := f.d.hh.(*BincHandle); ok { + return timeTypId + } + return 0 +} +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) IsJSONHandle() bool { + return f.d.js +} +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) HasExtensions() bool { + return len(f.d.h.extHandle) != 0 +} +// FOR USE BY CODECGEN ONLY. IT *WILL* CHANGE WITHOUT NOTICE. *DO NOT USE* +func (f genHelperDecoder) DecExt(v interface{}) (r bool) { + rt := reflect.TypeOf(v).Elem() + 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* +func (f genHelperDecoder) DecInferLen(clen, maxlen, unit int) (rvlen int, truncated bool) { + 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) + } +} {{/* diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/gen.generated.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/gen.generated.go index 8cc254e..2ace97b 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/gen.generated.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/gen.generated.go @@ -8,132 +8,168 @@ package codec const genDecMapTmpl = ` {{var "v"}} := *{{ .Varname }} {{var "l"}} := r.ReadMapStart() +{{var "bh"}} := z.DecBasicHandle() if {{var "v"}} == nil { - if {{var "l"}} > 0 { - {{var "v"}} = make(map[{{ .KTyp }}]{{ .Typ }}, {{var "l"}}) - } else { - {{var "v"}} = make(map[{{ .KTyp }}]{{ .Typ }}) // supports indefinite-length, etc - } + {{var "rl"}}, _ := z.DecInferLen({{var "l"}}, {{var "bh"}}.MaxInitLen, {{ .Size }}) + {{var "v"}} = make(map[{{ .KTyp }}]{{ .Typ }}, {{var "rl"}}) *{{ .Varname }} = {{var "v"}} } +var {{var "mk"}} {{ .KTyp }} +var {{var "mv"}} {{ .Typ }} +var {{var "mg"}} {{if decElemKindPtr}}, {{var "ms"}}, {{var "mok"}}{{end}} bool +if {{var "bh"}}.MapValueReset { + {{if decElemKindPtr}}{{var "mg"}} = true + {{else if decElemKindIntf}}if !{{var "bh"}}.InterfaceReset { {{var "mg"}} = true } + {{else if not decElemKindImmutable}}{{var "mg"}} = true + {{end}} } if {{var "l"}} > 0 { for {{var "j"}} := 0; {{var "j"}} < {{var "l"}}; {{var "j"}}++ { - var {{var "mk"}} {{ .KTyp }} + 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"}} { +{{ 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 }} - {{var "mv"}} := {{var "v"}}[{{var "mk"}}] + }{{ 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 {{var "v"}} != nil { + if {{if decElemKindPtr}} {{var "ms"}} && {{end}} {{var "v"}} != nil { {{var "v"}}[{{var "mk"}}] = {{var "mv"}} } } } else if {{var "l"}} < 0 { for {{var "j"}} := 0; !r.CheckBreak(); {{var "j"}}++ { - if {{var "j"}} > 0 { - r.ReadMapEntrySeparator() - } - var {{var "mk"}} {{ .KTyp }} + 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"}} { +{{ 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 }} - r.ReadMapKVSeparator() - {{var "mv"}} := {{var "v"}}[{{var "mk"}}] + }{{ 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 {{var "v"}} != nil { + if {{if decElemKindPtr}} {{var "ms"}} && {{end}} {{var "v"}} != nil { {{var "v"}}[{{var "mk"}}] = {{var "mv"}} } } -r.ReadMapEnd() } // else len==0: TODO: Should we clear map entries? +z.DecSendContainerState(codecSelfer_containerMapEnd{{ .Sfx }}) ` const genDecListTmpl = ` -{{var "v"}} := {{ if not isArray}}*{{ end }}{{ .Varname }} -{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() - -var {{var "c"}} bool -_ = {{var "c"}} - -{{ if not isArray }}if {{var "v"}} == nil { - if {{var "l"}} <= 0 { - {{var "v"}} = make({{ .CTyp }}, 0) - } else { - {{var "v"}} = make({{ .CTyp }}, {{var "l"}}) - } - {{var "c"}} = true -} -{{ end }} -if {{var "l"}} == 0 { {{ if isSlice }} - if len({{var "v"}}) != 0 { - {{var "v"}} = {{var "v"}}[:0] - {{var "c"}} = true - } {{ end }} +{{var "v"}} := {{if not isArray}}*{{end}}{{ .Varname }} +{{var "h"}}, {{var "l"}} := z.DecSliceHelperStart() {{/* // helper, containerLenS */}}{{if not isArray}} +var {{var "c"}} bool {{/* // changed */}} +_ = {{var "c"}}{{end}} +if {{var "l"}} == 0 { + {{if isSlice }}if {{var "v"}} == nil { + {{var "v"}} = []{{ .Typ }}{} + {{var "c"}} = true + } else if len({{var "v"}}) != 0 { + {{var "v"}} = {{var "v"}}[:0] + {{var "c"}} = true + } {{end}} {{if isChan }}if {{var "v"}} == nil { + {{var "v"}} = make({{ .CTyp }}, 0) + {{var "c"}} = true + } {{end}} } else if {{var "l"}} > 0 { - {{ if isChan }} + {{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"}}++ { + {{var "h"}}.ElemContainerState({{var "r"}}) var {{var "t"}} {{ .Typ }} {{ $x := printf "%st%s" .TempVar .Rand }}{{ decLineVar $x }} - {{var "v"}} <- {{var "t"}} - {{ else }} - {{var "n"}} := {{var "l"}} - if {{var "l"}} > cap({{var "v"}}) { - {{ if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "l"}}) - {{var "n"}} = len({{var "v"}}) - {{ else }}{{ if .Immutable }} - {{var "v2"}} := {{var "v"}} - {{var "v"}} = make([]{{ .Typ }}, {{var "l"}}, {{var "l"}}) - if len({{var "v"}}) > 0 { - copy({{var "v"}}, {{var "v2"}}[:cap({{var "v2"}})]) - } - {{ else }}{{var "v"}} = make([]{{ .Typ }}, {{var "l"}}, {{var "l"}}) - {{ end }}{{var "c"}} = true - {{ end }} - } else if {{var "l"}} != len({{var "v"}}) { - {{ if isSlice }}{{var "v"}} = {{var "v"}}[:{{var "l"}}] - {{var "c"}} = true {{ end }} + {{var "v"}} <- {{var "t"}} } + {{ 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 isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "l"}}) + {{ else }}{{if not .Immutable }} + {{var "rg"}} := len({{var "v"}}) > 0 + {{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 { + {{var "v"}} = make([]{{ .Typ }}, {{var "rl"}}) + } + {{var "c"}} = true + {{var "rr"}} = len({{var "v"}}) {{if not .Immutable }} + 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 "c"}} = true + } {{end}} {{/* end isSlice:47 */}} {{var "j"}} := 0 - for ; {{var "j"}} < {{var "n"}} ; {{var "j"}}++ { + 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"}}++ { + } + {{if isArray }}for ; {{var "j"}} < {{var "l"}} ; {{var "j"}}++ { + {{var "h"}}.ElemContainerState({{var "j"}}) z.DecSwallow() - }{{ end }} - {{ end }}{{/* closing if not chan */}} -} else { - for {{var "j"}} := 0; !r.CheckBreak(); {{var "j"}}++ { - if {{var "j"}} >= len({{var "v"}}) { - {{ if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "j"}}+1) - {{ else if isSlice}}{{var "v"}} = append({{var "v"}}, {{zero}})// var {{var "z"}} {{ .Typ }} - {{var "c"}} = true {{ end }} + } + {{ else }}if {{var "rt"}} { + for ; {{var "j"}} < {{var "l"}} ; {{var "j"}}++ { + {{var "v"}} = append({{var "v"}}, {{ zero}}) + {{var "h"}}.ElemContainerState({{var "j"}}) + {{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x }} } - if {{var "j"}} > 0 { - {{var "h"}}.Sep({{var "j"}}) - } - {{ if isChan}} + } {{end}} {{/* end isArray:56 */}} + {{end}} {{/* end isChan:16 */}} +} else { {{/* len < 0 */}} + {{var "j"}} := 0 + for ; !r.CheckBreak(); {{var "j"}}++ { + {{if isChan }} + {{var "h"}}.ElemContainerState({{var "j"}}) var {{var "t"}} {{ .Typ }} {{ $x := printf "%st%s" .TempVar .Rand }}{{ decLineVar $x }} {{var "v"}} <- {{var "t"}} {{ else }} + if {{var "j"}} >= len({{var "v"}}) { + {{if isArray }}z.DecArrayCannotExpand(len({{var "v"}}), {{var "j"}}+1) + {{ else }}{{var "v"}} = append({{var "v"}}, {{zero}})// var {{var "z"}} {{ .Typ }} + {{var "c"}} = true {{end}} + } + {{var "h"}}.ElemContainerState({{var "j"}}) if {{var "j"}} < len({{var "v"}}) { {{ $x := printf "%[1]vv%[2]v[%[1]vj%[2]v]" .TempVar .Rand }}{{ decLineVar $x }} } else { z.DecSwallow() } - {{ end }} + {{end}} } - {{var "h"}}.End() + {{if isSlice }}if {{var "j"}} < len({{var "v"}}) { + {{var "v"}} = {{var "v"}}[:{{var "j"}}] + {{var "c"}} = true + } else if {{var "j"}} == 0 && {{var "v"}} == nil { + {{var "v"}} = []{{ .Typ }}{} + {{var "c"}} = true + }{{end}} } -{{ if not isArray }}if {{var "c"}} { +{{var "h"}}.End() +{{if not isArray }}if {{var "c"}} { *{{ .Varname }} = {{var "v"}} -}{{ end }} - +}{{end}} ` diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/gen.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/gen.go index b1eee33..d4dcbdc 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/gen.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/gen.go @@ -12,24 +12,39 @@ import ( "io" "io/ioutil" "math/rand" + "os" "reflect" "regexp" + "sort" "strconv" "strings" "sync" "text/template" "time" + "unicode" + "unicode/utf8" ) // --------------------------------------------------- -// codecgen only works in the following: -// - extensions are not supported. Do not make a type a Selfer and an extension. -// - Selfer takes precedence. -// Any type that implements it knows how to encode/decode itself statically. -// Extensions are only known at runtime. -// codecgen only looks at the Kind of the type. +// codecgen supports the full cycle of reflection-based codec: +// - RawExt +// - Builtins +// - Extensions +// - (Binary|Text|JSON)(Unm|M)arshal +// - generic by-kind // -// - the following types are supported: +// This means that, for dynamic things, we MUST use reflection to at least get the reflect.Type. +// In those areas, we try to only do reflection or interface-conversion when NECESSARY: +// - Extensions, only if Extensions are configured. +// +// However, codecgen doesn't support the following: +// - Canonical option. (codecgen IGNORES it currently) +// This is just because it has not been implemented. +// +// During encode/decode, Selfer takes precedence. +// A type implementing Selfer will know how to encode/decode itself statically. +// +// The following field types are supported: // array: [n]T // slice: []T // map: map[K]V @@ -66,11 +81,25 @@ import ( // It was a concious decision to have gen.go always explicitly call EncodeNil or TryDecodeAsNil. // This way, there isn't a function call overhead just to see that we should not enter a block of code. -const GenVersion = 2 // increment this value each time codecgen changes fundamentally. +// GenVersion is the current version of codecgen. +// +// NOTE: Increment this value each time codecgen changes fundamentally. +// Fundamental changes are: +// - helper methods change (signature change, new ones added, some removed, etc) +// - codecgen command line changes +// +// v1: Initial Version +// v2: +// v3: Changes for Kubernetes: +// changes in signature of some unpublished helper methods and codecgen cmdline arguments. +// v4: Removed separator support from (en|de)cDriver, and refactored codec(gen) +// v5: changes to support faster json decoding. Let encoder/decoder maintain state of collections. +const GenVersion = 5 const ( - genCodecPkg = "codec1978" - genTempVarPfx = "yy" + genCodecPkg = "codec1978" + genTempVarPfx = "yy" + genTopLevelVarName = "x" // ignore canBeNil parameter, and always set to true. // This is because nil can appear anywhere, so we should always check. @@ -84,6 +113,14 @@ const ( genUseOneFunctionForDecStructMap = true ) +type genStructMapStyle uint8 + +const ( + genStructMapStyleConsolidated genStructMapStyle = iota + genStructMapStyleLenPrefix + genStructMapStyleCheckBreak +) + var ( genAllTypesSamePkgErr = errors.New("All types must be in the same package") genExpectArrayOrMapErr = errors.New("unexpected type. Expecting array/map/slice") @@ -94,30 +131,39 @@ var ( // genRunner holds some state used during a Gen run. type genRunner struct { w io.Writer // output - c uint64 // ctr used for generating varsfx + c uint64 // counter used for generating varsfx t []reflect.Type // list of types to run selfer on - tc reflect.Type // currently running selfer on this type - te map[uintptr]bool // types for which the encoder has been created - td map[uintptr]bool // types for which the decoder has been created - cp string // codec import path - im map[string]reflect.Type // imports to add + tc reflect.Type // currently running selfer on this type + te map[uintptr]bool // types for which the encoder has been created + td map[uintptr]bool // types for which the decoder has been created + cp string // codec import path + + im map[string]reflect.Type // imports to add + imn map[string]string // package names of imports to add + imc uint64 // counter for import numbers + is map[reflect.Type]struct{} // types seen during import search bp string // base PkgPath, for which we are generating for cpfx string // codec package prefix unsafe bool // is unsafe to be used in generated code? - ts map[reflect.Type]struct{} // types for which enc/dec must be generated - xs string // top level variable/constant suffix - hn string // fn helper type name + tm map[reflect.Type]struct{} // types for which enc/dec must be generated + ts []reflect.Type // types for which enc/dec must be generated - rr *rand.Rand // random generator for file-specific types + xs string // top level variable/constant suffix + hn string // fn helper type name + + ti *TypeInfos + // rr *rand.Rand // random generator for file-specific types } // Gen will write a complete go file containing Selfer implementations for each // type passed. All the types must be in the same package. -func Gen(w io.Writer, buildTags, pkgName string, useUnsafe bool, typ ...reflect.Type) { +// +// Library users: *DO NOT USE IT DIRECTLY. IT WILL CHANGE CONTINOUSLY WITHOUT NOTICE.* +func Gen(w io.Writer, buildTags, pkgName, uid string, useUnsafe bool, ti *TypeInfos, typ ...reflect.Type) { if len(typ) == 0 { return } @@ -128,17 +174,28 @@ func Gen(w io.Writer, buildTags, pkgName string, useUnsafe bool, typ ...reflect. te: make(map[uintptr]bool), td: make(map[uintptr]bool), im: make(map[string]reflect.Type), + imn: make(map[string]string), is: make(map[reflect.Type]struct{}), - ts: make(map[reflect.Type]struct{}), - bp: typ[0].PkgPath(), - rr: rand.New(rand.NewSource(time.Now().UnixNano())), + tm: make(map[reflect.Type]struct{}), + ts: []reflect.Type{}, + bp: genImportPath(typ[0]), + xs: uid, + ti: ti, + } + if x.ti == nil { + x.ti = defTypeInfos + } + if x.xs == "" { + rr := rand.New(rand.NewSource(time.Now().UnixNano())) + x.xs = strconv.FormatInt(rr.Int63n(9999), 10) } // gather imports first: - x.cp = reflect.TypeOf(x).PkgPath() + x.cp = genImportPath(reflect.TypeOf(x)) + x.imn[x.cp] = genCodecPkg for _, t := range typ { - // fmt.Printf("###########: PkgPath: '%v', Name: '%s'\n", t.PkgPath(), t.Name()) - if t.PkgPath() != x.bp { + // fmt.Printf("###########: PkgPath: '%v', Name: '%s'\n", genImportPath(t), t.Name()) + if genImportPath(t) != x.bp { panic(genAllTypesSamePkgErr) } x.genRefPkgs(t) @@ -162,8 +219,14 @@ func Gen(w io.Writer, buildTags, pkgName string, useUnsafe bool, typ ...reflect. x.cpfx = genCodecPkg + "." x.linef("%s \"%s\"", genCodecPkg, x.cp) } + // use a sorted set of im keys, so that we can get consistent output + imKeys := make([]string, 0, len(x.im)) for k, _ := range x.im { - x.line("\"" + k + "\"") + imKeys = append(imKeys, k) + } + sort.Strings(imKeys) + for _, k := range imKeys { // for k, _ := range x.im { + x.linef("%s \"%s\"", x.imn[k], k) } // add required packages for _, k := range [...]string{"reflect", "unsafe", "runtime", "fmt", "errors"} { @@ -177,13 +240,19 @@ func Gen(w io.Writer, buildTags, pkgName string, useUnsafe bool, typ ...reflect. x.line(")") x.line("") - x.xs = strconv.FormatInt(x.rr.Int63n(9999), 10) - x.line("const (") + x.linef("// ----- content types ----") x.linef("codecSelferC_UTF8%s = %v", x.xs, int64(c_UTF8)) x.linef("codecSelferC_RAW%s = %v", x.xs, int64(c_RAW)) - x.linef("codecSelverValueTypeArray%s = %v", x.xs, int64(valueTypeArray)) - x.linef("codecSelverValueTypeMap%s = %v", x.xs, int64(valueTypeMap)) + x.linef("// ----- value types used ----") + x.linef("codecSelferValueTypeArray%s = %v", x.xs, int64(valueTypeArray)) + x.linef("codecSelferValueTypeMap%s = %v", x.xs, int64(valueTypeMap)) + x.linef("// ----- containerStateValues ----") + x.linef("codecSelfer_containerMapKey%s = %v", x.xs, int64(containerMapKey)) + x.linef("codecSelfer_containerMapValue%s = %v", x.xs, int64(containerMapValue)) + x.linef("codecSelfer_containerMapEnd%s = %v", x.xs, int64(containerMapEnd)) + x.linef("codecSelfer_containerArrayElem%s = %v", x.xs, int64(containerArrayElem)) + x.linef("codecSelfer_containerArrayEnd%s = %v", x.xs, int64(containerArrayEnd)) x.line(")") x.line("var (") x.line("codecSelferBitsize" + x.xs + " = uint8(reflect.TypeOf(uint(0)).Bits())") @@ -205,13 +274,13 @@ func Gen(w io.Writer, buildTags, pkgName string, useUnsafe bool, typ ...reflect. x.line(`err := fmt.Errorf("codecgen version mismatch: current: %v, need %v. Re-generate file: %v", `) x.linef(`%v, %sGenVersion, file)`, GenVersion, x.cpfx) x.line("panic(err)") - // x.linef(`panic(fmt.Errorf("Re-run codecgen due to version mismatch: `+ - // `current: %%v, need %%v, file: %%v", %v, %sGenVersion, file))`, GenVersion, x.cpfx) x.linef("}") x.line("if false { // reference the types, but skip this branch at build/run time") var n int - for _, t := range x.im { - x.linef("var v%v %s", n, t.String()) + // for k, t := range x.im { + for _, k := range imKeys { + t := x.im[k] + x.linef("var v%v %s.%s", n, x.imn[k], t.Name()) n++ } if x.unsafe { @@ -239,7 +308,7 @@ func Gen(w io.Writer, buildTags, pkgName string, useUnsafe bool, typ ...reflect. x.selfer(false) } - for t, _ := range x.ts { + for _, t := range x.ts { rtid := reflect.ValueOf(t).Pointer() // generate enc functions for all these slice/map types. x.linef("func (x %s) enc%s(v %s%s, e *%sEncoder) {", x.hn, x.genMethodNameT(t), x.arr2str(t, "*"), x.genTypeName(t), x.cpfx) @@ -273,6 +342,12 @@ func Gen(w io.Writer, buildTags, pkgName string, useUnsafe bool, typ ...reflect. x.line("") } +func (x *genRunner) checkForSelfer(t reflect.Type, varname string) bool { + // return varname != genTopLevelVarName && t != x.tc + // the only time we checkForSelfer is if we are not at the TOP of the generated code. + return varname != genTopLevelVarName +} + func (x *genRunner) arr2str(t reflect.Type, s string) string { if t.Kind() == reflect.Array { return s @@ -294,11 +369,19 @@ func (x *genRunner) genRefPkgs(t reflect.Type) { if _, ok := x.is[t]; ok { return } - // fmt.Printf(">>>>>>: PkgPath: '%v', Name: '%s'\n", t.PkgPath(), t.Name()) + // fmt.Printf(">>>>>>: PkgPath: '%v', Name: '%s'\n", genImportPath(t), t.Name()) x.is[t] = struct{}{} - tpkg, tname := t.PkgPath(), t.Name() + tpkg, tname := genImportPath(t), t.Name() if tpkg != "" && tpkg != x.bp && tpkg != x.cp && tname != "" && tname[0] >= 'A' && tname[0] <= 'Z' { - x.im[tpkg] = t + if _, ok := x.im[tpkg]; !ok { + x.im[tpkg] = t + if idx := strings.LastIndex(tpkg, "/"); idx < 0 { + x.imn[tpkg] = tpkg + } else { + x.imc++ + x.imn[tpkg] = "pkg" + strconv.FormatUint(x.imc, 10) + "_" + genGoIdentifier(tpkg[idx+1:], false) + } + } } switch t.Kind() { case reflect.Array, reflect.Slice, reflect.Ptr, reflect.Chan: @@ -342,7 +425,65 @@ func (x *genRunner) outf(s string, params ...interface{}) { } func (x *genRunner) genTypeName(t reflect.Type) (n string) { - return genTypeName(t, x.tc) + // defer func() { fmt.Printf(">>>> ####: genTypeName: t: %v, name: '%s'\n", t, n) }() + + // if the type has a PkgPath, which doesn't match the current package, + // then include it. + // We cannot depend on t.String() because it includes current package, + // or t.PkgPath because it includes full import path, + // + var ptrPfx string + for t.Kind() == reflect.Ptr { + ptrPfx += "*" + t = t.Elem() + } + if tn := t.Name(); tn != "" { + return ptrPfx + x.genTypeNamePrim(t) + } + switch t.Kind() { + case reflect.Map: + return ptrPfx + "map[" + x.genTypeName(t.Key()) + "]" + x.genTypeName(t.Elem()) + case reflect.Slice: + return ptrPfx + "[]" + x.genTypeName(t.Elem()) + case reflect.Array: + return ptrPfx + "[" + strconv.FormatInt(int64(t.Len()), 10) + "]" + x.genTypeName(t.Elem()) + case reflect.Chan: + return ptrPfx + t.ChanDir().String() + " " + x.genTypeName(t.Elem()) + default: + if t == intfTyp { + return ptrPfx + "interface{}" + } else { + return ptrPfx + x.genTypeNamePrim(t) + } + } +} + +func (x *genRunner) genTypeNamePrim(t reflect.Type) (n string) { + if t.Name() == "" { + return t.String() + } else if genImportPath(t) == "" || genImportPath(t) == genImportPath(x.tc) { + return t.Name() + } else { + return x.imn[genImportPath(t)] + "." + t.Name() + // return t.String() // best way to get the package name inclusive + } +} + +func (x *genRunner) genZeroValueR(t reflect.Type) string { + // if t is a named type, w + switch t.Kind() { + case reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func, + reflect.Slice, reflect.Map, reflect.Invalid: + return "nil" + case reflect.Bool: + return "false" + case reflect.String: + return `""` + case reflect.Struct, reflect.Array: + return x.genTypeName(t) + "{}" + default: // all numbers + return "0" + } } func (x *genRunner) genMethodNameT(t reflect.Type) (s string) { @@ -368,16 +509,16 @@ func (x *genRunner) selfer(encode bool) { if encode { x.line(") CodecEncodeSelf(e *" + x.cpfx + "Encoder) {") x.genRequiredMethodVars(true) - // x.enc("x", t) - x.encVar("x", t) + // x.enc(genTopLevelVarName, t) + x.encVar(genTopLevelVarName, t) } else { x.line(") CodecDecodeSelf(d *" + x.cpfx + "Decoder) {") x.genRequiredMethodVars(false) // do not use decVar, as there is no need to check TryDecodeAsNil // or way to elegantly handle that, and also setting it to a // non-nil value doesn't affect the pointer passed. - // x.decVar("x", t, false) - x.dec("x", t0) + // x.decVar(genTopLevelVarName, t, false) + x.dec(genTopLevelVarName, t0) } x.line("}") x.line("") @@ -391,21 +532,21 @@ func (x *genRunner) selfer(encode bool) { x.out(fnSigPfx) x.line(") codecDecodeSelfFromMap(l int, d *" + x.cpfx + "Decoder) {") x.genRequiredMethodVars(false) - x.decStructMap("x", "l", reflect.ValueOf(t0).Pointer(), t0, 0) + x.decStructMap(genTopLevelVarName, "l", reflect.ValueOf(t0).Pointer(), t0, genStructMapStyleConsolidated) x.line("}") x.line("") } else { x.out(fnSigPfx) x.line(") codecDecodeSelfFromMapLenPrefix(l int, d *" + x.cpfx + "Decoder) {") x.genRequiredMethodVars(false) - x.decStructMap("x", "l", reflect.ValueOf(t0).Pointer(), t0, 1) + x.decStructMap(genTopLevelVarName, "l", reflect.ValueOf(t0).Pointer(), t0, genStructMapStyleLenPrefix) x.line("}") x.line("") x.out(fnSigPfx) x.line(") codecDecodeSelfFromMapCheckBreak(l int, d *" + x.cpfx + "Decoder) {") x.genRequiredMethodVars(false) - x.decStructMap("x", "l", reflect.ValueOf(t0).Pointer(), t0, 2) + x.decStructMap(genTopLevelVarName, "l", reflect.ValueOf(t0).Pointer(), t0, genStructMapStyleCheckBreak) x.line("}") x.line("") } @@ -414,7 +555,7 @@ func (x *genRunner) selfer(encode bool) { x.out(fnSigPfx) x.line(") codecDecodeSelfFromArray(l int, d *" + x.cpfx + "Decoder) {") x.genRequiredMethodVars(false) - x.decStructArray("x", "l", "return", reflect.ValueOf(t0).Pointer(), t0) + x.decStructArray(genTopLevelVarName, "l", "return", reflect.ValueOf(t0).Pointer(), t0) x.line("}") x.line("") @@ -424,17 +565,38 @@ func (x *genRunner) selfer(encode bool) { func (x *genRunner) xtraSM(varname string, encode bool, t reflect.Type) { if encode { x.linef("h.enc%s((%s%s)(%s), e)", x.genMethodNameT(t), x.arr2str(t, "*"), x.genTypeName(t), varname) - // x.line("h.enc" + x.genMethodNameT(t) + "(" + x.genTypeName(t) + "(" + varname + "), e)") } else { x.linef("h.dec%s((*%s)(%s), d)", x.genMethodNameT(t), x.genTypeName(t), varname) - // x.line("h.dec" + x.genMethodNameT(t) + "((*" + x.genTypeName(t) + ")(" + varname + "), d)") } - x.ts[t] = struct{}{} + x.registerXtraT(t) +} + +func (x *genRunner) registerXtraT(t reflect.Type) { + // recursively register the types + if _, ok := x.tm[t]; ok { + return + } + var tkey reflect.Type + switch t.Kind() { + case reflect.Chan, reflect.Slice, reflect.Array: + case reflect.Map: + tkey = t.Key() + default: + return + } + x.tm[t] = struct{}{} + x.ts = append(x.ts, t) + // check if this refers to any xtra types eg. a slice of array: add the array + x.registerXtraT(t.Elem()) + if tkey != nil { + x.registerXtraT(tkey) + } } // encVar will encode a variable. // The parameter, t, is the reflect.Type of the variable itself func (x *genRunner) encVar(varname string, t reflect.Type) { + // fmt.Printf(">>>>>> varname: %s, t: %v\n", varname, t) var checkNil bool switch t.Kind() { case reflect.Ptr, reflect.Interface, reflect.Slice, reflect.Map, reflect.Chan: @@ -467,49 +629,115 @@ func (x *genRunner) encVar(varname string, t reflect.Type) { } -// enc will encode a variable (varname) of type T, -// except t is of kind reflect.Struct or reflect.Array, wherein varname is of type *T (to prevent copying) +// enc will encode a variable (varname) of type t, +// except t is of kind reflect.Struct or reflect.Array, wherein varname is of type ptrTo(T) (to prevent copying) func (x *genRunner) enc(varname string, t reflect.Type) { - // varName here must be to a pointer to a struct, or to a value directly. rtid := reflect.ValueOf(t).Pointer() // We call CodecEncodeSelf if one of the following are honored: // - the type already implements Selfer, call that // - the type has a Selfer implementation just created, use that // - the type is in the list of the ones we will generate for, but it is not currently being generated - if t.Implements(selferTyp) { - x.line(varname + ".CodecEncodeSelf(e)") - return - } - if t.Kind() == reflect.Struct && reflect.PtrTo(t).Implements(selferTyp) { - x.line(varname + ".CodecEncodeSelf(e)") - return - } - if _, ok := x.te[rtid]; ok { - x.line(varname + ".CodecEncodeSelf(e)") - return + + mi := x.varsfx() + tptr := reflect.PtrTo(t) + tk := t.Kind() + if x.checkForSelfer(t, varname) { + if tk == reflect.Array || tk == reflect.Struct { // varname is of type *T + if tptr.Implements(selferTyp) || t.Implements(selferTyp) { + x.line(varname + ".CodecEncodeSelf(e)") + return + } + } else { // varname is of type T + if t.Implements(selferTyp) { + x.line(varname + ".CodecEncodeSelf(e)") + return + } else if tptr.Implements(selferTyp) { + x.linef("%ssf%s := &%s", genTempVarPfx, mi, varname) + x.linef("%ssf%s.CodecEncodeSelf(e)", genTempVarPfx, mi) + return + } + } + + if _, ok := x.te[rtid]; ok { + x.line(varname + ".CodecEncodeSelf(e)") + return + } } inlist := false for _, t0 := range x.t { if t == t0 { inlist = true - if t != x.tc { + if x.checkForSelfer(t, varname) { x.line(varname + ".CodecEncodeSelf(e)") return } break } } + var rtidAdded bool if t == x.tc { x.te[rtid] = true rtidAdded = true } + // check if + // - type is RawExt + // - the type implements (Text|JSON|Binary)(Unm|M)arshal + x.linef("%sm%s := z.EncBinary()", genTempVarPfx, mi) + x.linef("_ = %sm%s", genTempVarPfx, mi) + x.line("if false {") //start if block + defer func() { x.line("}") }() //end if block + + if t == rawExtTyp { + x.linef("} else { r.EncodeRawExt(%v, e)", varname) + return + } + // HACK: Support for Builtins. + // Currently, only Binc supports builtins, and the only builtin type is time.Time. + // Have a method that returns the rtid for time.Time if Handle is Binc. + if t == timeTyp { + vrtid := genTempVarPfx + "m" + x.varsfx() + x.linef("} else if %s := z.TimeRtidIfBinc(); %s != 0 { ", vrtid, vrtid) + x.linef("r.EncodeBuiltin(%s, %s)", vrtid, varname) + } + // only check for extensions if the type is named, and has a packagePath. + if genImportPath(t) != "" && t.Name() != "" { + // first check if extensions are configued, before doing the interface conversion + x.linef("} else if z.HasExtensions() && z.EncExt(%s) {", varname) + } + if tk == reflect.Array || tk == reflect.Struct { // varname is of type *T + if t.Implements(binaryMarshalerTyp) || tptr.Implements(binaryMarshalerTyp) { + x.linef("} else if %sm%s { z.EncBinaryMarshal(%v) ", genTempVarPfx, mi, varname) + } + if t.Implements(jsonMarshalerTyp) || tptr.Implements(jsonMarshalerTyp) { + x.linef("} else if !%sm%s && z.IsJSONHandle() { z.EncJSONMarshal(%v) ", genTempVarPfx, mi, varname) + } else if t.Implements(textMarshalerTyp) || tptr.Implements(textMarshalerTyp) { + x.linef("} else if !%sm%s { z.EncTextMarshal(%v) ", genTempVarPfx, mi, varname) + } + } else { // varname is of type T + if t.Implements(binaryMarshalerTyp) { + x.linef("} else if %sm%s { z.EncBinaryMarshal(%v) ", genTempVarPfx, mi, varname) + } else if tptr.Implements(binaryMarshalerTyp) { + x.linef("} else if %sm%s { z.EncBinaryMarshal(&%v) ", genTempVarPfx, mi, varname) + } + if t.Implements(jsonMarshalerTyp) { + x.linef("} else if !%sm%s && z.IsJSONHandle() { z.EncJSONMarshal(%v) ", genTempVarPfx, mi, varname) + } else if tptr.Implements(jsonMarshalerTyp) { + x.linef("} else if !%sm%s && z.IsJSONHandle() { z.EncJSONMarshal(&%v) ", genTempVarPfx, mi, varname) + } else if t.Implements(textMarshalerTyp) { + x.linef("} else if !%sm%s { z.EncTextMarshal(%v) ", genTempVarPfx, mi, varname) + } else if tptr.Implements(textMarshalerTyp) { + x.linef("} else if !%sm%s { z.EncTextMarshal(&%v) ", genTempVarPfx, mi, varname) + } + } + x.line("} else {") + switch t.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: x.line("r.EncodeInt(int64(" + varname + "))") - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: x.line("r.EncodeUint(uint64(" + varname + "))") case reflect.Float32: x.line("r.EncodeFloat32(float32(" + varname + "))") @@ -534,7 +762,7 @@ func (x *genRunner) enc(varname string, t reflect.Type) { if rtid == uint8SliceTypId { x.line("r.EncodeStringBytes(codecSelferC_RAW" + x.xs + ", []byte(" + varname + "))") } else if fastpathAV.index(rtid) != -1 { - g := genV{Slice: true, Elem: x.genTypeName(t.Elem())} + g := x.newGenV(t) x.line("z.F." + g.MethodNamePfx("Enc", false) + "V(" + varname + ", false, e)") } else { x.xtraSM(varname, true, t) @@ -548,9 +776,7 @@ func (x *genRunner) enc(varname string, t reflect.Type) { // - else call Encoder.encode(XXX) on it. // x.line("if " + varname + " == nil { \nr.EncodeNil()\n } else { ") if fastpathAV.index(rtid) != -1 { - g := genV{Slice: false, - Elem: x.genTypeName(t.Elem()), - MapKey: x.genTypeName(t.Key())} + g := x.newGenV(t) x.line("z.F." + g.MethodNamePfx("Enc", false) + "V(" + varname + ", false, e)") } else { x.xtraSM(varname, true, t) @@ -575,7 +801,7 @@ func (x *genRunner) encZero(t reflect.Type) { switch t.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: x.line("r.EncodeInt(0)") - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: x.line("r.EncodeUint(0)") case reflect.Float32: x.line("r.EncodeFloat32(0)") @@ -595,24 +821,22 @@ func (x *genRunner) encStruct(varname string, rtid uintptr, t reflect.Type) { // replicate code in kStruct i.e. for each field, deref type to non-pointer, and call x.enc on it // if t === type currently running selfer on, do for all - ti := getTypeInfo(rtid, t) + ti := x.ti.get(rtid, t) i := x.varsfx() sepVarname := genTempVarPfx + "sep" + i - firstVarname := genTempVarPfx + "first" + i numfieldsvar := genTempVarPfx + "q" + i ti2arrayvar := genTempVarPfx + "r" + i struct2arrvar := genTempVarPfx + "2arr" + i x.line(sepVarname + " := !z.EncBinary()") x.linef("%s := z.EncBasicHandle().StructToArray", struct2arrvar) - x.line("var " + firstVarname + " bool") tisfi := ti.sfip // always use sequence from file. decStruct expects same thing. // due to omitEmpty, we need to calculate the // number of non-empty things we write out first. // This is required as we need to pre-determine the size of the container, // to support length-prefixing. x.linef("var %s [%v]bool", numfieldsvar, len(tisfi)) - x.linef("_, _, _, _ = %s, %s, %s, %s", sepVarname, firstVarname, numfieldsvar, struct2arrvar) + x.linef("_, _, _ = %s, %s, %s", sepVarname, numfieldsvar, struct2arrvar) x.linef("const %s bool = %v", ti2arrayvar, ti.toArray) nn := 0 for j, si := range tisfi { @@ -647,16 +871,18 @@ func (x *genRunner) encStruct(varname string, rtid uintptr, t reflect.Type) { case reflect.Map, reflect.Slice, reflect.Array, reflect.Chan: omitline += "len(" + varname + "." + t2.Name + ") != 0" default: - omitline += varname + "." + t2.Name + " != " + genZeroValueR(t2.Type, x.tc) + omitline += varname + "." + t2.Name + " != " + x.genZeroValueR(t2.Type) } x.linef("%s[%v] = %s", numfieldsvar, j, omitline) } + x.linef("var %snn%s int", genTempVarPfx, i) x.linef("if %s || %s {", ti2arrayvar, struct2arrvar) // if ti.toArray { x.line("r.EncodeArrayStart(" + strconv.FormatInt(int64(len(tisfi)), 10) + ")") x.linef("} else {") // if not ti.toArray - x.linef("var %snn%s int = %v", genTempVarPfx, i, nn) + x.linef("%snn%s = %v", genTempVarPfx, i, nn) x.linef("for _, b := range %s { if b { %snn%s++ } }", numfieldsvar, genTempVarPfx, i) x.linef("r.EncodeMapStart(%snn%s)", genTempVarPfx, i) + x.linef("%snn%s = %v", genTempVarPfx, i, 0) // x.line("r.EncodeMapStart(" + strconv.FormatInt(int64(len(tisfi)), 10) + ")") x.line("}") // close if not StructToArray @@ -697,19 +923,12 @@ func (x *genRunner) encStruct(varname string, rtid uintptr, t reflect.Type) { // if the type of the field is a Selfer, or one of the ones x.linef("if %s || %s {", ti2arrayvar, struct2arrvar) // if ti.toArray - if j > 0 { - x.line("if " + sepVarname + " {") - x.line("r.EncodeArrayEntrySeparator()") - x.line("}") - } if labelUsed { x.line("if " + isNilVarName + " { r.EncodeNil() } else { ") } + x.linef("z.EncSendContainerState(codecSelfer_containerArrayElem%s)", x.xs) if si.omitEmpty { x.linef("if %s[%v] {", numfieldsvar, j) - // omitEmptyVarNameX := genTempVarPfx + "ov" + i - // x.line("var " + omitEmptyVarNameX + " " + x.genTypeName(t2.Type)) - // x.encVar(omitEmptyVarNameX, t2.Type) } x.encVar(varname+"."+t2.Name, t2.Type) if si.omitEmpty { @@ -720,30 +939,15 @@ func (x *genRunner) encStruct(varname string, rtid uintptr, t reflect.Type) { if labelUsed { x.line("}") } + x.linef("} else {") // if not ti.toArray - // omitEmptyVar := genTempVarPfx + "x" + i + t2.Name - // x.line("const " + omitEmptyVar + " bool = " + strconv.FormatBool(si.omitEmpty)) - // doOmitEmpty := si.omitEmpty && t2.Type.Kind() != reflect.Struct + if si.omitEmpty { x.linef("if %s[%v] {", numfieldsvar, j) - // x.linef(`println("Encoding field: %v")`, j) - // x.out("if ") - // if labelUsed { - // x.out("!" + isNilVarName + " && ") - // } - // x.line(varname + "." + t2.Name + " != " + genZeroValueR(t2.Type, x.tc) + " {") } - if j == 0 { - x.linef("%s = true", firstVarname) - } else { - x.linef("if %s { r.EncodeMapEntrySeparator() } else { %s = true }", firstVarname, firstVarname) - } - - // x.line("r.EncodeString(codecSelferC_UTF8" + x.xs + ", string(\"" + t2.Name + "\"))") + x.linef("z.EncSendContainerState(codecSelfer_containerMapKey%s)", x.xs) x.line("r.EncodeString(codecSelferC_UTF8" + x.xs + ", string(\"" + si.encName + "\"))") - x.line("if " + sepVarname + " {") - x.line("r.EncodeMapKVSeparator()") - x.line("}") + x.linef("z.EncSendContainerState(codecSelfer_containerMapValue%s)", x.xs) if labelUsed { x.line("if " + isNilVarName + " { r.EncodeNil() } else { ") x.encVar(varname+"."+t2.Name, t2.Type) @@ -756,69 +960,44 @@ func (x *genRunner) encStruct(varname string, rtid uintptr, t reflect.Type) { } x.linef("} ") // end if/else ti.toArray } - x.line("if " + sepVarname + " {") x.linef("if %s || %s {", ti2arrayvar, struct2arrvar) // if ti.toArray { - x.line("r.EncodeArrayEnd()") - x.linef("} else {") // if not ti.toArray - x.line("r.EncodeMapEnd()") - x.linef("} ") // end if/else ti.toArray + x.linef("z.EncSendContainerState(codecSelfer_containerArrayEnd%s)", x.xs) + x.line("} else {") + x.linef("z.EncSendContainerState(codecSelfer_containerMapEnd%s)", x.xs) x.line("}") + } func (x *genRunner) encListFallback(varname string, t reflect.Type) { i := x.varsfx() g := genTempVarPfx x.line("r.EncodeArrayStart(len(" + varname + "))") - x.line(genTempVarPfx + "s" + i + " := !z.EncBinary()") - x.line("if " + genTempVarPfx + "s" + i + " {") if t.Kind() == reflect.Chan { x.linef("for %si%s, %si2%s := 0, len(%s); %si%s < %si2%s; %si%s++ {", g, i, g, i, varname, g, i, g, i, g, i) + x.linef("z.EncSendContainerState(codecSelfer_containerArrayElem%s)", x.xs) x.linef("%sv%s := <-%s", g, i, varname) } else { - x.linef("for %si%s, %sv%s := range %s {", genTempVarPfx, i, genTempVarPfx, i, varname) - } - x.linef("if %si%s > 0 { r.EncodeArrayEntrySeparator() }", genTempVarPfx, i) - x.encVar(genTempVarPfx+"v"+i, t.Elem()) - x.line("}") - x.line("r.EncodeArrayEnd()") - x.line("} else {") - if t.Kind() == reflect.Chan { - x.linef("for %si%s, %si2%s := 0, len(%s); %si%s < %si2%s; %si%s++ {", g, i, g, i, varname, g, i, g, i, g, i) - x.linef("%sv%s := <-%s", g, i, varname) - } else { - x.line("for _, " + genTempVarPfx + "v" + i + " := range " + varname + " {") + // x.linef("for %si%s, %sv%s := range %s {", genTempVarPfx, i, genTempVarPfx, i, varname) + x.linef("for _, %sv%s := range %s {", genTempVarPfx, i, varname) + x.linef("z.EncSendContainerState(codecSelfer_containerArrayElem%s)", x.xs) } x.encVar(genTempVarPfx+"v"+i, t.Elem()) x.line("}") - x.line("}") + x.linef("z.EncSendContainerState(codecSelfer_containerArrayEnd%s)", x.xs) } func (x *genRunner) encMapFallback(varname string, t reflect.Type) { + // TODO: expand this to handle canonical. i := x.varsfx() x.line("r.EncodeMapStart(len(" + varname + "))") - x.line(genTempVarPfx + "s" + i + " := !z.EncBinary()") - - x.line(genTempVarPfx + "j" + i + " := 0") - - x.line("if " + genTempVarPfx + "s" + i + " {") - - x.line("for " + genTempVarPfx + "k" + i + ", " + - genTempVarPfx + "v" + i + " := range " + varname + " {") - x.line("if " + genTempVarPfx + "j" + i + " > 0 { r.EncodeMapEntrySeparator() }") - x.encVar(genTempVarPfx+"k"+i, t.Key()) - x.line("r.EncodeMapKVSeparator()") - x.encVar(genTempVarPfx+"v"+i, t.Elem()) - x.line(genTempVarPfx + "j" + i + "++") - x.line("}") - x.line("r.EncodeMapEnd()") - - x.line("} else {") x.linef("for %sk%s, %sv%s := range %s {", genTempVarPfx, i, genTempVarPfx, i, varname) + // x.line("for " + genTempVarPfx + "k" + i + ", " + genTempVarPfx + "v" + i + " := range " + varname + " {") + x.linef("z.EncSendContainerState(codecSelfer_containerMapKey%s)", x.xs) x.encVar(genTempVarPfx+"k"+i, t.Key()) + x.linef("z.EncSendContainerState(codecSelfer_containerMapValue%s)", x.xs) x.encVar(genTempVarPfx+"v"+i, t.Elem()) x.line("}") - - x.line("}") + x.linef("z.EncSendContainerState(codecSelfer_containerMapEnd%s)", x.xs) } func (x *genRunner) decVar(varname string, t reflect.Type, canBeNil bool) { @@ -836,23 +1015,17 @@ func (x *genRunner) decVar(varname string, t reflect.Type, canBeNil bool) { x.line("if r.TryDecodeAsNil() {") if t.Kind() == reflect.Ptr { x.line("if " + varname + " != nil { ") - // x.line("var " + genTempVarPfx + i + " " + x.genTypeName(t.Elem())) - // x.line("*" + varname + " = " + genTempVarPfx + i) // if varname is a field of a struct (has a dot in it), // then just set it to nil if strings.IndexByte(varname, '.') != -1 { x.line(varname + " = nil") } else { - x.line("*" + varname + " = " + genZeroValueR(t.Elem(), x.tc)) + x.line("*" + varname + " = " + x.genZeroValueR(t.Elem())) } - // x.line("*" + varname + " = nil") x.line("}") - } else { - // x.line("var " + genTempVarPfx + i + " " + x.genTypeName(t)) - // x.line(varname + " = " + genTempVarPfx + i) - x.line(varname + " = " + genZeroValueR(t, x.tc)) + x.line(varname + " = " + x.genZeroValueR(t)) } x.line("} else {") } else { @@ -894,38 +1067,82 @@ func (x *genRunner) decVar(varname string, t reflect.Type, canBeNil bool) { } } +// dec will decode a variable (varname) of type ptrTo(t). +// t is always a basetype (i.e. not of kind reflect.Ptr). func (x *genRunner) dec(varname string, t reflect.Type) { // assumptions: // - the varname is to a pointer already. No need to take address of it - + // - t is always a baseType T (not a *T, etc). rtid := reflect.ValueOf(t).Pointer() - if t.Implements(selferTyp) || (t.Kind() == reflect.Struct && - reflect.PtrTo(t).Implements(selferTyp)) { - x.line(varname + ".CodecDecodeSelf(d)") - return - } - if _, ok := x.td[rtid]; ok { - x.line(varname + ".CodecDecodeSelf(d)") - return + tptr := reflect.PtrTo(t) + if x.checkForSelfer(t, varname) { + if t.Implements(selferTyp) || tptr.Implements(selferTyp) { + x.line(varname + ".CodecDecodeSelf(d)") + return + } + if _, ok := x.td[rtid]; ok { + x.line(varname + ".CodecDecodeSelf(d)") + return + } } inlist := false for _, t0 := range x.t { if t == t0 { inlist = true - if t != x.tc { + if x.checkForSelfer(t, varname) { x.line(varname + ".CodecDecodeSelf(d)") return } break } } + var rtidAdded bool if t == x.tc { x.td[rtid] = true rtidAdded = true } + // check if + // - type is RawExt + // - the type implements (Text|JSON|Binary)(Unm|M)arshal + mi := x.varsfx() + x.linef("%sm%s := z.DecBinary()", genTempVarPfx, mi) + x.linef("_ = %sm%s", genTempVarPfx, mi) + x.line("if false {") //start if block + defer func() { x.line("}") }() //end if block + + if t == rawExtTyp { + x.linef("} else { r.DecodeExt(%v, 0, nil)", varname) + return + } + + // HACK: Support for Builtins. + // Currently, only Binc supports builtins, and the only builtin type is time.Time. + // Have a method that returns the rtid for time.Time if Handle is Binc. + if t == timeTyp { + vrtid := genTempVarPfx + "m" + x.varsfx() + x.linef("} else if %s := z.TimeRtidIfBinc(); %s != 0 { ", vrtid, vrtid) + x.linef("r.DecodeBuiltin(%s, %s)", vrtid, varname) + } + // only check for extensions if the type is named, and has a packagePath. + if genImportPath(t) != "" && t.Name() != "" { + // first check if extensions are configued, before doing the interface conversion + x.linef("} else if z.HasExtensions() && z.DecExt(%s) {", varname) + } + + if t.Implements(binaryUnmarshalerTyp) || tptr.Implements(binaryUnmarshalerTyp) { + x.linef("} else if %sm%s { z.DecBinaryUnmarshal(%v) ", genTempVarPfx, mi, varname) + } + if t.Implements(jsonUnmarshalerTyp) || tptr.Implements(jsonUnmarshalerTyp) { + x.linef("} else if !%sm%s && z.IsJSONHandle() { z.DecJSONUnmarshal(%v)", genTempVarPfx, mi, varname) + } else if t.Implements(textUnmarshalerTyp) || tptr.Implements(textUnmarshalerTyp) { + x.linef("} else if !%sm%s { z.DecTextUnmarshal(%v)", genTempVarPfx, mi, varname) + } + + x.line("} else {") + // Since these are pointers, we cannot share, and have to use them one by one switch t.Kind() { case reflect.Int: @@ -959,6 +1176,8 @@ func (x *genRunner) dec(varname string, t reflect.Type) { case reflect.Uint64: x.line("*((*uint64)(" + varname + ")) = uint64(r.DecodeUint(64))") //x.line("z.DecUint64((*uint64)(" + varname + "))") + case reflect.Uintptr: + x.line("*((*uintptr)(" + varname + ")) = uintptr(r.DecodeUint(codecSelferBitsize" + x.xs + "))") case reflect.Float32: x.line("*((*float32)(" + varname + ")) = float32(r.DecodeFloat(true))") @@ -985,10 +1204,8 @@ func (x *genRunner) dec(varname string, t reflect.Type) { if rtid == uint8SliceTypId { x.line("*" + varname + " = r.DecodeBytes(*(*[]byte)(" + varname + "), false, false)") } else if fastpathAV.index(rtid) != -1 { - g := genV{Slice: true, Elem: x.genTypeName(t.Elem())} + g := x.newGenV(t) x.line("z.F." + g.MethodNamePfx("Dec", false) + "X(" + varname + ", false, d)") - // x.line("z." + g.MethodNamePfx("Dec", false) + "(" + varname + ")") - // x.line(g.FastpathName(false) + "(" + varname + ", d)") } else { x.xtraSM(varname, false, t) // x.decListFallback(varname, rtid, false, t) @@ -999,10 +1216,8 @@ func (x *genRunner) dec(varname string, t reflect.Type) { // - if elements are primitives or Selfers, call dedicated function on each member. // - else call Encoder.encode(XXX) on it. if fastpathAV.index(rtid) != -1 { - g := genV{Slice: false, Elem: x.genTypeName(t.Elem()), MapKey: x.genTypeName(t.Key())} + g := x.newGenV(t) x.line("z.F." + g.MethodNamePfx("Dec", false) + "X(" + varname + ", false, d)") - // x.line("z." + g.MethodNamePfx("Dec", false) + "(" + varname + ")") - // x.line(g.FastpathName(false) + "(" + varname + ", d)") } else { x.xtraSM(varname, false, t) // x.decMapFallback(varname, rtid, t) @@ -1037,10 +1252,10 @@ func (x *genRunner) decTryAssignPrimitive(varname string, t reflect.Type) (tryAs // Consequently, we replace: // case reflect.Uint32: x.line(varname + " = uint32(r.DecodeUint(32))") // with: - // case reflect.Uint32: x.line(varname + " = " + genTypeNamePrimitiveKind(t, x.tc) + "(r.DecodeUint(32))") + // case reflect.Uint32: x.line(varname + " = " + genTypeNamePrim(t, x.tc) + "(r.DecodeUint(32))") xfn := func(t reflect.Type) string { - return genTypeNamePrimitiveKind(t, x.tc) + return x.genTypeNamePrim(t) } switch t.Kind() { case reflect.Int: @@ -1064,6 +1279,8 @@ func (x *genRunner) decTryAssignPrimitive(varname string, t reflect.Type) (tryAs x.linef("%s = %s(r.DecodeUint(32))", varname, xfn(t)) case reflect.Uint64: x.linef("%s = %s(r.DecodeUint(64))", varname, xfn(t)) + case reflect.Uintptr: + x.linef("%s = %s(r.DecodeUint(codecSelferBitsize%s))", varname, xfn(t), x.xs) case reflect.Float32: x.linef("%s = %s(r.DecodeFloat(true))", varname, xfn(t)) @@ -1088,11 +1305,13 @@ func (x *genRunner) decListFallback(varname string, rtid uintptr, t reflect.Type CTyp string Typ string Immutable bool + Size int } telem := t.Elem() - ts := tstruc{genTempVarPfx, x.varsfx(), varname, x.genTypeName(t), x.genTypeName(telem), genIsImmutable(telem)} + ts := tstruc{genTempVarPfx, x.varsfx(), varname, x.genTypeName(t), x.genTypeName(telem), genIsImmutable(telem), int(telem.Size())} funcs := make(template.FuncMap) + funcs["decLineVar"] = func(varname string) string { x.decVar(varname, telem, false) return "" @@ -1105,7 +1324,7 @@ func (x *genRunner) decListFallback(varname string, rtid uintptr, t reflect.Type return ts.TempVar + s + ts.Rand } funcs["zero"] = func() string { - return genZeroValueR(telem, x.tc) + return x.genZeroValueR(telem) } funcs["isArray"] = func() bool { return t.Kind() == reflect.Array @@ -1128,15 +1347,33 @@ func (x *genRunner) decListFallback(varname string, rtid uintptr, t reflect.Type func (x *genRunner) decMapFallback(varname string, rtid uintptr, t reflect.Type) { type tstruc struct { TempVar string + Sfx string Rand string Varname string KTyp string Typ string + Size int } telem := t.Elem() tkey := t.Key() - ts := tstruc{genTempVarPfx, x.varsfx(), varname, x.genTypeName(tkey), x.genTypeName(telem)} + ts := tstruc{ + genTempVarPfx, x.xs, x.varsfx(), varname, x.genTypeName(tkey), + x.genTypeName(telem), int(telem.Size() + tkey.Size()), + } + funcs := make(template.FuncMap) + funcs["decElemZero"] = func() string { + return x.genZeroValueR(telem) + } + funcs["decElemKindImmutable"] = func() bool { + return genIsImmutable(telem) + } + funcs["decElemKindPtr"] = func() bool { + return telem.Kind() == reflect.Ptr + } + funcs["decElemKindIntf"] = func() bool { + return telem.Kind() == reflect.Interface + } funcs["decLineVarK"] = func(varname string) string { x.decVar(varname, tkey, false) return "" @@ -1167,7 +1404,7 @@ func (x *genRunner) decMapFallback(varname string, rtid uintptr, t reflect.Type) } func (x *genRunner) decStructMapSwitch(kName string, varname string, rtid uintptr, t reflect.Type) { - ti := getTypeInfo(rtid, t) + ti := x.ti.get(rtid, t) tisfi := ti.sfip // always use sequence from file. decStruct expects same thing. x.line("switch (" + kName + ") {") for _, si := range tisfi { @@ -1176,6 +1413,7 @@ func (x *genRunner) decStructMapSwitch(kName string, varname string, rtid uintpt if si.i != -1 { t2 = t.Field(int(si.i)) } else { + //we must accomodate anonymous fields, where the embedded field is a nil pointer in the value. // t2 = t.FieldByIndex(si.is) t2typ := t varname3 := varname @@ -1187,8 +1425,7 @@ func (x *genRunner) decStructMapSwitch(kName string, varname string, rtid uintpt t2typ = t2.Type varname3 = varname3 + "." + t2.Name if t2typ.Kind() == reflect.Ptr { - x.line("if " + varname3 + " == nil {" + - varname3 + " = new(" + x.genTypeName(t2typ.Elem()) + ") }") + x.linef("if %s == nil { %s = new(%s) }", varname3, varname3, x.genTypeName(t2typ.Elem())) } } } @@ -1197,11 +1434,10 @@ func (x *genRunner) decStructMapSwitch(kName string, varname string, rtid uintpt x.line("default:") // pass the slice here, so that the string will not escape, and maybe save allocation x.line("z.DecStructFieldNotFound(-1, " + kName + ")") - // x.line("z.DecStructFieldNotFoundB(" + kName + "Slc)") x.line("} // end switch " + kName) } -func (x *genRunner) decStructMap(varname, lenvarname string, rtid uintptr, t reflect.Type, style uint8) { +func (x *genRunner) decStructMap(varname, lenvarname string, rtid uintptr, t reflect.Type, style genStructMapStyle) { tpfx := genTempVarPfx i := x.varsfx() kName := tpfx + "s" + i @@ -1223,28 +1459,21 @@ func (x *genRunner) decStructMap(varname, lenvarname string, rtid uintptr, t ref x.line("var " + kName + "Slc = z.DecScratchBuffer() // default slice to decode into") - // x.line("var " + kName + " string // default string to decode into") - // x.line("_ = " + kName) x.line("_ = " + kName + "Slc") - // x.linef("var %sb%s bool", tpfx, i) // break switch style { - case 1: + case genStructMapStyleLenPrefix: x.linef("for %sj%s := 0; %sj%s < %s; %sj%s++ {", tpfx, i, tpfx, i, lenvarname, tpfx, i) - case 2: + case genStructMapStyleCheckBreak: x.linef("for %sj%s := 0; !r.CheckBreak(); %sj%s++ {", tpfx, i, tpfx, i) - x.linef("if %sj%s > 0 { r.ReadMapEntrySeparator() }", tpfx, i) default: // 0, otherwise. x.linef("var %shl%s bool = %s >= 0", tpfx, i, lenvarname) // has length x.linef("for %sj%s := 0; ; %sj%s++ {", tpfx, i, tpfx, i) x.linef("if %shl%s { if %sj%s >= %s { break }", tpfx, i, tpfx, i, lenvarname) - x.linef("} else { if r.CheckBreak() { break }; if %sj%s > 0 { r.ReadMapEntrySeparator() } }", - tpfx, i) + x.line("} else { if r.CheckBreak() { break }; }") } - // x.line(kName + " = z.ReadStringAsBytes(" + kName + ")") - // x.line(kName + " = z.ReadString()") + x.linef("z.DecSendContainerState(codecSelfer_containerMapKey%s)", x.xs) x.line(kName + "Slc = r.DecodeBytes(" + kName + "Slc, true, true)") // let string be scoped to this loop alone, so it doesn't escape. - // x.line(kName + " := " + x.cpfx + "GenBytesToStringRO(" + kName + "Slc)") if x.unsafe { x.line(kName + "SlcHdr := codecSelferUnsafeString" + x.xs + "{uintptr(unsafe.Pointer(&" + kName + "Slc[0])), len(" + kName + "Slc)}") @@ -1252,53 +1481,50 @@ func (x *genRunner) decStructMap(varname, lenvarname string, rtid uintptr, t ref } else { x.line(kName + " := string(" + kName + "Slc)") } - switch style { - case 1: - case 2: - x.line("r.ReadMapKVSeparator()") - default: - x.linef("if !%shl%s { r.ReadMapKVSeparator() }", tpfx, i) - } + x.linef("z.DecSendContainerState(codecSelfer_containerMapValue%s)", x.xs) x.decStructMapSwitch(kName, varname, rtid, t) x.line("} // end for " + tpfx + "j" + i) - switch style { - case 1: - case 2: - x.line("r.ReadMapEnd()") - default: - x.linef("if !%shl%s { r.ReadMapEnd() }", tpfx, i) - } + x.linef("z.DecSendContainerState(codecSelfer_containerMapEnd%s)", x.xs) } func (x *genRunner) decStructArray(varname, lenvarname, breakString string, rtid uintptr, t reflect.Type) { tpfx := genTempVarPfx i := x.varsfx() - ti := getTypeInfo(rtid, t) + ti := x.ti.get(rtid, t) tisfi := ti.sfip // always use sequence from file. decStruct expects same thing. x.linef("var %sj%s int", tpfx, i) - x.linef("var %sb%s bool", tpfx, i) // break - // x.linef("var %sl%s := r.ReadArrayStart()", tpfx, i) + x.linef("var %sb%s bool", tpfx, i) // break x.linef("var %shl%s bool = %s >= 0", tpfx, i, lenvarname) // has length - for j, si := range tisfi { + for _, si := range tisfi { var t2 reflect.StructField if si.i != -1 { t2 = t.Field(int(si.i)) } else { - t2 = t.FieldByIndex(si.is) + //we must accomodate anonymous fields, where the embedded field is a nil pointer in the value. + // t2 = t.FieldByIndex(si.is) + t2typ := t + varname3 := varname + for _, ix := range si.is { + for t2typ.Kind() == reflect.Ptr { + t2typ = t2typ.Elem() + } + t2 = t2typ.Field(ix) + t2typ = t2.Type + varname3 = varname3 + "." + t2.Name + if t2typ.Kind() == reflect.Ptr { + x.linef("if %s == nil { %s = new(%s) }", varname3, varname3, x.genTypeName(t2typ.Elem())) + } + } } x.linef("%sj%s++; if %shl%s { %sb%s = %sj%s > %s } else { %sb%s = r.CheckBreak() }", tpfx, i, tpfx, i, tpfx, i, tpfx, i, lenvarname, tpfx, i) - // x.line("if " + tpfx + "j" + i + "++; " + tpfx + "j" + - // i + " <= " + tpfx + "l" + i + " {") - x.linef("if %sb%s { r.ReadArrayEnd(); %s }", tpfx, i, breakString) - if j > 0 { - x.line("r.ReadArrayEntrySeparator()") - } + x.linef("if %sb%s { z.DecSendContainerState(codecSelfer_containerArrayEnd%s); %s }", + tpfx, i, x.xs, breakString) + x.linef("z.DecSendContainerState(codecSelfer_containerArrayElem%s)", x.xs) x.decVar(varname+"."+t2.Name, t2.Type, true) - // x.line("} // end if " + tpfx + "j" + i + " <= " + tpfx + "l" + i) } // read remaining values and throw away. x.line("for {") @@ -1306,20 +1532,20 @@ func (x *genRunner) decStructArray(varname, lenvarname, breakString string, rtid tpfx, i, tpfx, i, tpfx, i, tpfx, i, lenvarname, tpfx, i) x.linef("if %sb%s { break }", tpfx, i) - x.linef("if %sj%s > 1 { r.ReadArrayEntrySeparator() }", tpfx, i) + x.linef("z.DecSendContainerState(codecSelfer_containerArrayElem%s)", x.xs) x.linef(`z.DecStructFieldNotFound(%sj%s - 1, "")`, tpfx, i) x.line("}") - x.line("r.ReadArrayEnd()") + x.linef("z.DecSendContainerState(codecSelfer_containerArrayEnd%s)", x.xs) } func (x *genRunner) decStruct(varname string, rtid uintptr, t reflect.Type) { // if container is map - // x.line("if z.DecContainerIsMap() { ") i := x.varsfx() - x.line("if r.IsContainerType(codecSelverValueTypeMap" + x.xs + ") {") + x.linef("%sct%s := r.ContainerType()", genTempVarPfx, i) + x.linef("if %sct%s == codecSelferValueTypeMap%s {", genTempVarPfx, i, x.xs) x.line(genTempVarPfx + "l" + i + " := r.ReadMapStart()") x.linef("if %sl%s == 0 {", genTempVarPfx, i) - x.line("r.ReadMapEnd()") + x.linef("z.DecSendContainerState(codecSelfer_containerMapEnd%s)", x.xs) if genUseOneFunctionForDecStructMap { x.line("} else { ") x.linef("x.codecDecodeSelfFromMap(%sl%s, d)", genTempVarPfx, i) @@ -1332,29 +1558,44 @@ func (x *genRunner) decStruct(varname string, rtid uintptr, t reflect.Type) { x.line("}") // else if container is array - // x.line("} else if z.DecContainerIsArray() { ") - x.line("} else if r.IsContainerType(codecSelverValueTypeArray" + x.xs + ") {") + x.linef("} else if %sct%s == codecSelferValueTypeArray%s {", genTempVarPfx, i, x.xs) x.line(genTempVarPfx + "l" + i + " := r.ReadArrayStart()") x.linef("if %sl%s == 0 {", genTempVarPfx, i) - x.line("r.ReadArrayEnd()") + x.linef("z.DecSendContainerState(codecSelfer_containerArrayEnd%s)", x.xs) x.line("} else { ") x.linef("x.codecDecodeSelfFromArray(%sl%s, d)", genTempVarPfx, i) x.line("}") // else panic x.line("} else { ") x.line("panic(codecSelferOnlyMapOrArrayEncodeToStructErr" + x.xs + ")") - // x.line("panic(`only encoded map or array can be decoded into a struct`)") x.line("} ") } // -------- type genV struct { - // genV is either a primitive (Primitive != "") or a slice (Slice = true) or a map. - Slice bool + // genV is either a primitive (Primitive != "") or a map (MapKey != "") or a slice MapKey string Elem string Primitive string + Size int +} + +func (x *genRunner) newGenV(t reflect.Type) (v genV) { + switch t.Kind() { + case reflect.Slice, reflect.Array: + te := t.Elem() + v.Elem = x.genTypeName(te) + v.Size = int(te.Size()) + case reflect.Map: + te, tk := t.Elem(), t.Key() + v.Elem = x.genTypeName(te) + v.MapKey = x.genTypeName(tk) + v.Size = int(te.Size() + tk.Size()) + default: + panic("unexpected type for newGenV. Requires map or slice type") + } + return } func (x *genV) MethodNamePfx(prefix string, prim bool) string { @@ -1365,7 +1606,7 @@ func (x *genV) MethodNamePfx(prefix string, prim bool) string { if prim { name = append(name, genTitleCaseName(x.Primitive)...) } else { - if x.Slice { + if x.MapKey == "" { name = append(name, "Slice"...) } else { name = append(name, "Map"...) @@ -1377,6 +1618,49 @@ func (x *genV) MethodNamePfx(prefix string, prim bool) string { } +var genCheckVendor = os.Getenv("GO15VENDOREXPERIMENT") == "1" + +// genImportPath returns import path of a non-predeclared named typed, or an empty string otherwise. +// +// This handles the misbehaviour that occurs when 1.5-style vendoring is enabled, +// where PkgPath returns the full path, including the vendoring pre-fix that should have been stripped. +// We strip it here. +func genImportPath(t reflect.Type) (s string) { + s = t.PkgPath() + if genCheckVendor { + // HACK: Misbehaviour occurs in go 1.5. May have to re-visit this later. + // if s contains /vendor/ OR startsWith vendor/, then return everything after it. + const vendorStart = "vendor/" + const vendorInline = "/vendor/" + if i := strings.LastIndex(s, vendorInline); i >= 0 { + s = s[i+len(vendorInline):] + } else if strings.HasPrefix(s, vendorStart) { + s = s[len(vendorStart):] + } + } + return +} + +// A go identifier is (letter|_)[letter|number|_]* +func genGoIdentifier(s string, checkFirstChar bool) string { + b := make([]byte, 0, len(s)) + t := make([]byte, 4) + var n int + for i, r := range s { + if checkFirstChar && i == 0 && !unicode.IsLetter(r) { + b = append(b, '_') + } + // r must be unicode_letter, unicode_digit or _ + if unicode.IsLetter(r) || unicode.IsDigit(r) { + n = utf8.EncodeRune(t, r) + b = append(b, t[:n]...) + } else { + b = append(b, '_') + } + } + return string(b) +} + func genNonPtr(t reflect.Type) reflect.Type { for t.Kind() == reflect.Ptr { t = t.Elem() @@ -1393,59 +1677,17 @@ func genTitleCaseName(s string) string { } } -func genTypeNamePrimitiveKind(t reflect.Type, tRef reflect.Type) (n string) { - if tRef != nil && t.PkgPath() == tRef.PkgPath() && t.Name() != "" { - return t.Name() - } else { - return t.String() // best way to get the package name inclusive - } -} - -func genTypeName(t reflect.Type, tRef reflect.Type) (n string) { - // defer func() { fmt.Printf(">>>> ####: genTypeName: t: %v, name: '%s'\n", t, n) }() - - // if the type has a PkgPath, which doesn't match the current package, - // then include it. - // We cannot depend on t.String() because it includes current package, - // or t.PkgPath because it includes full import path, - // - var ptrPfx string - for t.Kind() == reflect.Ptr { - ptrPfx += "*" - t = t.Elem() - } - if tn := t.Name(); tn != "" { - return ptrPfx + genTypeNamePrimitiveKind(t, tRef) - } - switch t.Kind() { - case reflect.Map: - return ptrPfx + "map[" + genTypeName(t.Key(), tRef) + "]" + genTypeName(t.Elem(), tRef) - case reflect.Slice: - return ptrPfx + "[]" + genTypeName(t.Elem(), tRef) - case reflect.Array: - return ptrPfx + "[" + strconv.FormatInt(int64(t.Len()), 10) + "]" + genTypeName(t.Elem(), tRef) - case reflect.Chan: - return ptrPfx + t.ChanDir().String() + " " + genTypeName(t.Elem(), tRef) - default: - if t == intfTyp { - return ptrPfx + "interface{}" - } else { - return ptrPfx + genTypeNamePrimitiveKind(t, tRef) - } - } -} - func genMethodNameT(t reflect.Type, tRef reflect.Type) (n string) { var ptrPfx string for t.Kind() == reflect.Ptr { ptrPfx += "Ptrto" t = t.Elem() } + tstr := t.String() if tn := t.Name(); tn != "" { - if tRef != nil && t.PkgPath() == tRef.PkgPath() { + if tRef != nil && genImportPath(t) == genImportPath(tRef) { return ptrPfx + tn } else { - tstr := t.String() if genQNameRegex.MatchString(tstr) { return ptrPfx + strings.Replace(tstr, ".", "_", 1000) } else { @@ -1475,17 +1717,16 @@ func genMethodNameT(t reflect.Type, tRef reflect.Type) (n string) { if t == intfTyp { return ptrPfx + "Interface" } else { - if tRef != nil && t.PkgPath() == tRef.PkgPath() { + if tRef != nil && genImportPath(t) == genImportPath(tRef) { if t.Name() != "" { return ptrPfx + t.Name() } else { - return ptrPfx + genCustomTypeName(t.String()) + return ptrPfx + genCustomTypeName(tstr) } } else { // best way to get the package name inclusive - // return ptrPfx + strings.Replace(t.String(), ".", "_", 1000) - // return ptrPfx + genBase64enc.EncodeToString([]byte(t.String())) - tstr := t.String() + // return ptrPfx + strings.Replace(tstr, ".", "_", 1000) + // return ptrPfx + genBase64enc.EncodeToString([]byte(tstr)) if t.Name() != "" && genQNameRegex.MatchString(tstr) { return ptrPfx + strings.Replace(tstr, ".", "_", 1000) } else { @@ -1513,24 +1754,7 @@ func genCustomTypeName(tstr string) string { } func genIsImmutable(t reflect.Type) (v bool) { - return isMutableKind(t.Kind()) -} - -func genZeroValueR(t reflect.Type, tRef reflect.Type) string { - // if t is a named type, w - switch t.Kind() { - case reflect.Ptr, reflect.Interface, reflect.Chan, reflect.Func, - reflect.Slice, reflect.Map, reflect.Invalid: - return "nil" - case reflect.Bool: - return "false" - case reflect.String: - return `""` - case reflect.Struct, reflect.Array: - return genTypeName(t, tRef) + "{}" - default: // all numbers - return "0" - } + return isImmutableKind(t.Kind()) } type genInternal struct { @@ -1593,6 +1817,8 @@ func genInternalDecCommandAsString(s string) string { return "uint32(dd.DecodeUint(32))" case "uint64": return "dd.DecodeUint(64)" + case "uintptr": + return "uintptr(dd.DecodeUint(uintBitsize))" case "int": return "int(dd.DecodeInt(intBitsize))" case "int8": @@ -1613,9 +1839,24 @@ func genInternalDecCommandAsString(s string) string { case "bool": return "dd.DecodeBool()" default: - panic(errors.New("unknown type for decode: " + s)) + panic(errors.New("gen internal: unknown type for decode: " + s)) } +} +func genInternalSortType(s string, elem bool) string { + for _, v := range [...]string{"int", "uint", "float", "bool", "string"} { + if strings.HasPrefix(s, v) { + if elem { + if v == "int" || v == "uint" || v == "float" { + return v + "64" + } else { + return v + } + } + return v + "Slice" + } + } + panic("sorttype: unexpected type: " + s) } // var genInternalMu sync.Mutex @@ -1634,6 +1875,7 @@ func genInternalInit() { "uint16", "uint32", "uint64", + "uintptr", "int", "int8", "int16", @@ -1651,6 +1893,7 @@ func genInternalInit() { "uint16", "uint32", "uint64", + "uintptr", "int", "int8", "int16", @@ -1660,23 +1903,39 @@ func genInternalInit() { "float64", "bool", } - mapvaltypes2 := make(map[string]bool) - for _, s := range mapvaltypes { - mapvaltypes2[s] = true + wordSizeBytes := int(intBitsize) / 8 + + mapvaltypes2 := map[string]int{ + "interface{}": 2 * wordSizeBytes, + "string": 2 * wordSizeBytes, + "uint": 1 * wordSizeBytes, + "uint8": 1, + "uint16": 2, + "uint32": 4, + "uint64": 8, + "uintptr": 1 * wordSizeBytes, + "int": 1 * wordSizeBytes, + "int8": 1, + "int16": 2, + "int32": 4, + "int64": 8, + "float32": 4, + "float64": 8, + "bool": 1, } var gt genInternal // For each slice or map type, there must be a (symetrical) Encode and Decode fast-path function for _, s := range types { - gt.Values = append(gt.Values, genV{false, "", "", s}) + gt.Values = append(gt.Values, genV{Primitive: s, Size: mapvaltypes2[s]}) if s != "uint8" { // do not generate fast path for slice of bytes. Treat specially already. - gt.Values = append(gt.Values, genV{true, "", s, ""}) + gt.Values = append(gt.Values, genV{Elem: s, Size: mapvaltypes2[s]}) } - if !mapvaltypes2[s] { - gt.Values = append(gt.Values, genV{false, s, s, ""}) + if _, ok := mapvaltypes2[s]; !ok { + gt.Values = append(gt.Values, genV{MapKey: s, Elem: s, Size: 2 * mapvaltypes2[s]}) } for _, ms := range mapvaltypes { - gt.Values = append(gt.Values, genV{false, s, ms, ""}) + gt.Values = append(gt.Values, genV{MapKey: s, Elem: ms, Size: mapvaltypes2[s] + mapvaltypes2[ms]}) } } @@ -1685,16 +1944,18 @@ func genInternalInit() { funcs["encmd"] = genInternalEncCommandAsString funcs["decmd"] = genInternalDecCommandAsString funcs["zerocmd"] = genInternalZeroValue + funcs["hasprefix"] = strings.HasPrefix + funcs["sorttype"] = genInternalSortType genInternalV = gt genInternalTmplFuncs = funcs } -// GenInternalGoFile is used to generate source files from templates. +// genInternalGoFile is used to generate source files from templates. // It is run by the program author alone. // Unfortunately, it has to be exported so that it can be called from a command line tool. // *** DO NOT USE *** -func GenInternalGoFile(r io.Reader, w io.Writer, safe bool) (err error) { +func genInternalGoFile(r io.Reader, w io.Writer, safe bool) (err error) { genInternalOnce.Do(genInternalInit) gt := genInternalV diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/helper.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/helper.go index 7848ea1..40065a0 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/helper.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/helper.go @@ -101,6 +101,7 @@ package codec // check for these error conditions. import ( + "bytes" "encoding" "encoding/binary" "errors" @@ -111,12 +112,11 @@ import ( "strings" "sync" "time" - "unicode" - "unicode/utf8" ) const ( scratchByteArrayLen = 32 + initCollectionCap = 32 // 32 is defensive. 16 is preferred. // Support encoding.(Binary|Text)(Unm|M)arshaler. // This constant flag will enable or disable it. @@ -147,10 +147,18 @@ const ( // if derefForIsEmptyValue, deref pointers and interfaces when checking isEmptyValue derefForIsEmptyValue = false + + // if resetSliceElemToZeroValue, then on decoding a slice, reset the element to a zero value first. + // Only concern is that, if the slice already contained some garbage, we will decode into that garbage. + // The chances of this are slim, so leave this "optimization". + // TODO: should this be true, to ensure that we always decode into a "zero" "empty" value? + resetSliceElemToZeroValue bool = false ) -var oneByteArr = [1]byte{0} -var zeroByteSlice = oneByteArr[:0:0] +var ( + oneByteArr = [1]byte{0} + zeroByteSlice = oneByteArr[:0:0] +) type charEncoding uint8 @@ -193,16 +201,61 @@ const ( seqTypeChan ) +// note that containerMapStart and containerArraySend are not sent. +// This is because the ReadXXXStart and EncodeXXXStart already does these. +type containerState uint8 + +const ( + _ containerState = iota + + containerMapStart // slot left open, since Driver method already covers it + containerMapKey + containerMapValue + containerMapEnd + containerArrayStart // slot left open, since Driver methods already cover it + containerArrayElem + containerArrayEnd +) + +type rgetPoolT struct { + encNames [8]string + fNames [8]string + etypes [8]uintptr + sfis [8]*structFieldInfo +} + +var rgetPool = sync.Pool{ + New: func() interface{} { return new(rgetPoolT) }, +} + +type rgetT struct { + fNames []string + encNames []string + etypes []uintptr + sfis []*structFieldInfo +} + +type containerStateRecv interface { + sendContainerState(containerState) +} + +// mirror json.Marshaler and json.Unmarshaler here, +// so we don't import the encoding/json package +type jsonMarshaler interface { + MarshalJSON() ([]byte, error) +} +type jsonUnmarshaler interface { + UnmarshalJSON([]byte) error +} + var ( bigen = binary.BigEndian structInfoFieldName = "_struct" - cachedTypeInfo = make(map[uintptr]*typeInfo, 64) - cachedTypeInfoMutex sync.RWMutex - - // mapStrIntfTyp = reflect.TypeOf(map[string]interface{}(nil)) - intfSliceTyp = reflect.TypeOf([]interface{}(nil)) - intfTyp = intfSliceTyp.Elem() + mapStrIntfTyp = reflect.TypeOf(map[string]interface{}(nil)) + mapIntfIntfTyp = reflect.TypeOf(map[interface{}]interface{}(nil)) + intfSliceTyp = reflect.TypeOf([]interface{}(nil)) + intfTyp = intfSliceTyp.Elem() stringTyp = reflect.TypeOf("") timeTyp = reflect.TypeOf(time.Time{}) @@ -217,6 +270,9 @@ var ( textMarshalerTyp = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() textUnmarshalerTyp = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem() + jsonMarshalerTyp = reflect.TypeOf((*jsonMarshaler)(nil)).Elem() + jsonUnmarshalerTyp = reflect.TypeOf((*jsonUnmarshaler)(nil)).Elem() + selferTyp = reflect.TypeOf((*Selfer)(nil)).Elem() uint8SliceTypId = reflect.ValueOf(uint8SliceTyp).Pointer() @@ -225,6 +281,9 @@ var ( timeTypId = reflect.ValueOf(timeTyp).Pointer() stringTypId = reflect.ValueOf(stringTyp).Pointer() + mapStrIntfTypId = reflect.ValueOf(mapStrIntfTyp).Pointer() + mapIntfIntfTypId = reflect.ValueOf(mapIntfIntfTyp).Pointer() + intfSliceTypId = reflect.ValueOf(intfSliceTyp).Pointer() // mapBySliceTypId = reflect.ValueOf(mapBySliceTyp).Pointer() intBitsize uint8 = uint8(reflect.TypeOf(int(0)).Bits()) @@ -238,6 +297,8 @@ var ( noFieldNameToStructFieldInfoErr = errors.New("no field name passed to parseStructFieldInfo") ) +var defTypeInfos = NewTypeInfos([]string{"codec", "json"}) + // Selfer defines methods by which a value can encode or decode itself. // // Any type which implements Selfer will be able to encode or decode itself. @@ -263,6 +324,11 @@ type MapBySlice interface { // // BasicHandle encapsulates the common options and extension functions. type BasicHandle struct { + // TypeInfos is used to get the type info for any type. + // + // If not configured, the default TypeInfos is used, which uses struct tag keys: codec, json + TypeInfos *TypeInfos + extHandle EncodeOptions DecodeOptions @@ -272,6 +338,13 @@ func (x *BasicHandle) getBasicHandle() *BasicHandle { return x } +func (x *BasicHandle) getTypeInfo(rtid uintptr, rt reflect.Type) (pti *typeInfo) { + if x.TypeInfos != nil { + return x.TypeInfos.get(rtid, rt) + } + return defTypeInfos.get(rtid, rt) +} + // Handle is the interface for a specific encoding format. // // Typically, a Handle is pre-configured before first time use, @@ -298,33 +371,45 @@ type RawExt struct { Value interface{} } -// Ext handles custom (de)serialization of custom types / extensions. -type Ext interface { +// BytesExt handles custom (de)serialization of types to/from []byte. +// It is used by codecs (e.g. binc, msgpack, simple) which do custom serialization of the types. +type BytesExt interface { // WriteExt converts a value to a []byte. - // It is used by codecs (e.g. binc, msgpack, simple) which do custom serialization of the types. + // + // Note: v *may* be a pointer to the extension type, if the extension type was a struct or array. WriteExt(v interface{}) []byte // ReadExt updates a value from a []byte. - // It is used by codecs (e.g. binc, msgpack, simple) which do custom serialization of the types. ReadExt(dst interface{}, src []byte) +} +// InterfaceExt handles custom (de)serialization of types to/from another interface{} value. +// The Encoder or Decoder will then handle the further (de)serialization of that known type. +// +// It is used by codecs (e.g. cbor, json) which use the format to do custom serialization of the types. +type InterfaceExt interface { // ConvertExt converts a value into a simpler interface for easy encoding e.g. convert time.Time to int64. - // It is used by codecs (e.g. cbor) which use the format to do custom serialization of the types. + // + // Note: v *may* be a pointer to the extension type, if the extension type was a struct or array. ConvertExt(v interface{}) interface{} // UpdateExt updates a value from a simpler interface for easy decoding e.g. convert int64 to time.Time. - // It is used by codecs (e.g. cbor) which use the format to do custom serialization of the types. UpdateExt(dst interface{}, src interface{}) } -// bytesExt is a wrapper implementation to support former AddExt exported method. -type bytesExt struct { +// Ext handles custom (de)serialization of custom types / extensions. +type Ext interface { + BytesExt + InterfaceExt +} + +// addExtWrapper is a wrapper implementation to support former AddExt exported method. +type addExtWrapper struct { encFn func(reflect.Value) ([]byte, error) decFn func(reflect.Value, []byte) error } -func (x bytesExt) WriteExt(v interface{}) []byte { - // fmt.Printf(">>>>>>>>>> WriteExt: %T, %v\n", v, v) +func (x addExtWrapper) WriteExt(v interface{}) []byte { bs, err := x.encFn(reflect.ValueOf(v)) if err != nil { panic(err) @@ -332,21 +417,56 @@ func (x bytesExt) WriteExt(v interface{}) []byte { return bs } -func (x bytesExt) ReadExt(v interface{}, bs []byte) { - // fmt.Printf(">>>>>>>>>> ReadExt: %T, %v\n", v, v) +func (x addExtWrapper) ReadExt(v interface{}, bs []byte) { if err := x.decFn(reflect.ValueOf(v), bs); err != nil { panic(err) } } -func (x bytesExt) ConvertExt(v interface{}) interface{} { +func (x addExtWrapper) ConvertExt(v interface{}) interface{} { return x.WriteExt(v) } -func (x bytesExt) UpdateExt(dest interface{}, v interface{}) { +func (x addExtWrapper) UpdateExt(dest interface{}, v interface{}) { x.ReadExt(dest, v.([]byte)) } +type setExtWrapper struct { + b BytesExt + i InterfaceExt +} + +func (x *setExtWrapper) WriteExt(v interface{}) []byte { + if x.b == nil { + panic("BytesExt.WriteExt is not supported") + } + return x.b.WriteExt(v) +} + +func (x *setExtWrapper) ReadExt(v interface{}, bs []byte) { + if x.b == nil { + panic("BytesExt.WriteExt is not supported") + + } + x.b.ReadExt(v, bs) +} + +func (x *setExtWrapper) ConvertExt(v interface{}) interface{} { + if x.i == nil { + panic("InterfaceExt.ConvertExt is not supported") + + } + return x.i.ConvertExt(v) +} + +func (x *setExtWrapper) UpdateExt(dest interface{}, v interface{}) { + if x.i == nil { + panic("InterfaceExxt.UpdateExt is not supported") + + } + x.i.UpdateExt(dest, v) +} + // type errorString string // func (x errorString) Error() string { return string(x) } @@ -399,9 +519,9 @@ type extTypeTagFn struct { ext Ext } -type extHandle []*extTypeTagFn +type extHandle []extTypeTagFn -// DEPRECATED: AddExt is deprecated in favor of SetExt. It exists for compatibility only. +// DEPRECATED: Use SetBytesExt or SetInterfaceExt on the Handle instead. // // AddExt registes an encode and decode function for a reflect.Type. // AddExt internally calls SetExt. @@ -413,10 +533,10 @@ func (o *extHandle) AddExt( if encfn == nil || decfn == nil { return o.SetExt(rt, uint64(tag), nil) } - return o.SetExt(rt, uint64(tag), bytesExt{encfn, decfn}) + return o.SetExt(rt, uint64(tag), addExtWrapper{encfn, decfn}) } -// SetExt registers a tag and Ext for a reflect.Type. +// DEPRECATED: Use SetBytesExt or SetInterfaceExt on the Handle instead. // // Note that the type must be a named type, and specifically not // a pointer or Interface. An error is returned if that is not honored. @@ -438,12 +558,17 @@ func (o *extHandle) SetExt(rt reflect.Type, tag uint64, ext Ext) (err error) { } } - *o = append(*o, &extTypeTagFn{rtid, rt, tag, ext}) + if *o == nil { + *o = make([]extTypeTagFn, 0, 4) + } + *o = append(*o, extTypeTagFn{rtid, rt, tag, ext}) return } func (o extHandle) getExt(rtid uintptr) *extTypeTagFn { - for _, v := range o { + var v *extTypeTagFn + for i := range o { + v = &o[i] if v.rtid == rtid { return v } @@ -452,7 +577,9 @@ func (o extHandle) getExt(rtid uintptr) *extTypeTagFn { } func (o extHandle) getExtForTag(tag uint64) *extTypeTagFn { - for _, v := range o { + var v *extTypeTagFn + for i := range o { + v = &o[i] if v.tag == tag { return v } @@ -471,6 +598,10 @@ type structFieldInfo struct { toArray bool // if field is _struct, is the toArray set? } +// func (si *structFieldInfo) isZero() bool { +// return si.encName == "" && len(si.is) == 0 && si.i == 0 && !si.omitEmpty && !si.toArray +// } + // rv returns the field of the struct. // If anonymous, it returns an Invalid func (si *structFieldInfo) field(v reflect.Value, update bool) (rv2 reflect.Value) { @@ -516,9 +647,9 @@ func (si *structFieldInfo) setToZeroValue(v reflect.Value) { } func parseStructFieldInfo(fname string, stag string) *structFieldInfo { - if fname == "" { - panic(noFieldNameToStructFieldInfoErr) - } + // if fname == "" { + // panic(noFieldNameToStructFieldInfoErr) + // } si := structFieldInfo{ encName: fname, } @@ -571,6 +702,8 @@ type typeInfo struct { rt reflect.Type rtid uintptr + numMeth uint16 // number of methods + // baseId gives pointer to the base reflect.Type, after deferencing // the pointers. E.g. base type of ***time.Time is time.Time. base reflect.Type @@ -589,6 +722,11 @@ type typeInfo struct { tmIndir int8 // number of indirections to get to textMarshaler type tunmIndir int8 // number of indirections to get to textUnmarshaler type + jm bool // base type (T or *T) is a jsonMarshaler + junm bool // base type (T or *T) is a jsonUnmarshaler + jmIndir int8 // number of indirections to get to jsonMarshaler type + junmIndir int8 // number of indirections to get to jsonUnmarshaler type + cs bool // base type (T or *T) is a Selfer csIndir int8 // number of indirections to get to Selfer type @@ -623,33 +761,49 @@ func (ti *typeInfo) indexForEncName(name string) int { return -1 } -func getStructTag(t reflect.StructTag) (s string) { +// TypeInfos caches typeInfo for each type on first inspection. +// +// It is configured with a set of tag keys, which are used to get +// configuration for the type. +type TypeInfos struct { + infos map[uintptr]*typeInfo + mu sync.RWMutex + tags []string +} + +// NewTypeInfos creates a TypeInfos given a set of struct tags keys. +// +// This allows users customize the struct tag keys which contain configuration +// of their types. +func NewTypeInfos(tags []string) *TypeInfos { + return &TypeInfos{tags: tags, infos: make(map[uintptr]*typeInfo, 64)} +} + +func (x *TypeInfos) structTag(t reflect.StructTag) (s string) { // check for tags: codec, json, in that order. // this allows seamless support for many configured structs. - s = t.Get("codec") - if s == "" { - s = t.Get("json") + for _, x := range x.tags { + s = t.Get(x) + if s != "" { + return s + } } return } -func getTypeInfo(rtid uintptr, rt reflect.Type) (pti *typeInfo) { +func (x *TypeInfos) get(rtid uintptr, rt reflect.Type) (pti *typeInfo) { var ok bool - cachedTypeInfoMutex.RLock() - pti, ok = cachedTypeInfo[rtid] - cachedTypeInfoMutex.RUnlock() + x.mu.RLock() + pti, ok = x.infos[rtid] + x.mu.RUnlock() if ok { return } - cachedTypeInfoMutex.Lock() - defer cachedTypeInfoMutex.Unlock() - if pti, ok = cachedTypeInfo[rtid]; ok { - return - } - + // do not hold lock while computing this. + // it may lead to duplication, but that's ok. ti := typeInfo{rt: rt, rtid: rtid} - pti = &ti + ti.numMeth = uint16(rt.NumMethod()) var indir int8 if ok, indir = implementsIntf(rt, binaryMarshalerTyp); ok { @@ -664,6 +818,12 @@ func getTypeInfo(rtid uintptr, rt reflect.Type) (pti *typeInfo) { if ok, indir = implementsIntf(rt, textUnmarshalerTyp); ok { ti.tunm, ti.tunmIndir = true, indir } + if ok, indir = implementsIntf(rt, jsonMarshalerTyp); ok { + ti.jm, ti.jmIndir = true, indir + } + if ok, indir = implementsIntf(rt, jsonUnmarshalerTyp); ok { + ti.junm, ti.junmIndir = true, indir + } if ok, indir = implementsIntf(rt, selferTyp); ok { ti.cs, ti.csIndir = true, indir } @@ -690,67 +850,131 @@ func getTypeInfo(rtid uintptr, rt reflect.Type) (pti *typeInfo) { if rt.Kind() == reflect.Struct { var siInfo *structFieldInfo if f, ok := rt.FieldByName(structInfoFieldName); ok { - siInfo = parseStructFieldInfo(structInfoFieldName, getStructTag(f.Tag)) + siInfo = parseStructFieldInfo(structInfoFieldName, x.structTag(f.Tag)) ti.toArray = siInfo.toArray } - sfip := make([]*structFieldInfo, 0, rt.NumField()) - rgetTypeInfo(rt, nil, make(map[string]bool, 16), &sfip, siInfo) - - ti.sfip = make([]*structFieldInfo, len(sfip)) - ti.sfi = make([]*structFieldInfo, len(sfip)) - copy(ti.sfip, sfip) - sort.Sort(sfiSortedByEncName(sfip)) - copy(ti.sfi, sfip) + pi := rgetPool.Get() + pv := pi.(*rgetPoolT) + pv.etypes[0] = ti.baseId + vv := rgetT{pv.fNames[:0], pv.encNames[:0], pv.etypes[:1], pv.sfis[:0]} + x.rget(rt, rtid, nil, &vv, siInfo) + ti.sfip = make([]*structFieldInfo, len(vv.sfis)) + ti.sfi = make([]*structFieldInfo, len(vv.sfis)) + copy(ti.sfip, vv.sfis) + sort.Sort(sfiSortedByEncName(vv.sfis)) + copy(ti.sfi, vv.sfis) + rgetPool.Put(pi) } // sfi = sfip - cachedTypeInfo[rtid] = pti + + x.mu.Lock() + if pti, ok = x.infos[rtid]; !ok { + pti = &ti + x.infos[rtid] = pti + } + x.mu.Unlock() return } -func rgetTypeInfo(rt reflect.Type, indexstack []int, fnameToHastag map[string]bool, - sfi *[]*structFieldInfo, siInfo *structFieldInfo, +func (x *TypeInfos) rget(rt reflect.Type, rtid uintptr, + indexstack []int, pv *rgetT, siInfo *structFieldInfo, ) { - for j := 0; j < rt.NumField(); j++ { + // This will read up the fields and store how to access the value. + // It uses the go language's rules for embedding, as below: + // - if a field has been seen while traversing, skip it + // - if an encName has been seen while traversing, skip it + // - if an embedded type has been seen, skip it + // + // Also, per Go's rules, embedded fields must be analyzed AFTER all top-level fields. + // + // Note: we consciously use slices, not a map, to simulate a set. + // Typically, types have < 16 fields, and iteration using equals is faster than maps there + + type anonField struct { + ft reflect.Type + idx int + } + + var anonFields []anonField + +LOOP: + for j, jlen := 0, rt.NumField(); j < jlen; j++ { f := rt.Field(j) - // func types are skipped. - if tk := f.Type.Kind(); tk == reflect.Func { + fkind := f.Type.Kind() + // skip if a func type, or is unexported, or structTag value == "-" + switch fkind { + case reflect.Func, reflect.Complex64, reflect.Complex128, reflect.UnsafePointer: + continue LOOP + } + + // if r1, _ := utf8.DecodeRuneInString(f.Name); r1 == utf8.RuneError || !unicode.IsUpper(r1) { + if f.PkgPath != "" && !f.Anonymous { // unexported, not embedded continue } - stag := getStructTag(f.Tag) + stag := x.structTag(f.Tag) if stag == "-" { continue } - if r1, _ := utf8.DecodeRuneInString(f.Name); r1 == utf8.RuneError || !unicode.IsUpper(r1) { - continue - } - // if anonymous and there is no struct tag and its a struct (or pointer to struct), inline it. - if f.Anonymous && stag == "" { - ft := f.Type - for ft.Kind() == reflect.Ptr { - ft = ft.Elem() + var si *structFieldInfo + // if anonymous and no struct tag (or it's blank), and a struct (or pointer to struct), inline it. + if f.Anonymous && fkind != reflect.Interface { + doInline := stag == "" + if !doInline { + si = parseStructFieldInfo("", stag) + doInline = si.encName == "" + // doInline = si.isZero() } - if ft.Kind() == reflect.Struct { - indexstack2 := make([]int, len(indexstack)+1, len(indexstack)+4) - copy(indexstack2, indexstack) - indexstack2[len(indexstack)] = j - // indexstack2 := append(append(make([]int, 0, len(indexstack)+4), indexstack...), j) - rgetTypeInfo(ft, indexstack2, fnameToHastag, sfi, siInfo) - continue + if doInline { + ft := f.Type + for ft.Kind() == reflect.Ptr { + ft = ft.Elem() + } + if ft.Kind() == reflect.Struct { + // handle anonymous fields after handling all the non-anon fields + anonFields = append(anonFields, anonField{ft, j}) + continue + } } } - // do not let fields with same name in embedded structs override field at higher level. - // this must be done after anonymous check, to allow anonymous field - // still include their child fields - if _, ok := fnameToHastag[f.Name]; ok { + + // after the anonymous dance: if an unexported field, skip + if f.PkgPath != "" { // unexported continue } - si := parseStructFieldInfo(f.Name, stag) + + if f.Name == "" { + panic(noFieldNameToStructFieldInfoErr) + } + + for _, k := range pv.fNames { + if k == f.Name { + continue LOOP + } + } + pv.fNames = append(pv.fNames, f.Name) + + if si == nil { + si = parseStructFieldInfo(f.Name, stag) + } else if si.encName == "" { + si.encName = f.Name + } + + for _, k := range pv.encNames { + if k == si.encName { + continue LOOP + } + } + pv.encNames = append(pv.encNames, si.encName) + // si.ikind = int(f.Type.Kind()) if len(indexstack) == 0 { si.i = int16(j) } else { si.i = -1 - si.is = append(append(make([]int, 0, len(indexstack)+4), indexstack...), j) + si.is = make([]int, len(indexstack)+1) + copy(si.is, indexstack) + si.is[len(indexstack)] = j + // si.is = append(append(make([]int, 0, len(indexstack)+4), indexstack...), j) } if siInfo != nil { @@ -758,8 +982,26 @@ func rgetTypeInfo(rt reflect.Type, indexstack []int, fnameToHastag map[string]bo si.omitEmpty = true } } - *sfi = append(*sfi, si) - fnameToHastag[f.Name] = stag != "" + pv.sfis = append(pv.sfis, si) + } + + // now handle anonymous fields +LOOP2: + for _, af := range anonFields { + // if etypes contains this, then do not call rget again (as the fields are already seen here) + ftid := reflect.ValueOf(af.ft).Pointer() + for _, k := range pv.etypes { + if k == ftid { + continue LOOP2 + } + } + pv.etypes = append(pv.etypes, ftid) + + indexstack2 := make([]int, len(indexstack)+1) + copy(indexstack2, indexstack) + indexstack2[len(indexstack)] = af.idx + // indexstack2 := append(append(make([]int, 0, len(indexstack)+4), indexstack...), j) + x.rget(af.ft, ftid, indexstack2, pv, siInfo) } } @@ -779,8 +1021,9 @@ func panicToErr(err *error) { // panic(fmt.Errorf("%s: "+format, params2...)) // } -func isMutableKind(k reflect.Kind) (v bool) { - return k == reflect.Int || +func isImmutableKind(k reflect.Kind) (v bool) { + return false || + k == reflect.Int || k == reflect.Int8 || k == reflect.Int16 || k == reflect.Int32 || @@ -790,6 +1033,7 @@ func isMutableKind(k reflect.Kind) (v bool) { k == reflect.Uint16 || k == reflect.Uint32 || k == reflect.Uint64 || + k == reflect.Uintptr || k == reflect.Float32 || k == reflect.Float64 || k == reflect.Bool || @@ -844,3 +1088,184 @@ func (_ checkOverflow) SignedInt(v uint64) (i int64, overflow bool) { i = int64(v) return } + +// ------------------ SORT ----------------- + +func isNaN(f float64) bool { return f != f } + +// ----------------------- + +type intSlice []int64 +type uintSlice []uint64 +type floatSlice []float64 +type boolSlice []bool +type stringSlice []string +type bytesSlice [][]byte + +func (p intSlice) Len() int { return len(p) } +func (p intSlice) Less(i, j int) bool { return p[i] < p[j] } +func (p intSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +func (p uintSlice) Len() int { return len(p) } +func (p uintSlice) Less(i, j int) bool { return p[i] < p[j] } +func (p uintSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +func (p floatSlice) Len() int { return len(p) } +func (p floatSlice) Less(i, j int) bool { + return p[i] < p[j] || isNaN(p[i]) && !isNaN(p[j]) +} +func (p floatSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +func (p stringSlice) Len() int { return len(p) } +func (p stringSlice) Less(i, j int) bool { return p[i] < p[j] } +func (p stringSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +func (p bytesSlice) Len() int { return len(p) } +func (p bytesSlice) Less(i, j int) bool { return bytes.Compare(p[i], p[j]) == -1 } +func (p bytesSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +func (p boolSlice) Len() int { return len(p) } +func (p boolSlice) Less(i, j int) bool { return !p[i] && p[j] } +func (p boolSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +// --------------------- + +type intRv struct { + v int64 + r reflect.Value +} +type intRvSlice []intRv +type uintRv struct { + v uint64 + r reflect.Value +} +type uintRvSlice []uintRv +type floatRv struct { + v float64 + r reflect.Value +} +type floatRvSlice []floatRv +type boolRv struct { + v bool + r reflect.Value +} +type boolRvSlice []boolRv +type stringRv struct { + v string + r reflect.Value +} +type stringRvSlice []stringRv +type bytesRv struct { + v []byte + r reflect.Value +} +type bytesRvSlice []bytesRv + +func (p intRvSlice) Len() int { return len(p) } +func (p intRvSlice) Less(i, j int) bool { return p[i].v < p[j].v } +func (p intRvSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +func (p uintRvSlice) Len() int { return len(p) } +func (p uintRvSlice) Less(i, j int) bool { return p[i].v < p[j].v } +func (p uintRvSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +func (p floatRvSlice) Len() int { return len(p) } +func (p floatRvSlice) Less(i, j int) bool { + return p[i].v < p[j].v || isNaN(p[i].v) && !isNaN(p[j].v) +} +func (p floatRvSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +func (p stringRvSlice) Len() int { return len(p) } +func (p stringRvSlice) Less(i, j int) bool { return p[i].v < p[j].v } +func (p stringRvSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +func (p bytesRvSlice) Len() int { return len(p) } +func (p bytesRvSlice) Less(i, j int) bool { return bytes.Compare(p[i].v, p[j].v) == -1 } +func (p bytesRvSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +func (p boolRvSlice) Len() int { return len(p) } +func (p boolRvSlice) Less(i, j int) bool { return !p[i].v && p[j].v } +func (p boolRvSlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +// ----------------- + +type bytesI struct { + v []byte + i interface{} +} + +type bytesISlice []bytesI + +func (p bytesISlice) Len() int { return len(p) } +func (p bytesISlice) Less(i, j int) bool { return bytes.Compare(p[i].v, p[j].v) == -1 } +func (p bytesISlice) Swap(i, j int) { p[i], p[j] = p[j], p[i] } + +// ----------------- + +type set []uintptr + +func (s *set) add(v uintptr) (exists bool) { + // e.ci is always nil, or len >= 1 + // defer func() { fmt.Printf("$$$$$$$$$$$ cirRef Add: %v, exists: %v\n", v, exists) }() + x := *s + if x == nil { + x = make([]uintptr, 1, 8) + x[0] = v + *s = x + return + } + // typically, length will be 1. make this perform. + if len(x) == 1 { + if j := x[0]; j == 0 { + x[0] = v + } else if j == v { + exists = true + } else { + x = append(x, v) + *s = x + } + return + } + // check if it exists + for _, j := range x { + if j == v { + exists = true + return + } + } + // try to replace a "deleted" slot + for i, j := range x { + if j == 0 { + x[i] = v + return + } + } + // if unable to replace deleted slot, just append it. + x = append(x, v) + *s = x + return +} + +func (s *set) remove(v uintptr) (exists bool) { + // defer func() { fmt.Printf("$$$$$$$$$$$ cirRef Rm: %v, exists: %v\n", v, exists) }() + x := *s + if len(x) == 0 { + return + } + if len(x) == 1 { + if x[0] == v { + x[0] = 0 + } + return + } + for i, j := range x { + if j == v { + exists = true + x[i] = 0 // set it to 0, as way to delete it. + // copy(x[i:], x[i+1:]) + // x = x[:len(x)-1] + return + } + } + return +} diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/helper_internal.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/helper_internal.go index c865246..dea981f 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/helper_internal.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/helper_internal.go @@ -149,3 +149,94 @@ func halfFloatToFloatBits(yy uint16) (d uint32) { m = m << 13 return (s << 31) | (e << 23) | m } + +// GrowCap will return a new capacity for a slice, given the following: +// - oldCap: current capacity +// - unit: in-memory size of an element +// - num: number of elements to add +func growCap(oldCap, unit, num int) (newCap int) { + // appendslice logic (if cap < 1024, *2, else *1.25): + // leads to many copy calls, especially when copying bytes. + // bytes.Buffer model (2*cap + n): much better for bytes. + // smarter way is to take the byte-size of the appended element(type) into account + + // maintain 3 thresholds: + // t1: if cap <= t1, newcap = 2x + // t2: if cap <= t2, newcap = 1.75x + // t3: if cap <= t3, newcap = 1.5x + // else newcap = 1.25x + // + // t1, t2, t3 >= 1024 always. + // i.e. if unit size >= 16, then always do 2x or 1.25x (ie t1, t2, t3 are all same) + // + // With this, appending for bytes increase by: + // 100% up to 4K + // 75% up to 8K + // 50% up to 16K + // 25% beyond that + + // unit can be 0 e.g. for struct{}{}; handle that appropriately + var t1, t2, t3 int // thresholds + if unit <= 1 { + t1, t2, t3 = 4*1024, 8*1024, 16*1024 + } else if unit < 16 { + t3 = 16 / unit * 1024 + t1 = t3 * 1 / 4 + t2 = t3 * 2 / 4 + } else { + t1, t2, t3 = 1024, 1024, 1024 + } + + var x int // temporary variable + + // x is multiplier here: one of 5, 6, 7 or 8; incr of 25%, 50%, 75% or 100% respectively + if oldCap <= t1 { // [0,t1] + x = 8 + } else if oldCap > t3 { // (t3,infinity] + x = 5 + } else if oldCap <= t2 { // (t1,t2] + x = 7 + } else { // (t2,t3] + x = 6 + } + newCap = x * oldCap / 4 + + if num > 0 { + newCap += num + } + + // ensure newCap is a multiple of 64 (if it is > 64) or 16. + if newCap > 64 { + if x = newCap % 64; x != 0 { + x = newCap / 64 + newCap = 64 * (x + 1) + } + } else { + if x = newCap % 16; x != 0 { + x = newCap / 16 + newCap = 16 * (x + 1) + } + } + return +} + +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 +} diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/helper_unsafe.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/helper_unsafe.go index d799496..373b2b1 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/helper_unsafe.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/helper_unsafe.go @@ -26,6 +26,9 @@ type unsafeBytes struct { // In unsafe mode, it doesn't incur allocation and copying caused by conversion. // In regular safe mode, it is an allocation and copy. func stringView(v []byte) string { + if len(v) == 0 { + return "" + } x := unsafeString{uintptr(unsafe.Pointer(&v[0])), len(v)} return *(*string)(unsafe.Pointer(&x)) } @@ -34,6 +37,9 @@ func stringView(v []byte) string { // 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 { + if len(v) == 0 { + return zeroByteSlice + } x := unsafeBytes{uintptr(unsafe.Pointer(&v)), len(v), len(v)} return *(*[]byte)(unsafe.Pointer(&x)) } diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/json.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/json.go index cb370d4..a04dfcb 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/json.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/json.go @@ -3,8 +3,9 @@ package codec -// This json support uses base64 encoding for bytes, because you cannot +// By default, this json support uses base64 encoding for bytes, because you cannot // store and read any arbitrary string in json (only unicode). +// However, the user can configre how to encode/decode bytes. // // This library specifically supports UTF-8 for encoding and decoding only. // @@ -27,10 +28,14 @@ package codec // - encode does not beautify. There is no whitespace when encoding. // - rpc calls which take single integer arguments or write single numeric arguments will need care. +// Top-level methods of json(End|Dec)Driver (which are implementations of (en|de)cDriver +// MUST not call one-another. + import ( "bytes" "encoding/base64" "fmt" + "reflect" "strconv" "unicode/utf16" "unicode/utf8" @@ -38,26 +43,32 @@ import ( //-------------------------------- -var jsonLiterals = [...]byte{'t', 'r', 'u', 'e', 'f', 'a', 'l', 's', 'e', 'n', 'u', 'l', 'l'} +var ( + jsonLiterals = [...]byte{'t', 'r', 'u', 'e', 'f', 'a', 'l', 's', 'e', 'n', 'u', 'l', 'l'} -var jsonFloat64Pow10 = [...]float64{ - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, - 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, - 1e20, 1e21, 1e22, -} + jsonFloat64Pow10 = [...]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 jsonUint64Pow10 = [...]uint64{ - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, - 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, -} + jsonUint64Pow10 = [...]uint64{ + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + } + + // jsonTabs and jsonSpaces are used as caches for indents + jsonTabs, jsonSpaces string +) const ( - // if jsonTrackSkipWhitespace, we track Whitespace and reduce the number of redundant checks. - // Make it a const flag, so that it can be elided during linking if false. + // jsonUnreadAfterDecNum controls whether we unread after decoding a number. // - // It is not a clear win, because we continually set a flag behind a pointer - // and then check it each time, as opposed to just 4 conditionals on a stack variable. - jsonTrackSkipWhitespace = true + // instead of unreading, just update d.tok (iff it's not a whitespace char) + // However, doing this means that we may HOLD onto some data which belongs to another stream. + // Thus, it is safest to unread the data when done. + // keep behind a constant flag for now. + jsonUnreadAfterDecNum = true // If !jsonValidateSymbols, decoding will be faster, by skipping some checks: // - If we see first character of null, false or true, @@ -79,17 +90,100 @@ const ( jsonNumUintMaxVal = 1< 1<<53 || v < -(1<<53)) { + e.w.writen1('"') + e.w.writeb(strconv.AppendInt(e.b[:0], v, 10)) + e.w.writen1('"') + return + } e.w.writeb(strconv.AppendInt(e.b[:0], v, 10)) } func (e *jsonEncDriver) EncodeUint(v uint64) { + if x := e.h.IntegerAsString; x == 'A' || x == 'L' && v > 1<<53 { + e.w.writen1('"') + e.w.writeb(strconv.AppendUint(e.b[:0], v, 10)) + e.w.writen1('"') + return + } e.w.writeb(strconv.AppendUint(e.b[:0], v, 10)) } func (e *jsonEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, en *Encoder) { if v := ext.ConvertExt(rv); v == nil { - e.EncodeNil() + e.w.writeb(jsonLiterals[9:13]) // null // e.EncodeNil() } else { en.encode(v) } @@ -130,38 +236,26 @@ func (e *jsonEncDriver) EncodeExt(rv interface{}, xtag uint64, ext Ext, en *Enco func (e *jsonEncDriver) EncodeRawExt(re *RawExt, en *Encoder) { // only encodes re.Value (never re.Data) if re.Value == nil { - e.EncodeNil() + e.w.writeb(jsonLiterals[9:13]) // null // e.EncodeNil() } else { en.encode(re.Value) } } func (e *jsonEncDriver) EncodeArrayStart(length int) { + if e.d { + e.dl++ + } e.w.writen1('[') -} - -func (e *jsonEncDriver) EncodeArrayEntrySeparator() { - e.w.writen1(',') -} - -func (e *jsonEncDriver) EncodeArrayEnd() { - e.w.writen1(']') + e.c = containerArrayStart } func (e *jsonEncDriver) EncodeMapStart(length int) { + if e.d { + e.dl++ + } e.w.writen1('{') -} - -func (e *jsonEncDriver) EncodeMapEntrySeparator() { - e.w.writen1(',') -} - -func (e *jsonEncDriver) EncodeMapKVSeparator() { - e.w.writen1(':') -} - -func (e *jsonEncDriver) EncodeMapEnd() { - e.w.writen1('}') + e.c = containerMapStart } func (e *jsonEncDriver) EncodeString(c charEncoding, v string) { @@ -175,11 +269,13 @@ func (e *jsonEncDriver) EncodeSymbol(v string) { } func (e *jsonEncDriver) EncodeStringBytes(c charEncoding, v []byte) { + // if encoding raw bytes and RawBytesExt is configured, use it to encode + if c == c_RAW && e.se.i != nil { + e.EncodeExt(v, 0, &e.se, e.e) + return + } if c == c_RAW { slen := base64.StdEncoding.EncodedLen(len(v)) - if e.bs == nil { - e.bs = e.b[:] - } if cap(e.bs) >= slen { e.bs = e.bs[:slen] } else { @@ -195,6 +291,10 @@ func (e *jsonEncDriver) EncodeStringBytes(c charEncoding, v []byte) { } } +func (e *jsonEncDriver) EncodeAsis(v []byte) { + e.w.writeb(v) +} + func (e *jsonEncDriver) quoteStr(s string) { // adapted from std pkg encoding/json const hex = "0123456789abcdef" @@ -266,7 +366,7 @@ func (e *jsonEncDriver) quoteStr(s string) { //-------------------------------- type jsonNum struct { - bytes []byte // may have [+-.eE0-9] + // bytes []byte // may have [+-.eE0-9] mantissa uint64 // where mantissa ends, and maybe dot begins. exponent int16 // exponent value. manOverflow bool @@ -276,7 +376,6 @@ type jsonNum struct { } func (x *jsonNum) reset() { - x.bytes = x.bytes[:0] x.manOverflow = false x.neg = false x.dot = false @@ -309,29 +408,26 @@ func (x *jsonNum) uintExp() (n uint64, overflow bool) { // return } -func (x *jsonNum) floatVal() (f float64) { +// these constants are only used withn floatVal. +// They are brought out, so that floatVal can be inlined. +const ( + jsonUint64MantissaBits = 52 + jsonMaxExponent = int16(len(jsonFloat64Pow10)) - 1 +) + +func (x *jsonNum) floatVal() (f float64, parseUsingStrConv bool) { // We do not want to lose precision. // Consequently, we will delegate to strconv.ParseFloat if any of the following happen: // - There are more digits than in math.MaxUint64: 18446744073709551615 (20 digits) // We expect up to 99.... (19 digits) // - The mantissa cannot fit into a 52 bits of uint64 // - The exponent is beyond our scope ie beyong 22. - const uint64MantissaBits = 52 - const maxExponent = int16(len(jsonFloat64Pow10)) - 1 + parseUsingStrConv = x.manOverflow || + x.exponent > jsonMaxExponent || + (x.exponent < 0 && -(x.exponent) > jsonMaxExponent) || + x.mantissa>>jsonUint64MantissaBits != 0 - parseUsingStrConv := x.manOverflow || - x.exponent > maxExponent || - (x.exponent < 0 && -(x.exponent) > maxExponent) || - x.mantissa>>uint64MantissaBits != 0 if parseUsingStrConv { - var err error - if f, err = strconv.ParseFloat(stringView(x.bytes), 64); err != nil { - panic(fmt.Errorf("parse float: %s, %v", x.bytes, err)) - return - } - if x.neg { - f = -f - } return } @@ -350,162 +446,230 @@ func (x *jsonNum) floatVal() (f float64) { } type jsonDecDriver struct { - d *Decoder - h *JsonHandle - r decReader // *bytesDecReader decReader - ct valueType // container type. one of unset, array or map. - bstr [8]byte // scratch used for string \UXXX parsing - b [64]byte // scratch + noBuiltInTypes + d *Decoder + h *JsonHandle + r decReader - wsSkipped bool // whitespace skipped + c containerState + // tok is used to store the token read right after skipWhiteSpace. + tok uint8 + + bstr [8]byte // scratch used for string \UXXX parsing + b [64]byte // scratch, used for parsing strings or numbers + b2 [64]byte // scratch, used only for decodeBytes (after base64) + bs []byte // scratch. Initialized from b. Used for parsing strings or numbers. + + se setExtWrapper n jsonNum - noBuiltInTypes } -// This will skip whitespace characters and return the next byte to read. -// The next byte determines what the value will be one of. -func (d *jsonDecDriver) skipWhitespace(unread bool) (b byte) { - // as initReadNext is not called all the time, we set ct to unSet whenever - // we skipwhitespace, as this is the signal that something new is about to be read. - d.ct = valueTypeUnset - b = d.r.readn1() - if !jsonTrackSkipWhitespace || !d.wsSkipped { - for ; b == ' ' || b == '\t' || b == '\r' || b == '\n'; b = d.r.readn1() { - } - if jsonTrackSkipWhitespace { - d.wsSkipped = true - } - } - if unread { +func jsonIsWS(b byte) bool { + return b == ' ' || b == '\t' || b == '\r' || b == '\n' +} + +// // This will skip whitespace characters and return the next byte to read. +// // The next byte determines what the value will be one of. +// func (d *jsonDecDriver) skipWhitespace() { +// // fast-path: do not enter loop. Just check first (in case no whitespace). +// b := d.r.readn1() +// if jsonIsWS(b) { +// r := d.r +// for b = r.readn1(); jsonIsWS(b); b = r.readn1() { +// } +// } +// d.tok = b +// } + +func (d *jsonDecDriver) uncacheRead() { + if d.tok != 0 { d.r.unreadn1() + d.tok = 0 } - return b +} + +func (d *jsonDecDriver) sendContainerState(c containerState) { + if d.tok == 0 { + var b byte + r := d.r + for b = r.readn1(); jsonIsWS(b); b = r.readn1() { + } + d.tok = b + } + var xc uint8 // char expected + if c == containerMapKey { + if d.c != containerMapStart { + xc = ',' + } + } else if c == containerMapValue { + xc = ':' + } else if c == containerMapEnd { + xc = '}' + } else if c == containerArrayElem { + if d.c != containerArrayStart { + xc = ',' + } + } else if c == containerArrayEnd { + xc = ']' + } + if xc != 0 { + if d.tok != xc { + d.d.errorf("json: expect char '%c' but got char '%c'", xc, d.tok) + } + d.tok = 0 + } + d.c = c } func (d *jsonDecDriver) CheckBreak() bool { - b := d.skipWhitespace(true) - return b == '}' || b == ']' + if d.tok == 0 { + var b byte + r := d.r + for b = r.readn1(); jsonIsWS(b); b = r.readn1() { + } + d.tok = b + } + if d.tok == '}' || d.tok == ']' { + // d.tok = 0 // only checking, not consuming + return true + } + return false } func (d *jsonDecDriver) readStrIdx(fromIdx, toIdx uint8) { bs := d.r.readx(int(toIdx - fromIdx)) + d.tok = 0 if jsonValidateSymbols { if !bytes.Equal(bs, jsonLiterals[fromIdx:toIdx]) { d.d.errorf("json: expecting %s: got %s", jsonLiterals[fromIdx:toIdx], bs) return } } - if jsonTrackSkipWhitespace { - d.wsSkipped = false - } } func (d *jsonDecDriver) TryDecodeAsNil() bool { - b := d.skipWhitespace(true) - if b == 'n' { - d.readStrIdx(9, 13) // null - d.ct = valueTypeNil + if d.tok == 0 { + var b byte + r := d.r + for b = r.readn1(); jsonIsWS(b); b = r.readn1() { + } + d.tok = b + } + if d.tok == 'n' { + d.readStrIdx(10, 13) // ull return true } return false } func (d *jsonDecDriver) DecodeBool() bool { - b := d.skipWhitespace(false) - if b == 'f' { + if d.tok == 0 { + var b byte + r := d.r + for b = r.readn1(); jsonIsWS(b); b = r.readn1() { + } + d.tok = b + } + if d.tok == 'f' { d.readStrIdx(5, 9) // alse return false } - if b == 't' { + if d.tok == 't' { d.readStrIdx(1, 4) // rue return true } - d.d.errorf("json: decode bool: got first char %c", b) + d.d.errorf("json: decode bool: got first char %c", d.tok) return false // "unreachable" } func (d *jsonDecDriver) ReadMapStart() int { - d.expectChar('{') - d.ct = valueTypeMap + if d.tok == 0 { + var b byte + r := d.r + for b = r.readn1(); jsonIsWS(b); b = r.readn1() { + } + d.tok = b + } + if d.tok != '{' { + d.d.errorf("json: expect char '%c' but got char '%c'", '{', d.tok) + } + d.tok = 0 + d.c = containerMapStart return -1 } func (d *jsonDecDriver) ReadArrayStart() int { - d.expectChar('[') - d.ct = valueTypeArray + if d.tok == 0 { + var b byte + r := d.r + for b = r.readn1(); jsonIsWS(b); b = r.readn1() { + } + d.tok = b + } + if d.tok != '[' { + d.d.errorf("json: expect char '%c' but got char '%c'", '[', d.tok) + } + d.tok = 0 + d.c = containerArrayStart return -1 } -func (d *jsonDecDriver) ReadMapEnd() { - d.expectChar('}') -} -func (d *jsonDecDriver) ReadArrayEnd() { - d.expectChar(']') -} -func (d *jsonDecDriver) ReadArrayEntrySeparator() { - d.expectChar(',') -} -func (d *jsonDecDriver) ReadMapEntrySeparator() { - d.expectChar(',') -} -func (d *jsonDecDriver) ReadMapKVSeparator() { - d.expectChar(':') -} -func (d *jsonDecDriver) expectChar(c uint8) { - b := d.skipWhitespace(false) - if b != c { - d.d.errorf("json: expect char %c but got char %c", c, b) - return - } - if jsonTrackSkipWhitespace { - d.wsSkipped = false - } -} -func (d *jsonDecDriver) IsContainerType(vt valueType) bool { +func (d *jsonDecDriver) ContainerType() (vt valueType) { // check container type by checking the first char - if d.ct == valueTypeUnset { - b := d.skipWhitespace(true) - if b == '{' { - d.ct = valueTypeMap - } else if b == '[' { - d.ct = valueTypeArray - } else if b == 'n' { - d.ct = valueTypeNil - } else if b == '"' { - d.ct = valueTypeString + if d.tok == 0 { + var b byte + r := d.r + for b = r.readn1(); jsonIsWS(b); b = r.readn1() { } + d.tok = b } - if vt == valueTypeNil || vt == valueTypeBytes || vt == valueTypeString || - vt == valueTypeArray || vt == valueTypeMap { - return d.ct == vt + if b := d.tok; b == '{' { + return valueTypeMap + } else if b == '[' { + return valueTypeArray + } else if b == 'n' { + return valueTypeNil + } else if b == '"' { + return valueTypeString } - // ugorji: made switch into conditionals, so that IsContainerType can be inlined. - // switch vt { - // case valueTypeNil, valueTypeBytes, valueTypeString, valueTypeArray, valueTypeMap: - // return d.ct == vt - // } - d.d.errorf("isContainerType: unsupported parameter: %v", vt) - return false // "unreachable" + return valueTypeUnset + // d.d.errorf("isContainerType: unsupported parameter: %v", vt) + // return false // "unreachable" } func (d *jsonDecDriver) decNum(storeBytes bool) { - // storeBytes = true // TODO: remove. - // If it is has a . or an e|E, decode as a float; else decode as an int. - b := d.skipWhitespace(false) + if d.tok == 0 { + var b byte + r := d.r + for b = r.readn1(); jsonIsWS(b); b = r.readn1() { + } + d.tok = b + } + b := d.tok + var str bool + if b == '"' { + str = true + b = d.r.readn1() + } if !(b == '+' || b == '-' || b == '.' || (b >= '0' && b <= '9')) { d.d.errorf("json: decNum: got first char '%c'", b) return } + d.tok = 0 const cutoff = (1<<64-1)/uint64(10) + 1 // cutoff64(base) const jsonNumUintMaxVal = 1<= slen { + if slen <= cap(bs) { bsOut = bs[:slen] + } else if zerocopy && slen <= cap(d.b2) { + bsOut = d.b2[:slen] } else { bsOut = make([]byte, slen) } @@ -745,17 +944,36 @@ func (d *jsonDecDriver) DecodeBytes(bs []byte, isstring, zerocopy bool) (bsOut [ } func (d *jsonDecDriver) DecodeString() (s string) { - return string(d.appendStringAsBytes(d.b[:0])) + d.appendStringAsBytes() + // if x := d.s.sc; x != nil && x.so && x.st == '}' { // map key + if d.c == containerMapKey { + return d.d.string(d.bs) + } + return string(d.bs) } -func (d *jsonDecDriver) appendStringAsBytes(v []byte) []byte { - d.expectChar('"') +func (d *jsonDecDriver) appendStringAsBytes() { + if d.tok == 0 { + var b byte + r := d.r + for b = r.readn1(); jsonIsWS(b); b = r.readn1() { + } + d.tok = b + } + if d.tok != '"' { + d.d.errorf("json: expect char '%c' but got char '%c'", '"', d.tok) + } + d.tok = 0 + + v := d.bs[:0] + var c uint8 + r := d.r for { - c := d.r.readn1() + c = r.readn1() if c == '"' { break } else if c == '\\' { - c = d.r.readn1() + c = r.readn1() switch c { case '"', '\\', '/', '\'': v = append(v, c) @@ -779,27 +997,24 @@ func (d *jsonDecDriver) appendStringAsBytes(v []byte) []byte { v = append(v, d.bstr[:w2]...) default: d.d.errorf("json: unsupported escaped value: %c", c) - return nil } } else { v = append(v, c) } } - if jsonTrackSkipWhitespace { - d.wsSkipped = false - } - return v + d.bs = v } func (d *jsonDecDriver) jsonU4(checkSlashU bool) rune { - if checkSlashU && !(d.r.readn1() == '\\' && d.r.readn1() == 'u') { + r := d.r + if checkSlashU && !(r.readn1() == '\\' && r.readn1() == 'u') { d.d.errorf(`json: unquoteStr: invalid unicode sequence. Expecting \u`) return 0 } // u, _ := strconv.ParseUint(string(d.bstr[:4]), 16, 64) var u uint32 for i := 0; i < 4; i++ { - v := d.r.readn1() + v := r.readn1() if '0' <= v && v <= '9' { v = v - '0' } else if 'a' <= v && v <= 'z' { @@ -815,69 +1030,83 @@ func (d *jsonDecDriver) jsonU4(checkSlashU bool) rune { return rune(u) } -func (d *jsonDecDriver) DecodeNaked() (v interface{}, vt valueType, decodeFurther bool) { - n := d.skipWhitespace(true) - switch n { +func (d *jsonDecDriver) DecodeNaked() { + z := &d.d.n + // var decodeFurther bool + + if d.tok == 0 { + var b byte + r := d.r + for b = r.readn1(); jsonIsWS(b); b = r.readn1() { + } + d.tok = b + } + switch d.tok { case 'n': - d.readStrIdx(9, 13) // null - vt = valueTypeNil + d.readStrIdx(10, 13) // ull + z.v = valueTypeNil case 'f': - d.readStrIdx(4, 9) // false - vt = valueTypeBool - v = false + d.readStrIdx(5, 9) // alse + z.v = valueTypeBool + z.b = false case 't': - d.readStrIdx(0, 4) // true - vt = valueTypeBool - v = true + d.readStrIdx(1, 4) // rue + z.v = valueTypeBool + z.b = true case '{': - vt = valueTypeMap - decodeFurther = true + z.v = valueTypeMap + // d.tok = 0 // don't consume. kInterfaceNaked will call ReadMapStart + // decodeFurther = true case '[': - vt = valueTypeArray - decodeFurther = true + z.v = valueTypeArray + // d.tok = 0 // don't consume. kInterfaceNaked will call ReadArrayStart + // decodeFurther = true case '"': - vt = valueTypeString - v = d.DecodeString() + z.v = valueTypeString + z.s = d.DecodeString() default: // number d.decNum(true) n := &d.n // if the string had a any of [.eE], then decode as float. switch { case n.explicitExponent, n.dot, n.exponent < 0, n.manOverflow: - vt = valueTypeFloat - v = n.floatVal() + z.v = valueTypeFloat + z.f = d.floatVal() case n.exponent == 0: u := n.mantissa switch { case n.neg: - vt = valueTypeInt - v = -int64(u) + z.v = valueTypeInt + z.i = -int64(u) case d.h.SignedInteger: - vt = valueTypeInt - v = int64(u) + z.v = valueTypeInt + z.i = int64(u) default: - vt = valueTypeUint - v = u + z.v = valueTypeUint + z.u = u } default: u, overflow := n.uintExp() switch { case overflow: - vt = valueTypeFloat - v = n.floatVal() + z.v = valueTypeFloat + z.f = d.floatVal() case n.neg: - vt = valueTypeInt - v = -int64(u) + z.v = valueTypeInt + z.i = -int64(u) case d.h.SignedInteger: - vt = valueTypeInt - v = int64(u) + z.v = valueTypeInt + z.i = int64(u) default: - vt = valueTypeUint - v = u + z.v = valueTypeUint + z.u = u } } // fmt.Printf("DecodeNaked: Number: %T, %v\n", v, v) } + // if decodeFurther { + // d.s.sc.retryRead() + // } return } @@ -887,7 +1116,8 @@ func (d *jsonDecDriver) DecodeNaked() (v interface{}, vt valueType, decodeFurthe // // Json is comprehensively supported: // - decodes numbers into interface{} as int, uint or float64 -// - encodes and decodes []byte using base64 Std Encoding +// - configurable way to encode/decode []byte . +// by default, encodes and decodes []byte using base64 Std Encoding // - UTF-8 support for encoding and decoding // // It has better performance than the json library in the standard library, @@ -899,21 +1129,80 @@ func (d *jsonDecDriver) DecodeNaked() (v interface{}, vt valueType, decodeFurthe // For example, a user can read a json value, then a cbor value, then a msgpack value, // all from the same stream in sequence. type JsonHandle struct { - BasicHandle textEncodingType + BasicHandle + // RawBytesExt, if configured, is used to encode and decode raw bytes in a custom way. + // If not configured, raw bytes are encoded to/from base64 text. + RawBytesExt InterfaceExt + + // Indent indicates how a value is encoded. + // - If positive, indent by that number of spaces. + // - If negative, indent by that number of tabs. + Indent int8 + + // IntegerAsString controls how integers (signed and unsigned) are encoded. + // + // Per the JSON Spec, JSON numbers are 64-bit floating point numbers. + // Consequently, integers > 2^53 cannot be represented as a JSON number without losing precision. + // This can be mitigated by configuring how to encode integers. + // + // IntegerAsString interpretes the following values: + // - if 'L', then encode integers > 2^53 as a json string. + // - if 'A', then encode all integers as a json string + // containing the exact integer representation as a decimal. + // - else encode all integers as a json number (default) + IntegerAsString uint8 +} + +func (h *JsonHandle) SetInterfaceExt(rt reflect.Type, tag uint64, ext InterfaceExt) (err error) { + return h.SetExt(rt, tag, &setExtWrapper{i: ext}) } func (h *JsonHandle) newEncDriver(e *Encoder) encDriver { - return &jsonEncDriver{e: e, w: e.w, h: h} + hd := jsonEncDriver{e: e, h: h} + hd.bs = hd.b[:0] + + hd.reset() + + return &hd } func (h *JsonHandle) newDecDriver(d *Decoder) decDriver { // d := jsonDecDriver{r: r.(*bytesDecReader), h: h} - hd := jsonDecDriver{d: d, r: d.r, h: h} - hd.n.bytes = d.b[:] + hd := jsonDecDriver{d: d, h: h} + hd.bs = hd.b[:0] + hd.reset() return &hd } +func (e *jsonEncDriver) reset() { + e.w = e.e.w + e.se.i = e.h.RawBytesExt + if e.bs != nil { + e.bs = e.bs[:0] + } + e.d, e.dt, e.dl, e.ds = false, false, 0, "" + e.c = 0 + if e.h.Indent > 0 { + e.d = true + e.ds = jsonSpaces[:e.h.Indent] + } else if e.h.Indent < 0 { + e.d = true + e.dt = true + e.ds = jsonTabs[:-(e.h.Indent)] + } +} + +func (d *jsonDecDriver) reset() { + d.r = d.d.r + d.se.i = d.h.RawBytesExt + if d.bs != nil { + d.bs = d.bs[:0] + } + d.c, d.tok = 0, 0 + d.n.reset() +} + var jsonEncodeTerminate = []byte{' '} func (h *JsonHandle) rpcEncodeTerminate() []byte { diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/msgpack.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/msgpack.go index 5cfc2a2..f9f8723 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/msgpack.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/msgpack.go @@ -24,6 +24,7 @@ import ( "io" "math" "net/rpc" + "reflect" ) const ( @@ -102,11 +103,11 @@ var ( //--------------------------------------------- type msgpackEncDriver struct { + noBuiltInTypes + encNoSeparator e *Encoder w encWriter h *MsgpackHandle - noBuiltInTypes - encNoSeparator x [8]byte } @@ -270,7 +271,6 @@ type msgpackDecDriver struct { bd byte bdRead bool br bool // bytes reader - bdType valueType noBuiltInTypes noStreamingCodec decNoSeparator @@ -281,106 +281,100 @@ type msgpackDecDriver struct { // It is called when a nil interface{} is passed, leaving it up to the DecDriver // to introspect the stream and decide how best to decode. // It deciphers the value by looking at the stream first. -func (d *msgpackDecDriver) DecodeNaked() (v interface{}, vt valueType, decodeFurther bool) { +func (d *msgpackDecDriver) DecodeNaked() { if !d.bdRead { d.readNextBd() } bd := d.bd + n := &d.d.n + var decodeFurther bool switch bd { case mpNil: - vt = valueTypeNil + n.v = valueTypeNil d.bdRead = false case mpFalse: - vt = valueTypeBool - v = false + n.v = valueTypeBool + n.b = false case mpTrue: - vt = valueTypeBool - v = true + n.v = valueTypeBool + n.b = true case mpFloat: - vt = valueTypeFloat - v = float64(math.Float32frombits(bigen.Uint32(d.r.readx(4)))) + n.v = valueTypeFloat + n.f = float64(math.Float32frombits(bigen.Uint32(d.r.readx(4)))) case mpDouble: - vt = valueTypeFloat - v = math.Float64frombits(bigen.Uint64(d.r.readx(8))) + n.v = valueTypeFloat + n.f = math.Float64frombits(bigen.Uint64(d.r.readx(8))) case mpUint8: - vt = valueTypeUint - v = uint64(d.r.readn1()) + n.v = valueTypeUint + n.u = uint64(d.r.readn1()) case mpUint16: - vt = valueTypeUint - v = uint64(bigen.Uint16(d.r.readx(2))) + n.v = valueTypeUint + n.u = uint64(bigen.Uint16(d.r.readx(2))) case mpUint32: - vt = valueTypeUint - v = uint64(bigen.Uint32(d.r.readx(4))) + n.v = valueTypeUint + n.u = uint64(bigen.Uint32(d.r.readx(4))) case mpUint64: - vt = valueTypeUint - v = uint64(bigen.Uint64(d.r.readx(8))) + n.v = valueTypeUint + n.u = uint64(bigen.Uint64(d.r.readx(8))) case mpInt8: - vt = valueTypeInt - v = int64(int8(d.r.readn1())) + n.v = valueTypeInt + n.i = int64(int8(d.r.readn1())) case mpInt16: - vt = valueTypeInt - v = int64(int16(bigen.Uint16(d.r.readx(2)))) + n.v = valueTypeInt + n.i = int64(int16(bigen.Uint16(d.r.readx(2)))) case mpInt32: - vt = valueTypeInt - v = int64(int32(bigen.Uint32(d.r.readx(4)))) + n.v = valueTypeInt + n.i = int64(int32(bigen.Uint32(d.r.readx(4)))) case mpInt64: - vt = valueTypeInt - v = int64(int64(bigen.Uint64(d.r.readx(8)))) + n.v = valueTypeInt + n.i = int64(int64(bigen.Uint64(d.r.readx(8)))) default: switch { case bd >= mpPosFixNumMin && bd <= mpPosFixNumMax: // positive fixnum (always signed) - vt = valueTypeInt - v = int64(int8(bd)) + n.v = valueTypeInt + n.i = int64(int8(bd)) case bd >= mpNegFixNumMin && bd <= mpNegFixNumMax: // negative fixnum - vt = valueTypeInt - v = int64(int8(bd)) + n.v = valueTypeInt + n.i = int64(int8(bd)) case bd == mpStr8, bd == mpStr16, bd == mpStr32, bd >= mpFixStrMin && bd <= mpFixStrMax: if d.h.RawToString { - var rvm string - vt = valueTypeString - v = &rvm + n.v = valueTypeString + n.s = d.DecodeString() } else { - var rvm = zeroByteSlice - vt = valueTypeBytes - v = &rvm + n.v = valueTypeBytes + n.l = d.DecodeBytes(nil, false, false) } - decodeFurther = true case bd == mpBin8, bd == mpBin16, bd == mpBin32: - var rvm = zeroByteSlice - vt = valueTypeBytes - v = &rvm - decodeFurther = true + n.v = valueTypeBytes + n.l = d.DecodeBytes(nil, false, false) case bd == mpArray16, bd == mpArray32, bd >= mpFixArrayMin && bd <= mpFixArrayMax: - vt = valueTypeArray + n.v = valueTypeArray decodeFurther = true case bd == mpMap16, bd == mpMap32, bd >= mpFixMapMin && bd <= mpFixMapMax: - vt = valueTypeMap + n.v = valueTypeMap decodeFurther = true case bd >= mpFixExt1 && bd <= mpFixExt16, bd >= mpExt8 && bd <= mpExt32: + n.v = valueTypeExt clen := d.readExtLen() - var re RawExt - re.Tag = uint64(d.r.readn1()) - re.Data = d.r.readx(clen) - v = &re - vt = valueTypeExt + n.u = uint64(d.r.readn1()) + n.l = d.r.readx(clen) default: d.d.errorf("Nil-Deciphered DecodeValue: %s: hex: %x, dec: %d", msgBadDesc, bd, bd) - return } } if !decodeFurther { d.bdRead = false } - if vt == valueTypeUint && d.h.SignedInteger { - d.bdType = valueTypeInt - v = int64(v.(uint64)) + if n.v == valueTypeUint && d.h.SignedInteger { + n.v = valueTypeInt + n.i = int64(n.u) } return } @@ -536,15 +530,11 @@ func (d *msgpackDecDriver) DecodeBytes(bs []byte, isstring, zerocopy bool) (bsOu d.readNextBd() } var clen int - if isstring { - clen = d.readContainerLen(msgpackContainerStr) + // ignore isstring. Expect that the bytes may be found from msgpackContainerStr or msgpackContainerBin + if bd := d.bd; bd == mpBin8 || bd == mpBin16 || bd == mpBin32 { + clen = d.readContainerLen(msgpackContainerBin) } else { - // bytes can be decoded from msgpackContainerStr or msgpackContainerBin - if bd := d.bd; bd == mpBin8 || bd == mpBin16 || bd == mpBin32 { - clen = d.readContainerLen(msgpackContainerBin) - } else { - clen = d.readContainerLen(msgpackContainerStr) - } + clen = d.readContainerLen(msgpackContainerStr) } // println("DecodeBytes: clen: ", clen) d.bdRead = false @@ -569,28 +559,27 @@ func (d *msgpackDecDriver) DecodeString() (s string) { func (d *msgpackDecDriver) readNextBd() { d.bd = d.r.readn1() d.bdRead = true - d.bdType = valueTypeUnset } -func (d *msgpackDecDriver) IsContainerType(vt valueType) bool { +func (d *msgpackDecDriver) ContainerType() (vt valueType) { bd := d.bd - switch vt { - case valueTypeNil: - return bd == mpNil - case valueTypeBytes: - return bd == mpBin8 || bd == mpBin16 || bd == mpBin32 || - (!d.h.RawToString && - (bd == mpStr8 || bd == mpStr16 || bd == mpStr32 || (bd >= mpFixStrMin && bd <= mpFixStrMax))) - case valueTypeString: - return d.h.RawToString && - (bd == mpStr8 || bd == mpStr16 || bd == mpStr32 || (bd >= mpFixStrMin && bd <= mpFixStrMax)) - case valueTypeArray: - return bd == mpArray16 || bd == mpArray32 || (bd >= mpFixArrayMin && bd <= mpFixArrayMax) - case valueTypeMap: - return bd == mpMap16 || bd == mpMap32 || (bd >= mpFixMapMin && bd <= mpFixMapMax) + if bd == mpNil { + return valueTypeNil + } else if bd == mpBin8 || bd == mpBin16 || bd == mpBin32 || + (!d.h.RawToString && + (bd == mpStr8 || bd == mpStr16 || bd == mpStr32 || (bd >= mpFixStrMin && bd <= mpFixStrMax))) { + return valueTypeBytes + } else if d.h.RawToString && + (bd == mpStr8 || bd == mpStr16 || bd == mpStr32 || (bd >= mpFixStrMin && bd <= mpFixStrMax)) { + return valueTypeString + } else if bd == mpArray16 || bd == mpArray32 || (bd >= mpFixArrayMin && bd <= mpFixArrayMax) { + return valueTypeArray + } else if bd == mpMap16 || bd == mpMap32 || (bd >= mpFixMapMin && bd <= mpFixMapMax) { + return valueTypeMap + } else { + // d.d.errorf("isContainerType: unsupported parameter: %v", vt) } - d.d.errorf("isContainerType: unsupported parameter: %v", vt) - return false // "unreachable" + return valueTypeUnset } func (d *msgpackDecDriver) TryDecodeAsNil() (v bool) { @@ -617,7 +606,7 @@ func (d *msgpackDecDriver) readContainerLen(ct msgpackContainerType) (clen int) } else if (ct.bFixMin & bd) == ct.bFixMin { clen = int(ct.bFixMin ^ bd) } else { - d.d.errorf("readContainerLen: %s: hex: %x, dec: %d", msgBadDesc, bd, bd) + d.d.errorf("readContainerLen: %s: hex: %x, decimal: %d", msgBadDesc, bd, bd) return } d.bdRead = false @@ -704,7 +693,6 @@ func (d *msgpackDecDriver) decodeExtV(verifyTag bool, tag byte) (xtag byte, xbs //MsgpackHandle is a Handle for the Msgpack Schema-Free Encoding Format. type MsgpackHandle struct { BasicHandle - binaryEncodingType // RawToString controls how raw bytes are decoded into a nil interface{}. RawToString bool @@ -720,6 +708,11 @@ type MsgpackHandle struct { // type is provided (e.g. decoding into a nil interface{}), you get back // a []byte or string based on the setting of RawToString. WriteExt bool + binaryEncodingType +} + +func (h *MsgpackHandle) SetBytesExt(rt reflect.Type, tag uint64, ext BytesExt) (err error) { + return h.SetExt(rt, tag, &setExtWrapper{b: ext}) } func (h *MsgpackHandle) newEncDriver(e *Encoder) encDriver { @@ -730,6 +723,15 @@ func (h *MsgpackHandle) newDecDriver(d *Decoder) decDriver { return &msgpackDecDriver{d: d, r: d.r, h: h, br: d.bytes} } +func (e *msgpackEncDriver) reset() { + e.w = e.e.w +} + +func (d *msgpackDecDriver) reset() { + d.r = d.d.r + d.bd, d.bdRead = 0, false +} + //-------------------------------------------------- type msgpackSpecRpcCodec struct { diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/noop.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/noop.go index 25bef4f..cfee3d0 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/noop.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/noop.go @@ -11,6 +11,7 @@ import ( // 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{} @@ -37,38 +38,57 @@ type noopHandle struct { } type noopDrv struct { + d *Decoder + e *Encoder i int S []string B [][]byte - mk bool // are we about to read a map key? - ct valueType // last request for IsContainerType. - cb bool // last response for IsContainerType. + 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(_ *Encoder) encDriver { return h } -func (h *noopDrv) newDecDriver(_ *Decoder) decDriver { return h } +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 -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) {} -func (h *noopDrv) EncodeArrayEnd() {} -func (h *noopDrv) EncodeArrayEntrySeparator() {} -func (h *noopDrv) EncodeMapStart(length int) {} -func (h *noopDrv) EncodeMapEnd() {} -func (h *noopDrv) EncodeMapEntrySeparator() {} -func (h *noopDrv) EncodeMapKVSeparator() {} +// 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) {} @@ -90,28 +110,54 @@ func (h *noopDrv) DecodeString() (s string) { return h.S[h.m(8 func (h *noopDrv) DecodeBytes(bs []byte, isstring, zerocopy bool) []byte { return h.B[h.m(len(h.B))] } -func (h *noopDrv) ReadMapEnd() { h.mk = false } -func (h *noopDrv) ReadArrayEnd() {} -func (h *noopDrv) ReadArrayEntrySeparator() {} -func (h *noopDrv) ReadMapEntrySeparator() { h.mk = true } -func (h *noopDrv) ReadMapKVSeparator() { h.mk = false } +func (h *noopDrv) ReadEnd() { h.end() } // toggle map/slice -func (h *noopDrv) ReadMapStart() int { h.mk = true; return h.m(10) } -func (h *noopDrv) ReadArrayStart() int { return h.m(10) } +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) IsContainerType(vt valueType) bool { +func (h *noopDrv) ContainerType() (vt valueType) { // return h.m(2) == 0 - // handle kStruct - 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 + // 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 { @@ -124,7 +170,7 @@ func (h *noopDrv) DecodeExt(rv interface{}, xtag uint64, ext Ext) uint64 { return 0 } -func (h *noopDrv) DecodeNaked() (v interface{}, vt valueType, decodeFurther bool) { +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 { @@ -133,32 +179,35 @@ func (h *noopDrv) DecodeNaked() (v interface{}, vt valueType, decodeFurther bool } else { sk = h.r(12) } + n := &h.d.n switch sk { case 0: - vt = valueTypeNil + n.v = valueTypeNil case 1: - vt, v = valueTypeBool, false + n.v, n.b = valueTypeBool, false case 2: - vt, v = valueTypeBool, true + n.v, n.b = valueTypeBool, true case 3: - vt, v = valueTypeInt, h.DecodeInt(64) + n.v, n.i = valueTypeInt, h.DecodeInt(64) case 4: - vt, v = valueTypeUint, h.DecodeUint(64) + n.v, n.u = valueTypeUint, h.DecodeUint(64) case 5: - vt, v = valueTypeFloat, h.DecodeFloat(true) + n.v, n.f = valueTypeFloat, h.DecodeFloat(true) case 6: - vt, v = valueTypeFloat, h.DecodeFloat(false) + n.v, n.f = valueTypeFloat, h.DecodeFloat(false) case 7: - vt, v = valueTypeString, h.DecodeString() + n.v, n.s = valueTypeString, h.DecodeString() case 8: - vt, v = valueTypeBytes, h.B[h.m(len(h.B))] + n.v, n.l = valueTypeBytes, h.B[h.m(len(h.B))] case 9: - vt, decodeFurther = valueTypeArray, true + n.v = valueTypeArray case 10: - vt, decodeFurther = valueTypeMap, true + n.v = valueTypeMap default: - vt, v = valueTypeExt, &RawExt{Tag: h.DecodeUint(64), Data: h.B[h.m(len(h.B))]} + n.v = valueTypeExt + n.u = h.DecodeUint(64) + n.l = h.B[h.m(len(h.B))] } - h.ct = vt + h.ct = n.v return } diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/prebuild.sh b/Godeps/_workspace/src/github.com/ugorji/go/codec/prebuild.sh index c1916f3..909f4bb 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/prebuild.sh +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/prebuild.sh @@ -49,7 +49,8 @@ _build() { # [ -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 + 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 < fast-path.generated.go < gen-from-tmpl.codec.generated.go < gen-from-tmpl.generated.go <>>>>>> 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 diff --git a/Godeps/_workspace/src/github.com/ugorji/go/codec/time.go b/Godeps/_workspace/src/github.com/ugorji/go/codec/time.go index 733fc3f..718b731 100644 --- a/Godeps/_workspace/src/github.com/ugorji/go/codec/time.go +++ b/Godeps/_workspace/src/github.com/ugorji/go/codec/time.go @@ -4,13 +4,53 @@ package codec import ( + "fmt" + "reflect" "time" ) var ( - timeDigits = [...]byte{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'} + 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. // diff --git a/Godeps/_workspace/src/golang.org/x/net/context/context.go b/Godeps/_workspace/src/golang.org/x/net/context/context.go index 66aff7c..11bd8d3 100644 --- a/Godeps/_workspace/src/golang.org/x/net/context/context.go +++ b/Godeps/_workspace/src/golang.org/x/net/context/context.go @@ -64,18 +64,21 @@ type Context interface { // // Done is provided for use in select statements: // - // // DoSomething calls DoSomethingSlow and returns as soon as - // // it returns or ctx.Done is closed. - // func DoSomething(ctx context.Context) (Result, error) { - // c := make(chan Result, 1) - // go func() { c <- DoSomethingSlow(ctx) }() - // select { - // case res := <-c: - // return res, nil - // case <-ctx.Done(): - // return nil, ctx.Err() - // } - // } + // // Stream generates values with DoSomething and sends them to out + // // until DoSomething returns an error or ctx.Done is closed. + // func Stream(ctx context.Context, out <-chan Value) error { + // for { + // v, err := DoSomething(ctx) + // if err != nil { + // return err + // } + // select { + // case <-ctx.Done(): + // return ctx.Err() + // case out <- v: + // } + // } + // } // // See http://blog.golang.org/pipelines for more examples of how to use // a Done channel for cancelation. @@ -186,7 +189,7 @@ func Background() Context { } // TODO returns a non-nil, empty Context. Code should use context.TODO when -// it's unclear which Context to use or it's is not yet available (because the +// it's unclear which Context to use or it is not yet available (because the // surrounding function has not yet been extended to accept a Context // parameter). TODO is recognized by static analysis tools that determine // whether Contexts are propagated correctly in a program. @@ -202,6 +205,9 @@ type CancelFunc func() // WithCancel returns a copy of parent with a new Done channel. The returned // context's Done channel is closed when the returned cancel function is called // or when the parent context's Done channel is closed, whichever happens first. +// +// Canceling this context releases resources associated with it, so code should +// call cancel as soon as the operations running in this Context complete. func WithCancel(parent Context) (ctx Context, cancel CancelFunc) { c := newCancelCtx(parent) propagateCancel(parent, &c) @@ -262,6 +268,19 @@ func parentCancelCtx(parent Context) (*cancelCtx, bool) { } } +// removeChild removes a context from its parent. +func removeChild(parent Context, child canceler) { + p, ok := parentCancelCtx(parent) + if !ok { + return + } + p.mu.Lock() + if p.children != nil { + delete(p.children, child) + } + p.mu.Unlock() +} + // A canceler is a context type that can be canceled directly. The // implementations are *cancelCtx and *timerCtx. type canceler interface { @@ -316,13 +335,7 @@ func (c *cancelCtx) cancel(removeFromParent bool, err error) { c.mu.Unlock() if removeFromParent { - if p, ok := parentCancelCtx(c.Context); ok { - p.mu.Lock() - if p.children != nil { - delete(p.children, c) - } - p.mu.Unlock() - } + removeChild(c.Context, c) } } @@ -333,9 +346,8 @@ func (c *cancelCtx) cancel(removeFromParent bool, err error) { // cancel function is called, or when the parent context's Done channel is // closed, whichever happens first. // -// Canceling this context releases resources associated with the deadline -// timer, so code should call cancel as soon as the operations running in this -// Context complete. +// Canceling this context releases resources associated with it, so code should +// call cancel as soon as the operations running in this Context complete. func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc) { if cur, ok := parent.Deadline(); ok && cur.Before(deadline) { // The current deadline is already sooner than the new one. @@ -380,7 +392,11 @@ func (c *timerCtx) String() string { } func (c *timerCtx) cancel(removeFromParent bool, err error) { - c.cancelCtx.cancel(removeFromParent, err) + c.cancelCtx.cancel(false, err) + if removeFromParent { + // Remove this timerCtx from its parent cancelCtx's children. + removeChild(c.cancelCtx.Context, c) + } c.mu.Lock() if c.timer != nil { c.timer.Stop() @@ -391,9 +407,8 @@ func (c *timerCtx) cancel(removeFromParent bool, err error) { // WithTimeout returns WithDeadline(parent, time.Now().Add(timeout)). // -// Canceling this context releases resources associated with the deadline -// timer, so code should call cancel as soon as the operations running in this -// Context complete: +// Canceling this context releases resources associated with it, so code should +// call cancel as soon as the operations running in this Context complete: // // func slowOperationWithTimeout(ctx context.Context) (Result, error) { // ctx, cancel := context.WithTimeout(ctx, 100*time.Millisecond) diff --git a/Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq.go b/Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq.go new file mode 100644 index 0000000..e3170e3 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq.go @@ -0,0 +1,19 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build go1.5 + +package ctxhttp + +import "net/http" + +func canceler(client *http.Client, req *http.Request) func() { + // TODO(djd): Respect any existing value of req.Cancel. + ch := make(chan struct{}) + req.Cancel = ch + + return func() { + close(ch) + } +} diff --git a/Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq_go14.go b/Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq_go14.go new file mode 100644 index 0000000..56bcbad --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq_go14.go @@ -0,0 +1,23 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !go1.5 + +package ctxhttp + +import "net/http" + +type requestCanceler interface { + CancelRequest(*http.Request) +} + +func canceler(client *http.Client, req *http.Request) func() { + rc, ok := client.Transport.(requestCanceler) + if !ok { + return func() {} + } + return func() { + rc.CancelRequest(req) + } +} diff --git a/Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/ctxhttp.go b/Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/ctxhttp.go new file mode 100644 index 0000000..5bb8095 --- /dev/null +++ b/Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/ctxhttp.go @@ -0,0 +1,123 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package ctxhttp provides helper functions for performing context-aware HTTP requests. +package ctxhttp + +import ( + "io" + "net/http" + "net/url" + "strings" + + "github.com/sorintlab/stolon/Godeps/_workspace/src/golang.org/x/net/context" +) + +// Do sends an HTTP request with the provided http.Client and returns an HTTP response. +// If the client is nil, http.DefaultClient is used. +// If the context is canceled or times out, ctx.Err() will be returned. +func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) { + if client == nil { + client = http.DefaultClient + } + + // Request cancelation changed in Go 1.5, see cancelreq.go and cancelreq_go14.go. + cancel := canceler(client, req) + + type responseAndError struct { + resp *http.Response + err error + } + result := make(chan responseAndError, 1) + + go func() { + resp, err := client.Do(req) + result <- responseAndError{resp, err} + }() + + var resp *http.Response + + select { + case <-ctx.Done(): + cancel() + return nil, ctx.Err() + case r := <-result: + var err error + resp, err = r.resp, r.err + if err != nil { + return resp, err + } + } + + c := make(chan struct{}) + go func() { + select { + case <-ctx.Done(): + cancel() + case <-c: + // The response's Body is closed. + } + }() + resp.Body = ¬ifyingReader{resp.Body, c} + + return resp, nil +} + +// Get issues a GET request via the Do function. +func Get(ctx context.Context, client *http.Client, url string) (*http.Response, error) { + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return nil, err + } + return Do(ctx, client, req) +} + +// Head issues a HEAD request via the Do function. +func Head(ctx context.Context, client *http.Client, url string) (*http.Response, error) { + req, err := http.NewRequest("HEAD", url, nil) + if err != nil { + return nil, err + } + return Do(ctx, client, req) +} + +// Post issues a POST request via the Do function. +func Post(ctx context.Context, client *http.Client, url string, bodyType string, body io.Reader) (*http.Response, error) { + req, err := http.NewRequest("POST", url, body) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", bodyType) + return Do(ctx, client, req) +} + +// PostForm issues a POST request via the Do function. +func PostForm(ctx context.Context, client *http.Client, url string, data url.Values) (*http.Response, error) { + return Post(ctx, client, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode())) +} + +// notifyingReader is an io.ReadCloser that closes the notify channel after +// Close is called or a Read fails on the underlying ReadCloser. +type notifyingReader struct { + io.ReadCloser + notify chan<- struct{} +} + +func (r *notifyingReader) Read(p []byte) (int, error) { + n, err := r.ReadCloser.Read(p) + if err != nil && r.notify != nil { + close(r.notify) + r.notify = nil + } + return n, err +} + +func (r *notifyingReader) Close() error { + err := r.ReadCloser.Close() + if r.notify != nil { + close(r.notify) + r.notify = nil + } + return err +} diff --git a/README.md b/README.md index 79c1eaf..d4f5903 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ stolon is a cloud native PostgreSQL manager for PostgreSQL high availability. It * Leverages PostgreSQL streaming replication. * [kubernetes integration](examples/kubernetes/README.md) letting you achieve postgreSQL high availability. -* Uses [etcd](https://github.com/coreos/etcd) as an high available data store and for leader election +* Uses a cluster store like [etcd](https://github.com/coreos/etcd) or [consul](https://www.consul.io) as an high available data store and for leader election * Asynchronous (default) and [synchronous](doc/syncrepl.md) replication. * Full cluster setup in minutes. * Easy [cluster admininistration](doc/stolonctl.md) @@ -26,12 +26,12 @@ Stolon is composed of 3 main components ## Project Status -Stolon is under active development and used in different environments. But its on disk format (etcd hierarchy and key contents) is not stable and will change for introducing new features. We hope that at the end of the year (2015) the most breaking changes will be merged and we can commit to a stable on disk format. +Stolon is under active development and used in different environments. But its on disk format (store hierarchy and key contents) is not stable and will change for introducing new features. We hope that at the end of the year (2015) the most breaking changes will be merged and we can commit to a stable on disk format. ## Requirements * PostgreSQL >= 9.4 -* etcd >= 2.0 +* etcd >= 2.0 or consul >=0.6 ## build diff --git a/cmd/keeper/keeper.go b/cmd/keeper/keeper.go index 352cf82..9bc1fc5 100644 --- a/cmd/keeper/keeper.go +++ b/cmd/keeper/keeper.go @@ -29,11 +29,11 @@ import ( "github.com/sorintlab/stolon/common" "github.com/sorintlab/stolon/pkg/cluster" - etcdm "github.com/sorintlab/stolon/pkg/etcd" "github.com/sorintlab/stolon/pkg/flagutil" "github.com/sorintlab/stolon/pkg/kubernetes" "github.com/sorintlab/stolon/pkg/postgresql" pg "github.com/sorintlab/stolon/pkg/postgresql" + "github.com/sorintlab/stolon/pkg/store" "github.com/sorintlab/stolon/pkg/util" "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/coreos/pkg/capnslog" @@ -58,7 +58,8 @@ var cmdKeeper = &cobra.Command{ type config struct { id string - etcdEndpoints string + storeBackend string + storeEndpoints string dataDir string clusterName string listenAddress string @@ -74,7 +75,8 @@ var cfg config func init() { cmdKeeper.PersistentFlags().StringVar(&cfg.id, "id", "", "keeper id (must be unique in the cluster and can contain only lower-case letters, numbers and the underscore character). If not provided a random id will be generated.") - cmdKeeper.PersistentFlags().StringVar(&cfg.etcdEndpoints, "etcd-endpoints", common.DefaultEtcdEndpoints, "a comma-delimited list of etcd endpoints") + cmdKeeper.PersistentFlags().StringVar(&cfg.storeBackend, "store-backend", "", "store backend type (etcd or consul)") + cmdKeeper.PersistentFlags().StringVar(&cfg.storeEndpoints, "store-endpoints", "", "a comma-delimited list of store endpoints (defaults: 127.0.0.1:2379 for etcd, 127.0.0.1:8500 for consul)") cmdKeeper.PersistentFlags().StringVar(&cfg.dataDir, "data-dir", "", "data directory") cmdKeeper.PersistentFlags().StringVar(&cfg.clusterName, "cluster-name", "", "cluster name") cmdKeeper.PersistentFlags().StringVar(&cfg.listenAddress, "listen-address", "localhost", "keeper listening address") @@ -132,7 +134,7 @@ func (p *PostgresKeeper) createPGParameters(followersIDs []string) pg.Parameters type PostgresKeeper struct { id string dataDir string - e *etcdm.EtcdManager + e *store.StoreManager pgm *postgresql.Manager stop chan bool end chan error @@ -152,11 +154,13 @@ type PostgresKeeper struct { } func NewPostgresKeeper(id string, cfg config, stop chan bool, end chan error) (*PostgresKeeper, error) { - etcdPath := filepath.Join(common.EtcdBasePath, cfg.clusterName) - e, err := etcdm.NewEtcdManager(cfg.etcdEndpoints, etcdPath, common.DefaultEtcdRequestTimeout) + storePath := filepath.Join(common.StoreBasePath, cfg.clusterName) + + kvstore, err := store.NewStore(store.Backend(cfg.storeBackend), cfg.storeEndpoints) if err != nil { - return nil, fmt.Errorf("cannot create etcd manager: %v", err) + return nil, fmt.Errorf("cannot create store: %v", err) } + e := store.NewStoreManager(kvstore, storePath) cd, _, err := e.GetClusterData() if err != nil { @@ -198,7 +202,7 @@ func NewPostgresKeeper(id string, cfg config, stop chan bool, end chan error) (* func (p *PostgresKeeper) publish() error { if kubernetes.OnKubernetes() { - log.Infof("running under kubernetes. Not publishing ourself to etcd") + log.Infof("running under kubernetes. Not using store discovery") return nil } discoveryInfo := &cluster.KeeperDiscoveryInfo{ @@ -207,7 +211,7 @@ func (p *PostgresKeeper) publish() error { } log.Debugf(spew.Sprintf("discoveryInfo: %#v", discoveryInfo)) - if _, err := p.e.SetKeeperDiscoveryInfo(p.id, discoveryInfo); err != nil { + if err := p.e.SetKeeperDiscoveryInfo(p.id, discoveryInfo); err != nil { return err } return nil @@ -718,6 +722,9 @@ func keeper(cmd *cobra.Command, args []string) { if cfg.clusterName == "" { log.Fatalf("cluster name required") } + if cfg.storeBackend == "" { + log.Fatalf("store backend type required") + } if err := os.MkdirAll(cfg.dataDir, 0700); err != nil { log.Fatalf("error: %v", err) diff --git a/cmd/proxy/proxy.go b/cmd/proxy/proxy.go index 909d733..5757f79 100644 --- a/cmd/proxy/proxy.go +++ b/cmd/proxy/proxy.go @@ -23,8 +23,8 @@ import ( "github.com/sorintlab/stolon/common" "github.com/sorintlab/stolon/pkg/cluster" - etcdm "github.com/sorintlab/stolon/pkg/etcd" "github.com/sorintlab/stolon/pkg/flagutil" + "github.com/sorintlab/stolon/pkg/store" "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/coreos/pkg/capnslog" "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/davecgh/go-spew/spew" @@ -46,18 +46,20 @@ var cmdProxy = &cobra.Command{ } type config struct { - etcdEndpoints string - clusterName string - listenAddress string - port string - stopListening bool - debug bool + storeBackend string + storeEndpoints string + clusterName string + listenAddress string + port string + stopListening bool + debug bool } var cfg config func init() { - cmdProxy.PersistentFlags().StringVar(&cfg.etcdEndpoints, "etcd-endpoints", common.DefaultEtcdEndpoints, "a comma-delimited list of etcd endpoints") + cmdProxy.PersistentFlags().StringVar(&cfg.storeBackend, "store-backend", "", "store backend type (etcd or consul)") + cmdProxy.PersistentFlags().StringVar(&cfg.storeEndpoints, "store-endpoints", "", "a comma-delimited list of store endpoints (defaults: 127.0.0.1:2379 for etcd, 127.0.0.1:8500 for consul)") cmdProxy.PersistentFlags().StringVar(&cfg.clusterName, "cluster-name", "", "cluster name") cmdProxy.PersistentFlags().StringVar(&cfg.listenAddress, "listen-address", "127.0.0.1", "proxy listening address") cmdProxy.PersistentFlags().StringVar(&cfg.port, "port", "5432", "proxy listening port") @@ -74,16 +76,18 @@ type ClusterChecker struct { listener *net.TCPListener pp *pollon.Proxy - e *etcdm.EtcdManager + e *store.StoreManager endPollonProxyCh chan error } func NewClusterChecker(id string, cfg config) (*ClusterChecker, error) { - etcdPath := filepath.Join(common.EtcdBasePath, cfg.clusterName) - e, err := etcdm.NewEtcdManager(cfg.etcdEndpoints, etcdPath, common.DefaultEtcdRequestTimeout) + storePath := filepath.Join(common.StoreBasePath, cfg.clusterName) + + kvstore, err := store.NewStore(store.Backend(cfg.storeBackend), cfg.storeEndpoints) if err != nil { - return nil, err + return nil, fmt.Errorf("cannot create store: %v", err) } + e := store.NewStoreManager(kvstore, storePath) return &ClusterChecker{ id: id, @@ -141,7 +145,7 @@ func (c *ClusterChecker) sendPollonConfData(confData pollon.ConfData) { } } -func (c *ClusterChecker) SetProxyInfo(e *etcdm.EtcdManager, cvVersion int, ttl time.Duration) error { +func (c *ClusterChecker) SetProxyInfo(e *store.StoreManager, cvVersion int, ttl time.Duration) error { proxyInfo := &cluster.ProxyInfo{ ID: c.id, ListenAddress: c.listenAddress, @@ -150,7 +154,7 @@ func (c *ClusterChecker) SetProxyInfo(e *etcdm.EtcdManager, cvVersion int, ttl t } log.Debugf(spew.Sprintf("proxyInfo: %#v", proxyInfo)) - if _, err := c.e.SetProxyInfo(proxyInfo, ttl); err != nil { + if err := c.e.SetProxyInfo(proxyInfo, ttl); err != nil { return err } return nil @@ -242,6 +246,9 @@ func proxy(cmd *cobra.Command, args []string) { if cfg.clusterName == "" { log.Fatalf("cluster name required") } + if cfg.storeBackend == "" { + log.Fatalf("store backend type required") + } u := uuid.NewV4() id := fmt.Sprintf("%x", u[:4]) diff --git a/cmd/sentinel/handlers.go b/cmd/sentinel/handlers.go index 3da8baa..b8b9c47 100644 --- a/cmd/sentinel/handlers.go +++ b/cmd/sentinel/handlers.go @@ -48,7 +48,7 @@ func (s *Sentinel) updateConfigHandler(w http.ResponseWriter, req *http.Request) s.updateMutex.Lock() defer s.updateMutex.Unlock() - if !isLeader(s.l, s.id) { + if !s.isLeader() { log.Errorf("we aren't the sentinels leader. cannot process config update request.") http.Error(w, "we aren't the sentinels leader. cannot process config update request.", http.StatusBadRequest) } @@ -57,15 +57,11 @@ func (s *Sentinel) updateConfigHandler(w http.ResponseWriter, req *http.Request) e := s.e - cd, res, err := e.GetClusterData() + cd, pair, err := e.GetClusterData() if err != nil { log.Errorf("error retrieving cluster data: %v", err) http.Error(w, fmt.Sprintf("error retrieving cluster data: %v", err), http.StatusInternalServerError) } - var prevCDIndex uint64 - if res != nil { - prevCDIndex = res.Node.ModifiedIndex - } if cd == nil { log.Errorf("empty cluster data") @@ -81,8 +77,7 @@ func (s *Sentinel) updateConfigHandler(w http.ResponseWriter, req *http.Request) newcv := cd.ClusterView.Copy() newcv.Config = config newcv.Version += 1 - _, err = e.SetClusterData(cd.KeepersState, newcv, prevCDIndex) - if err != nil { + if _, err := e.SetClusterData(cd.KeepersState, newcv, pair); err != nil { log.Errorf("error saving clusterdata: %v", err) http.Error(w, fmt.Sprintf("error saving clusterdata: %v", err), http.StatusInternalServerError) } diff --git a/cmd/sentinel/sentinel.go b/cmd/sentinel/sentinel.go index 8522845..e3e8020 100644 --- a/cmd/sentinel/sentinel.go +++ b/cmd/sentinel/sentinel.go @@ -30,13 +30,13 @@ import ( "github.com/sorintlab/stolon/common" "github.com/sorintlab/stolon/pkg/cluster" - etcdm "github.com/sorintlab/stolon/pkg/etcd" "github.com/sorintlab/stolon/pkg/flagutil" "github.com/sorintlab/stolon/pkg/kubernetes" + "github.com/sorintlab/stolon/pkg/store" - "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/coreos/fleet/pkg/lease" "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/coreos/pkg/capnslog" "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/davecgh/go-spew/spew" + "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/docker/swarm/leadership" "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/jmoiron/jsonq" "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/satori/go.uuid" "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/spf13/cobra" @@ -51,7 +51,8 @@ var cmdSentinel = &cobra.Command{ } type config struct { - etcdEndpoints string + storeBackend string + storeEndpoints string clusterName string listenAddress string port string @@ -63,7 +64,8 @@ type config struct { var cfg config func init() { - cmdSentinel.PersistentFlags().StringVar(&cfg.etcdEndpoints, "etcd-endpoints", common.DefaultEtcdEndpoints, "a comma-delimited list of etcd endpoints") + cmdSentinel.PersistentFlags().StringVar(&cfg.storeBackend, "store-backend", "", "store backend type (etcd or consul)") + cmdSentinel.PersistentFlags().StringVar(&cfg.storeEndpoints, "store-endpoints", "", "a comma-delimited list of store endpoints (defaults: 127.0.0.1:2379 for etcd, 127.0.0.1:8500 for consul)") cmdSentinel.PersistentFlags().StringVar(&cfg.clusterName, "cluster-name", "", "cluster name") cmdSentinel.PersistentFlags().StringVar(&cfg.listenAddress, "listen-address", "localhost", "sentinel listening address") cmdSentinel.PersistentFlags().StringVar(&cfg.port, "port", "6431", "sentinel listening port") @@ -76,72 +78,41 @@ func init() { capnslog.SetFormatter(capnslog.NewPrettyFormatter(os.Stderr, true)) } -func acquireLeadership(lManager lease.Manager, machID string, ver int, ttl time.Duration) lease.Lease { - existing, err := lManager.GetLease(common.SentinelLeaseName) - if err != nil { - log.Errorf("unable to determine current lessee: %v", err) - return nil - } - - var l lease.Lease - if existing == nil { - l, err = lManager.AcquireLease(common.SentinelLeaseName, machID, ver, ttl) +func (s *Sentinel) electionLoop() { + for { + log.Infof("Trying to acquire sentinels leadership") + electedCh, errCh, err := s.candidate.RunForElection() if err != nil { - log.Errorf("sentinel leadership acquisition failed: %v", err) - return nil - } else if l == nil { - log.Debugf("unable to acquire sentinel leadership") - return nil + return } - log.Infof("sentinel leadership acquired") - return l + for { + select { + case elected := <-electedCh: + s.leaderMutex.Lock() + if elected { + log.Infof("sentinel leadership acquired") + s.leader = true + } else { + if s.leader { + log.Infof("sentinel leadership lost") + } + s.leader = false + } + s.leaderMutex.Unlock() + + case err := <-errCh: + if err != nil { + log.Errorf("election loop error: %v", err) + } + goto end + case <-s.stop: + log.Debugf("stopping election Loop") + return + } + } + end: + time.Sleep(10 * time.Second) } - - if existing.Version() >= ver { - log.Debugf("lease already held by Machine(%s) operating at acceptable version %d", existing.MachineID(), existing.Version()) - return existing - } - - rem := existing.TimeRemaining() - l, err = lManager.StealLease(common.SentinelLeaseName, machID, ver, ttl+rem, existing.Index()) - if err != nil { - log.Errorf("sentinel leadership steal failed: %v", err) - return nil - } else if l == nil { - log.Debugf("unable to steal sentinel leadership") - return nil - } - - log.Infof("stole sentinel leadership from Machine(%s)", existing.MachineID()) - - if rem > 0 { - log.Infof("waiting %v for previous lease to expire before continuing reconciliation", rem) - <-time.After(rem) - } - - return l -} - -func renewLeadership(l lease.Lease, ttl time.Duration) lease.Lease { - err := l.Renew(ttl) - - if err != nil { - log.Errorf("sentinel leadership lost, renewal failed: %v", err) - return nil - } - - log.Debugf("sentinel leadership renewed") - return l -} - -func isLeader(l lease.Lease, machID string) bool { - if l == nil { - return false - } - if l.MachineID() != machID { - return false - } - return true } func getKeeperInfo(ctx context.Context, kdi *cluster.KeeperDiscoveryInfo) (*cluster.KeeperInfo, error) { @@ -220,21 +191,7 @@ func (s *Sentinel) setSentinelInfo(ttl time.Duration) error { } log.Debugf(spew.Sprintf("sentinelInfo: %#v", sentinelInfo)) - if _, err := s.e.SetSentinelInfo(sentinelInfo, ttl); err != nil { - return err - } - return nil -} - -func (s *Sentinel) setLeaderSentinelInfo(ttl time.Duration) error { - sentinelInfo := &cluster.SentinelInfo{ - ID: s.id, - ListenAddress: s.listenAddress, - Port: s.port, - } - log.Debugf(spew.Sprintf("sentinelInfo: %#v", sentinelInfo)) - - if _, err := s.e.SetLeaderSentinelInfo(sentinelInfo, ttl); err != nil { + if err := s.e.SetSentinelInfo(sentinelInfo, ttl); err != nil { return err } return nil @@ -654,26 +611,30 @@ func (s *Sentinel) isKeeperConverged(keeperState *cluster.KeeperState, cv *clust } type Sentinel struct { - id string - e *etcdm.EtcdManager - lManager lease.Manager - l lease.Lease - stop chan bool - end chan bool + id string + e *store.StoreManager + + candidate *leadership.Candidate + stop chan bool + end chan bool listenAddress string port string clusterConfig *cluster.Config updateMutex sync.Mutex + leader bool + leaderMutex sync.Mutex } func NewSentinel(id string, cfg config, stop chan bool, end chan bool) (*Sentinel, error) { - etcdPath := filepath.Join(common.EtcdBasePath, cfg.clusterName) - e, err := etcdm.NewEtcdManager(cfg.etcdEndpoints, etcdPath, common.DefaultEtcdRequestTimeout) + storePath := filepath.Join(common.StoreBasePath, cfg.clusterName) + + kvstore, err := store.NewStore(store.Backend(cfg.storeBackend), cfg.storeEndpoints) if err != nil { - return nil, fmt.Errorf("cannot create etcd manager: %v", err) + return nil, fmt.Errorf("cannot create store: %v", err) } + e := store.NewStoreManager(kvstore, storePath) cd, _, err := e.GetClusterData() if err != nil { @@ -694,14 +655,15 @@ func NewSentinel(id string, cfg config, stop chan bool, end chan bool) (*Sentine } log.Debugf(spew.Sprintf("clusterConfig: %#v", clusterConfig)) - lManager := e.NewLeaseManager() + candidate := leadership.NewCandidate(kvstore, filepath.Join(storePath, common.SentinelLeaderKey), id, 15*time.Second) return &Sentinel{ id: id, e: e, listenAddress: cfg.listenAddress, port: cfg.port, - lManager: lManager, + candidate: candidate, + leader: false, clusterConfig: clusterConfig, stop: stop, end: end}, nil @@ -719,11 +681,14 @@ func (s *Sentinel) Start() { ctx, cancel := context.WithCancel(context.Background()) timerCh := time.NewTimer(0).C + go s.electionLoop() + for true { select { case <-s.stop: log.Debugf("stopping stolon sentinel") cancel() + s.candidate.Stop() s.end <- true return case <-timerCh: @@ -742,20 +707,22 @@ func (s *Sentinel) Start() { } } +func (s *Sentinel) isLeader() bool { + s.leaderMutex.Lock() + defer s.leaderMutex.Unlock() + return s.leader +} + func (s *Sentinel) clusterSentinelCheck(pctx context.Context) { s.updateMutex.Lock() defer s.updateMutex.Unlock() e := s.e - cd, res, err := e.GetClusterData() + cd, prevCDPair, err := e.GetClusterData() if err != nil { log.Errorf("error retrieving cluster data: %v", err) return } - var prevCDIndex uint64 - if res != nil { - prevCDIndex = res.Node.ModifiedIndex - } var cv *cluster.ClusterView var keepersState cluster.KeepersState @@ -774,13 +741,10 @@ func (s *Sentinel) clusterSentinelCheck(pctx context.Context) { s.clusterConfig = cv.Config.ToConfig() if err := s.setSentinelInfo(2 * s.clusterConfig.SleepInterval); err != nil { - log.Errorf("cannot update leader sentinel info: %v", err) + log.Errorf("cannot update sentinel info: %v", err) return } - // TODO(sgotti) better ways to calculate leaseTTL? - leaseTTL := s.clusterConfig.SleepInterval + s.clusterConfig.RequestTimeout*4 - ctx, cancel := context.WithTimeout(pctx, s.clusterConfig.RequestTimeout) keepersDiscoveryInfo, err := s.discover(ctx) cancel() @@ -804,29 +768,7 @@ func (s *Sentinel) clusterSentinelCheck(pctx context.Context) { cancel() log.Debugf(spew.Sprintf("keepersPGState: %#v", keepersPGState)) - var l lease.Lease - if isLeader(s.l, s.id) { - log.Infof("I'm the sentinels leader") - l = renewLeadership(s.l, leaseTTL) - } else { - log.Infof("trying to acquire sentinels leadership") - l = acquireLeadership(s.lManager, s.id, 1, leaseTTL) - } - - // log all leadership changes - if l != nil && s.l == nil && l.MachineID() != s.id { - log.Infof("sentinel leader is %s", l.MachineID()) - } else if l != nil && s.l != nil && l.MachineID() != l.MachineID() { - log.Infof("sentinel leadership changed from %s to %s", l.MachineID(), l.MachineID()) - } - - s.l = l - - if !isLeader(s.l, s.id) { - return - } - if err := s.setLeaderSentinelInfo(leaseTTL); err != nil { - log.Errorf("cannot update leader sentinel info: %v", err) + if !s.isLeader() { return } @@ -834,8 +776,7 @@ func (s *Sentinel) clusterSentinelCheck(pctx context.Context) { // Cluster first initialization newcv := cluster.NewClusterView() newcv.Version = 1 - _, err = e.SetClusterData(nil, newcv, 0) - if err != nil { + if _, err = e.SetClusterData(nil, newcv, nil); err != nil { log.Errorf("error saving clusterdata: %v", err) } return @@ -854,8 +795,7 @@ func (s *Sentinel) clusterSentinelCheck(pctx context.Context) { log.Debugf("newcv changed from previous cv") } - _, err = e.SetClusterData(newKeepersState, newcv, prevCDIndex) - if err != nil { + if _, err := e.SetClusterData(newKeepersState, newcv, prevCDPair); err != nil { log.Errorf("error saving clusterdata: %v", err) } } @@ -880,6 +820,9 @@ func sentinel(cmd *cobra.Command, args []string) { if cfg.clusterName == "" { log.Fatalf("cluster name required") } + if cfg.storeBackend == "" { + log.Fatalf("store backend type required") + } if kubernetes.OnKubernetes() { if cfg.keeperKubeLabelSelector == "" { log.Fatalf("keeper-kube-label-selector must be define under kubernetes") diff --git a/cmd/stolonctl/config_get.go b/cmd/stolonctl/config_get.go index 56c070a..a9fb342 100644 --- a/cmd/stolonctl/config_get.go +++ b/cmd/stolonctl/config_get.go @@ -22,7 +22,7 @@ import ( "github.com/sorintlab/stolon/common" "github.com/sorintlab/stolon/pkg/cluster" - etcdm "github.com/sorintlab/stolon/pkg/etcd" + "github.com/sorintlab/stolon/pkg/store" "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/spf13/cobra" ) @@ -37,7 +37,7 @@ func init() { cmdConfig.AddCommand(cmdConfigGet) } -func getConfig(e *etcdm.EtcdManager) (*cluster.NilConfig, error) { +func getConfig(e *store.StoreManager) (*cluster.NilConfig, error) { cv, _, err := e.GetClusterView() if err != nil { return nil, fmt.Errorf("cannot get clusterview: %v", err) @@ -53,11 +53,13 @@ func getConfig(e *etcdm.EtcdManager) (*cluster.NilConfig, error) { } func configGet(cmd *cobra.Command, args []string) { - etcdPath := filepath.Join(common.EtcdBasePath, cfg.clusterName) - e, err := etcdm.NewEtcdManager(cfg.etcdEndpoints, etcdPath, common.DefaultEtcdRequestTimeout) + storePath := filepath.Join(common.StoreBasePath, cfg.clusterName) + + kvstore, err := store.NewStore(store.Backend(cfg.storeBackend), cfg.storeEndpoints) if err != nil { - die("error: %v", err) + die("cannot create store: %v", err) } + e := store.NewStoreManager(kvstore, storePath) cfg, err := getConfig(e) if err != nil { diff --git a/cmd/stolonctl/config_patch.go b/cmd/stolonctl/config_patch.go index 6ea22f2..120b827 100644 --- a/cmd/stolonctl/config_patch.go +++ b/cmd/stolonctl/config_patch.go @@ -23,7 +23,7 @@ import ( "github.com/sorintlab/stolon/common" "github.com/sorintlab/stolon/pkg/cluster" - etcdm "github.com/sorintlab/stolon/pkg/etcd" + "github.com/sorintlab/stolon/pkg/store" "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/spf13/cobra" "github.com/sorintlab/stolon/Godeps/_workspace/src/k8s.io/kubernetes/pkg/util/strategicpatch" @@ -47,7 +47,7 @@ func init() { cmdConfig.AddCommand(cmdConfigPatch) } -func patchConfig(e *etcdm.EtcdManager, ncj []byte) error { +func patchConfig(e *store.StoreManager, ncj []byte) error { curnc, err := getConfig(e) if err != nil { return fmt.Errorf("cannot get config: %v", err) @@ -97,11 +97,12 @@ func configPatch(cmd *cobra.Command, args []string) { } } - etcdPath := filepath.Join(common.EtcdBasePath, cfg.clusterName) - e, err := etcdm.NewEtcdManager(cfg.etcdEndpoints, etcdPath, common.DefaultEtcdRequestTimeout) + storePath := filepath.Join(common.StoreBasePath, cfg.clusterName) + kvstore, err := store.NewStore(store.Backend(cfg.storeBackend), cfg.storeEndpoints) if err != nil { - die("error: %v", err) + die("cannot create store: %v", err) } + e := store.NewStoreManager(kvstore, storePath) if err = patchConfig(e, config); err != nil { die("failed to patch config: %v", err) diff --git a/cmd/stolonctl/config_replace.go b/cmd/stolonctl/config_replace.go index b615f2e..0927e4b 100644 --- a/cmd/stolonctl/config_replace.go +++ b/cmd/stolonctl/config_replace.go @@ -23,7 +23,7 @@ import ( "path/filepath" "github.com/sorintlab/stolon/common" - etcdm "github.com/sorintlab/stolon/pkg/etcd" + "github.com/sorintlab/stolon/pkg/store" "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/spf13/cobra" ) @@ -46,8 +46,13 @@ func init() { cmdConfig.AddCommand(cmdConfigReplace) } -func replaceConfig(e *etcdm.EtcdManager, config []byte) error { - lsi, _, err := e.GetLeaderSentinelInfo() +func replaceConfig(e *store.StoreManager, config []byte) error { + lsid, err := e.GetLeaderSentinelId() + if err != nil { + die("cannot get leader sentinel info") + } + + lsi, _, err := e.GetSentinelInfo(lsid) if lsi == nil { return fmt.Errorf("leader sentinel info not available") } @@ -88,11 +93,13 @@ func configReplace(cmd *cobra.Command, args []string) { } } - etcdPath := filepath.Join(common.EtcdBasePath, cfg.clusterName) - e, err := etcdm.NewEtcdManager(cfg.etcdEndpoints, etcdPath, common.DefaultEtcdRequestTimeout) + storePath := filepath.Join(common.StoreBasePath, cfg.clusterName) + + kvstore, err := store.NewStore(store.Backend(cfg.storeBackend), cfg.storeEndpoints) if err != nil { - die("error: %v", err) + die("cannot create store: %v", err) } + e := store.NewStoreManager(kvstore, storePath) if err = replaceConfig(e, config); err != nil { die("error: %v", err) diff --git a/cmd/stolonctl/listclusters.go b/cmd/stolonctl/listclusters.go index 9618a08..02b8efa 100644 --- a/cmd/stolonctl/listclusters.go +++ b/cmd/stolonctl/listclusters.go @@ -15,17 +15,15 @@ package main import ( - "net/http" + "fmt" "path/filepath" "sort" - "strings" "github.com/sorintlab/stolon/common" - etcdm "github.com/sorintlab/stolon/pkg/etcd" + "github.com/sorintlab/stolon/pkg/store" - etcd "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/coreos/etcd/client" + libkvstore "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/docker/libkv/store" "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/spf13/cobra" - "github.com/sorintlab/stolon/Godeps/_workspace/src/golang.org/x/net/context" ) var cmdListClusters = &cobra.Command{ @@ -37,32 +35,29 @@ func init() { cmdStolonCtl.AddCommand(cmdListClusters) } -func getClusters(etcdBasePath string) ([]string, error) { - eCfg := etcd.Config{ - Transport: &http.Transport{}, - Endpoints: strings.Split(cfg.etcdEndpoints, ","), - } - eClient, err := etcd.New(eCfg) +func getClusters(storeBasePath string) ([]string, error) { + kvstore, err := store.NewStore(store.Backend(cfg.storeBackend), cfg.storeEndpoints) if err != nil { - return nil, err + return nil, fmt.Errorf("cannot create store: %v", err) } - kAPI := etcd.NewKeysAPI(eClient) clusters := []string{} - res, err := kAPI.Get(context.Background(), etcdBasePath, &etcd.GetOptions{Recursive: true, Quorum: true}) - if err != nil && !etcdm.IsEtcdNotFound(err) { - return nil, err - } else if !etcdm.IsEtcdNotFound(err) { - for _, node := range res.Node.Nodes { - clusters = append(clusters, filepath.Base(node.Key)) + pairs, err := kvstore.List(storeBasePath) + if err != nil { + if err != libkvstore.ErrKeyNotFound { + return nil, err } + return clusters, nil + } + for _, pair := range pairs { + clusters = append(clusters, filepath.Base(pair.Key)) } sort.Strings(clusters) return clusters, nil } func listClusters(cmd *cobra.Command, args []string) { - clusters, err := getClusters(common.EtcdBasePath) + clusters, err := getClusters(common.StoreBasePath) if err != nil { die("cannot get clusters: %v", err) } diff --git a/cmd/stolonctl/status.go b/cmd/stolonctl/status.go index aedbdbb..a11ed65 100644 --- a/cmd/stolonctl/status.go +++ b/cmd/stolonctl/status.go @@ -23,7 +23,7 @@ import ( "github.com/sorintlab/stolon/common" "github.com/sorintlab/stolon/pkg/cluster" - etcdm "github.com/sorintlab/stolon/pkg/etcd" + "github.com/sorintlab/stolon/pkg/store" "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/spf13/cobra" ) @@ -82,18 +82,20 @@ func status(cmd *cobra.Command, args []string) { if cfg.clusterName == "" { die("cluster name required") } - etcdPath := filepath.Join(common.EtcdBasePath, cfg.clusterName) - e, err := etcdm.NewEtcdManager(cfg.etcdEndpoints, etcdPath, common.DefaultEtcdRequestTimeout) + storePath := filepath.Join(common.StoreBasePath, cfg.clusterName) + + kvstore, err := store.NewStore(store.Backend(cfg.storeBackend), cfg.storeEndpoints) if err != nil { - die("cannot create etcd manager: %v", err) + die("cannot create store: %v", err) } + e := store.NewStoreManager(kvstore, storePath) sentinelsInfo, err := e.GetSentinelsInfo() if err != nil { die("cannot get sentinels info: %v", err) } - lsi, _, err := e.GetLeaderSentinelInfo() + lsid, err := e.GetLeaderSentinelId() if err != nil { die("cannot get leader sentinel info") } @@ -107,8 +109,8 @@ func status(cmd *cobra.Command, args []string) { fmt.Fprintf(tabOut, "ID\tLISTENADDRESS\tLEADER\n") for _, si := range sentinelsInfo { leader := false - if lsi != nil { - if si.ID == lsi.ID { + if lsid != "" { + if si.ID == lsid { leader = true } } diff --git a/cmd/stolonctl/stolonctl.go b/cmd/stolonctl/stolonctl.go index a639385..3b2d52c 100644 --- a/cmd/stolonctl/stolonctl.go +++ b/cmd/stolonctl/stolonctl.go @@ -19,7 +19,6 @@ import ( "os" "strings" - "github.com/sorintlab/stolon/common" "github.com/sorintlab/stolon/pkg/flagutil" "github.com/sorintlab/stolon/Godeps/_workspace/src/github.com/spf13/cobra" @@ -28,17 +27,27 @@ import ( var cmdStolonCtl = &cobra.Command{ Use: "stolonctl", Short: "stolon command line client", + PersistentPreRun: func(cmd *cobra.Command, args []string) { + if cfg.clusterName == "" { + die("cluster name required") + } + if cfg.storeBackend == "" { + die("store backend type required") + } + }, } type config struct { - etcdEndpoints string - clusterName string + storeBackend string + storeEndpoints string + clusterName string } var cfg config func init() { - cmdStolonCtl.PersistentFlags().StringVar(&cfg.etcdEndpoints, "etcd-endpoints", common.DefaultEtcdEndpoints, "a comma-delimited list of etcd endpoints") + cmdStolonCtl.PersistentFlags().StringVar(&cfg.storeBackend, "store-backend", "", "store backend type (etcd or consul)") + cmdStolonCtl.PersistentFlags().StringVar(&cfg.storeEndpoints, "store-endpoints", "", "a comma-delimited list of store endpoints (defaults: 127.0.0.1:2379 for etcd, 127.0.0.1:8500 for consul)") cmdStolonCtl.PersistentFlags().StringVar(&cfg.clusterName, "cluster-name", "", "cluster name") } diff --git a/common/common.go b/common/common.go index f6fbc19..1ee3bb4 100644 --- a/common/common.go +++ b/common/common.go @@ -14,17 +14,10 @@ package common -import "time" - const ( - EtcdBasePath = "/stolon/cluster" - EtcdLeaderKey = "leader" + StoreBasePath = "stolon/cluster" - SentinelLeaseName = "sentinel-leader" - - DefaultEtcdRequestTimeout = 5 * time.Second - - DefaultEtcdEndpoints = "http://127.0.0.1:4001,http://127.0.0.1:2379" + SentinelLeaderKey = "sentinel-leader" ) type Role uint8 diff --git a/doc/architecture.png b/doc/architecture.png index ed96ae496c01de2c58973449a0d1a6081d6a6362..8547a0d2a930fb2dd68f95a24f08cf4b8d59ec8a 100644 GIT binary patch literal 88169 zcma%jWmH^2vn?8e2MWa}^(){?f7g#R;0Kc1 z2YHRxz?c7P^RK|~sLpb_Zou>NFW>N@e{{}(i^T39b=*HWS-N|fx>~?_d3mwfING_H znL1mrIk{S8ort`HgQJ9#mzLD<&OTc6^8aK()OThq#9%nxFuqP=?({~@nG)-bkIUu< z7idV^5PYb<3o}#Uw!}wxT`GpJN8LAU7Vfn?J}?303!y%>GTa5$Np=vVY^Zeq4a<9<1-)^7 zWq^LCH6b+-u@3J5KAV$|s{|prhn0EHj|t&0IITHLn#)4cc>CSQcVx-uTq|0+`}NT< zx;=ZoK2npf{qGqG5<+9KBp5Y6-ykkT$cCQ|ZwLN%Aa`&V0i$cylBmpKak6B(yeUR; zC#V}=EK5NXk(5EnPhm=Yv*{8H6J5@JRn1IH8h38F##S?SNBwWPht$cOMFE*fxhdtG zwL9eB`vOS=4=21LGj%bO-GK@FNYRkYR}qC860_2Zj2p8=`3}$u=@BgsA;LXGJ@@Jl z_7fZlHxFX3B8xQoW?miv5#_7QF%<2niTyMOFBtuMOB@Xfk;7vx@mFM#a3^5BulZIB zn(tbls*o8j(4hR!u%8h)Z2DO=5wMOwlEi`blz^vGKnmqtg;8lB1;!E$;+K(uOBFHJ zg)es)HD!2aKnleB-%Xj{n%pNU76rN7Utp834Z_XEV{kl;e#iU1N16jtNHzL81J6*B zBCgwdOA}Sfg&L1h@KDkmgC)yo!2v881P&APapl&Bi7Fcu$ypwCFCI9jfL_f3uiI;W zwV{@mw)PqRYgLt#wgTfu5!66|v39;Kz~WtNt-bqO1xAm_mudKDc>V}4{-g^x_y>)e zq0B!zQJ+OC3AbTXZv6cZUt}hkv=aw5(V<^U$=?Sxu&G59Hn>tjv_;T&3gsY0RnChG zKfl|-20nOGz+v}nBm(38^7XeNtdg!T-eK_?!^ZYS)GJt7cSlHdgbM8afWu`;`_v*ImJcgUuG zenw{~@z0^t117uFa?Yb_+#LF8gbVG7WyF5(vlxg(_p`;nVl0EipnR@zM3z zsF+@VK`1MQgmuOtZYWf&F2sRZb?)KYvVpInlr4W04KHI>P@v%OuLaK}vzGIjwu#HP zplDy#!izxYpY&yp?E=d#w+&w`d&M6L)!$-Z6?O$9PRo*zY(@e(1kM>Wgc@WzILuhg zk3Lb6!BTzPed)nNi_ZRGv?E}2nEv;4^EJ+PGHME&Txhnf$4{Ge!8FqwUfM0WjuEpA z{$mNFBwiD9!{MO$)C4s@T+MDrf#Z9PBFRGqf3868&Of<(3)t6OkAVx_3ILv1{u*~^ zKZzo|>)H5WrCG6n2|4y#Fq>@QfXqF`1T-72Pi1+;z*9Cftk#Byqs-m?d`JGEp9<<> zoW`wYFcES_UW6Dlov4Q|W}1G{n*MMX@-y3E?^hH?%d=l*j@_h5GYI>ZwC&YfWSVy* z1vmP9hYTpK&hUc`paW!NMp+g(wpP|Ep zRCv{V-4(9KZGr%f|AbqxmIUH%l+?v6A}jbz23y#WY5P=_-t)rbdqNrw@(Ixazdiyb(dQO6QzV{W=Pxv z0)A3utGc7KmkR;I9Ia)H_8*UBi{(nD>JjAR3g1TDXBe=gV3fa+Ub9qxi4L;|km3_R zL&>8tC9Pf_f?-&w@+!;`g{`-!e&&pUUA(_Q}46S7;DP8nSshCIg>P)K3pXOK? zh*4nNlMhL-o=53GT)kCd4wF*vF}a*$b%@eJDZU(0F{3_LnW-owtTKSo7ApFSR>-4Hvp0D2k zp>^WgY~q79#)_AmTamnHScV;g5`j365%-bUiR_f~6g5zfN9YZ1^*=aH-k&jXQg;c9 znLf<3O<9BCicSurF;T*R#WSuSweGPhmG^A-ZiJ$%iDi0Co9|wbUC%E~Fz>`{G~-

3?XmOcio*vtN=_?%0S}(A!7oY)Mib?I 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 #8 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

=)LK~H0_CUwX{{&}`fQ-5`CC82NiC_TL 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 diff --git a/doc/architecture.svg b/doc/architecture.svg index 8d0d5f8..9e96aca 100644 --- a/doc/architecture.svg +++ b/doc/architecture.svg @@ -5,6 +5,7 @@ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.1" @@ -31,12 +32,12 @@ id="namedview4072" showgrid="false" inkscape:zoom="1.3781786" - inkscape:cx="336.08005" - inkscape:cy="256.66142" + inkscape:cx="156.4952" + inkscape:cy="255.21023" inkscape:window-x="0" inkscape:window-y="34" inkscape:window-maximized="1" - inkscape:current-layer="layer1" + inkscape:current-layer="g8944" fit-margin-top="0" fit-margin-left="0" fit-margin-right="0" @@ -218,7 +219,7 @@ image/svg+xml - + @@ -353,13 +354,13 @@ @@ -383,13 +384,101 @@ etcd cluster + x="195.50092" + y="673.745">etcd or consul store + o1q1|?9(c(>Ljp&nP+{PKUq4($q}8B-A3tcb2;grRCn;@L z5D>_-|1Qux55F4VAdZ{3mYb@hg`20bi#dp=rzeB8gRQHnv6DH2ql;zs6(24L$WIVy zF<~{YoQqsfFSX&7pzY16mInn`nC_^DE#Fj%ZfLNmue!nj6?L_tUqL3q!aszCgsD}; zN}?kkFnJ1-6OiWtPoH1d4dbXbV-}p_{`r(h8=bC})6-kNSDCDq(?Md+?oC=LbzG?svU^hpa^ z%5T|&@Ns4BKanH39q_82eFt{!WOv~uO;L>I8!2}Ss+yd0Y*(0jcG`NsCe=tyaUEwm z2y>YS&FZ?&?Yx0^n$cjX0&mpReS%4sg{6h^bR^%$TwIyhkuNaI${hxgw#HChB#e5R z@(qd?t7n1r55)^D`{~)2Mpte75L*fsS&?|@EO1>0kwrkI$zW4D?0-`k zE|mA3Z}xo96rVfL-}sP65jsp`3Kg9c%&-(M(_HCV94t~^y=DqqN|d&LKWfls#A0r! z&A+SdT>-`I^_Z1rXYgKe=?3=5_%xsZALtTF^5(78{YvMnJK$TnJ&))&r5b1ms?OJ{ zcEI}{eyfT5OSqL4Zyg(>-&=`1vp?Slh;V7M7QKdsKSu1hQK3inPYQ<0_`ry;&E8R_ zz zWp3R(-g=$gO9S6FABxypxO3I&LcvH*H~eqP-MkgDp%Z9&%Q^x^pKr3No+yh8&gMT$ zED^Gls;_QCpk^#MrWQ*-ell}J1Le;KNd4Hpbd=R83bqz~W_A=oM+^9?xaraV;9HCe z5a1r1oT3Mr^^v(=Pl{>`c!iWn^>d9a13jB21=xUzuq&Vrwr9X&DqPCL8#15k;We&y zOeB~S!fNHvYjTu7QMg#y^09KX78tx6fq)ILsa2l8E3M$USp>XZ&@oO`O0Nf_w4CRE zw?P`la8G_)EQ@)(+pE*e=dSeBnDSnIx`=B`3qV0b9HLc-Fr=gCY!w^zmWU+|;>Z9r z|0Fu%J}IzY7baJxiGc&+B=kki6k{361OALZZAI3S2mhY91Yx}r`T}2uR$K3 zzh#`jKV(_})g^f{NxAe>$%&g}Lu)l@fQDZIQ)Pt*&IM{FlyO(7X`(eFV`(Qd=%o!qNE&~`$ki5rI;5@fC-0w1`GgKtZ(_!WHw(}+ewP1K#+b)(5%rP zZku)EkpF#xRi6kHNH%)z^sI6>SpS5iKKc^+_+qpp5T^ba&9W3)6dgHTprXGmsiNb) z_CvYcp6NI3M`U__l!pJHx2wUXpMUM>kZ!g5#RYen-_40)zFLZyd1`jBqxv%8Km3`J zt4=Ju$22aZ@Z$B9qge7Q*+ZXz54SQjegx1N8Y})wdK`l8_#Gj zg&602BpW%K_2E8VPVF2wtX7$sc@8~g$7o2ZuC-gdMxKn$UsC&G;y$aIWLrp%bEy4C zQ|;+~43# zDE|ntIl0#nUvK9>H`Nx{$6uK#N5d~HHP3f?>sB7;Kx;brRBiin@FR8k?)jKZ8E;RXj zv&hcfQNm9t_pck;c8@oFCjM5IVf>9u9@{0#1n`96aT#lFVNz7^W%&de4fy2l4UE|? z^k9Ry9SMsi7C>~KoL^1=htx?jv`-?Cw!NKwy7%XE=4RUKub7I08%Q?I1D^YFtX6vF zdH#wQj!KQf!ywSf;7F3!_Qs$1IGhXG&FS!y$` zNQ$Od?RWJ1)agK@_DWNZe?ah zxjwB{|71K9T>9g7klaBJwdw~CeB?o78F23vKQwtOZzMHbi1TCpA+x60Hroh$HwIjehXtIgyJ{_yO9Z*jsO8;nLyxQI1d9 zg^ut2>d55rVW$NMZmVV%ce!MOZNW(eh7wRksAN z0#hHrGN<%>tby$sXJX1$+fK*tHBZKN|CemjmEl@hlSg&j?(bkeuOuJs+xCr~G-^ zad%&RNuM`j)@}Eu2b96?#art)xD@mF1Ds73Onx35HT*?2Oj=W8%+mNs&?#D)zyYct}=a#u*{ zABhZfES#r0;i)RbQp&bct%ihJr$#&5LJl#49k^SMaL8><>|Tj z;yLS_HCcWyb6ovWvFLi2{2%Mqc~C@?%XqQ(a(XT4?R z2>Y7X1E+sta-Ed4=*PWOWxk}U9JjX;rd?Do2IRXED-vMXye1{uG;N0G1w4@=mCD48 z?__<&gqM!d(1Toqr0S1}I-IpMA_-TlvM?#)gl5N#Y>Hf+N{(GFPL2qQB~x;y49H6? zK?X?iR?G6imrk@Ldx^%6Th+I75Qf@)F95S@h1UD7is5!L3HFAe3x6XjszQ+l;AadZ zoNaHnk>{5&rCTM(4dqX@!P@-%8P`~Wg%7EQmmd{UiX0suc3uuqO{L_-%IMVktI5i$ zRrinoip4&CqhXu~dUj`2)KK|CTKeD9AD?fpSoF+uIH8+OvW+{NXcnm& z^+at4cG|Gm+zd^&En;({IK)WbAoqsWJ))jo>++Or*E%JXc&~SS8trxTm4$NI*~Nz!pE#Q-MSU_hJ$V3in2yN`pi`SVBJ0O;cv><_SO5|53|%OH*@ z)L|KG^Ac>VFP6`Xh z0oQ=S0aM+y{ONtZ0R8xmopw&#u*u;H~ayJ?GF18LO!H>ktd&psnd6OoCc~ zD)JQiTkcH%wp1o3Bg{&wY!U&rJk05a?Sgmf{&aLMZ{yx0&ykZ>*D;Pj@0%Wg_k+a; zu~6z#&6AM<+?Id|AknGIQT>qtWTt62e1VsNp`lDK?nRU|;Vbg(=;-F~CIGkm1*)n2 zlJP6zFzUxv(aW&g9}wz-@p>tlsvkck;pg-s%_E#5w1wJ|%@e6~{u|w?ytOV5x{WYe z3{XfDFFN^2O%GFE1YY*@*Q0>sO9&a+l_Z}@w{4`5icSpxcSy+@QfXnlL8^^|BILSG zObInL4eXW_3!=fa0~b8B0b5;UV2L_XrV4#JGHiws(}>VS_Z26o*L672NjYlTp(;MI z@!pyn+!8A7D80MS+6dJo%{d)7o8W{Qij8l!Y| z5Gs*iAvF{_{>G_>3ss?H=toAHSgAU`cJvtTEpbh{Q|-{C4L1(35Mdg1E{YD-6&!K; zMpRR;CLPP-fy$)64Io#NVu7`pQJjPZ;zbN39az_Y3U! zi%n!}C|C)uPb8;k>?X=7ko1`lz^baGX#8XXy`|`Y@dC5YrAgeECZ{a3#Vw#4YOw{I z8dKKU5;_;L>m@6cxUkBLMXf)!s4p#{s;2GB?n54G$k^|rFPBmCq65VQHv~I$&8^+< z<4`2V^ji_-6AP!}{?z|>f|ATsyCGlzs^*@@g$gl_D5i9(E|#^Q6oy;>g9>Oa)*WxC zmR9iFhPH@**UAIV@WOx7+QRDW-nlgKBY&Ad3@F=6&;?WfaTDswlq3d2B}jd;AS~*w zZvAH5?x&ZIiNfnv6m*{2#;ZueF}!(ZCrk#5 z=sDz)4v9pg1$F~rAo-GuiXwVci$ANtR<{BAD6^4k6@piyrHZY*fT2t?TIB2)IgT8( z6q&f@qyN)JUZk*vdN3;c46|c07dti|91FHkowEQ5R~{>+vfw?fNo!;7l-7tNv}jqZ zPz6(OEidL_q+;<{i3Tq4Xx4^3G1DD8+8V`#rGQBZM6r0z&DW@x_t)Ratg%C!3ii3s zEf0>O?f8u=&+v`&IQ5^f!^mcL5N?dawq3q3|tf%38e)evd@L>=*_`f;o%`CnW!BdgS4H$&Vulq^=v=8ZvPU zA3>Fot!=8-n&86MFo7gH_Maueq5AV*N0j|l4Ony^f{DACTS@VJ0%(=SND zo^uG77T7^>dN??Qj|&yf3t+?j_!brYzHy`T%H3hQW`MxTMty2SOT_fo1nDG%;Q_?;Abb`8}_e5 zCVuAPv8Q-p-5!%?gdBr*>$4Cs<4r)ikIw&<5`kHsBotUJBqNJLPnu6kNT5<_^H7qW zRL^)Mj`6|4oDNQw6d!tms}*hJ;65yq|5aAKGr;|?4Oc{VP&0aGSw4dm{OJ<&@QgD! zed|}B(bxp~3cC&B=KIm&l`6$=6w`}Cokv!^s4&hg4?iNV-;S0d(H>4b zupS=}4i2-v$W3Pnsul}6D4%+TuypUBsC&E75C!hxv9>$4?g^Qo7*zwT#l&QCdaZ5( zR!y^(QVROvPXjg8On2s7?(lK=L35^;=1~IR=K*NPo6*)uan}~Yjmu6~YK>q^B7SS%_Yb0d>A?k7hdwmr1R!1Cuczh-PV6)&~IToP&(y$Ok1s`ttJMZK7RFE{$Fc7w;?P=$LICrK$2O<;DlH zd*89T(3gUa9FuPX<#IyElOKfZDc{$C-FXPDPB;=kl&j+6ukx(u?4lWDFCXNKZ3M?| zko?JDYqZ_w$Qv_#<(@%RCV$w!hA_V+B3yY}g;Yo$XpXXZ02nuyDt0JaEI5;2S`X45 zM5B7Y*?C>xo-K0f6h;+(?J@#)MhYv>>i=Ne%~dQkX7w_r>w4!=tASMA3W;FZD+L>H zsanAf&`rAMEh!%;b7!*FDfIU*XL&x(2}q|E>-D^dqyM}2#;(;(Frk4w3Uj+>{(csc zb6hfW8Ib=B(Z#9yaQeN4{HcEk^J0{Po!G@8ox-Szg3E^XY0%ljm7d7(_sE$DeakZt z8t5hyW#+!``uPVZcpfHe{=4Ig1z1~YalHZj&gjDRTIXIwG^5C@SjAc zEom?w2&n?b>;iO2CLjAu2)Wj8sV~w>+)g1h8DWM~R5BQLGuIP9NM2YPXy)Q-RB*3+we3ZiEYXWAzl&mlMy{1d{+#dK4CY; zQvHh0(70jY#E7<5uW_p@XlXRd&W{Z+7_Wr&cMh0eE_9WSuAVK2>I8kwZbxkj**YKS z{$0Ohpd*wXx=WhKI}%ALGzcE=+Xm+3xIHgj3G^i7WVrry507XtVmVUx`{@TVXSs7C zY^?p!Ik?5Bq<7m(iYL)`DMt%)`^=E+q^bqp^YwHL{`;afnKtAwAq%XUH<2=`*PrvY z(@u*#E>M?*P%4(=d%L{C$r3Z^BA_?5bNhO1C=r?QYCVW|8tO;?)W#5^E`J4LtzOAPBPDA7k^lezfR=vXgnfa|Yhu{=i z+>Yfpl%X6N;`l}i1Gv0yG?e8M%dIG&qzjo3?>!)B8p z5f<&o?^V4Xko-XCT;GVoXTkLg0Bx$t$=5n+1P>kEe$q`5$gb9m{0G9Vqf^aSXXEy7 z(P4kWz|m&Ur}tD@rhD+YYrMel-0Vw0C-tyXz@dt9WG>%P(x(Ai%5nq5zz2jedG)t^ z7si$3pv6GRRujkZMp?5+BD({1TruL{Mf}dC;!dpRP~CksR%o#R=Vy4NttLHMPhC=- zndv_6?73^4<~N;13D{NgdX0}fbBRGa+p(Svtlid6{KubXe&-OormqjW*tdciA3D>6 zney9(PFL`LY&d6Z$oAd{Jzc zu)fxn83%byLrnnk`NYWnm;yNr>^s`V)TN~Zy5DFDU*!(hZ4X~^C)>)CVgU)Xp4tEp6Dl`Wg-N-zA6@=N zUW&WDyzclOc44(xhyH-$5k?S$OpwO1fz;>$n$0$e$rt`W-|yK>BB4F{j8?tH$2%@& zTCQF4j9xI^vXDAxt2qrV@C6IrulEkvo`4%UB&!wi$ppu5xE?*P?||n=G-95Ga_C-D zF>U7kiY3@@;=W_m;ZI)6NUzg4Z`H|*I3jStkF0%3IGEoWm*Qi?P!M^&wL05`)4`Yrp`n6&e)OP_(}aD zPyg%{zTA!C_offXYw6*wL>LD;j0Rjnnw<5RdP)YUuI!!m7xlI}qA~`D(u!+|auDQA z@S=iX-{GrO!UozSe{MDQz99JfiEn5)QB4|T>?5hR^*=a`(V2cX4W}h{u6o`tOcY$nm7#KZSRdgsgw+0Xb)gm#&fYef=HbfPm1 z0F!(YwQ0!6a8cGwm|>6#YWIMSnj&hc%4J~o7L;c8)fE*j;}jZyxz?J zHa;9MwWCY|3DEZPj?TOzKhJF?9v9tNOG~TGcP-cB=hJtYSlRu!mOpM0JTpITxu!Gl z8*IPawue6b)z$(m1Q8QEL&d4+m;l_1`-PXVj30aw#{WhL&{)M}$RSp=U>mWGImzXN zvyf60n^rQMVaGyjUB{{FTwQV6t)h{+aCyTwT`>#wZy#C!v>9^f>#DP&5IX4EaB79^ z@CWFsD94drJB3i8hr-dGo~>K~v8 zPOTCD^o%uJK+)1HS??r?p3O|?4K;-Ntb;ki^fSU$w^0`d-$Q6u@28}V-%!sTGu%xy zzVXSj$&fhL-`qJ7q!%$7u}nEB(e@^1-ZC;GF0Y!KQvK1YuCvKZtrcWV$Yh=mrmr5Y zSRX$T<~cQxe0a|~)ad#6C#5kG@vCNQ?p^-1U@0KpU^~14gXQLlI*X#ofKsx${^0#B z#SAB%v8`C+TS8;msxPtD%(H3jnmOxDxx6s=2KsmsS+{y`M*E!2JyQemvN0j6m1^Yu z|9b(F!We8p>K6LxZRV_wjad*1Jp92+0SCR?@)U_tZ#S8dNiscT$CwPAS>?7jZ4`~5S z3ZgQCb4q`dKr9BE4gPrS#J2*?`Qac?@V6@IM-B*wYTGA+Gu9a>kqTRC4QmC&gG&pt zI5ayG`0cNh1S+OV(EMF|Kxu_C7L_nt3;vmrAn21(w6A9lJAQhea>t}V!@sH;>#@j+`q>Eb8QY|bsn3`4Y1 zjek%XBH+ECc0(9W-9Sq|7WeYJ@J{m*oSY4WwQ$KZ%Y)v4m6k4LVi8;$9$jRZ$Z%t} znPh%D(;DD&Pw;+egv4@1J4|t@fQq?s5pip)xDu7aLnE%TL zvLz{_Po_Ls0VP*zw()O9$t7p@GH84nQ$%DyIVB}WZxF@WFNzmDSowd4=2D7Zjt_8Q z#DHdiV#PfSN>wrn*jP9jxI!}3^qPJj5i1vk z2fJe`mLv)ji5iK-l)h(~+9h@iSEEMyk*E$den?28v!tD!QjUvD_pds#Xt+FRK{IPh zI1=Jrnu?%IA#+PO6``2Y7rSL8*q5|D?wIrhFS>?L@?m1im2Bwqk_uJC#6SI;tG}eA z+GtpI^b7tpLU_xKC_jku*ns3KeVCpB6%9$JUQ<0oLlNC7lA$dz=Vpj}_}#`}NE$}b zol8GPnshm;0)iQGsI?fTv57*Apo+XLJP?|Yl4i?_#SEVA%lbpJ)!+-NNoYeCbI6lQ z=6Mx4Wbjkk%Te4M}$ z!Dxf5(c_ttQH7Q7*i*~~PJ4#c>xM&BdwpX`xmgzZcG zammSG(J@REhgE}cjK}SqE5)A6;1fXUoLYW9|3ocR0@hs|Kx7k0wxWL^CBJFLd69~f zd{7UYTT2KhLJWbe1P`{x6GZZoK-&Bi;pRi4>-fxst#?nQb;4mrd!G3X%Y#ju;5XWy z8}YD`9^4z;iY$6H&%X2a&d z+0YPU8$$u0F?#Nv*pdhJwo!{(wTOPqRQ`R&(&Q*_p6r7%c9>M-gKSxZrq#Tg@|f)S z#jI7m{M-68Y`4!FicNiKP@f%O*3xu7+wiN|wCe6`S$;x=W(=)#o_!-FQ(I!Ax#rfd ztn9QMGkan>kWsr=uWcnG=PxU+{PHs$CO|W23sin0xbRA+b>e}yDd)`TEd%Bs=_m&P$V&p_Ehh}>UfT>Bd=HYRfE&tKL(!Td#H~+)7)%% zgFnr>@tZ^YuN*73oGQwoU!Q?Bgf+Xvs03mq9@G2pX_?Rg_N{;7nWa^6%y*C52$03? z^v}$mM3|`)_C+$(`3+B_!e<;)6Bt1u+S?k_qbiX)^{*| zDSLxk#>~wWAl!O$19oKK&2HL3jsnh{)DNztr$}a#Qqg-8U`T z6|Wm0%2=oQ?UoWso&qkthGPG!W~ll{ybs@ox|@}Hzx`K(DE*YhxzA1*KJee^O@Ysk zPlc;2u#*eBBL?oV!0;LjEr0P$MT%C<%&DWi1J*O0V&#C@YJGC;6%UA3plVD+?|#|<7G;LV{PeEuS+XSk+5U8w^+66Cfs?VRz2A~_VpR*}hg4YO=!b?S@s2~8rr*hIVj>BlJ!WRHGRzB7@- zk&T>8u>bRxepNg5#=-0O^lYh#ccA`KR4@bupg19|hVsmfkNQuCZ<_QB6S6x`-obkc zXhfv!{!pfuTv=y%MT6GgoNlLRSf*2)3uDjQ5)|vt8bTHy(dm(%z3QyT-gb zu}=9i7%dT%w_zsBxJ-N!4M-N6@3WX$;K<%a@GiF5rs(Hg=}qk_Ujd(&YTJurrmF$= z_gu`J)luqrAo9(S8?O61;dW*Itn-c{8JWde4Ra=4*XNF|w()!V2oNIClpQe@o4&$mrh1FqHnl&RS=XLk zD+LvZ;e6wVdkIU`re-QuuXHsW`P7ZJd#yjA&0I3mB#B6D7Fgh$JDUDz88vJ~Yr8)0 z=)anN{qsQ#+ArU$*!R%BLY>-Cqy1 z&!;4_AOQ+Gb@fnf*~MbJc;nx7w_rI5>@{Y}vOje5L7VArPwT_o3%L1n$IKu0ZTHM# zyAp^(YG5cDzblAlU`Y|1pJiCE-3tsQTt-E6#r7>DL_{Qay`SzDX^G{M^p?kYvKQLl z_|28!1)Le!ck?t7@D)>e?lZSjlAAA%pRQ~b1S7ht;y>HxtSoLaQsFPOe}6AWv-mE@ z7Ks;2ZTSTz>*Kv68XjLSk-l6ll)s#(TY3dZ>2G;CqWS!W38H58aJtukr1Xf{eaGR~ z`qCG~oVuE7`;&c1SO-{1!nwBt=U^lnY2fzvYS8JwWIwA>-`lO3zmIswt5l1E#Q?nX zy772Ef6=m?*9QTkxb6k8RgnTq5zv*I8kl2pTxmHTkvG{a>X?v{GkLgS;q%h z1K%EIoVjFaLBU91IL#fmA9~ZBUt`cZcFm>hl*Caz3xAI|24>p zIhK^316v9xX;R^KmZg;~R&xa8KD?skZ_QcnI|H@3dj)}NtTtPa;kD*lK0R~8-Ym6p zHazCTU2NX)0jDCj?s2hd$Zpp<1J{-s?UtNzmk=lqC&g+A{knzT3q`aACoN>Hfk%A@ zf8#0_v^NEex69Uu6gK|v4}qjHr+T~FlSr zfqNJ742H56LqTg~f@8`PZ$tg zUjkiqke%6Et#$W2LYh20y%l1A(4FHd_PYqY44vxbS(V_p^+k)ruw*yFu8=?bYd3R4 z9%E)KKzwoy*qDKGY%Y}Uh6WiB?Rxc6@eSB^%c9Fgi5{NNgnME>j9qTBQiBYdRWb16 zX$Qw^&27Z%fOzY?za8?RN`>v>Tk^YC)+}PAY_Ja3qGLK9{baL69&clwQliEH&X>j6 zMz@w{A?VJmjq{qyNLFgVixnp9@9WnY#NHq~;vm08q=&w|xAT%z5+Y+N^v==#YrDk% zt|1Wr)Y;2zHMxXgVL_P8Uj-K=qG!pB5!kF;=oU3k`zD0wn?NX+lAAW^Kjy!E#xVEs zsFcaCS<>#|n5fCc3STN$)<=<9=rSf_6j04~4A?-5FggtdAhCX4A};!?xGA$R^xy8rWuzVcT<3)N(J&rZmD<&1marS5zzB&8YtKm8D<) zlb@#r`rJsK7|xuoTL*>x28jAKWLSxF@dvE+I?8{R;&8ehzj(96dkJ^b9pC4#TU4Oh zyx1e@audB}5!VPog6MK#fF}|PkoNMakdj?#+({qw7-Y-c3R$8F*ymv%LNI95p-!2| zxmGG`V(bsj%Mr*IYJE!O_P(N6F;zWf>iY^98)I>~`t>>Ar?Uh%{nm|EJt7auS4p8( zl>&SIJNhu5n6Y|jP=C1hTq1G3jm!OtLW9EI%5Y>xLxLiC?tV4@aso(U zrT!758Fyzrfd{=c4`c`&6E(O=OdGU?j+^b?dw(-KN>8(RU;V~V%0i_ z8T}NnX~wf?T$(DZni`F@9_b-n0n$LqmKtmeRSKI_tEYqMbZD5KPK-o?0B5gzI1i1* zO{tE-=adXO%owP*PSSJ$(5>XWi!mHytv$AV(4&$t)O4#=kgs&e@6!p2bl)dhnt!co zs9ZCs|Iu3Bf_PqYjfIB0-P4JQNWPq_hh3ssRYdLLsZ89AJ}>}iIn0bEWR;amEE!24 z{xyAmJt=&wP}>sFjj8%;Nk`YwTsw&bK)gMEx`+4fD7*BNsmucsNC~9s^kdxb^>aMc z`G+5Go!iYZwej5!Ju5P#RqV$BC)@il1EP0`zx`dcyFzc@xzw!xEWv7gG6nUUYRor0 zi?n?4`~W_K;HO7S>u5`tBX6LCVEmj_OZU`@1JCbH z4e8j*evl?xgSh+^vD>#33Usv_JLdwo3eM=>3;B1@=u=>tKgU8ESr8RJyaNS-^hUD` zFB~1GO)4I4GoDWDIzPb7^+OGxB6)cE8Awke6{X5$#0wK_)DVv5m(1P-$g3ARlM}(u zXa5TSAT|8XrOO>Z>Zwp>&%iiWn5|b2^+im!RYS0tiz02ZRVEDFen(nDB#18c4X5EA z9W{-FzVFwsD)Bk|dEkQ6vy}z)wHz8em~WJ-($Bd4R4QJ~(sa?CpnB|piht7I1Y@81 zamr!fYe`zgnP>94Mnw_O6uMhm4cWJ?37||~zwbZh_4d9a`n%;7^&iiBO|FI~Y-Ca7 z-3w zL*y6#YWPBwHV+qwlhn1R$Y6UbU| zGEKsv2fA-ofc^G%{jga>{muwqmi7rWL`X1hp}CVnDa?>pTH*4D3K)RAf&DKrwX% z(s#Dx5h!JY2+|Yzx5Fim53HN&-YtK-a9GvoFeiuxcK1DScV_Z`3&KmV0^gQSfu5gD ztq%;xTsY&kH4K;sPs?@3!BZA9n9FxYi-j4{*Ne?K;ERb*>$WrCMzEMA}<1Lg~pH9bWkwQ7k1 zSmRA=DwH}uJs&RgLZ82DV;jZ2f12a^B?cV&xG)->4;t)W{^@D3=?{wVm;&%BHTWjy z8SiWi>jHz9WYGWSZZf<5C+R{T5POw6B3arS@!Rl*!Ky$amq!K9O;7Qx?^urmZfO&MoYbRT>?XSLB+jSP;eU!%`>KRn8CrwVo zgaS0+N-V_NwH2OTv!?t%miX190~Bj#j*7|(Q^}lr*~>4R{8q~CF91r!IK{sLUtW67 z?a7Q1yB5n*>JRIFX(OkH3*^Hx)`sL)@#WzY9B^KYd>cf1kV9;*p9uhSwWuzC4h}gKu ze=V7);!)wagcheULz|Ozy4cjl@#*DJ1t6NMl*M1Z z8Cnj8*mB7ak-I6mk=EMbHRDU@CmNmUjsXcrmd5Kn`J+n#`Q{_T#+_(`2Y;Gg>QSP} z>uiPl`4@yA?Nz6$RdfXTempfQ&?O;CCUgt=? z7EO$HE}R9y;~XV8Bk0bUvJuN)}iXv91my3TsJ0*AO^WA^jCPsKdOs#EvwX{Z(y`+do~7A*De)AgaQiD>yDPYkX@y0`sJIc-3Hs$zT2)eaC;X@+=+Qlw3ulR% z@%B2+m%py9!|7;#GdL5@{iHyIjwBUkS+DcDJs${SY_0}#YwVRg;Z;e*pFbVDDCbam z?oIM{hje{rxcug@g^GcqWcRwTOg@!Kf^DikfI~w6F#U6mtmNE_WHNqbZRzKRCf8!I z397d5150wpV!P(!^T8?4VMgaW+crH&WEJ&BWl{+Y4KK)92FQy=D%mJi#Q&xCTBB(YMX?MVM->2KLk^hwT4u9sen z^m>pN+&WW=b|0<1IsE9B^J^9t_QwF06YkGD&~m&TK_;LsG&3q$ofs6%3}>k@)S&M? zqt=|D`Ka@9Wu0$)-VpAoN4Mn+`}0iw=j3xg_2jeI z=)za@qhH4+gvb-lBhK1T%{W z;a-pFIkC(EZ`b%s&nkUX&{cP=u1BO0^!tKUvKz zt#g6Zr8VRDCT)0r+w}e!{V7#;(pw*QV&?J87b|tS?{nzUT1plE#dzmjo84+<K=ly!m*+lU)OMItT{95nPd8bE^cM6U5%5_rU9`;@y#k$yJ46IcL zDI7=7NRT{4I^rU$p6h+}6wf50INb*u`pGO#yx*Tc=?IoM3<+|xbxOgxI$3V}A&8Pb zB~2>yIgp7i2PHEVFXw{FFk}*QtP3WG%)9LYuE3Jc`cNo1U|6 ztx%ar*FQGB^;}V^mHSDp4f$jcBl#y`q00nXCNzgFH&Ht~-qmzO35+i!dCjigqP*1N zpeUD(4r{3Ox9-p6$Qj6~?TLSfzFKTWkEYL-*)+yEFISB7tngkw=yC^NTi`3$2Gtj$ z>5N!AQ&Dr5ptp8ipYH){>IkDYp`Ypdk%~)m1$GI!kKQB{kqewjw{w+NdIH$L#|Kh} z+`#zQ@Vjz^N_r`U4RBT5AwBZr2WRxG6rG zqgb8CbJ`O{mXHl;(ow?zMf{f5N*rTX-b~si(MENqC*0k1I z92p~rM0~hj$o4d04c9yDoobREX&N$>h>r4K^Q8tosc|9I3N(~4Tfn#Z_o3I;xk3EX(t!2%E9Cs6L}kc} z6DfH#GvLd3{S><)h9bKwye5K(v$L@gXSRUvTVnLE3h8PHXcHBk{@12GG#0AV8RER! zPFSEN4(RyLFr%Pb3gP-=;U^064bN9Rx0OyU_>_FBWK3NQQf2b|jKDTSd2&wlAb- zu!3K{X&S7{g`Am*0JE_}XmW2}NG0NQ;$)b^_R|A(;3Lg&;H!<9|7RvzL2mv-b#FBHq8odr;8i#Cy|vCk&A|n@dM#FI<3PmzuYg}913Sq@ zUSU-K7QBO2;vv*UGW=1x5|O9FMq&l)%tgO2iRAzH0u;tb%6jqw_tQcN2uJee_{pu> zrM%L!2vaIDP1%j7?DL^AJyM!r&1B4`t2Ac52z_5ZVqaBb7ld`Zr(*B;aR^oP$B-gI z7(q;>$FpOpbm2nK&OVC{vj=|`9;q2mTLMk+!!_)8a=t`$iYg^b5Dl@we^zj`-`G+*kh27 zZhczs*vAEOeP+mLSO$ndi{Dll(RucwRTG8SQ<#-qojLyLd(zWvO3eSV+eI(^`HHjD z4}r+xcjxv$G+kv>99`4IA-Dtx5_oWTcXxMpcXtmE+=4s7-Q6L$yDd&|cZYZKo%8+5 zVcG1=y|=r%s(Q8&5kwrv`tbP~H4n4*+kH>fmU(eY$H-$cs;d0j^?Ti(b7uN!`fLl+ zM$Xp`ml*BN#N0=*Tif|D-%nW?ea-r)**CcgX`^T>y=->1eon&N$T;<632;@a{isdT z18d{HH*tGsF7n$h4#vq)n7YKd#aB$`t?nMel)tps%p=ShY2C+^U8hNABsiFO0}ixoENhnmP$-X7MbcWhGXrJt~FXe)8BC+ zji0{drkK&>7PB~8Iurgocw_YE^KG$Mh2tn?qQg(_rNWaA8qaDkwHzD$seXF{`*>yKEVZ1Bpt#6Ee; zb2q-Emm%kF(Jo3O^%2aRt9Wx(dn`bXIyO#bTlBg3x16&MFhy*)I@F37VRS)}i|_?H zswM;Z-+jB@p*C`&O@TdXt+?SIqA>n-q`_d}-lo)Mxb(flmZw^Sd! zrdj!F8!4QmFIT36M-QYHxGOG1u>e&nxjlEs)@G%`S}X>)i?KHzdFrI<~;iK#VkLaWCdu zh2ldS*J(Q?j*l{@UC)JQvddWv$P^5yRQ_zi#)(dLD2yISq@yFdapoMXZ5$SFq-Kd`Ml_QWYmM*$B{--{}|GPqBQe%&T( zv4gJYx`Bn}hMcs4x}7Y>(5!k`^<~eN+V37>8(Ts%>)rXOY1B>qvpL#)eSNZ$*F9m_ ze?$851x*zCmC?b0cgulmaEOJfQot`FP0=8U`HLJeV-SJp_+F#XlquP#z^?0Po(7@@5yqlbriTAp76 zE&=C-k`8}!+83|X#?sy$H3*)pAag7E`nO=GuD7T0xH1!l@A~X)_e-!XpG?ouKwJ4D zhcs(qVsM~do6j3m^7vE2fG==5$Pz?Y5l5g_a)U|%nBF>>)YbI(zOMU<#56rg?e3pz zMBTiLRYcv=IMCW8zq_TCZ(0B9)md5N;)IOa?ze0>{k6W6)$zJAS7R;*CV|*-#-{2@ z=cPh4ZHlV@j`ghyS_LU2)?kjwP0*VfD3b&05B*Z@AVWR{nmTUe71X3s&~ME=4hF5{ zz*b;7vw4FIoV3gat($%&RHZ;Xf$Wo)4)!?${5Z@ zGqQF;#B%C|m&*R9XKmdQs5QVC9G-h}pH_uz#OaUM>a2WgnWtH;2HkjfKp2?YVCEZ+P-0hV`13dNfJlU<~E2K1@3~Kk-}R z2P2YnjsLuH-Srqj=|)_$0w)1%w3aJl!Xm{lEvGw(uuqQl2d`jjaNgw&C#u8&;{?ob z$m-8z5AaRVv{`Jh9*AMEB=}=7LWk!nJ4NZ=Qlg4w?k)oSz9`dgZNWb;KY~+r$KI~_ zN)HYPr(BLZpMd0rVG(Z##r9^cvq~U$x0C!#uPDR$JGq77U3c=_-C5^KC}1b>Cxjje zNWbf@`~fR{k`?)fhtb-H&aOAGs!f9*nxw?NGE)RE__6_)S^ZJV~~Qm>7t z$q}u|-vqagmLUv^qIVjWoV2Pa3IxZqB-)vpMQHz%)kLa*T}fYCfV(nUW$_zZ*C0*^ z4`(EtSMnqz68Cj6r0pMT1)stBrZQHdqzixTZ@ za}_wOhmQ{zTR?bhxvv5C@?bRB({5DXcuQX}Xi3sEkOQQT*8KS2S;)b8OiPDEq7R#i zY{v~nLY<85^_$M;POAOiU?MvQuip*NmjhxaKVMAhH9g&~_1DD1ZZ3L%Nl|OI+bV&klx{&cWcLU$YB1GlX*Qk$vm-$xnTGk-U%jT);j^=flPwJhUh(pG92L%yK z9%32KeU+@)a>0w7CCoL?B3M#a?wYS&vno2HD@Y%S#H+mG_RWZ4zx?>+8J?eDZPREI zx92iqFRlSwv*!ryQNcDrD{n9Ly9Ib_jT2JN#X;v3eX*vF@~CFuuWoqzsl(IQx;IO7 z>9V9V;_ohmZmrSnP%H#TBTKEUH;pf2%@@XpgvW8qWU4jU0Ls(V4c4^+Ww&L78V^U>Z;6EMM#<+ zBxPQ>Japb(a5w7fPC+PHFLpo`D2{H9XO}P9X9ggBn0+MpJCLv|tUt`eY*=USZ*N}T zy;|A0tiNYY7pJ_wY&{NKpC2S5+a~xZT7mxH;Ki{tirM*ZVT4Ut9<*J=*ohYa)k@2m z6D?{{dOU-Ocdd-z6Q5H-yW7wnb+^FO_YlT5M#kj4%yhvUL(jN^snZORIKj~+6~Gud zRmy;K9*NqxABP=IFCzeosjXtMdb> zYWor4fdJ$%qe)U88>>#GB_eqzrt(zbA==-nT9zO53pf$uBNFtO^R?b!#G*j;`&Gge zUol${FMah(W)^2MYjQ+{98E=lx7WO@h9jLxr&4l&82Il>JOkJQMeo$yQ~+DH=DYt> zgNqfs-LFx~p(wz+osvL@AEW|X<)Mzhoo*kK5V^B~3A^e>9~=f6u0Pd<5$QG<-sJe{ zNX{2G><{XHeQY5ckQg0R?Mp1m=z$Ma6_yRpwL_>Epo)5E`lBdG=G%Nhnd-dQxzIqR z70O*qyY>gt?u4<{>Z^-K_WtfZ-vs^!4p0a|D5=c#ZitT@aR;v6^uYN`r-xMM))+cA zSi-PY4KnadITMpDACxD?K0hfgZ!7-#Z~p z;^09@x6vF}_ogd;_Uy!f7bqcI>>q0(e{aZa!0`%sDP2j3pDOtSV(CoY9>d^$=Eyml ziw6=(;+KmjkP{!vJ(yq(&DjTuO%g|{6j@2SNDOzD{WB@EZ%qP0WuF9vdamDK8O)j5 zG*~n!rFDmb3T^+bEmi~8g_A3@&V^ltVVw}5DGyJs=5go!dFD!IaucR^3V2o;JYOp? z%b&fN+B{TJ@Z|>#>*Ifw6bB?~BRZ&M%IDIScuoFy!wLhC2-|dKRDq(bT#qcH)dW&t zZ9om~n6{{O8~YEaWK;ljf9!d)!eB5F`43neG#uU&0bngYxhdGaB-ol8$#U#f>0O;W zZ>F709UkCeXoD*O#aycO6`bKcQrm&JOE5TB`AR(w`JqXx#3QC^>c{)xnJ!xKos~Ec znWJrDh&Ec80mxa0MLBZdebW91M^huD#@1m^H@ymYU{5Xv5HTbWUZ4Jb(FLth3{1#T z;4IKal7(S-{g%KWzqhvb_z*ca9$h?owk%~t)2VX2%id|myekZFzXbsU?Y<`6`O<}b za3H3OPUwt3{CjP)r-zQPhD%sAo`)9ZdV6IAf_7owsirI$>zE#f6<}IbFo6vDx3V`>)5ctTBlBf)@W( z9F?QCW%P_Svm#yn0S32dgHTW#JQ$xIEt9}p5ALgYfDaEdLmFN zk#0%o3`7pwcT^uA^Y>q)aOQ|JVAmF?7NxLIvkpFaM017$M~!!U-Gls|?<*it(Y8bT zY{hL@>lmmKk(rF#e`|;mb7p15tQzkJj6Z^6@g}i$S#D)S4_b9f2?-1_$`%k1{$n$^ z%0A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 literal 36265 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 n17MAg2qA