Compare commits

...

568 Commits

Author SHA1 Message Date
Kubernetes Publisher ed85fd7430 Fix Godeps.json to point to kubernetes-1.9.9 tags 2018-06-29 08:22:50 +00:00
Kubernetes Publisher e0611f3d05 Merge pull request #65298 from nikhita/cherrypick-jsoniter-bump-1.9
Automatic merge from submit-queue.

Manual cherrypick of #65034 to 1.9: make json serializer case sensitive

fixes partially https://github.com/kubernetes/kubernetes/issues/64612

This PR imports the latest jsoniterator library so that case sensitivity during unmarshalling is optional. The PR also sets Kubernetes json serializer to be case sensitive.

**Release note**:

```release-note
ACTION REQUIRED: Kubernetes JSON deserializer is now case-sensitive to restore compatibility with pre-1.8 servers. If your config files contains fields with wrong case, the config files will be now invalid.
```

/sig api-machinery
/kind bug
/assign caesarxuchao liggitt thockin sttts mbohlool

Kubernetes-commit: f4cf484c2cb6056e28fb9759a3c913be3eed990a
2018-06-27 08:49:37 +00:00
Nikhita Raghunath dd4f9e79b8 update staging godeps
Kubernetes-commit: 0f9246104e2c75a96150d8d06a87dfe7b40024c8
2018-06-21 11:59:07 +05:30
Kubernetes Publisher 77833cd56b Merge pull request #63626 from roycaihw/release-1.9
Automatic merge from submit-queue.

Manual cherrypick of kube-openapi changes for release-1.9

**What this PR does / why we need it**:
Cherry-picks https://github.com/kubernetes/kube-openapi/pull/64 and https://github.com/kubernetes/kube-openapi/pull/67
Fixes bugs that make apiserver panic when aggregating valid but not well formed OpenAPI spec (with empty `Paths`/`Definitions`)

**Release note**:

```release-note
Fixes bugs that make apiserver panic when aggregating valid but not well formed OpenAPI spec
```

/cc @mbohlool
/sig api-machinery

Kubernetes-commit: 8d48604c2eca912159636be258a5e68bfc4c6643
2018-05-10 15:37:37 +00:00
Haowei Cai 666c7f735a generated
Kubernetes-commit: 446c4f107857f2e3589f8ce1632ad697161aba11
2018-05-09 15:22:42 -07:00
Kubernetes Publisher 9d60f698b8 sync: update godeps 2018-04-17 15:29:40 +00:00
Kubernetes Publisher 9bcfb16e0e Merge pull request #62028 from nikhita/automated-cherry-pick-of-#57243-upstream-release-1.9
Automatic merge from submit-queue.

Automated cherry pick of #57243: Register metav1 types into samplecontroller api scheme

Fixes kubernetes/sample-controller#14

Cherry pick of #57243 on release-1.9.

#57243: Register metav1 types into samplecontroller api scheme

```release-note
Fix error message regarding conversion of `v1.ListOptions` to `samplecontroller.k8s.io/v1alpha1`.
```

Kubernetes-commit: 53daf2849cdd6c31a7f801c987e8386bb2fd404d
2018-04-15 23:19:05 +00:00
Kubernetes Publisher b7e50d1f46 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-04-09 11:24:24 +00:00
Kubernetes Publisher 5505589d66 sync: update required packages 2018-04-09 03:57:07 +00:00
Kubernetes Publisher 40c99c90ab sync: update godeps 2018-04-09 03:57:06 +00:00
Kubernetes Publisher 31535e4b2c sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-04-09 03:56:50 +00:00
Kubernetes Publisher 48ead0a103 sync: update required packages 2018-04-08 23:57:27 +00:00
Kubernetes Publisher 89d4b438a9 sync: update godeps 2018-04-08 23:57:27 +00:00
Kubernetes Publisher 91a11b7265 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-04-08 23:57:11 +00:00
Kubernetes Publisher 01c2d0d977 sync: update required packages 2018-04-08 19:57:40 +00:00
Kubernetes Publisher c03ae22c88 sync: update godeps 2018-04-08 19:57:40 +00:00
Kubernetes Publisher f34d956640 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-04-08 19:57:18 +00:00
Kubernetes Publisher 79859ee6b4 sync: update required packages 2018-04-08 15:56:28 +00:00
Kubernetes Publisher 15169be8b7 sync: update godeps 2018-04-08 15:56:28 +00:00
Kubernetes Publisher 3e565e8d13 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-04-08 15:56:11 +00:00
Kubernetes Publisher c9e66f884f sync: update required packages 2018-04-08 11:58:35 +00:00
Kubernetes Publisher 9805f78ed8 sync: update godeps 2018-04-08 11:58:35 +00:00
Kubernetes Publisher aaf097dc2c sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-04-08 11:58:19 +00:00
Kubernetes Publisher 370e21e6ac sync: update required packages 2018-04-08 07:57:55 +00:00
Kubernetes Publisher 00eef0056a sync: update godeps 2018-04-08 07:57:55 +00:00
Kubernetes Publisher 81cbcf8b43 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-04-08 07:57:39 +00:00
Kubernetes Publisher 9db1fe1142 sync: update required packages 2018-04-08 03:56:23 +00:00
Kubernetes Publisher 33b61d6ee0 sync: update godeps 2018-04-08 03:56:23 +00:00
Kubernetes Publisher 1172c606cf sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-04-08 03:56:04 +00:00
Kubernetes Publisher 5b2be3e834 sync: update required packages 2018-04-07 23:56:22 +00:00
Kubernetes Publisher 5d2cb1ffcd sync: update godeps 2018-04-07 23:56:22 +00:00
Kubernetes Publisher 0693f7d9f5 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-04-07 23:56:06 +00:00
Kubernetes Publisher 6a94facd76 sync: update required packages 2018-04-07 19:56:48 +00:00
Kubernetes Publisher 78802a16da sync: update godeps 2018-04-07 19:56:48 +00:00
Kubernetes Publisher dc0261e124 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-04-07 19:56:31 +00:00
Kubernetes Publisher 5ce173c831 sync: update required packages 2018-04-07 15:56:55 +00:00
Kubernetes Publisher 789b653f4e sync: update godeps 2018-04-07 15:56:54 +00:00
Kubernetes Publisher eab374c0ce sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-04-07 15:56:38 +00:00
Kubernetes Publisher 4a9c498f71 sync: update required packages 2018-04-07 11:56:47 +00:00
Kubernetes Publisher 3e12fc7430 sync: update godeps 2018-04-07 11:56:47 +00:00
Kubernetes Publisher 31e98b39f9 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-04-07 11:56:31 +00:00
Kubernetes Publisher 7158d5b151 sync: update required packages 2018-04-07 07:58:00 +00:00
Kubernetes Publisher 1437c07c81 sync: update godeps 2018-04-07 07:58:00 +00:00
Kubernetes Publisher 861fb89c5a sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-04-07 07:57:44 +00:00
Kubernetes Publisher 4c39992cfc sync: update required packages 2018-04-07 03:57:26 +00:00
Kubernetes Publisher 5cd1d8fcf0 sync: update godeps 2018-04-07 03:57:25 +00:00
Kubernetes Publisher 723f028710 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-04-07 03:57:09 +00:00
Kubernetes Publisher 3f0b110807 sync: update required packages 2018-04-06 23:56:43 +00:00
Kubernetes Publisher f3356673b1 sync: update godeps 2018-04-06 23:56:43 +00:00
Kubernetes Publisher e74eecb6a5 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-04-06 23:56:16 +00:00
Kubernetes Publisher affa9f42a6 sync: update required packages 2018-04-06 19:55:34 +00:00
Kubernetes Publisher 9be544dd78 sync: update godeps 2018-04-06 19:55:34 +00:00
Kubernetes Publisher e105d4753f sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-04-06 19:55:12 +00:00
Kubernetes Publisher f07fdd5433 sync: update required packages 2018-04-06 15:58:12 +00:00
Kubernetes Publisher 2572123197 sync: update godeps 2018-04-06 15:58:12 +00:00
Kubernetes Publisher 41d0ae3162 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-04-06 15:57:55 +00:00
Kubernetes Publisher cfd7646563 sync: update required packages 2018-04-06 12:08:26 +00:00
Kubernetes Publisher be5633101c sync: update godeps 2018-04-06 12:08:25 +00:00
Kubernetes Publisher b4c220b23a sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-04-06 12:08:08 +00:00
Kubernetes Publisher ad2add216d sync: update required packages 2018-03-30 19:49:37 +00:00
Kubernetes Publisher 60dd841254 sync: update godeps 2018-03-30 19:49:37 +00:00
Kubernetes Publisher f27f3a4e25 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-30 19:49:21 +00:00
Kubernetes Publisher e3a3550cd1 sync: update required packages 2018-03-30 16:03:38 +00:00
Kubernetes Publisher 705db51c65 sync: update godeps 2018-03-30 16:03:38 +00:00
Kubernetes Publisher 8328c32c62 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-30 16:03:21 +00:00
Kubernetes Publisher 136e706b4c sync: update required packages 2018-03-30 12:02:36 +00:00
Kubernetes Publisher 636e3563e9 sync: update godeps 2018-03-30 12:02:36 +00:00
Kubernetes Publisher ebdedbf1bd sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-30 12:02:19 +00:00
Kubernetes Publisher 39a08d806b sync: update required packages 2018-03-30 08:01:30 +00:00
Kubernetes Publisher a3edbf0f55 sync: update godeps 2018-03-30 08:01:29 +00:00
Kubernetes Publisher c0a5c7afc3 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-30 08:01:13 +00:00
Kubernetes Publisher f32d99a8b0 sync: update required packages 2018-03-30 04:01:08 +00:00
Kubernetes Publisher f1f5b1bdfd sync: update godeps 2018-03-30 04:01:08 +00:00
Kubernetes Publisher 1e3e1ed2e5 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-30 04:00:52 +00:00
Kubernetes Publisher 0c9e8c5f70 sync: update required packages 2018-03-30 00:03:16 +00:00
Kubernetes Publisher 28b4cad66f sync: update godeps 2018-03-30 00:03:15 +00:00
Kubernetes Publisher 35803781a3 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-30 00:02:59 +00:00
Kubernetes Publisher c3464f21df sync: update required packages 2018-03-29 19:52:32 +00:00
Kubernetes Publisher 0c7c8fd549 sync: update godeps 2018-03-29 19:52:32 +00:00
Kubernetes Publisher 4dee085a73 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-29 19:52:15 +00:00
Kubernetes Publisher 2bf2d7dbe8 sync: update required packages 2018-03-29 15:49:09 +00:00
Kubernetes Publisher 257069fde5 sync: update godeps 2018-03-29 15:49:08 +00:00
Kubernetes Publisher 04301fd3c5 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-29 15:48:52 +00:00
Kubernetes Publisher a38154c6f0 sync: update required packages 2018-03-29 11:48:10 +00:00
Kubernetes Publisher 8cb48ea581 sync: update godeps 2018-03-29 11:48:10 +00:00
Kubernetes Publisher 794493552f sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-29 11:47:55 +00:00
Kubernetes Publisher aeced7fc1b sync: update required packages 2018-03-29 07:47:36 +00:00
Kubernetes Publisher 5d4cc7f0df sync: update godeps 2018-03-29 07:47:36 +00:00
Kubernetes Publisher cc1587bce1 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-29 07:47:21 +00:00
Kubernetes Publisher 9cfc94aec0 sync: update required packages 2018-03-29 03:48:53 +00:00
Kubernetes Publisher f22830a5a4 sync: update godeps 2018-03-29 03:48:53 +00:00
Kubernetes Publisher c94b786fd6 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-29 03:48:37 +00:00
Kubernetes Publisher 88807ad857 sync: update required packages 2018-03-28 23:48:33 +00:00
Kubernetes Publisher c4f9a274d5 sync: update godeps 2018-03-28 23:48:33 +00:00
Kubernetes Publisher e532577d08 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-28 23:48:17 +00:00
Kubernetes Publisher f11d3b975c sync: update required packages 2018-03-28 19:49:49 +00:00
Kubernetes Publisher 19ef491e61 sync: update godeps 2018-03-28 19:49:49 +00:00
Kubernetes Publisher b3551d48e9 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-28 19:49:32 +00:00
Kubernetes Publisher a5df989be9 sync: update required packages 2018-03-28 15:50:57 +00:00
Kubernetes Publisher 1b307a2992 sync: update godeps 2018-03-28 15:50:57 +00:00
Kubernetes Publisher e30c026764 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-28 15:50:42 +00:00
Kubernetes Publisher 801aa68b9a sync: update required packages 2018-03-28 11:48:59 +00:00
Kubernetes Publisher 3e5ef906c9 sync: update godeps 2018-03-28 11:48:58 +00:00
Kubernetes Publisher 3e8c2df88f sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-28 11:48:43 +00:00
Kubernetes Publisher cabbdd3a4a sync: update required packages 2018-03-28 07:50:46 +00:00
Kubernetes Publisher a53169b342 sync: update godeps 2018-03-28 07:50:46 +00:00
Kubernetes Publisher e2632c74c7 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-28 07:50:30 +00:00
Kubernetes Publisher 3ba3801e6b sync: update required packages 2018-03-28 03:47:44 +00:00
Kubernetes Publisher ead8264daa sync: update godeps 2018-03-28 03:47:44 +00:00
Kubernetes Publisher 6c0c6fda6c sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-28 03:47:28 +00:00
Kubernetes Publisher 5e18a249f3 sync: update required packages 2018-03-27 23:57:52 +00:00
Kubernetes Publisher c669b1200b sync: update godeps 2018-03-27 23:57:52 +00:00
Kubernetes Publisher a66ec0f631 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-27 23:57:37 +00:00
Kubernetes Publisher f2b8a6a1ce sync: update required packages 2018-03-27 19:30:47 +00:00
Kubernetes Publisher 2ce2991d13 sync: update godeps 2018-03-27 19:30:46 +00:00
Kubernetes Publisher 57da285c45 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-27 19:30:30 +00:00
Kubernetes Publisher 090204ee74 sync: update required packages 2018-03-27 15:28:23 +00:00
Kubernetes Publisher 196664ef0a sync: update godeps 2018-03-27 15:28:22 +00:00
Kubernetes Publisher ab66a41a45 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-27 15:28:03 +00:00
Kubernetes Publisher c6072492ab sync: update required packages 2018-03-27 11:27:27 +00:00
Kubernetes Publisher 4889956629 sync: update godeps 2018-03-27 11:27:27 +00:00
Kubernetes Publisher 01ca511fab sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-27 11:27:12 +00:00
Kubernetes Publisher 24d03c1990 sync: update required packages 2018-03-27 07:26:25 +00:00
Kubernetes Publisher 2d343b3104 sync: update godeps 2018-03-27 07:26:25 +00:00
Kubernetes Publisher b8d8379a63 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-27 07:26:08 +00:00
Kubernetes Publisher e776beac72 sync: update required packages 2018-03-27 03:26:40 +00:00
Kubernetes Publisher 7a8e1471ac sync: update godeps 2018-03-27 03:26:40 +00:00
Kubernetes Publisher 52394067ca sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-27 03:26:26 +00:00
Kubernetes Publisher 944e612cf6 sync: update required packages 2018-03-26 23:26:54 +00:00
Kubernetes Publisher 5b3315c9ad sync: update godeps 2018-03-26 23:26:54 +00:00
Kubernetes Publisher c126cee505 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-26 23:26:40 +00:00
Kubernetes Publisher 96d5ebc58c sync: update required packages 2018-03-26 19:26:44 +00:00
Kubernetes Publisher 5f1cdfb762 sync: update godeps 2018-03-26 19:26:44 +00:00
Kubernetes Publisher 1e88dd3b14 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-26 19:26:27 +00:00
Kubernetes Publisher e5bd4b7263 sync: update required packages 2018-03-26 15:26:26 +00:00
Kubernetes Publisher a02cb5fa93 sync: update godeps 2018-03-26 15:26:25 +00:00
Kubernetes Publisher e3cff51486 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-26 15:26:12 +00:00
Kubernetes Publisher d557917bc6 sync: update required packages 2018-03-26 11:26:01 +00:00
Kubernetes Publisher 6ecf33226c sync: update godeps 2018-03-26 11:26:01 +00:00
Kubernetes Publisher 0d0d55ce39 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-26 11:25:40 +00:00
Kubernetes Publisher b21258f277 sync: update required packages 2018-03-26 07:25:23 +00:00
Kubernetes Publisher bc5cf53ea8 sync: update godeps 2018-03-26 07:25:23 +00:00
Kubernetes Publisher 1c7d62fc2b sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-26 07:25:08 +00:00
Kubernetes Publisher a4e2048a95 sync: update required packages 2018-03-26 03:28:57 +00:00
Kubernetes Publisher 69189ff05f sync: update godeps 2018-03-26 03:28:57 +00:00
Kubernetes Publisher 303509fc61 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-26 03:28:43 +00:00
Kubernetes Publisher 4ea14d0f28 sync: update required packages 2018-03-25 23:29:30 +00:00
Kubernetes Publisher 4b56f384b1 sync: update godeps 2018-03-25 23:29:29 +00:00
Kubernetes Publisher b530b0149f sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-25 23:29:14 +00:00
Kubernetes Publisher 9ac6ab8ab4 sync: update required packages 2018-03-24 23:32:08 +00:00
Kubernetes Publisher f1cf4d202c sync: update godeps 2018-03-24 23:32:08 +00:00
Kubernetes Publisher 752d40238d sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-24 23:31:53 +00:00
Kubernetes Publisher 7c83fbaa4e sync: update required packages 2018-03-24 19:32:58 +00:00
Kubernetes Publisher 5de1f33eb5 sync: update godeps 2018-03-24 19:32:58 +00:00
Kubernetes Publisher 984ed70c43 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-24 19:32:43 +00:00
Kubernetes Publisher d16a860a84 sync: update required packages 2018-03-24 15:32:29 +00:00
Kubernetes Publisher f4a700098e sync: update godeps 2018-03-24 15:32:28 +00:00
Kubernetes Publisher 8de7e5c929 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-24 15:32:13 +00:00
Kubernetes Publisher 506a03ddc2 sync: update required packages 2018-03-24 11:33:31 +00:00
Kubernetes Publisher 7002b8320c sync: update godeps 2018-03-24 11:33:31 +00:00
Kubernetes Publisher 4b90c6d90b sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-24 11:33:10 +00:00
Kubernetes Publisher c8878a7ab0 sync: update required packages 2018-03-24 07:35:49 +00:00
Kubernetes Publisher 0dc4d8ffd1 sync: update godeps 2018-03-24 07:35:49 +00:00
Kubernetes Publisher 33737a7505 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-24 07:35:33 +00:00
Kubernetes Publisher 47b0434129 sync: update required packages 2018-03-24 03:34:06 +00:00
Kubernetes Publisher 8db7761355 sync: update godeps 2018-03-24 03:34:06 +00:00
Kubernetes Publisher 372e59a9bc sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-24 03:33:46 +00:00
Kubernetes Publisher d682b42c10 sync: update required packages 2018-03-23 23:32:21 +00:00
Kubernetes Publisher bfcb8b515a sync: update godeps 2018-03-23 23:32:20 +00:00
Kubernetes Publisher a2c3c85472 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-23 23:32:05 +00:00
Kubernetes Publisher b71d090eaa sync: update required packages 2018-03-23 19:34:28 +00:00
Kubernetes Publisher 232fc56e6d sync: update godeps 2018-03-23 19:34:27 +00:00
Kubernetes Publisher e10ce13fcf sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-23 19:34:13 +00:00
Kubernetes Publisher 4cc0d45751 sync: update required packages 2018-03-23 15:33:05 +00:00
Kubernetes Publisher fca461f716 sync: update godeps 2018-03-23 15:33:05 +00:00
Kubernetes Publisher 1e85dcee05 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-23 15:32:50 +00:00
Kubernetes Publisher 336f9cc4f4 sync: update required packages 2018-03-23 11:33:11 +00:00
Kubernetes Publisher ea5e19f218 sync: update godeps 2018-03-23 11:33:11 +00:00
Kubernetes Publisher 1d48ee6a82 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-23 11:32:54 +00:00
Kubernetes Publisher 6d7fa9df76 sync: update required packages 2018-03-23 07:32:59 +00:00
Kubernetes Publisher b3245822a0 sync: update godeps 2018-03-23 07:32:58 +00:00
Kubernetes Publisher 9b9376ca13 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-23 07:32:43 +00:00
Kubernetes Publisher 62b8ebe870 sync: update required packages 2018-03-23 03:33:39 +00:00
Kubernetes Publisher 8f01773354 sync: update godeps 2018-03-23 03:33:39 +00:00
Kubernetes Publisher a10dae27b0 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-23 03:33:25 +00:00
Kubernetes Publisher 0e4fb00c5a sync: update required packages 2018-03-22 23:33:37 +00:00
Kubernetes Publisher f63a4e14f0 sync: update godeps 2018-03-22 23:33:37 +00:00
Kubernetes Publisher 9564ec8fed sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-22 23:33:23 +00:00
Kubernetes Publisher bac76c5aba sync: update required packages 2018-03-22 19:30:54 +00:00
Kubernetes Publisher fd4c4a6f66 sync: update godeps 2018-03-22 19:30:54 +00:00
Kubernetes Publisher 47672c745e sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-22 19:30:37 +00:00
Kubernetes Publisher 2d9cfd3124 sync: update required packages 2018-03-22 15:36:55 +00:00
Kubernetes Publisher 866e5a4ba4 sync: update godeps 2018-03-22 15:36:55 +00:00
Kubernetes Publisher b303c556ed sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-22 15:36:36 +00:00
Kubernetes Publisher 6d849d7b88 sync: update required packages 2018-03-22 11:32:48 +00:00
Kubernetes Publisher 58a5799828 sync: update godeps 2018-03-22 11:32:47 +00:00
Kubernetes Publisher ed2c93f4c5 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-22 11:32:31 +00:00
Kubernetes Publisher 1043547d9e sync: update required packages 2018-03-22 07:34:01 +00:00
Kubernetes Publisher b34ea26403 sync: update godeps 2018-03-22 07:34:01 +00:00
Kubernetes Publisher ff09ce689e sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-22 07:33:46 +00:00
Kubernetes Publisher 50fad5266b sync: update required packages 2018-03-22 03:30:13 +00:00
Kubernetes Publisher 40501ad430 sync: update godeps 2018-03-22 03:30:13 +00:00
Kubernetes Publisher 7e1decea89 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-22 03:29:58 +00:00
Kubernetes Publisher 1545e7608e sync: update required packages 2018-03-21 23:31:20 +00:00
Kubernetes Publisher 0bc0fca5ad sync: update godeps 2018-03-21 23:31:19 +00:00
Kubernetes Publisher 623572ae55 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-21 23:31:02 +00:00
Kubernetes Publisher 8ec9c07706 sync: update required packages 2018-03-21 19:34:32 +00:00
Kubernetes Publisher 66469e2e2c sync: update godeps 2018-03-21 19:34:31 +00:00
Kubernetes Publisher 173a5af9a0 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-21 19:34:14 +00:00
Kubernetes Publisher 571239366f sync: update required packages 2018-03-21 15:29:05 +00:00
Kubernetes Publisher bb8ccc9d1c sync: update godeps 2018-03-21 15:29:04 +00:00
Kubernetes Publisher e1d7bb7b27 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-21 15:28:50 +00:00
Kubernetes Publisher 7cca023b75 sync: update required packages 2018-03-21 11:29:09 +00:00
Kubernetes Publisher d54ee108ed sync: update godeps 2018-03-21 11:29:09 +00:00
Kubernetes Publisher 6a77b41613 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-21 11:28:55 +00:00
Kubernetes Publisher aff0f5186c sync: update required packages 2018-03-21 07:27:50 +00:00
Kubernetes Publisher 51d41171cd sync: update godeps 2018-03-21 07:27:49 +00:00
Kubernetes Publisher d64a6cb57b sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-21 07:27:35 +00:00
Kubernetes Publisher 014b34a2ed sync: update required packages 2018-03-21 03:28:04 +00:00
Kubernetes Publisher 060cadb8fb sync: update godeps 2018-03-21 03:28:03 +00:00
Kubernetes Publisher 190c4fd874 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-21 03:27:49 +00:00
Kubernetes Publisher c018c988b1 sync: update required packages 2018-03-20 23:28:49 +00:00
Kubernetes Publisher f377caac7b sync: update godeps 2018-03-20 23:28:49 +00:00
Kubernetes Publisher 7286cccb85 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-20 23:28:35 +00:00
Kubernetes Publisher 6a6a1784f2 sync: update required packages 2018-03-20 19:31:06 +00:00
Kubernetes Publisher 2f912ec7a8 sync: update godeps 2018-03-20 19:31:06 +00:00
Kubernetes Publisher e1d54b229f sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-20 19:30:51 +00:00
Kubernetes Publisher a0e84100b1 sync: update required packages 2018-03-20 15:36:38 +00:00
Kubernetes Publisher ba451bd597 sync: update godeps 2018-03-20 15:36:37 +00:00
Kubernetes Publisher fc859d5209 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-20 15:36:21 +00:00
Kubernetes Publisher aa9264bc07 sync: update required packages 2018-03-20 10:16:46 +00:00
Kubernetes Publisher 70d11f2a30 sync: update godeps 2018-03-20 10:16:46 +00:00
Kubernetes Publisher 69ffb08101 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-20 10:16:23 +00:00
Kubernetes Publisher 059e9239e9 sync: update required packages 2018-03-20 06:18:57 +00:00
Kubernetes Publisher 917b53770e sync: update godeps 2018-03-20 06:18:57 +00:00
Kubernetes Publisher 63fb83ce79 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-20 06:18:41 +00:00
Kubernetes Publisher 13da09bc0b sync: update required packages 2018-03-20 02:31:30 +00:00
Kubernetes Publisher 57b73875d5 sync: update godeps 2018-03-20 02:31:30 +00:00
Kubernetes Publisher 53b546852b sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-20 02:31:14 +00:00
Kubernetes Publisher afffe07c71 sync: update required packages 2018-03-19 22:09:59 +00:00
Kubernetes Publisher 8158424898 sync: update godeps 2018-03-19 22:09:58 +00:00
Kubernetes Publisher a6d5698393 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-19 22:09:46 +00:00
Kubernetes Publisher 7b904c986a sync: update required packages 2018-03-19 18:12:52 +00:00
Kubernetes Publisher 8517759dd8 sync: update godeps 2018-03-19 18:12:51 +00:00
Kubernetes Publisher a6eeb2126d sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-19 18:12:36 +00:00
Kubernetes Publisher 72b40086de sync: update required packages 2018-03-19 14:06:48 +00:00
Kubernetes Publisher 1e1ae0deb6 sync: update godeps 2018-03-19 14:06:48 +00:00
Kubernetes Publisher 5438934527 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-19 14:06:35 +00:00
Kubernetes Publisher d99e6c8091 sync: update required packages 2018-03-19 10:05:02 +00:00
Kubernetes Publisher 55c0b9177f sync: update godeps 2018-03-19 10:05:02 +00:00
Kubernetes Publisher 0e131efa8a sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-19 10:04:50 +00:00
Kubernetes Publisher 7b409b5d44 sync: update required packages 2018-03-19 06:05:28 +00:00
Kubernetes Publisher 13898fe855 sync: update godeps 2018-03-19 06:05:28 +00:00
Kubernetes Publisher c465ff81af sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-19 06:05:16 +00:00
Kubernetes Publisher 18d80fdaa3 sync: update required packages 2018-03-19 02:05:48 +00:00
Kubernetes Publisher 41bd698990 sync: update godeps 2018-03-19 02:05:48 +00:00
Kubernetes Publisher 655c7262e0 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-19 02:05:35 +00:00
Kubernetes Publisher 43e6337581 sync: update required packages 2018-03-18 22:06:10 +00:00
Kubernetes Publisher ca7ed5f32d sync: update godeps 2018-03-18 22:06:09 +00:00
Kubernetes Publisher b6481a76d9 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-18 22:05:57 +00:00
Kubernetes Publisher 72974accc2 sync: update required packages 2018-03-18 18:05:40 +00:00
Kubernetes Publisher 8951e10159 sync: update godeps 2018-03-18 18:05:39 +00:00
Kubernetes Publisher f4267e0146 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-18 18:05:27 +00:00
Kubernetes Publisher 4ba4467316 sync: update required packages 2018-03-18 14:05:12 +00:00
Kubernetes Publisher 9a85163d45 sync: update godeps 2018-03-18 14:05:11 +00:00
Kubernetes Publisher d146a35b91 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-18 14:04:59 +00:00
Kubernetes Publisher 2a95d0ebf7 sync: update required packages 2018-03-18 10:04:46 +00:00
Kubernetes Publisher 545c0a2511 sync: update godeps 2018-03-18 10:04:46 +00:00
Kubernetes Publisher 6a2e9d3200 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-18 10:04:34 +00:00
Kubernetes Publisher 3d22156e9e sync: update required packages 2018-03-18 06:04:16 +00:00
Kubernetes Publisher 5c2d7051fe sync: update godeps 2018-03-18 06:04:16 +00:00
Kubernetes Publisher 81b94b904d sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-18 06:04:03 +00:00
Kubernetes Publisher 8d701b19f5 sync: update required packages 2018-03-18 02:04:56 +00:00
Kubernetes Publisher d76152b457 sync: update godeps 2018-03-18 02:04:55 +00:00
Kubernetes Publisher dedfb2d82a sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-18 02:04:42 +00:00
Kubernetes Publisher de9ca2b0a7 sync: update required packages 2018-03-17 22:05:26 +00:00
Kubernetes Publisher 2b9e8c3b82 sync: update godeps 2018-03-17 22:05:25 +00:00
Kubernetes Publisher 10c3b98a0d sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-17 22:05:13 +00:00
Kubernetes Publisher 369c48f882 sync: update required packages 2018-03-17 18:05:55 +00:00
Kubernetes Publisher 9e98f67046 sync: update godeps 2018-03-17 18:05:54 +00:00
Kubernetes Publisher e130d8c483 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-17 18:05:42 +00:00
Kubernetes Publisher dd6f3a04ef sync: update required packages 2018-03-17 14:05:08 +00:00
Kubernetes Publisher 22c2eae497 sync: update godeps 2018-03-17 14:05:07 +00:00
Kubernetes Publisher 1113ab3764 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-17 14:04:55 +00:00
Kubernetes Publisher 6e3ceee05f sync: update required packages 2018-03-17 10:04:29 +00:00
Kubernetes Publisher e1bb61dc32 sync: update godeps 2018-03-17 10:04:29 +00:00
Kubernetes Publisher 0f932205bc sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-17 10:04:16 +00:00
Kubernetes Publisher 75ace777e0 sync: update required packages 2018-03-17 06:04:35 +00:00
Kubernetes Publisher 54eb7c8c42 sync: update godeps 2018-03-17 06:04:35 +00:00
Kubernetes Publisher facd585c31 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-17 06:04:23 +00:00
Kubernetes Publisher 50a0923dd6 sync: update required packages 2018-03-17 02:05:32 +00:00
Kubernetes Publisher 44d7caaa9d sync: update godeps 2018-03-17 02:05:31 +00:00
Kubernetes Publisher 5e77d6b95d sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-17 02:05:18 +00:00
Kubernetes Publisher 3fe21ebe51 sync: update required packages 2018-03-16 22:05:17 +00:00
Kubernetes Publisher 86272edfa5 sync: update godeps 2018-03-16 22:05:17 +00:00
Kubernetes Publisher 4e8ca57d20 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-16 22:05:04 +00:00
Kubernetes Publisher a2355fc8fe sync: update required packages 2018-03-16 18:05:17 +00:00
Kubernetes Publisher d26dc4b326 sync: update godeps 2018-03-16 18:05:17 +00:00
Kubernetes Publisher 29aec055d1 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-16 18:05:04 +00:00
Kubernetes Publisher c1de96833f sync: update required packages 2018-03-16 14:05:35 +00:00
Kubernetes Publisher 2f7d854d66 sync: update godeps 2018-03-16 14:05:35 +00:00
Kubernetes Publisher 6fa40109a4 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-16 14:05:22 +00:00
Kubernetes Publisher 085505ea2d sync: update required packages 2018-03-16 10:04:51 +00:00
Kubernetes Publisher 0c3d9bdeab sync: update godeps 2018-03-16 10:04:51 +00:00
Kubernetes Publisher be735f1c19 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-16 10:04:39 +00:00
Kubernetes Publisher 842cfbbdb7 sync: update required packages 2018-03-16 06:03:23 +00:00
Kubernetes Publisher 5074ef82d2 sync: update godeps 2018-03-16 06:03:23 +00:00
Kubernetes Publisher 0a18cf3397 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-16 06:03:11 +00:00
Kubernetes Publisher 5ead969852 sync: update required packages 2018-03-16 02:05:18 +00:00
Kubernetes Publisher f8106b9564 sync: update godeps 2018-03-16 02:05:18 +00:00
Kubernetes Publisher e7f796cb9f sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-16 02:05:06 +00:00
Kubernetes Publisher 7c52cc3846 sync: update required packages 2018-03-15 22:05:16 +00:00
Kubernetes Publisher 49500d5614 sync: update godeps 2018-03-15 22:05:15 +00:00
Kubernetes Publisher e27847e63b sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-15 22:05:03 +00:00
Kubernetes Publisher 65d06de2f3 sync: update required packages 2018-03-15 18:05:45 +00:00
Kubernetes Publisher 496c0fb7c6 sync: update godeps 2018-03-15 18:05:45 +00:00
Kubernetes Publisher 2d749b5ee4 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-15 18:05:23 +00:00
Kubernetes Publisher 3b3c86ad0a sync: update required packages 2018-03-15 14:04:28 +00:00
Kubernetes Publisher 8b48e5925f sync: update godeps 2018-03-15 14:04:28 +00:00
Kubernetes Publisher 2831cd8c7d sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-15 14:04:15 +00:00
Kubernetes Publisher 5bd6bbb0f3 sync: update required packages 2018-03-15 10:11:27 +00:00
Kubernetes Publisher 0af3465cf7 sync: update godeps 2018-03-15 10:11:27 +00:00
Kubernetes Publisher 7c1c1c3231 sync: initially remove files BUILD */BUILD BUILD.bazel */BUILD.bazel 2018-03-15 10:11:15 +00:00
Kubernetes Publisher 7d340d449b sync: update required packages 2018-03-14 19:32:56 +00:00
Kubernetes Publisher 678a801515 sync: update godeps 2018-03-14 19:32:56 +00:00
Kubernetes Publisher 082d762348 sync: update required packages 2018-03-14 15:32:15 +00:00
Kubernetes Publisher 7916e7170c sync: update godeps 2018-03-14 15:32:14 +00:00
Kubernetes Publisher 980a06392d sync: update required packages 2018-03-14 11:33:23 +00:00
Kubernetes Publisher ca5aa904ad sync: update godeps 2018-03-14 11:33:23 +00:00
Kubernetes Publisher 9167ba3418 sync: update required packages 2018-03-14 07:31:48 +00:00
Kubernetes Publisher 8eabf90249 sync: update godeps 2018-03-14 07:31:47 +00:00
Kubernetes Publisher 4c769facf5 sync: update required packages 2018-03-14 03:32:57 +00:00
Kubernetes Publisher 69d9adf603 sync: update godeps 2018-03-14 03:32:56 +00:00
Kubernetes Publisher 210ae25d64 sync: update required packages 2018-03-13 23:32:45 +00:00
Kubernetes Publisher f253a601ea sync: update godeps 2018-03-13 23:32:44 +00:00
Kubernetes Publisher e6ffb98f4b sync: update required packages 2018-03-13 19:39:31 +00:00
Kubernetes Publisher cb0ed97306 sync: update godeps 2018-03-13 19:39:30 +00:00
Kubernetes Publisher 5ca0e41e23 sync: update required packages 2018-03-13 15:35:10 +00:00
Kubernetes Publisher d12153b9cb sync: update godeps 2018-03-13 15:35:10 +00:00
Kubernetes Publisher 6f2a867803 sync: update required packages 2018-03-13 11:37:13 +00:00
Kubernetes Publisher f47092e6df sync: update godeps 2018-03-13 11:37:13 +00:00
Kubernetes Publisher ac65c3e8db sync: update required packages 2018-03-13 07:36:40 +00:00
Kubernetes Publisher 0ebc5f0dc2 sync: update godeps 2018-03-13 07:36:40 +00:00
Kubernetes Publisher d15195aaf5 sync: update required packages 2018-03-13 03:38:53 +00:00
Kubernetes Publisher 624f37ce80 sync: update godeps 2018-03-13 03:38:53 +00:00
Kubernetes Publisher e924edbb01 sync: update required packages 2018-03-12 23:38:44 +00:00
Kubernetes Publisher bb942c7c0f sync: update godeps 2018-03-12 23:38:44 +00:00
Kubernetes Publisher 287183cf60 sync: update required packages 2018-03-12 19:34:56 +00:00
Kubernetes Publisher 4c529afd2e sync: update godeps 2018-03-12 19:34:55 +00:00
Kubernetes Publisher 03c69a0ee3 sync: update required packages 2018-03-12 15:33:20 +00:00
Kubernetes Publisher 5bb111d6f9 sync: update godeps 2018-03-12 15:33:20 +00:00
Kubernetes Publisher 4d3eb95e4a sync: update required packages 2018-03-12 11:34:33 +00:00
Kubernetes Publisher e0035eb4bf sync: update godeps 2018-03-12 11:34:33 +00:00
Kubernetes Publisher 9bf6c22881 sync: update required packages 2018-03-12 07:33:22 +00:00
Kubernetes Publisher 0c2ed9f43a sync: update godeps 2018-03-12 07:33:22 +00:00
Kubernetes Publisher 84b4ee98ce sync: update required packages 2018-03-12 03:41:28 +00:00
Kubernetes Publisher 14f24ae3a7 sync: update godeps 2018-03-12 03:41:28 +00:00
Kubernetes Publisher 3da33816ed sync: update required packages 2018-03-11 23:40:28 +00:00
Kubernetes Publisher d81fb5dbf0 sync: update godeps 2018-03-11 23:40:28 +00:00
Kubernetes Publisher d3aa8af507 sync: update required packages 2018-03-11 19:33:30 +00:00
Kubernetes Publisher 5532d0eb0b sync: update godeps 2018-03-11 19:33:30 +00:00
Kubernetes Publisher 9abc0196af sync: update required packages 2018-03-11 15:32:15 +00:00
Kubernetes Publisher 388cd37bbd sync: update godeps 2018-03-11 15:32:15 +00:00
Kubernetes Publisher b7b46f2c49 sync: update required packages 2018-03-11 11:31:19 +00:00
Kubernetes Publisher 9e804d3f1a sync: update godeps 2018-03-11 11:31:19 +00:00
Kubernetes Publisher 634ece07d8 sync: update required packages 2018-03-11 07:32:00 +00:00
Kubernetes Publisher ad21141682 sync: update godeps 2018-03-11 07:32:00 +00:00
Kubernetes Publisher 5d741260f8 sync: update required packages 2018-03-11 03:33:58 +00:00
Kubernetes Publisher 507f78b23c sync: update godeps 2018-03-11 03:33:58 +00:00
Kubernetes Publisher 82f419b119 sync: update required packages 2018-03-10 23:30:44 +00:00
Kubernetes Publisher 61cfaed5c9 sync: update godeps 2018-03-10 23:30:43 +00:00
Kubernetes Publisher d3c2557301 sync: update required packages 2018-03-10 19:34:06 +00:00
Kubernetes Publisher 6b3f16892d sync: update godeps 2018-03-10 19:34:05 +00:00
Kubernetes Publisher 4b19c8ed86 sync: update required packages 2018-03-10 15:32:44 +00:00
Kubernetes Publisher 1cdde8260e sync: update godeps 2018-03-10 15:32:43 +00:00
Kubernetes Publisher 1e7d636d3c sync: update required packages 2018-03-10 11:33:45 +00:00
Kubernetes Publisher a5d6700ca5 sync: update godeps 2018-03-10 11:33:45 +00:00
Kubernetes Publisher daa07de354 sync: update required packages 2018-03-10 07:33:10 +00:00
Kubernetes Publisher f30c1c7ec0 sync: update godeps 2018-03-10 07:33:10 +00:00
Kubernetes Publisher 4e1d276383 sync: update required packages 2018-03-10 03:32:18 +00:00
Kubernetes Publisher 49d58a13f1 sync: update godeps 2018-03-10 03:32:17 +00:00
Kubernetes Publisher 5dd8225d4a sync: update required packages 2018-03-09 23:35:34 +00:00
Kubernetes Publisher 1b6af89cc8 sync: update godeps 2018-03-09 23:35:33 +00:00
Kubernetes Publisher 60d0fdecd7 sync: update required packages 2018-03-09 19:37:31 +00:00
Kubernetes Publisher 89abbbb290 sync: update godeps 2018-03-09 19:37:30 +00:00
Kubernetes Publisher 5137dc6fac sync: update required packages 2018-03-09 15:34:13 +00:00
Kubernetes Publisher e493bc5a04 sync: update godeps 2018-03-09 15:34:13 +00:00
Kubernetes Publisher 78273b5003 sync: update required packages 2018-03-09 11:31:06 +00:00
Kubernetes Publisher cb9153ce16 sync: update godeps 2018-03-09 11:31:06 +00:00
Kubernetes Publisher 0f5009c80c sync: update required packages 2018-03-09 07:33:51 +00:00
Kubernetes Publisher aad8d36591 sync: update godeps 2018-03-09 07:33:51 +00:00
Kubernetes Publisher 70477c2803 sync: update required packages 2018-03-09 03:34:08 +00:00
Kubernetes Publisher ac2b699c47 sync: update godeps 2018-03-09 03:34:08 +00:00
Kubernetes Publisher fcb27565f9 sync: update required packages 2018-03-08 23:41:00 +00:00
Kubernetes Publisher c2d33650e6 sync: update godeps 2018-03-08 23:41:00 +00:00
Kubernetes Publisher b4279d9727 sync: update required packages 2018-03-08 19:51:44 +00:00
Kubernetes Publisher f5b7d74914 sync: update godeps 2018-03-08 19:51:43 +00:00
Kubernetes Publisher 4276946744 sync: update required packages 2018-03-08 15:50:44 +00:00
Kubernetes Publisher 0ecd18def0 sync: update godeps 2018-03-08 15:50:43 +00:00
Kubernetes Publisher 5cc9c89e9c sync: update required packages 2018-03-08 11:49:57 +00:00
Kubernetes Publisher 0c779380a7 sync: update godeps 2018-03-08 11:49:57 +00:00
Kubernetes Publisher 792ff950ed sync: update required packages 2018-03-08 07:51:38 +00:00
Kubernetes Publisher a7477f6a56 sync: update godeps 2018-03-08 07:51:38 +00:00
Kubernetes Publisher 1dac7c7c47 sync: update required packages 2018-03-08 03:52:04 +00:00
Kubernetes Publisher 841b6a8a9a sync: update godeps 2018-03-08 03:52:04 +00:00
Kubernetes Publisher 6aa66afdd0 sync: update required packages 2018-03-07 23:59:11 +00:00
Kubernetes Publisher b9ad2957a6 sync: update godeps 2018-03-07 23:59:10 +00:00
Kubernetes Publisher 14be768882 sync: update required packages 2018-03-07 19:59:00 +00:00
Kubernetes Publisher 17a7c8df92 sync: update godeps 2018-03-07 19:59:00 +00:00
Kubernetes Publisher 84e8c768cb sync: update required packages 2018-03-07 15:49:32 +00:00
Kubernetes Publisher a3e1c89e31 sync: update godeps 2018-03-07 15:49:31 +00:00
Kubernetes Publisher 8c8415e082 sync: update required packages 2018-03-07 11:49:49 +00:00
Kubernetes Publisher 3bc7b5ba7a sync: update godeps 2018-03-07 11:49:49 +00:00
Kubernetes Publisher 4125f9c0dd sync: update required packages 2018-03-07 07:52:13 +00:00
Kubernetes Publisher 8ef820ed39 sync: update godeps 2018-03-07 07:52:12 +00:00
Kubernetes Publisher 429189f29c sync: update required packages 2018-03-07 04:12:09 +00:00
Kubernetes Publisher be44b253d5 sync: update godeps 2018-03-07 04:12:09 +00:00
Kubernetes Publisher e68a0e4264 sync: update required packages 2018-03-06 23:56:37 +00:00
Kubernetes Publisher 5353bcd9e1 sync: update godeps 2018-03-06 23:56:36 +00:00
Kubernetes Publisher 6fee01c3f0 sync: update required packages 2018-03-06 19:59:32 +00:00
Kubernetes Publisher 7d7fc3adaf sync: update godeps 2018-03-06 19:59:31 +00:00
Kubernetes Publisher 4cb0cb2765 sync: update required packages 2018-03-06 15:58:36 +00:00
Kubernetes Publisher d61958cb23 sync: update godeps 2018-03-06 15:58:36 +00:00
Kubernetes Publisher b98412556b sync: update required packages 2018-03-06 11:49:06 +00:00
Kubernetes Publisher 2e6b971ed3 sync: update godeps 2018-03-06 11:49:06 +00:00
Kubernetes Publisher b9e68f7a2f sync: update required packages 2018-03-06 07:49:24 +00:00
Kubernetes Publisher 2f2a3ea54e sync: update godeps 2018-03-06 07:49:24 +00:00
Kubernetes Publisher 7ab3ce3a27 sync: update required packages 2018-03-06 03:59:10 +00:00
Kubernetes Publisher 7b852c8aff sync: update godeps 2018-03-06 03:59:10 +00:00
Kubernetes Publisher d4c1318544 sync: update required packages 2018-03-05 23:58:09 +00:00
Kubernetes Publisher a3bd2e0656 sync: update godeps 2018-03-05 23:58:09 +00:00
Kubernetes Publisher cc30125c64 sync: update required packages 2018-03-05 20:00:07 +00:00
Kubernetes Publisher 19b8e3540a sync: update godeps 2018-03-05 20:00:07 +00:00
Kubernetes Publisher 75cf0f528c sync: update required packages 2018-03-05 15:56:05 +00:00
Kubernetes Publisher a16c4fb99b sync: update godeps 2018-03-05 15:56:05 +00:00
Kubernetes Publisher 9088d7142a sync: update required packages 2018-03-05 11:48:29 +00:00
Kubernetes Publisher 31b57c47c8 sync: update godeps 2018-03-05 11:48:29 +00:00
Kubernetes Publisher 0b86001e9b sync: update required packages 2018-03-05 07:44:26 +00:00
Kubernetes Publisher 5ad3ab254f sync: update godeps 2018-03-05 07:44:26 +00:00
Kubernetes Publisher 9e8d1fbac4 sync: update required packages 2018-03-05 03:49:24 +00:00
Kubernetes Publisher 3f83e68bc6 sync: update godeps 2018-03-05 03:49:24 +00:00
Kubernetes Publisher 50a4134f7a sync: update required packages 2018-03-04 23:55:48 +00:00
Kubernetes Publisher ccea8ee456 sync: update godeps 2018-03-04 23:55:47 +00:00
Kubernetes Publisher d2c5632382 sync: update required packages 2018-03-04 20:00:01 +00:00
Kubernetes Publisher cfef5fe0ba sync: update godeps 2018-03-04 20:00:01 +00:00
Kubernetes Publisher e34dc1f6e6 sync: update required packages 2018-03-04 15:53:12 +00:00
Kubernetes Publisher f2855d13f5 sync: update godeps 2018-03-04 15:53:12 +00:00
Kubernetes Publisher 0583c2a4d0 sync: update required packages 2018-03-04 11:40:30 +00:00
Kubernetes Publisher 69ff418f23 sync: update godeps 2018-03-04 11:40:30 +00:00
Kubernetes Publisher 5570564744 sync: update required packages 2018-03-04 07:42:21 +00:00
Kubernetes Publisher d312ad8870 sync: update godeps 2018-03-04 07:42:21 +00:00
Kubernetes Publisher f4c5a481a9 sync: update required packages 2018-03-04 03:44:23 +00:00
Kubernetes Publisher 7f8129ae63 sync: update godeps 2018-03-04 03:44:22 +00:00
Kubernetes Publisher 4196a8f28d sync: update required packages 2018-03-03 23:50:39 +00:00
Kubernetes Publisher b562b505e4 sync: update godeps 2018-03-03 23:50:39 +00:00
Kubernetes Publisher be6ef5ae3c sync: update required packages 2018-03-03 19:52:39 +00:00
Kubernetes Publisher 79eba74050 sync: update godeps 2018-03-03 19:52:39 +00:00
Kubernetes Publisher 7e97c9c5dd sync: update required packages 2018-03-03 16:11:59 +00:00
Kubernetes Publisher 41bb33bcd1 sync: update godeps 2018-03-03 16:11:59 +00:00
Kubernetes Publisher a803a63815 sync: update required packages 2018-03-03 11:42:17 +00:00
Kubernetes Publisher 180391af66 sync: update godeps 2018-03-03 11:42:17 +00:00
Kubernetes Publisher cc91eb9269 sync: update required packages 2018-03-03 07:42:46 +00:00
Kubernetes Publisher 1f655253ed sync: update godeps 2018-03-03 07:42:46 +00:00
Kubernetes Publisher f7ca68e207 sync: update required packages 2018-03-03 03:59:53 +00:00
Kubernetes Publisher 9bddf931ac sync: update godeps 2018-03-03 03:59:53 +00:00
Kubernetes Publisher e9102ed147 sync: update required packages 2018-03-02 23:47:39 +00:00
Kubernetes Publisher 19b0c0e5d5 sync: update godeps 2018-03-02 23:47:39 +00:00
Kubernetes Publisher 0d6167db53 sync: update required packages 2018-03-02 19:55:30 +00:00
Kubernetes Publisher f0136d9ef6 sync: update godeps 2018-03-02 19:55:29 +00:00
Kubernetes Publisher d240e98dbf sync: update required packages 2018-03-01 14:06:31 +00:00
Kubernetes Publisher 7e7bd92fcc sync: update godeps 2018-03-01 14:06:31 +00:00
Kubernetes Publisher 8b87f64d92 sync: update required packages 2018-03-01 10:08:33 +00:00
Kubernetes Publisher e0a5573a16 sync: update godeps 2018-03-01 10:08:33 +00:00
Kubernetes Publisher 8104f25e9c sync: update required packages 2018-03-01 06:04:15 +00:00
Kubernetes Publisher 9d53e197e3 sync: update godeps 2018-03-01 06:04:15 +00:00
Kubernetes Publisher bbd7d73a17 sync: update required packages 2018-03-01 02:04:18 +00:00
Kubernetes Publisher 05f8c9c368 sync: update godeps 2018-03-01 02:04:17 +00:00
Kubernetes Publisher d8cec7dd7f sync: update required packages 2018-02-28 22:04:00 +00:00
Kubernetes Publisher 6b94834b03 sync: update godeps 2018-02-28 22:04:00 +00:00
Kubernetes Publisher 9362e12f91 sync: update required packages 2018-02-28 18:05:21 +00:00
Kubernetes Publisher 6709183647 sync: update godeps 2018-02-28 18:05:21 +00:00
Kubernetes Publisher 68e80ea442 sync: update required packages 2018-02-28 14:04:17 +00:00
Kubernetes Publisher 53d077b6c5 sync: update godeps 2018-02-28 14:04:17 +00:00
Kubernetes Publisher a7cb310dc7 sync: update required packages 2018-02-28 10:04:03 +00:00
Kubernetes Publisher d035305bd3 sync: update godeps 2018-02-28 10:04:03 +00:00
Kubernetes Publisher 59ae96900f sync: update required packages 2018-02-28 06:08:32 +00:00
Kubernetes Publisher 84c0d3015d sync: update godeps 2018-02-28 06:08:31 +00:00
Kubernetes Publisher cf90a35856 sync: update required packages 2018-02-27 18:03:10 +00:00
Kubernetes Publisher d29a0202ed sync: update godeps 2018-02-27 18:03:10 +00:00
Kubernetes Publisher 7cbb8b720b sync: update required packages 2018-02-27 14:02:21 +00:00
Kubernetes Publisher a6f3c78c6c sync: update godeps 2018-02-27 14:02:21 +00:00
Kubernetes Publisher f48ef6c21f sync: update required packages 2018-02-27 10:05:52 +00:00
Kubernetes Publisher 8f3858614e sync: update godeps 2018-02-27 10:05:52 +00:00
Kubernetes Publisher bc192d0caa sync: update required packages 2018-02-27 06:02:50 +00:00
Kubernetes Publisher 142711e628 sync: update godeps 2018-02-27 06:02:49 +00:00
Kubernetes Publisher d725f17bf7 sync: update required packages 2018-02-27 02:19:09 +00:00
Kubernetes Publisher dec30864c6 sync: update godeps 2018-02-27 02:19:09 +00:00
Kubernetes Publisher 84c2646f90 sync: update required packages 2018-02-20 05:58:37 +00:00
Kubernetes Publisher 91d9864e1d sync: update godeps 2018-02-20 05:58:37 +00:00
Kubernetes Publisher ce55123f3e sync: update required packages 2018-02-20 02:00:22 +00:00
Kubernetes Publisher 805e61cfd6 sync: update godeps 2018-02-20 02:00:22 +00:00
Kubernetes Publisher 451f001f73 sync: update required packages 2018-02-19 22:00:58 +00:00
Kubernetes Publisher 56cfe6abbb sync: update godeps 2018-02-19 22:00:58 +00:00
Kubernetes Publisher 12c53a6ab6 sync: update required packages 2018-02-19 17:59:27 +00:00
Kubernetes Publisher b7f6f6f28a sync: update godeps 2018-02-19 17:59:27 +00:00
Kubernetes Publisher 134ab0b427 sync: update required packages 2018-02-19 13:55:41 +00:00
Kubernetes Publisher 2a02277721 sync: update godeps 2018-02-19 13:55:40 +00:00
Kubernetes Publisher e38ca3f036 sync: update required packages 2018-02-19 09:55:32 +00:00
Kubernetes Publisher 2ec915b1b1 sync: update godeps 2018-02-19 09:55:32 +00:00
Kubernetes Publisher 61588233ac sync: update required packages 2018-02-19 05:55:04 +00:00
Kubernetes Publisher 31ef9cb12c sync: update godeps 2018-02-19 05:55:03 +00:00
Kubernetes Publisher ba6f924a21 sync: update required packages 2018-02-19 01:56:26 +00:00
Kubernetes Publisher 338746c7cf sync: update godeps 2018-02-19 01:56:25 +00:00
Kubernetes Publisher 0e53eaf550 sync: update required packages 2018-02-18 21:55:32 +00:00
Kubernetes Publisher 55f322f22a sync: update godeps 2018-02-18 21:55:32 +00:00
Kubernetes Publisher e2c80626e2 sync: update required packages 2018-02-18 17:55:05 +00:00
Kubernetes Publisher 6b5b7ab360 sync: update godeps 2018-02-18 17:55:05 +00:00
Kubernetes Publisher 3d80126e25 sync: update required packages 2018-02-18 13:55:08 +00:00
Kubernetes Publisher 34542966a9 sync: update godeps 2018-02-18 13:55:07 +00:00
Kubernetes Publisher bebf37070e sync: update required packages 2018-02-18 09:55:29 +00:00
Kubernetes Publisher 3c4bf10ec4 sync: update godeps 2018-02-18 09:55:29 +00:00
Kubernetes Publisher 6d17a3ab97 sync: update required packages 2018-02-18 01:58:15 +00:00
Kubernetes Publisher c19e1bad73 sync: update godeps 2018-02-18 01:58:15 +00:00
Kubernetes Publisher 8834415ee0 sync: update required packages 2018-02-17 21:59:16 +00:00
Kubernetes Publisher 0a4e351759 sync: update godeps 2018-02-17 21:59:16 +00:00
Kubernetes Publisher 972458bc4a sync: update required packages 2018-02-17 17:56:34 +00:00
Kubernetes Publisher d8e448e238 sync: update godeps 2018-02-17 17:56:34 +00:00
Kubernetes Publisher 911c4bddb3 sync: update required packages 2018-02-17 13:55:36 +00:00
Kubernetes Publisher bbb9d6e6cf sync: update godeps 2018-02-17 13:55:36 +00:00
Kubernetes Publisher 9ddb9dd975 sync: update required packages 2018-02-17 09:56:16 +00:00
Kubernetes Publisher 326e0fa643 sync: update godeps 2018-02-17 09:56:16 +00:00
Kubernetes Publisher e2cdd4167d sync: update required packages 2018-02-17 01:57:39 +00:00
Kubernetes Publisher 84e9db4824 sync: update godeps 2018-02-17 01:57:39 +00:00
Kubernetes Publisher f6fbb7c9e6 sync: update required packages 2018-02-16 21:59:09 +00:00
Kubernetes Publisher 893fcc8883 sync: update godeps 2018-02-16 21:59:08 +00:00
Kubernetes Publisher c580a09219 sync: update required packages 2018-02-16 17:57:18 +00:00
Kubernetes Publisher 7edd44b8ae sync: update godeps 2018-02-16 17:57:17 +00:00
Kubernetes Publisher 22d95131ed sync: update required packages 2018-02-16 13:59:32 +00:00
Kubernetes Publisher f0bc03cb6e sync: update godeps 2018-02-16 13:59:31 +00:00
Kubernetes Publisher 50df46ee8a sync: update required packages 2018-02-14 22:41:30 +00:00
Kubernetes Publisher 7773a08d1f sync: update godeps 2018-02-14 22:41:30 +00:00
Kubernetes Publisher 3994e6e1e9 sync: update required packages 2018-02-14 18:39:07 +00:00
Kubernetes Publisher 40010f9d80 sync: update godeps 2018-02-14 18:39:07 +00:00
Kubernetes Publisher 8f67176b70 sync: update required packages 2018-02-14 14:38:02 +00:00
Kubernetes Publisher 6e9d3f4357 sync: update godeps 2018-02-14 14:38:02 +00:00
Kubernetes Publisher 0d8e4e9897 sync: update required packages 2018-02-14 10:37:58 +00:00
Kubernetes Publisher 6ef250b07e sync: update godeps 2018-02-14 10:37:58 +00:00
Kubernetes Publisher 858bbdb28a sync: update required packages 2018-02-14 06:37:48 +00:00
Kubernetes Publisher 05ea3b7b8e sync: update godeps 2018-02-14 06:37:48 +00:00
Kubernetes Publisher 6554d14778 sync: update required packages 2018-02-14 02:39:29 +00:00
Kubernetes Publisher f57acb722c sync: update godeps 2018-02-14 02:39:29 +00:00
Kubernetes Publisher 3eddd4a21c sync: update required packages 2018-02-13 22:41:21 +00:00
Kubernetes Publisher 3a36453eed sync: update godeps 2018-02-13 22:41:20 +00:00
Kubernetes Publisher da193dcba3 sync: update required packages 2018-02-13 18:39:16 +00:00
Kubernetes Publisher 3910befcef sync: update godeps 2018-02-13 18:39:16 +00:00
Kubernetes Publisher 8627abbcbb sync: update required packages 2018-02-13 14:38:00 +00:00
Kubernetes Publisher e484b004e9 sync: update godeps 2018-02-13 14:38:00 +00:00
Kubernetes Publisher 1d93e36736 sync: update required packages 2018-02-13 10:37:54 +00:00
Kubernetes Publisher a30a66741b sync: update godeps 2018-02-13 10:37:53 +00:00
Kubernetes Publisher ca886847d4 sync: update required packages 2018-02-13 06:36:49 +00:00
Kubernetes Publisher 992029bae7 sync: update godeps 2018-02-13 06:36:49 +00:00
Kubernetes Publisher 847abf4722 sync: update required packages 2018-02-13 02:41:45 +00:00
Kubernetes Publisher edf73dabe5 Merge pull request #57767 from mbohlool/automated-cherry-pick-of-#57735-upstream-release-1.9
Automated cherry pick of #57735: Update boilerplate for 2018

Kubernetes-commit: 3968dfcc5de611f872995476b524bca12aec13eb
2018-01-03 02:19:13 +00:00
Christoph Blecker 8ec2db261d Regenerate all generated code
Kubernetes-commit: 1526308622b9e9c27c71151edf59b2f15e9e02f7
2018-01-02 00:21:07 -08:00
James Munnelly e83deb8c0f Register metav1 types into samplecontroller api scheme
Kubernetes-commit: c2df2ad4a089bf1d8f7686125db77bd1ce53e88d
2017-12-15 12:21:16 +00:00
Kubernetes Publisher 541fac8336 Merge remote-tracking branch 'origin/master' into release-1.9
Kubernetes-commit: 7c9967f6de296b968505885781e9ed9fc65156c3
2017-12-07 05:06:33 +00:00
Kubernetes Publisher 0f1d5c27c3 Merge remote-tracking branch 'origin/master' into release-1.9
Kubernetes-commit: 1e8eb335b3a59daa26c25333c28d50def634961d
2017-12-07 05:06:20 +00:00
Kubernetes Publisher 86077011f5 Merge remote-tracking branch 'origin/master' into release-1.9
Kubernetes-commit: fb2de097796aafb38cdb6dc4d3184ebd43d525b4
2017-12-07 05:06:20 +00:00
1380 changed files with 137432 additions and 12874 deletions
-64
View File
@@ -1,64 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
go_library(
name = "go_default_library",
srcs = [
"controller.go",
"main.go",
],
importpath = "k8s.io/sample-controller",
visibility = ["//visibility:private"],
deps = [
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/k8s.io/api/apps/v1beta2:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//vendor/k8s.io/client-go/informers:go_default_library",
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
"//vendor/k8s.io/client-go/kubernetes/scheme:go_default_library",
"//vendor/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library",
"//vendor/k8s.io/client-go/listers/apps/v1beta2:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
"//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
"//vendor/k8s.io/client-go/tools/record:go_default_library",
"//vendor/k8s.io/client-go/util/workqueue:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/client/clientset/versioned:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/client/clientset/versioned/scheme:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/client/informers/externalversions:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/client/listers/samplecontroller/v1alpha1:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/signals:go_default_library",
],
)
go_binary(
name = "sample-controller",
importpath = "k8s.io/sample-controller",
library = ":go_default_library",
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller:all-srcs",
"//staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned:all-srcs",
"//staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions:all-srcs",
"//staging/src/k8s.io/sample-controller/pkg/client/listers/samplecontroller/v1alpha1:all-srcs",
"//staging/src/k8s.io/sample-controller/pkg/signals:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
+198 -190
View File
@@ -1,7 +1,7 @@
{
"ImportPath": "k8s.io/sample-controller",
"GoVersion": "go1.9",
"GodepVersion": "v79",
"GodepVersion": "v80",
"Packages": [
"./..."
],
@@ -128,7 +128,7 @@
},
{
"ImportPath": "github.com/json-iterator/go",
"Rev": "36b14963da70d11297d313183d7e6388c8510e1e"
"Rev": "f2b4162afba35581b6d4a50d3b8f34e33c144682"
},
{
"ImportPath": "github.com/juju/ratelimit",
@@ -146,6 +146,14 @@
"ImportPath": "github.com/mailru/easyjson/jwriter",
"Rev": "2f5df55504ebc322e4d52d34df6a1f5b503bf26d"
},
{
"ImportPath": "github.com/modern-go/concurrent",
"Rev": "bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94"
},
{
"ImportPath": "github.com/modern-go/reflect2",
"Rev": "05fbef0ca5da472bbf96c9322b84a53edc03c9fd"
},
{
"ImportPath": "github.com/peterbourgon/diskv",
"Rev": "5f041e8faa004a95c88a202771f4cc3e991971e6"
@@ -240,755 +248,755 @@
},
{
"ImportPath": "k8s.io/api/admissionregistration/v1alpha1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/admissionregistration/v1beta1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/apps/v1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/apps/v1beta1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/apps/v1beta2",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/authentication/v1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/authentication/v1beta1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/authorization/v1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/authorization/v1beta1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/autoscaling/v1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/autoscaling/v2beta1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/batch/v1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/batch/v1beta1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/batch/v2alpha1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/certificates/v1beta1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/core/v1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/events/v1beta1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/extensions/v1beta1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/networking/v1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/policy/v1beta1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/rbac/v1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/rbac/v1alpha1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/rbac/v1beta1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/scheduling/v1alpha1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/settings/v1alpha1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/storage/v1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/storage/v1alpha1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/api/storage/v1beta1",
"Rev": "c18c417b5eb7424945ae723ef240465d00ddf054"
"Rev": "25573032e785e9f96d2ec111cd899efa39c8c392"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/api/errors",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/api/meta",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/api/resource",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/internalversion",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/apis/meta/v1alpha1",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/conversion",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/conversion/queryparams",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/fields",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/labels",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/schema",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/json",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/protobuf",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/recognizer",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/streaming",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/runtime/serializer/versioning",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/selection",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/types",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/cache",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/clock",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/diff",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/errors",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/framer",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/intstr",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/json",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/mergepatch",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/net",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/runtime",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/sets",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/strategicpatch",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/validation",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/validation/field",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/wait",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/util/yaml",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/version",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/pkg/watch",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/json",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/apimachinery/third_party/forked/golang/reflect",
"Rev": "a04e753f5223cf882db01ac64212682ea28767b4"
"Rev": "fb40df2b502912cbe3a93aa61c2b2487f39cb42f"
},
{
"ImportPath": "k8s.io/client-go/discovery",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/discovery/fake",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/admissionregistration",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/admissionregistration/v1alpha1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/admissionregistration/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/apps",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/apps/v1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/apps/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/apps/v1beta2",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/autoscaling",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/autoscaling/v1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/autoscaling/v2beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/batch",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/batch/v1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/batch/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/batch/v2alpha1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/certificates",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/certificates/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/core",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/core/v1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/events",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/events/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/extensions",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/extensions/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/internalinterfaces",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/networking",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/networking/v1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/policy",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/policy/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/rbac",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/rbac/v1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/rbac/v1alpha1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/rbac/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/scheduling",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/scheduling/v1alpha1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/settings",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/settings/v1alpha1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/storage",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/storage/v1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/storage/v1alpha1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/informers/storage/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/scheme",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/admissionregistration/v1alpha1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/admissionregistration/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/apps/v1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/apps/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/apps/v1beta2",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/authentication/v1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/authentication/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/authorization/v1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/authorization/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/autoscaling/v1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/autoscaling/v2beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/batch/v1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/batch/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/batch/v2alpha1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/certificates/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/core/v1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/events/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/extensions/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/networking/v1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/policy/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/rbac/v1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/rbac/v1alpha1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/rbac/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/scheduling/v1alpha1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/settings/v1alpha1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/storage/v1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/storage/v1alpha1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/kubernetes/typed/storage/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/listers/admissionregistration/v1alpha1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/listers/admissionregistration/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/listers/apps/v1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/listers/apps/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/listers/apps/v1beta2",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/listers/autoscaling/v1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/listers/autoscaling/v2beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/listers/batch/v1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/listers/batch/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/listers/batch/v2alpha1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/listers/certificates/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/listers/core/v1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/listers/events/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/listers/extensions/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/listers/networking/v1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/listers/policy/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/listers/rbac/v1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/listers/rbac/v1alpha1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/listers/rbac/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/listers/scheduling/v1alpha1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/listers/settings/v1alpha1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/listers/storage/v1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/listers/storage/v1alpha1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/listers/storage/v1beta1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/pkg/version",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/rest",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/rest/watch",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/testing",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/tools/auth",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/tools/cache",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/tools/clientcmd",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/tools/clientcmd/api",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/tools/clientcmd/api/latest",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/tools/clientcmd/api/v1",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/tools/metrics",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/tools/pager",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/tools/record",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/tools/reference",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/transport",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/util/buffer",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/util/cert",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/util/flowcontrol",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/util/homedir",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/util/integer",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/client-go/util/workqueue",
"Rev": "375bcf98d2ce9bb76438e825b3534a5a7932d5b0"
"Rev": "164c15bbca33ee58b2f20d54d249fcfa537c83a1"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/common",
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
"Rev": "7ee50c0aa8059d610950c952a9ed7a5e33ab336a"
},
{
"ImportPath": "k8s.io/kube-openapi/pkg/util/proto",
"Rev": "39a7bf85c140f972372c2a0d1ee40adbf0c8bfe1"
"Rev": "7ee50c0aa8059d610950c952a9ed7a5e33ab336a"
}
]
}
-25
View File
@@ -1,25 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["register.go"],
importpath = "k8s.io/sample-controller/pkg/apis/samplecontroller",
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//staging/src/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
-33
View File
@@ -1,33 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"register.go",
"types.go",
"zz_generated.deepcopy.go",
],
importpath = "k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1",
visibility = ["//visibility:public"],
deps = [
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/apis/samplecontroller:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
@@ -17,6 +17,7 @@ limitations under the License.
package v1alpha1
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
@@ -47,5 +48,6 @@ func addKnownTypes(scheme *runtime.Scheme) error {
&Foo{},
&FooList{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
}
@@ -1,7 +1,7 @@
// +build !ignore_autogenerated
/*
Copyright 2017 The Kubernetes Authors.
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
-37
View File
@@ -1,37 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"clientset.go",
"doc.go",
],
importpath = "k8s.io/sample-controller/pkg/client/clientset/versioned",
visibility = ["//visibility:public"],
deps = [
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/k8s.io/client-go/discovery:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/util/flowcontrol:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/fake:all-srcs",
"//staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/scheme:all-srcs",
"//staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright 2017 The Kubernetes Authors.
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright 2017 The Kubernetes Authors.
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
-40
View File
@@ -1,40 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"clientset_generated.go",
"doc.go",
"register.go",
],
importpath = "k8s.io/sample-controller/pkg/client/clientset/versioned/fake",
visibility = ["//visibility:public"],
deps = [
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
"//vendor/k8s.io/client-go/discovery:go_default_library",
"//vendor/k8s.io/client-go/discovery/fake:go_default_library",
"//vendor/k8s.io/client-go/testing:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/client/clientset/versioned:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/fake:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
@@ -1,5 +1,5 @@
/*
Copyright 2017 The Kubernetes Authors.
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright 2017 The Kubernetes Authors.
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
/*
Copyright 2017 The Kubernetes Authors.
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -1,32 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"register.go",
],
importpath = "k8s.io/sample-controller/pkg/client/clientset/versioned/scheme",
visibility = ["//visibility:public"],
deps = [
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
+1 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright 2017 The Kubernetes Authors.
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
/*
Copyright 2017 The Kubernetes Authors.
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -1,39 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"foo.go",
"generated_expansion.go",
"samplecontroller_client.go",
],
importpath = "k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1",
visibility = ["//visibility:public"],
deps = [
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/serializer:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/client/clientset/versioned/scheme:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//staging/src/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/fake:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
@@ -1,5 +1,5 @@
/*
Copyright 2017 The Kubernetes Authors.
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -1,37 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"fake_foo.go",
"fake_samplecontroller_client.go",
],
importpath = "k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1/fake",
visibility = ["//visibility:public"],
deps = [
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/testing:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/client/clientset/versioned/typed/samplecontroller/v1alpha1:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
@@ -1,5 +1,5 @@
/*
Copyright 2017 The Kubernetes Authors.
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
/*
Copyright 2017 The Kubernetes Authors.
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
/*
Copyright 2017 The Kubernetes Authors.
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
/*
Copyright 2017 The Kubernetes Authors.
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
/*
Copyright 2017 The Kubernetes Authors.
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
/*
Copyright 2017 The Kubernetes Authors.
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -1,39 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"factory.go",
"generic.go",
],
importpath = "k8s.io/sample-controller/pkg/client/informers/externalversions",
visibility = ["//visibility:public"],
deps = [
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/client/clientset/versioned:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/client/informers/externalversions/internalinterfaces:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/internalinterfaces:all-srcs",
"//staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
@@ -1,5 +1,5 @@
/*
Copyright 2017 The Kubernetes Authors.
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
/*
Copyright 2017 The Kubernetes Authors.
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -1,28 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["factory_interfaces.go"],
importpath = "k8s.io/sample-controller/pkg/client/informers/externalversions/internalinterfaces",
visibility = ["//visibility:public"],
deps = [
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/client/clientset/versioned:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
@@ -1,5 +1,5 @@
/*
Copyright 2017 The Kubernetes Authors.
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -1,29 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = ["interface.go"],
importpath = "k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller",
visibility = ["//visibility:public"],
deps = [
"//vendor/k8s.io/sample-controller/pkg/client/informers/externalversions/internalinterfaces:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/v1alpha1:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [
":package-srcs",
"//staging/src/k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/v1alpha1:all-srcs",
],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
@@ -1,5 +1,5 @@
/*
Copyright 2017 The Kubernetes Authors.
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -1,35 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"foo.go",
"interface.go",
],
importpath = "k8s.io/sample-controller/pkg/client/informers/externalversions/samplecontroller/v1alpha1",
visibility = ["//visibility:public"],
deps = [
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/watch:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/client/clientset/versioned:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/client/informers/externalversions/internalinterfaces:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/client/listers/samplecontroller/v1alpha1:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
@@ -1,5 +1,5 @@
/*
Copyright 2017 The Kubernetes Authors.
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
/*
Copyright 2017 The Kubernetes Authors.
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -1,31 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"expansion_generated.go",
"foo.go",
],
importpath = "k8s.io/sample-controller/pkg/client/listers/samplecontroller/v1alpha1",
visibility = ["//visibility:public"],
deps = [
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/labels:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
"//vendor/k8s.io/sample-controller/pkg/apis/samplecontroller/v1alpha1:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
@@ -1,5 +1,5 @@
/*
Copyright 2017 The Kubernetes Authors.
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
/*
Copyright 2017 The Kubernetes Authors.
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
-30
View File
@@ -1,30 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"signal.go",
"signal_posix.go",
] + select({
"@io_bazel_rules_go//go/platform:windows_amd64": [
"signal_windows.go",
],
"//conditions:default": [],
}),
importpath = "k8s.io/sample-controller/pkg/signals",
visibility = ["//visibility:public"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
+3 -2
View File
@@ -1,3 +1,4 @@
.idea
/vendor
/bug_test.go
/coverage.txt
/profile.out
/.idea
+1
View File
@@ -2,6 +2,7 @@ language: go
go:
- 1.8.x
- 1.x
before_install:
- go get -t -v ./...
+27
View File
@@ -0,0 +1,27 @@
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
[[projects]]
name = "github.com/json-iterator/go"
packages = ["."]
revision = "ca39e5af3ece67bbcda3d0f4f56a8e24d9f2dad4"
version = "1.1.3"
[[projects]]
name = "github.com/modern-go/concurrent"
packages = ["."]
revision = "e0a39a4cb4216ea8db28e22a69f4ec25610d513a"
version = "1.0.0"
[[projects]]
name = "github.com/modern-go/reflect2"
packages = ["."]
revision = "1df9eeb2bb81f327b96228865c5687bc2194af3f"
version = "1.0.0"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "56a0b9e9e61d2bc8af5e1b68537401b7f4d60805eda3d107058f3171aa5cf793"
solver-name = "gps-cdcl"
solver-version = 1
+26
View File
@@ -0,0 +1,26 @@
# Gopkg.toml example
#
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
# for detailed Gopkg.toml documentation.
#
# required = ["github.com/user/thing/cmd/thing"]
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
#
# [[constraint]]
# name = "github.com/user/project"
# version = "1.0.0"
#
# [[constraint]]
# name = "github.com/user/project2"
# branch = "dev"
# source = "github.com/myfork/project2"
#
# [[override]]
# name = "github.com/x/y"
# version = "2.4.0"
ignored = ["github.com/davecgh/go-spew*","github.com/google/gofuzz*","github.com/stretchr/testify*"]
[[constraint]]
name = "github.com/modern-go/reflect2"
version = "1.0.0"
+13 -2
View File
@@ -8,6 +8,8 @@
A high-performance 100% compatible drop-in replacement of "encoding/json"
You can also use thrift like JSON using [thrift-iterator](https://github.com/thrift-iterator/go)
```
Go开发者们请加入我们,滴滴出行平台技术部 taowen@didichuxing.com
```
@@ -29,6 +31,9 @@ Raw Result (easyjson requires static code generation)
| easyjson encode | 883 ns/op | 576 B/op | 3 allocs/op |
| jsoniter encode | 837 ns/op | 384 B/op | 4 allocs/op |
Always benchmark with your own workload.
The result depends heavily on the data input.
# Usage
100% compatibility with standard lib
@@ -44,7 +49,9 @@ with
```go
import "github.com/json-iterator/go"
jsoniter.Marshal(&data)
var json = jsoniter.ConfigCompatibleWithStandardLibrary
json.Marshal(&data)
```
Replace
@@ -58,7 +65,9 @@ with
```go
import "github.com/json-iterator/go"
jsoniter.Unmarshal(input, &data)
var json = jsoniter.ConfigCompatibleWithStandardLibrary
json.Unmarshal(input, &data)
```
[More documentation](http://jsoniter.com/migrate-from-go-std.html)
@@ -76,5 +85,7 @@ Contributors
* [thockin](https://github.com/thockin)
* [mattn](https://github.com/mattn)
* [cch123](https://github.com/cch123)
* [Oleg Shaldybin](https://github.com/olegshaldybin)
* [Jason Toffaletti](https://github.com/toffaletti)
Report issue or pull request, or email taowen@gmail.com, or [![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/json-iterator/Lobby)
@@ -16,15 +16,6 @@ func Unmarshal(data []byte, v interface{}) error {
return ConfigDefault.Unmarshal(data, v)
}
func lastNotSpacePos(data []byte) int {
for i := len(data) - 1; i >= 0; i-- {
if data[i] != ' ' && data[i] != '\t' && data[i] != '\r' && data[i] != '\n' {
return i + 1
}
}
return 0
}
// UnmarshalFromString convenient method to read from string instead of []byte
func UnmarshalFromString(str string, v interface{}) error {
return ConfigDefault.UnmarshalFromString(str, v)
@@ -71,6 +62,11 @@ type Decoder struct {
// Decode decode JSON into interface{}
func (adapter *Decoder) Decode(obj interface{}) error {
if adapter.iter.head == adapter.iter.tail && adapter.iter.reader != nil {
if !adapter.iter.loadMore() {
return io.EOF
}
}
adapter.iter.ReadVal(obj)
err := adapter.iter.Error
if err == io.EOF {
@@ -81,7 +77,14 @@ func (adapter *Decoder) Decode(obj interface{}) error {
// More is there more?
func (adapter *Decoder) More() bool {
return adapter.iter.head != adapter.iter.tail
iter := adapter.iter
if iter.Error != nil {
return false
}
if iter.head != iter.tail {
return true
}
return iter.loadMore()
}
// Buffered remaining buffer
@@ -90,11 +93,21 @@ func (adapter *Decoder) Buffered() io.Reader {
return bytes.NewReader(remaining)
}
// UseNumber for number JSON element, use float64 or json.NumberValue (alias of string)
// UseNumber causes the Decoder to unmarshal a number into an interface{} as a
// Number instead of as a float64.
func (adapter *Decoder) UseNumber() {
origCfg := adapter.iter.cfg.configBeforeFrozen
origCfg.UseNumber = true
adapter.iter.cfg = origCfg.Froze().(*frozenConfig)
cfg := adapter.iter.cfg.configBeforeFrozen
cfg.UseNumber = true
adapter.iter.cfg = cfg.frozeWithCacheReuse()
}
// DisallowUnknownFields causes the Decoder to return an error when the destination
// is a struct and the input contains object keys which do not match any
// non-ignored, exported fields in the destination.
func (adapter *Decoder) DisallowUnknownFields() {
cfg := adapter.iter.cfg.configBeforeFrozen
cfg.DisallowUnknownFields = true
adapter.iter.cfg = cfg.frozeWithCacheReuse()
}
// NewEncoder same as json.NewEncoder
@@ -110,18 +123,26 @@ type Encoder struct {
// Encode encode interface{} as JSON to io.Writer
func (adapter *Encoder) Encode(val interface{}) error {
adapter.stream.WriteVal(val)
adapter.stream.WriteRaw("\n")
adapter.stream.Flush()
return adapter.stream.Error
}
// SetIndent set the indention. Prefix is not supported
func (adapter *Encoder) SetIndent(prefix, indent string) {
adapter.stream.cfg.indentionStep = len(indent)
config := adapter.stream.cfg.configBeforeFrozen
config.IndentionStep = len(indent)
adapter.stream.cfg = config.frozeWithCacheReuse()
}
// SetEscapeHTML escape html by default, set to false to disable
func (adapter *Encoder) SetEscapeHTML(escapeHTML bool) {
config := adapter.stream.cfg.configBeforeFrozen
config.EscapeHTML = escapeHTML
adapter.stream.cfg = config.Froze().(*frozenConfig)
adapter.stream.cfg = config.frozeWithCacheReuse()
}
// Valid reports whether data is a valid JSON encoding.
func Valid(data []byte) bool {
return ConfigDefault.Valid(data)
}
@@ -1,9 +1,13 @@
package jsoniter
import (
"errors"
"fmt"
"github.com/modern-go/reflect2"
"io"
"reflect"
"strconv"
"unsafe"
)
// Any generic object representation.
@@ -24,7 +28,6 @@ type Any interface {
ToString() string
ToVal(val interface{})
Get(path ...interface{}) Any
// TODO: add Set
Size() int
Keys() []string
GetInterface() interface{}
@@ -34,7 +37,7 @@ type Any interface {
type baseAny struct{}
func (any *baseAny) Get(path ...interface{}) Any {
return &invalidAny{baseAny{}, fmt.Errorf("Get %v from simple value", path)}
return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)}
}
func (any *baseAny) Size() int {
@@ -88,7 +91,7 @@ func Wrap(val interface{}) Any {
if isAny {
return asAny
}
typ := reflect.TypeOf(val)
typ := reflect2.TypeOf(val)
switch typ.Kind() {
case reflect.Slice:
return wrapArray(val)
@@ -99,6 +102,9 @@ func Wrap(val interface{}) Any {
case reflect.String:
return WrapString(val.(string))
case reflect.Int:
if strconv.IntSize == 32 {
return WrapInt32(int32(val.(int)))
}
return WrapInt64(int64(val.(int)))
case reflect.Int8:
return WrapInt32(int32(val.(int8)))
@@ -109,7 +115,15 @@ func Wrap(val interface{}) Any {
case reflect.Int64:
return WrapInt64(val.(int64))
case reflect.Uint:
if strconv.IntSize == 32 {
return WrapUint32(uint32(val.(uint)))
}
return WrapUint64(uint64(val.(uint)))
case reflect.Uintptr:
if ptrSize == 32 {
return WrapUint32(uint32(val.(uintptr)))
}
return WrapUint64(uint64(val.(uintptr)))
case reflect.Uint8:
return WrapUint32(uint32(val.(uint8)))
case reflect.Uint16:
@@ -157,6 +171,8 @@ func (iter *Iterator) readAny() Any {
return iter.readArrayAny()
case '-':
return iter.readNumberAny(false)
case 0:
return &invalidAny{baseAny{}, errors.New("input is empty")}
default:
return iter.readNumberAny(true)
}
@@ -240,3 +256,66 @@ func locatePath(iter *Iterator, path []interface{}) Any {
}
return iter.readAny()
}
var anyType = reflect2.TypeOfPtr((*Any)(nil)).Elem()
func createDecoderOfAny(ctx *ctx, typ reflect2.Type) ValDecoder {
if typ == anyType {
return &directAnyCodec{}
}
if typ.Implements(anyType) {
return &anyCodec{
valType: typ,
}
}
return nil
}
func createEncoderOfAny(ctx *ctx, typ reflect2.Type) ValEncoder {
if typ == anyType {
return &directAnyCodec{}
}
if typ.Implements(anyType) {
return &anyCodec{
valType: typ,
}
}
return nil
}
type anyCodec struct {
valType reflect2.Type
}
func (codec *anyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
panic("not implemented")
}
func (codec *anyCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
obj := codec.valType.UnsafeIndirect(ptr)
any := obj.(Any)
any.WriteTo(stream)
}
func (codec *anyCodec) IsEmpty(ptr unsafe.Pointer) bool {
obj := codec.valType.UnsafeIndirect(ptr)
any := obj.(Any)
return any.Size() == 0
}
type directAnyCodec struct {
}
func (codec *directAnyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
*(*Any)(ptr) = iter.readAny()
}
func (codec *directAnyCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
any := *(*Any)(ptr)
any.WriteTo(stream)
}
func (codec *directAnyCodec) IsEmpty(ptr unsafe.Pointer) bool {
any := *(*Any)(ptr)
return any.Size() == 0
}
@@ -1,6 +1,9 @@
package jsoniter
import "unsafe"
import (
"io"
"unsafe"
)
type numberLazyAny struct {
baseAny
@@ -29,7 +32,9 @@ func (any *numberLazyAny) ToInt() int {
iter := any.cfg.BorrowIterator(any.buf)
defer any.cfg.ReturnIterator(iter)
val := iter.ReadInt()
any.err = iter.Error
if iter.Error != nil && iter.Error != io.EOF {
any.err = iter.Error
}
return val
}
@@ -37,7 +42,9 @@ func (any *numberLazyAny) ToInt32() int32 {
iter := any.cfg.BorrowIterator(any.buf)
defer any.cfg.ReturnIterator(iter)
val := iter.ReadInt32()
any.err = iter.Error
if iter.Error != nil && iter.Error != io.EOF {
any.err = iter.Error
}
return val
}
@@ -45,7 +52,9 @@ func (any *numberLazyAny) ToInt64() int64 {
iter := any.cfg.BorrowIterator(any.buf)
defer any.cfg.ReturnIterator(iter)
val := iter.ReadInt64()
any.err = iter.Error
if iter.Error != nil && iter.Error != io.EOF {
any.err = iter.Error
}
return val
}
@@ -53,7 +62,9 @@ func (any *numberLazyAny) ToUint() uint {
iter := any.cfg.BorrowIterator(any.buf)
defer any.cfg.ReturnIterator(iter)
val := iter.ReadUint()
any.err = iter.Error
if iter.Error != nil && iter.Error != io.EOF {
any.err = iter.Error
}
return val
}
@@ -61,7 +72,9 @@ func (any *numberLazyAny) ToUint32() uint32 {
iter := any.cfg.BorrowIterator(any.buf)
defer any.cfg.ReturnIterator(iter)
val := iter.ReadUint32()
any.err = iter.Error
if iter.Error != nil && iter.Error != io.EOF {
any.err = iter.Error
}
return val
}
@@ -69,7 +82,9 @@ func (any *numberLazyAny) ToUint64() uint64 {
iter := any.cfg.BorrowIterator(any.buf)
defer any.cfg.ReturnIterator(iter)
val := iter.ReadUint64()
any.err = iter.Error
if iter.Error != nil && iter.Error != io.EOF {
any.err = iter.Error
}
return val
}
@@ -77,7 +92,9 @@ func (any *numberLazyAny) ToFloat32() float32 {
iter := any.cfg.BorrowIterator(any.buf)
defer any.cfg.ReturnIterator(iter)
val := iter.ReadFloat32()
any.err = iter.Error
if iter.Error != nil && iter.Error != io.EOF {
any.err = iter.Error
}
return val
}
@@ -85,7 +102,9 @@ func (any *numberLazyAny) ToFloat64() float64 {
iter := any.cfg.BorrowIterator(any.buf)
defer any.cfg.ReturnIterator(iter)
val := iter.ReadFloat64()
any.err = iter.Error
if iter.Error != nil && iter.Error != io.EOF {
any.err = iter.Error
}
return val
}
@@ -14,7 +14,7 @@ func (any *stringAny) Get(path ...interface{}) Any {
if len(path) == 0 {
return any
}
return &invalidAny{baseAny{}, fmt.Errorf("Get %v from simple value", path)}
return &invalidAny{baseAny{}, fmt.Errorf("GetIndex %v from simple value", path)}
}
func (any *stringAny) Parse() *Iterator {
Generated Vendored Executable
+12
View File
@@ -0,0 +1,12 @@
#!/bin/bash
set -e
set -x
if [ ! -d /tmp/build-golang/src/github.com/json-iterator ]; then
mkdir -p /tmp/build-golang/src/github.com/json-iterator
ln -s $PWD /tmp/build-golang/src/github.com/json-iterator/go
fi
export GOPATH=/tmp/build-golang
go get -u github.com/golang/dep/cmd/dep
cd /tmp/build-golang/src/github.com/json-iterator/go
exec $GOPATH/bin/dep ensure -update
+372
View File
@@ -0,0 +1,372 @@
package jsoniter
import (
"encoding/json"
"io"
"reflect"
"sync"
"unsafe"
"github.com/modern-go/concurrent"
"github.com/modern-go/reflect2"
)
// Config customize how the API should behave.
// The API is created from Config by Froze.
type Config struct {
IndentionStep int
MarshalFloatWith6Digits bool
EscapeHTML bool
SortMapKeys bool
UseNumber bool
DisallowUnknownFields bool
TagKey string
OnlyTaggedField bool
ValidateJsonRawMessage bool
ObjectFieldMustBeSimpleString bool
CaseSensitive bool
}
// API the public interface of this package.
// Primary Marshal and Unmarshal.
type API interface {
IteratorPool
StreamPool
MarshalToString(v interface{}) (string, error)
Marshal(v interface{}) ([]byte, error)
MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)
UnmarshalFromString(str string, v interface{}) error
Unmarshal(data []byte, v interface{}) error
Get(data []byte, path ...interface{}) Any
NewEncoder(writer io.Writer) *Encoder
NewDecoder(reader io.Reader) *Decoder
Valid(data []byte) bool
RegisterExtension(extension Extension)
DecoderOf(typ reflect2.Type) ValDecoder
EncoderOf(typ reflect2.Type) ValEncoder
}
// ConfigDefault the default API
var ConfigDefault = Config{
EscapeHTML: true,
}.Froze()
// ConfigCompatibleWithStandardLibrary tries to be 100% compatible with standard library behavior
var ConfigCompatibleWithStandardLibrary = Config{
EscapeHTML: true,
SortMapKeys: true,
ValidateJsonRawMessage: true,
}.Froze()
// ConfigFastest marshals float with only 6 digits precision
var ConfigFastest = Config{
EscapeHTML: false,
MarshalFloatWith6Digits: true, // will lose precession
ObjectFieldMustBeSimpleString: true, // do not unescape object field
}.Froze()
type frozenConfig struct {
configBeforeFrozen Config
sortMapKeys bool
indentionStep int
objectFieldMustBeSimpleString bool
onlyTaggedField bool
disallowUnknownFields bool
decoderCache *concurrent.Map
encoderCache *concurrent.Map
extensions []Extension
streamPool *sync.Pool
iteratorPool *sync.Pool
caseSensitive bool
}
func (cfg *frozenConfig) initCache() {
cfg.decoderCache = concurrent.NewMap()
cfg.encoderCache = concurrent.NewMap()
}
func (cfg *frozenConfig) addDecoderToCache(cacheKey uintptr, decoder ValDecoder) {
cfg.decoderCache.Store(cacheKey, decoder)
}
func (cfg *frozenConfig) addEncoderToCache(cacheKey uintptr, encoder ValEncoder) {
cfg.encoderCache.Store(cacheKey, encoder)
}
func (cfg *frozenConfig) getDecoderFromCache(cacheKey uintptr) ValDecoder {
decoder, found := cfg.decoderCache.Load(cacheKey)
if found {
return decoder.(ValDecoder)
}
return nil
}
func (cfg *frozenConfig) getEncoderFromCache(cacheKey uintptr) ValEncoder {
encoder, found := cfg.encoderCache.Load(cacheKey)
if found {
return encoder.(ValEncoder)
}
return nil
}
var cfgCache = concurrent.NewMap()
func getFrozenConfigFromCache(cfg Config) *frozenConfig {
obj, found := cfgCache.Load(cfg)
if found {
return obj.(*frozenConfig)
}
return nil
}
func addFrozenConfigToCache(cfg Config, frozenConfig *frozenConfig) {
cfgCache.Store(cfg, frozenConfig)
}
// Froze forge API from config
func (cfg Config) Froze() API {
api := &frozenConfig{
sortMapKeys: cfg.SortMapKeys,
indentionStep: cfg.IndentionStep,
objectFieldMustBeSimpleString: cfg.ObjectFieldMustBeSimpleString,
onlyTaggedField: cfg.OnlyTaggedField,
disallowUnknownFields: cfg.DisallowUnknownFields,
caseSensitive: cfg.CaseSensitive,
}
api.streamPool = &sync.Pool{
New: func() interface{} {
return NewStream(api, nil, 512)
},
}
api.iteratorPool = &sync.Pool{
New: func() interface{} {
return NewIterator(api)
},
}
api.initCache()
encoderExtension := EncoderExtension{}
decoderExtension := DecoderExtension{}
if cfg.MarshalFloatWith6Digits {
api.marshalFloatWith6Digits(encoderExtension)
}
if cfg.EscapeHTML {
api.escapeHTML(encoderExtension)
}
if cfg.UseNumber {
api.useNumber(decoderExtension)
}
if cfg.ValidateJsonRawMessage {
api.validateJsonRawMessage(encoderExtension)
}
if len(encoderExtension) > 0 {
api.extensions = append(api.extensions, encoderExtension)
}
if len(decoderExtension) > 0 {
api.extensions = append(api.extensions, decoderExtension)
}
api.configBeforeFrozen = cfg
return api
}
func (cfg Config) frozeWithCacheReuse() *frozenConfig {
api := getFrozenConfigFromCache(cfg)
if api != nil {
return api
}
api = cfg.Froze().(*frozenConfig)
addFrozenConfigToCache(cfg, api)
return api
}
func (cfg *frozenConfig) validateJsonRawMessage(extension EncoderExtension) {
encoder := &funcEncoder{func(ptr unsafe.Pointer, stream *Stream) {
rawMessage := *(*json.RawMessage)(ptr)
iter := cfg.BorrowIterator([]byte(rawMessage))
iter.Read()
if iter.Error != nil {
stream.WriteRaw("null")
} else {
cfg.ReturnIterator(iter)
stream.WriteRaw(string(rawMessage))
}
}, func(ptr unsafe.Pointer) bool {
return false
}}
extension[reflect2.TypeOfPtr((*json.RawMessage)(nil)).Elem()] = encoder
extension[reflect2.TypeOfPtr((*RawMessage)(nil)).Elem()] = encoder
}
func (cfg *frozenConfig) useNumber(extension DecoderExtension) {
extension[reflect2.TypeOfPtr((*interface{})(nil)).Elem()] = &funcDecoder{func(ptr unsafe.Pointer, iter *Iterator) {
exitingValue := *((*interface{})(ptr))
if exitingValue != nil && reflect.TypeOf(exitingValue).Kind() == reflect.Ptr {
iter.ReadVal(exitingValue)
return
}
if iter.WhatIsNext() == NumberValue {
*((*interface{})(ptr)) = json.Number(iter.readNumberAsString())
} else {
*((*interface{})(ptr)) = iter.Read()
}
}}
}
func (cfg *frozenConfig) getTagKey() string {
tagKey := cfg.configBeforeFrozen.TagKey
if tagKey == "" {
return "json"
}
return tagKey
}
func (cfg *frozenConfig) RegisterExtension(extension Extension) {
cfg.extensions = append(cfg.extensions, extension)
}
type lossyFloat32Encoder struct {
}
func (encoder *lossyFloat32Encoder) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteFloat32Lossy(*((*float32)(ptr)))
}
func (encoder *lossyFloat32Encoder) IsEmpty(ptr unsafe.Pointer) bool {
return *((*float32)(ptr)) == 0
}
type lossyFloat64Encoder struct {
}
func (encoder *lossyFloat64Encoder) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteFloat64Lossy(*((*float64)(ptr)))
}
func (encoder *lossyFloat64Encoder) IsEmpty(ptr unsafe.Pointer) bool {
return *((*float64)(ptr)) == 0
}
// EnableLossyFloatMarshalling keeps 10**(-6) precision
// for float variables for better performance.
func (cfg *frozenConfig) marshalFloatWith6Digits(extension EncoderExtension) {
// for better performance
extension[reflect2.TypeOfPtr((*float32)(nil)).Elem()] = &lossyFloat32Encoder{}
extension[reflect2.TypeOfPtr((*float64)(nil)).Elem()] = &lossyFloat64Encoder{}
}
type htmlEscapedStringEncoder struct {
}
func (encoder *htmlEscapedStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
str := *((*string)(ptr))
stream.WriteStringWithHTMLEscaped(str)
}
func (encoder *htmlEscapedStringEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return *((*string)(ptr)) == ""
}
func (cfg *frozenConfig) escapeHTML(encoderExtension EncoderExtension) {
encoderExtension[reflect2.TypeOfPtr((*string)(nil)).Elem()] = &htmlEscapedStringEncoder{}
}
func (cfg *frozenConfig) cleanDecoders() {
typeDecoders = map[string]ValDecoder{}
fieldDecoders = map[string]ValDecoder{}
*cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig))
}
func (cfg *frozenConfig) cleanEncoders() {
typeEncoders = map[string]ValEncoder{}
fieldEncoders = map[string]ValEncoder{}
*cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig))
}
func (cfg *frozenConfig) MarshalToString(v interface{}) (string, error) {
stream := cfg.BorrowStream(nil)
defer cfg.ReturnStream(stream)
stream.WriteVal(v)
if stream.Error != nil {
return "", stream.Error
}
return string(stream.Buffer()), nil
}
func (cfg *frozenConfig) Marshal(v interface{}) ([]byte, error) {
stream := cfg.BorrowStream(nil)
defer cfg.ReturnStream(stream)
stream.WriteVal(v)
if stream.Error != nil {
return nil, stream.Error
}
result := stream.Buffer()
copied := make([]byte, len(result))
copy(copied, result)
return copied, nil
}
func (cfg *frozenConfig) MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
if prefix != "" {
panic("prefix is not supported")
}
for _, r := range indent {
if r != ' ' {
panic("indent can only be space")
}
}
newCfg := cfg.configBeforeFrozen
newCfg.IndentionStep = len(indent)
return newCfg.frozeWithCacheReuse().Marshal(v)
}
func (cfg *frozenConfig) UnmarshalFromString(str string, v interface{}) error {
data := []byte(str)
iter := cfg.BorrowIterator(data)
defer cfg.ReturnIterator(iter)
iter.ReadVal(v)
c := iter.nextToken()
if c == 0 {
if iter.Error == io.EOF {
return nil
}
return iter.Error
}
iter.ReportError("Unmarshal", "there are bytes left after unmarshal")
return iter.Error
}
func (cfg *frozenConfig) Get(data []byte, path ...interface{}) Any {
iter := cfg.BorrowIterator(data)
defer cfg.ReturnIterator(iter)
return locatePath(iter, path)
}
func (cfg *frozenConfig) Unmarshal(data []byte, v interface{}) error {
iter := cfg.BorrowIterator(data)
defer cfg.ReturnIterator(iter)
iter.ReadVal(v)
c := iter.nextToken()
if c == 0 {
if iter.Error == io.EOF {
return nil
}
return iter.Error
}
iter.ReportError("Unmarshal", "there are bytes left after unmarshal")
return iter.Error
}
func (cfg *frozenConfig) NewEncoder(writer io.Writer) *Encoder {
stream := NewStream(cfg, writer, 512)
return &Encoder{stream}
}
func (cfg *frozenConfig) NewDecoder(reader io.Reader) *Decoder {
iter := Parse(cfg, reader, 512)
return &Decoder{iter}
}
func (cfg *frozenConfig) Valid(data []byte) bool {
iter := cfg.BorrowIterator(data)
defer cfg.ReturnIterator(iter)
iter.Skip()
return iter.Error == nil
}
-312
View File
@@ -1,312 +0,0 @@
package jsoniter
import (
"encoding/json"
"errors"
"io"
"reflect"
"sync/atomic"
"unsafe"
)
// Config customize how the API should behave.
// The API is created from Config by Froze.
type Config struct {
IndentionStep int
MarshalFloatWith6Digits bool
EscapeHTML bool
SortMapKeys bool
UseNumber bool
TagKey string
}
type frozenConfig struct {
configBeforeFrozen Config
sortMapKeys bool
indentionStep int
decoderCache unsafe.Pointer
encoderCache unsafe.Pointer
extensions []Extension
streamPool chan *Stream
iteratorPool chan *Iterator
}
// API the public interface of this package.
// Primary Marshal and Unmarshal.
type API interface {
IteratorPool
StreamPool
MarshalToString(v interface{}) (string, error)
Marshal(v interface{}) ([]byte, error)
MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)
UnmarshalFromString(str string, v interface{}) error
Unmarshal(data []byte, v interface{}) error
Get(data []byte, path ...interface{}) Any
NewEncoder(writer io.Writer) *Encoder
NewDecoder(reader io.Reader) *Decoder
}
// ConfigDefault the default API
var ConfigDefault = Config{
EscapeHTML: true,
}.Froze()
// ConfigCompatibleWithStandardLibrary tries to be 100% compatible with standard library behavior
var ConfigCompatibleWithStandardLibrary = Config{
EscapeHTML: true,
SortMapKeys: true,
}.Froze()
// ConfigFastest marshals float with only 6 digits precision
var ConfigFastest = Config{
EscapeHTML: false,
MarshalFloatWith6Digits: true,
}.Froze()
// Froze forge API from config
func (cfg Config) Froze() API {
// TODO: cache frozen config
frozenConfig := &frozenConfig{
sortMapKeys: cfg.SortMapKeys,
indentionStep: cfg.IndentionStep,
streamPool: make(chan *Stream, 16),
iteratorPool: make(chan *Iterator, 16),
}
atomic.StorePointer(&frozenConfig.decoderCache, unsafe.Pointer(&map[string]ValDecoder{}))
atomic.StorePointer(&frozenConfig.encoderCache, unsafe.Pointer(&map[string]ValEncoder{}))
if cfg.MarshalFloatWith6Digits {
frozenConfig.marshalFloatWith6Digits()
}
if cfg.EscapeHTML {
frozenConfig.escapeHTML()
}
if cfg.UseNumber {
frozenConfig.useNumber()
}
frozenConfig.configBeforeFrozen = cfg
return frozenConfig
}
func (cfg *frozenConfig) useNumber() {
cfg.addDecoderToCache(reflect.TypeOf((*interface{})(nil)).Elem(), &funcDecoder{func(ptr unsafe.Pointer, iter *Iterator) {
if iter.WhatIsNext() == NumberValue {
*((*interface{})(ptr)) = json.Number(iter.readNumberAsString())
} else {
*((*interface{})(ptr)) = iter.Read()
}
}})
}
func (cfg *frozenConfig) getTagKey() string {
tagKey := cfg.configBeforeFrozen.TagKey
if tagKey == "" {
return "json"
}
return tagKey
}
func (cfg *frozenConfig) registerExtension(extension Extension) {
cfg.extensions = append(cfg.extensions, extension)
}
type lossyFloat32Encoder struct {
}
func (encoder *lossyFloat32Encoder) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteFloat32Lossy(*((*float32)(ptr)))
}
func (encoder *lossyFloat32Encoder) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, encoder)
}
func (encoder *lossyFloat32Encoder) IsEmpty(ptr unsafe.Pointer) bool {
return *((*float32)(ptr)) == 0
}
type lossyFloat64Encoder struct {
}
func (encoder *lossyFloat64Encoder) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteFloat64Lossy(*((*float64)(ptr)))
}
func (encoder *lossyFloat64Encoder) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, encoder)
}
func (encoder *lossyFloat64Encoder) IsEmpty(ptr unsafe.Pointer) bool {
return *((*float64)(ptr)) == 0
}
// EnableLossyFloatMarshalling keeps 10**(-6) precision
// for float variables for better performance.
func (cfg *frozenConfig) marshalFloatWith6Digits() {
// for better performance
cfg.addEncoderToCache(reflect.TypeOf((*float32)(nil)).Elem(), &lossyFloat32Encoder{})
cfg.addEncoderToCache(reflect.TypeOf((*float64)(nil)).Elem(), &lossyFloat64Encoder{})
}
type htmlEscapedStringEncoder struct {
}
func (encoder *htmlEscapedStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
str := *((*string)(ptr))
stream.WriteStringWithHTMLEscaped(str)
}
func (encoder *htmlEscapedStringEncoder) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, encoder)
}
func (encoder *htmlEscapedStringEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return *((*string)(ptr)) == ""
}
func (cfg *frozenConfig) escapeHTML() {
cfg.addEncoderToCache(reflect.TypeOf((*string)(nil)).Elem(), &htmlEscapedStringEncoder{})
}
func (cfg *frozenConfig) addDecoderToCache(cacheKey reflect.Type, decoder ValDecoder) {
done := false
for !done {
ptr := atomic.LoadPointer(&cfg.decoderCache)
cache := *(*map[reflect.Type]ValDecoder)(ptr)
copied := map[reflect.Type]ValDecoder{}
for k, v := range cache {
copied[k] = v
}
copied[cacheKey] = decoder
done = atomic.CompareAndSwapPointer(&cfg.decoderCache, ptr, unsafe.Pointer(&copied))
}
}
func (cfg *frozenConfig) addEncoderToCache(cacheKey reflect.Type, encoder ValEncoder) {
done := false
for !done {
ptr := atomic.LoadPointer(&cfg.encoderCache)
cache := *(*map[reflect.Type]ValEncoder)(ptr)
copied := map[reflect.Type]ValEncoder{}
for k, v := range cache {
copied[k] = v
}
copied[cacheKey] = encoder
done = atomic.CompareAndSwapPointer(&cfg.encoderCache, ptr, unsafe.Pointer(&copied))
}
}
func (cfg *frozenConfig) getDecoderFromCache(cacheKey reflect.Type) ValDecoder {
ptr := atomic.LoadPointer(&cfg.decoderCache)
cache := *(*map[reflect.Type]ValDecoder)(ptr)
return cache[cacheKey]
}
func (cfg *frozenConfig) getEncoderFromCache(cacheKey reflect.Type) ValEncoder {
ptr := atomic.LoadPointer(&cfg.encoderCache)
cache := *(*map[reflect.Type]ValEncoder)(ptr)
return cache[cacheKey]
}
func (cfg *frozenConfig) cleanDecoders() {
typeDecoders = map[string]ValDecoder{}
fieldDecoders = map[string]ValDecoder{}
*cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig))
}
func (cfg *frozenConfig) cleanEncoders() {
typeEncoders = map[string]ValEncoder{}
fieldEncoders = map[string]ValEncoder{}
*cfg = *(cfg.configBeforeFrozen.Froze().(*frozenConfig))
}
func (cfg *frozenConfig) MarshalToString(v interface{}) (string, error) {
stream := cfg.BorrowStream(nil)
defer cfg.ReturnStream(stream)
stream.WriteVal(v)
if stream.Error != nil {
return "", stream.Error
}
return string(stream.Buffer()), nil
}
func (cfg *frozenConfig) Marshal(v interface{}) ([]byte, error) {
stream := cfg.BorrowStream(nil)
defer cfg.ReturnStream(stream)
stream.WriteVal(v)
if stream.Error != nil {
return nil, stream.Error
}
result := stream.Buffer()
copied := make([]byte, len(result))
copy(copied, result)
return copied, nil
}
func (cfg *frozenConfig) MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) {
if prefix != "" {
panic("prefix is not supported")
}
for _, r := range indent {
if r != ' ' {
panic("indent can only be space")
}
}
newCfg := cfg.configBeforeFrozen
newCfg.IndentionStep = len(indent)
return newCfg.Froze().Marshal(v)
}
func (cfg *frozenConfig) UnmarshalFromString(str string, v interface{}) error {
data := []byte(str)
data = data[:lastNotSpacePos(data)]
iter := cfg.BorrowIterator(data)
defer cfg.ReturnIterator(iter)
iter.ReadVal(v)
if iter.head == iter.tail {
iter.loadMore()
}
if iter.Error == io.EOF {
return nil
}
if iter.Error == nil {
iter.ReportError("UnmarshalFromString", "there are bytes left after unmarshal")
}
return iter.Error
}
func (cfg *frozenConfig) Get(data []byte, path ...interface{}) Any {
iter := cfg.BorrowIterator(data)
defer cfg.ReturnIterator(iter)
return locatePath(iter, path)
}
func (cfg *frozenConfig) Unmarshal(data []byte, v interface{}) error {
data = data[:lastNotSpacePos(data)]
iter := cfg.BorrowIterator(data)
defer cfg.ReturnIterator(iter)
typ := reflect.TypeOf(v)
if typ.Kind() != reflect.Ptr {
// return non-pointer error
return errors.New("the second param must be ptr type")
}
iter.ReadVal(v)
if iter.head == iter.tail {
iter.loadMore()
}
if iter.Error == io.EOF {
return nil
}
if iter.Error == nil {
iter.ReportError("Unmarshal", "there are bytes left after unmarshal")
}
return iter.Error
}
func (cfg *frozenConfig) NewEncoder(writer io.Writer) *Encoder {
stream := NewStream(cfg, writer, 512)
return &Encoder{stream}
}
func (cfg *frozenConfig) NewDecoder(reader io.Reader) *Decoder {
iter := Parse(cfg, reader, 512)
return &Decoder{iter}
}
-15
View File
@@ -1,15 +0,0 @@
package jsoniter
import "encoding/json"
type Number string
func CastJsonNumber(val interface{}) (string, bool) {
switch typedVal := val.(type) {
case json.Number:
return string(typedVal), true
case Number:
return string(typedVal), true
}
return "", false
}
-691
View File
@@ -1,691 +0,0 @@
package jsoniter
import (
"encoding"
"encoding/json"
"fmt"
"reflect"
"time"
"unsafe"
)
// ValDecoder is an internal type registered to cache as needed.
// Don't confuse jsoniter.ValDecoder with json.Decoder.
// For json.Decoder's adapter, refer to jsoniter.AdapterDecoder(todo link).
//
// Reflection on type to create decoders, which is then cached
// Reflection on value is avoided as we can, as the reflect.Value itself will allocate, with following exceptions
// 1. create instance of new value, for example *int will need a int to be allocated
// 2. append to slice, if the existing cap is not enough, allocate will be done using Reflect.New
// 3. assignment to map, both key and value will be reflect.Value
// For a simple struct binding, it will be reflect.Value free and allocation free
type ValDecoder interface {
Decode(ptr unsafe.Pointer, iter *Iterator)
}
// ValEncoder is an internal type registered to cache as needed.
// Don't confuse jsoniter.ValEncoder with json.Encoder.
// For json.Encoder's adapter, refer to jsoniter.AdapterEncoder(todo godoc link).
type ValEncoder interface {
IsEmpty(ptr unsafe.Pointer) bool
Encode(ptr unsafe.Pointer, stream *Stream)
EncodeInterface(val interface{}, stream *Stream)
}
type checkIsEmpty interface {
IsEmpty(ptr unsafe.Pointer) bool
}
// WriteToStream the default implementation for TypeEncoder method EncodeInterface
func WriteToStream(val interface{}, stream *Stream, encoder ValEncoder) {
e := (*emptyInterface)(unsafe.Pointer(&val))
if e.word == nil {
stream.WriteNil()
return
}
if reflect.TypeOf(val).Kind() == reflect.Ptr {
encoder.Encode(unsafe.Pointer(&e.word), stream)
} else {
encoder.Encode(e.word, stream)
}
}
var jsonNumberType reflect.Type
var jsoniterNumberType reflect.Type
var jsonRawMessageType reflect.Type
var jsoniterRawMessageType reflect.Type
var anyType reflect.Type
var marshalerType reflect.Type
var unmarshalerType reflect.Type
var textMarshalerType reflect.Type
var textUnmarshalerType reflect.Type
func init() {
jsonNumberType = reflect.TypeOf((*json.Number)(nil)).Elem()
jsoniterNumberType = reflect.TypeOf((*Number)(nil)).Elem()
jsonRawMessageType = reflect.TypeOf((*json.RawMessage)(nil)).Elem()
jsoniterRawMessageType = reflect.TypeOf((*RawMessage)(nil)).Elem()
anyType = reflect.TypeOf((*Any)(nil)).Elem()
marshalerType = reflect.TypeOf((*json.Marshaler)(nil)).Elem()
unmarshalerType = reflect.TypeOf((*json.Unmarshaler)(nil)).Elem()
textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem()
textUnmarshalerType = reflect.TypeOf((*encoding.TextUnmarshaler)(nil)).Elem()
}
type optionalDecoder struct {
valueType reflect.Type
valueDecoder ValDecoder
}
func (decoder *optionalDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
if iter.ReadNil() {
*((*unsafe.Pointer)(ptr)) = nil
} else {
if *((*unsafe.Pointer)(ptr)) == nil {
//pointer to null, we have to allocate memory to hold the value
value := reflect.New(decoder.valueType)
newPtr := extractInterface(value.Interface()).word
decoder.valueDecoder.Decode(newPtr, iter)
*((*uintptr)(ptr)) = uintptr(newPtr)
} else {
//reuse existing instance
decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter)
}
}
}
type deferenceDecoder struct {
// only to deference a pointer
valueType reflect.Type
valueDecoder ValDecoder
}
func (decoder *deferenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
if *((*unsafe.Pointer)(ptr)) == nil {
//pointer to null, we have to allocate memory to hold the value
value := reflect.New(decoder.valueType)
newPtr := extractInterface(value.Interface()).word
decoder.valueDecoder.Decode(newPtr, iter)
*((*uintptr)(ptr)) = uintptr(newPtr)
} else {
//reuse existing instance
decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter)
}
}
type optionalEncoder struct {
valueEncoder ValEncoder
}
func (encoder *optionalEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
if *((*unsafe.Pointer)(ptr)) == nil {
stream.WriteNil()
} else {
encoder.valueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream)
}
}
func (encoder *optionalEncoder) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, encoder)
}
func (encoder *optionalEncoder) IsEmpty(ptr unsafe.Pointer) bool {
if *((*unsafe.Pointer)(ptr)) == nil {
return true
}
return false
}
type placeholderEncoder struct {
cfg *frozenConfig
cacheKey reflect.Type
}
func (encoder *placeholderEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
encoder.getRealEncoder().Encode(ptr, stream)
}
func (encoder *placeholderEncoder) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, encoder)
}
func (encoder *placeholderEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return encoder.getRealEncoder().IsEmpty(ptr)
}
func (encoder *placeholderEncoder) getRealEncoder() ValEncoder {
for i := 0; i < 30; i++ {
realDecoder := encoder.cfg.getEncoderFromCache(encoder.cacheKey)
_, isPlaceholder := realDecoder.(*placeholderEncoder)
if isPlaceholder {
time.Sleep(time.Second)
} else {
return realDecoder
}
}
panic(fmt.Sprintf("real encoder not found for cache key: %v", encoder.cacheKey))
}
type placeholderDecoder struct {
cfg *frozenConfig
cacheKey reflect.Type
}
func (decoder *placeholderDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
for i := 0; i < 30; i++ {
realDecoder := decoder.cfg.getDecoderFromCache(decoder.cacheKey)
_, isPlaceholder := realDecoder.(*placeholderDecoder)
if isPlaceholder {
time.Sleep(time.Second)
} else {
realDecoder.Decode(ptr, iter)
return
}
}
panic(fmt.Sprintf("real decoder not found for cache key: %v", decoder.cacheKey))
}
// emptyInterface is the header for an interface{} value.
type emptyInterface struct {
typ unsafe.Pointer
word unsafe.Pointer
}
// emptyInterface is the header for an interface with method (not interface{})
type nonEmptyInterface struct {
// see ../runtime/iface.go:/Itab
itab *struct {
ityp unsafe.Pointer // static interface type
typ unsafe.Pointer // dynamic concrete type
link unsafe.Pointer
bad int32
unused int32
fun [100000]unsafe.Pointer // method table
}
word unsafe.Pointer
}
// ReadVal copy the underlying JSON into go interface, same as json.Unmarshal
func (iter *Iterator) ReadVal(obj interface{}) {
typ := reflect.TypeOf(obj)
cacheKey := typ.Elem()
decoder, err := decoderOfType(iter.cfg, cacheKey)
if err != nil {
iter.Error = err
return
}
e := (*emptyInterface)(unsafe.Pointer(&obj))
decoder.Decode(e.word, iter)
}
// WriteVal copy the go interface into underlying JSON, same as json.Marshal
func (stream *Stream) WriteVal(val interface{}) {
if nil == val {
stream.WriteNil()
return
}
typ := reflect.TypeOf(val)
cacheKey := typ
encoder, err := encoderOfType(stream.cfg, cacheKey)
if err != nil {
stream.Error = err
return
}
encoder.EncodeInterface(val, stream)
}
type prefix string
func (p prefix) addToDecoder(decoder ValDecoder, err error) (ValDecoder, error) {
if err != nil {
return nil, fmt.Errorf("%s: %s", p, err.Error())
}
return decoder, err
}
func (p prefix) addToEncoder(encoder ValEncoder, err error) (ValEncoder, error) {
if err != nil {
return nil, fmt.Errorf("%s: %s", p, err.Error())
}
return encoder, err
}
func decoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
cacheKey := typ
decoder := cfg.getDecoderFromCache(cacheKey)
if decoder != nil {
return decoder, nil
}
decoder = getTypeDecoderFromExtension(typ)
if decoder != nil {
cfg.addDecoderToCache(cacheKey, decoder)
return decoder, nil
}
decoder = &placeholderDecoder{cfg: cfg, cacheKey: cacheKey}
cfg.addDecoderToCache(cacheKey, decoder)
decoder, err := createDecoderOfType(cfg, typ)
for _, extension := range extensions {
decoder = extension.DecorateDecoder(typ, decoder)
}
cfg.addDecoderToCache(cacheKey, decoder)
return decoder, err
}
func createDecoderOfType(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
typeName := typ.String()
if typ == jsonRawMessageType {
return &jsonRawMessageCodec{}, nil
}
if typ == jsoniterRawMessageType {
return &jsoniterRawMessageCodec{}, nil
}
if typ.AssignableTo(jsonNumberType) {
return &jsonNumberCodec{}, nil
}
if typ.AssignableTo(jsoniterNumberType) {
return &jsoniterNumberCodec{}, nil
}
if typ.Implements(unmarshalerType) {
templateInterface := reflect.New(typ).Elem().Interface()
var decoder ValDecoder = &unmarshalerDecoder{extractInterface(templateInterface)}
if typ.Kind() == reflect.Ptr {
decoder = &optionalDecoder{typ.Elem(), decoder}
}
return decoder, nil
}
if reflect.PtrTo(typ).Implements(unmarshalerType) {
templateInterface := reflect.New(typ).Interface()
var decoder ValDecoder = &unmarshalerDecoder{extractInterface(templateInterface)}
return decoder, nil
}
if typ.Implements(textUnmarshalerType) {
templateInterface := reflect.New(typ).Elem().Interface()
var decoder ValDecoder = &textUnmarshalerDecoder{extractInterface(templateInterface)}
if typ.Kind() == reflect.Ptr {
decoder = &optionalDecoder{typ.Elem(), decoder}
}
return decoder, nil
}
if reflect.PtrTo(typ).Implements(textUnmarshalerType) {
templateInterface := reflect.New(typ).Interface()
var decoder ValDecoder = &textUnmarshalerDecoder{extractInterface(templateInterface)}
return decoder, nil
}
if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 {
sliceDecoder, err := prefix("[slice]").addToDecoder(decoderOfSlice(cfg, typ))
if err != nil {
return nil, err
}
return &base64Codec{sliceDecoder: sliceDecoder}, nil
}
if typ.Implements(anyType) {
return &anyCodec{}, nil
}
switch typ.Kind() {
case reflect.String:
if typeName != "string" {
return decoderOfType(cfg, reflect.TypeOf((*string)(nil)).Elem())
}
return &stringCodec{}, nil
case reflect.Int:
if typeName != "int" {
return decoderOfType(cfg, reflect.TypeOf((*int)(nil)).Elem())
}
return &intCodec{}, nil
case reflect.Int8:
if typeName != "int8" {
return decoderOfType(cfg, reflect.TypeOf((*int8)(nil)).Elem())
}
return &int8Codec{}, nil
case reflect.Int16:
if typeName != "int16" {
return decoderOfType(cfg, reflect.TypeOf((*int16)(nil)).Elem())
}
return &int16Codec{}, nil
case reflect.Int32:
if typeName != "int32" {
return decoderOfType(cfg, reflect.TypeOf((*int32)(nil)).Elem())
}
return &int32Codec{}, nil
case reflect.Int64:
if typeName != "int64" {
return decoderOfType(cfg, reflect.TypeOf((*int64)(nil)).Elem())
}
return &int64Codec{}, nil
case reflect.Uint:
if typeName != "uint" {
return decoderOfType(cfg, reflect.TypeOf((*uint)(nil)).Elem())
}
return &uintCodec{}, nil
case reflect.Uint8:
if typeName != "uint8" {
return decoderOfType(cfg, reflect.TypeOf((*uint8)(nil)).Elem())
}
return &uint8Codec{}, nil
case reflect.Uint16:
if typeName != "uint16" {
return decoderOfType(cfg, reflect.TypeOf((*uint16)(nil)).Elem())
}
return &uint16Codec{}, nil
case reflect.Uint32:
if typeName != "uint32" {
return decoderOfType(cfg, reflect.TypeOf((*uint32)(nil)).Elem())
}
return &uint32Codec{}, nil
case reflect.Uintptr:
if typeName != "uintptr" {
return decoderOfType(cfg, reflect.TypeOf((*uintptr)(nil)).Elem())
}
return &uintptrCodec{}, nil
case reflect.Uint64:
if typeName != "uint64" {
return decoderOfType(cfg, reflect.TypeOf((*uint64)(nil)).Elem())
}
return &uint64Codec{}, nil
case reflect.Float32:
if typeName != "float32" {
return decoderOfType(cfg, reflect.TypeOf((*float32)(nil)).Elem())
}
return &float32Codec{}, nil
case reflect.Float64:
if typeName != "float64" {
return decoderOfType(cfg, reflect.TypeOf((*float64)(nil)).Elem())
}
return &float64Codec{}, nil
case reflect.Bool:
if typeName != "bool" {
return decoderOfType(cfg, reflect.TypeOf((*bool)(nil)).Elem())
}
return &boolCodec{}, nil
case reflect.Interface:
if typ.NumMethod() == 0 {
return &emptyInterfaceCodec{}, nil
}
return &nonEmptyInterfaceCodec{}, nil
case reflect.Struct:
return prefix(fmt.Sprintf("[%s]", typeName)).addToDecoder(decoderOfStruct(cfg, typ))
case reflect.Array:
return prefix("[array]").addToDecoder(decoderOfArray(cfg, typ))
case reflect.Slice:
return prefix("[slice]").addToDecoder(decoderOfSlice(cfg, typ))
case reflect.Map:
return prefix("[map]").addToDecoder(decoderOfMap(cfg, typ))
case reflect.Ptr:
return prefix("[optional]").addToDecoder(decoderOfOptional(cfg, typ))
default:
return nil, fmt.Errorf("unsupported type: %v", typ)
}
}
func encoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
cacheKey := typ
encoder := cfg.getEncoderFromCache(cacheKey)
if encoder != nil {
return encoder, nil
}
encoder = getTypeEncoderFromExtension(typ)
if encoder != nil {
cfg.addEncoderToCache(cacheKey, encoder)
return encoder, nil
}
encoder = &placeholderEncoder{cfg: cfg, cacheKey: cacheKey}
cfg.addEncoderToCache(cacheKey, encoder)
encoder, err := createEncoderOfType(cfg, typ)
for _, extension := range extensions {
encoder = extension.DecorateEncoder(typ, encoder)
}
cfg.addEncoderToCache(cacheKey, encoder)
return encoder, err
}
func createEncoderOfType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
if typ == jsonRawMessageType {
return &jsonRawMessageCodec{}, nil
}
if typ == jsoniterRawMessageType {
return &jsoniterRawMessageCodec{}, nil
}
if typ.AssignableTo(jsonNumberType) {
return &jsonNumberCodec{}, nil
}
if typ.AssignableTo(jsoniterNumberType) {
return &jsoniterNumberCodec{}, nil
}
if typ.Implements(marshalerType) {
checkIsEmpty, err := createCheckIsEmpty(typ)
if err != nil {
return nil, err
}
templateInterface := reflect.New(typ).Elem().Interface()
var encoder ValEncoder = &marshalerEncoder{
templateInterface: extractInterface(templateInterface),
checkIsEmpty: checkIsEmpty,
}
if typ.Kind() == reflect.Ptr {
encoder = &optionalEncoder{encoder}
}
return encoder, nil
}
if typ.Implements(textMarshalerType) {
checkIsEmpty, err := createCheckIsEmpty(typ)
if err != nil {
return nil, err
}
templateInterface := reflect.New(typ).Elem().Interface()
var encoder ValEncoder = &textMarshalerEncoder{
templateInterface: extractInterface(templateInterface),
checkIsEmpty: checkIsEmpty,
}
if typ.Kind() == reflect.Ptr {
encoder = &optionalEncoder{encoder}
}
return encoder, nil
}
if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 {
return &base64Codec{}, nil
}
if typ.Implements(anyType) {
return &anyCodec{}, nil
}
return createEncoderOfSimpleType(cfg, typ)
}
func createCheckIsEmpty(typ reflect.Type) (checkIsEmpty, error) {
kind := typ.Kind()
switch kind {
case reflect.String:
return &stringCodec{}, nil
case reflect.Int:
return &intCodec{}, nil
case reflect.Int8:
return &int8Codec{}, nil
case reflect.Int16:
return &int16Codec{}, nil
case reflect.Int32:
return &int32Codec{}, nil
case reflect.Int64:
return &int64Codec{}, nil
case reflect.Uint:
return &uintCodec{}, nil
case reflect.Uint8:
return &uint8Codec{}, nil
case reflect.Uint16:
return &uint16Codec{}, nil
case reflect.Uint32:
return &uint32Codec{}, nil
case reflect.Uintptr:
return &uintptrCodec{}, nil
case reflect.Uint64:
return &uint64Codec{}, nil
case reflect.Float32:
return &float32Codec{}, nil
case reflect.Float64:
return &float64Codec{}, nil
case reflect.Bool:
return &boolCodec{}, nil
case reflect.Interface:
if typ.NumMethod() == 0 {
return &emptyInterfaceCodec{}, nil
}
return &nonEmptyInterfaceCodec{}, nil
case reflect.Struct:
return &structEncoder{}, nil
case reflect.Array:
return &arrayEncoder{}, nil
case reflect.Slice:
return &sliceEncoder{}, nil
case reflect.Map:
return &mapEncoder{}, nil
case reflect.Ptr:
return &optionalEncoder{}, nil
default:
return nil, fmt.Errorf("unsupported type: %v", typ)
}
}
func createEncoderOfSimpleType(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
typeName := typ.String()
kind := typ.Kind()
switch kind {
case reflect.String:
if typeName != "string" {
return encoderOfType(cfg, reflect.TypeOf((*string)(nil)).Elem())
}
return &stringCodec{}, nil
case reflect.Int:
if typeName != "int" {
return encoderOfType(cfg, reflect.TypeOf((*int)(nil)).Elem())
}
return &intCodec{}, nil
case reflect.Int8:
if typeName != "int8" {
return encoderOfType(cfg, reflect.TypeOf((*int8)(nil)).Elem())
}
return &int8Codec{}, nil
case reflect.Int16:
if typeName != "int16" {
return encoderOfType(cfg, reflect.TypeOf((*int16)(nil)).Elem())
}
return &int16Codec{}, nil
case reflect.Int32:
if typeName != "int32" {
return encoderOfType(cfg, reflect.TypeOf((*int32)(nil)).Elem())
}
return &int32Codec{}, nil
case reflect.Int64:
if typeName != "int64" {
return encoderOfType(cfg, reflect.TypeOf((*int64)(nil)).Elem())
}
return &int64Codec{}, nil
case reflect.Uint:
if typeName != "uint" {
return encoderOfType(cfg, reflect.TypeOf((*uint)(nil)).Elem())
}
return &uintCodec{}, nil
case reflect.Uint8:
if typeName != "uint8" {
return encoderOfType(cfg, reflect.TypeOf((*uint8)(nil)).Elem())
}
return &uint8Codec{}, nil
case reflect.Uint16:
if typeName != "uint16" {
return encoderOfType(cfg, reflect.TypeOf((*uint16)(nil)).Elem())
}
return &uint16Codec{}, nil
case reflect.Uint32:
if typeName != "uint32" {
return encoderOfType(cfg, reflect.TypeOf((*uint32)(nil)).Elem())
}
return &uint32Codec{}, nil
case reflect.Uintptr:
if typeName != "uintptr" {
return encoderOfType(cfg, reflect.TypeOf((*uintptr)(nil)).Elem())
}
return &uintptrCodec{}, nil
case reflect.Uint64:
if typeName != "uint64" {
return encoderOfType(cfg, reflect.TypeOf((*uint64)(nil)).Elem())
}
return &uint64Codec{}, nil
case reflect.Float32:
if typeName != "float32" {
return encoderOfType(cfg, reflect.TypeOf((*float32)(nil)).Elem())
}
return &float32Codec{}, nil
case reflect.Float64:
if typeName != "float64" {
return encoderOfType(cfg, reflect.TypeOf((*float64)(nil)).Elem())
}
return &float64Codec{}, nil
case reflect.Bool:
if typeName != "bool" {
return encoderOfType(cfg, reflect.TypeOf((*bool)(nil)).Elem())
}
return &boolCodec{}, nil
case reflect.Interface:
if typ.NumMethod() == 0 {
return &emptyInterfaceCodec{}, nil
}
return &nonEmptyInterfaceCodec{}, nil
case reflect.Struct:
return prefix(fmt.Sprintf("[%s]", typeName)).addToEncoder(encoderOfStruct(cfg, typ))
case reflect.Array:
return prefix("[array]").addToEncoder(encoderOfArray(cfg, typ))
case reflect.Slice:
return prefix("[slice]").addToEncoder(encoderOfSlice(cfg, typ))
case reflect.Map:
return prefix("[map]").addToEncoder(encoderOfMap(cfg, typ))
case reflect.Ptr:
return prefix("[optional]").addToEncoder(encoderOfOptional(cfg, typ))
default:
return nil, fmt.Errorf("unsupported type: %v", typ)
}
}
func decoderOfOptional(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
elemType := typ.Elem()
decoder, err := decoderOfType(cfg, elemType)
if err != nil {
return nil, err
}
return &optionalDecoder{elemType, decoder}, nil
}
func encoderOfOptional(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
elemType := typ.Elem()
elemEncoder, err := encoderOfType(cfg, elemType)
if err != nil {
return nil, err
}
encoder := &optionalEncoder{elemEncoder}
if elemType.Kind() == reflect.Map {
encoder = &optionalEncoder{encoder}
}
return encoder, nil
}
func decoderOfMap(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
decoder, err := decoderOfType(cfg, typ.Elem())
if err != nil {
return nil, err
}
mapInterface := reflect.New(typ).Interface()
return &mapDecoder{typ, typ.Key(), typ.Elem(), decoder, extractInterface(mapInterface)}, nil
}
func extractInterface(val interface{}) emptyInterface {
return *((*emptyInterface)(unsafe.Pointer(&val)))
}
func encoderOfMap(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
elemType := typ.Elem()
encoder, err := encoderOfType(cfg, elemType)
if err != nil {
return nil, err
}
mapInterface := reflect.New(typ).Elem().Interface()
if cfg.sortMapKeys {
return &sortKeysMapEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil
}
return &mapEncoder{typ, elemType, encoder, *((*emptyInterface)(unsafe.Pointer(&mapInterface)))}, nil
}
-99
View File
@@ -1,99 +0,0 @@
package jsoniter
import (
"fmt"
"io"
"reflect"
"unsafe"
)
func decoderOfArray(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
decoder, err := decoderOfType(cfg, typ.Elem())
if err != nil {
return nil, err
}
return &arrayDecoder{typ, typ.Elem(), decoder}, nil
}
func encoderOfArray(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
encoder, err := encoderOfType(cfg, typ.Elem())
if err != nil {
return nil, err
}
if typ.Elem().Kind() == reflect.Map {
encoder = &optionalEncoder{encoder}
}
return &arrayEncoder{typ, typ.Elem(), encoder}, nil
}
type arrayEncoder struct {
arrayType reflect.Type
elemType reflect.Type
elemEncoder ValEncoder
}
func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteArrayStart()
elemPtr := unsafe.Pointer(ptr)
encoder.elemEncoder.Encode(elemPtr, stream)
for i := 1; i < encoder.arrayType.Len(); i++ {
stream.WriteMore()
elemPtr = unsafe.Pointer(uintptr(elemPtr) + encoder.elemType.Size())
encoder.elemEncoder.Encode(unsafe.Pointer(elemPtr), stream)
}
stream.WriteArrayEnd()
if stream.Error != nil && stream.Error != io.EOF {
stream.Error = fmt.Errorf("%v: %s", encoder.arrayType, stream.Error.Error())
}
}
func (encoder *arrayEncoder) EncodeInterface(val interface{}, stream *Stream) {
// special optimization for interface{}
e := (*emptyInterface)(unsafe.Pointer(&val))
if e.word == nil {
stream.WriteArrayStart()
stream.WriteNil()
stream.WriteArrayEnd()
return
}
elemType := encoder.arrayType.Elem()
if encoder.arrayType.Len() == 1 && (elemType.Kind() == reflect.Ptr || elemType.Kind() == reflect.Map) {
ptr := uintptr(e.word)
e.word = unsafe.Pointer(&ptr)
}
if reflect.TypeOf(val).Kind() == reflect.Ptr {
encoder.Encode(unsafe.Pointer(&e.word), stream)
} else {
encoder.Encode(e.word, stream)
}
}
func (encoder *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return false
}
type arrayDecoder struct {
arrayType reflect.Type
elemType reflect.Type
elemDecoder ValDecoder
}
func (decoder *arrayDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
decoder.doDecode(ptr, iter)
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.arrayType, iter.Error.Error())
}
}
func (decoder *arrayDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
offset := uintptr(0)
iter.ReadArrayCB(func(iter *Iterator) bool {
if offset < decoder.arrayType.Size() {
decoder.elemDecoder.Decode(unsafe.Pointer(uintptr(ptr)+offset), iter)
offset += decoder.elemType.Size()
} else {
iter.Skip()
}
return true
})
}
-244
View File
@@ -1,244 +0,0 @@
package jsoniter
import (
"encoding"
"encoding/json"
"reflect"
"sort"
"strconv"
"unsafe"
)
type mapDecoder struct {
mapType reflect.Type
keyType reflect.Type
elemType reflect.Type
elemDecoder ValDecoder
mapInterface emptyInterface
}
func (decoder *mapDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
// dark magic to cast unsafe.Pointer back to interface{} using reflect.Type
mapInterface := decoder.mapInterface
mapInterface.word = ptr
realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
realVal := reflect.ValueOf(*realInterface).Elem()
if iter.ReadNil() {
realVal.Set(reflect.Zero(decoder.mapType))
return
}
if realVal.IsNil() {
realVal.Set(reflect.MakeMap(realVal.Type()))
}
iter.ReadMapCB(func(iter *Iterator, keyStr string) bool {
elem := reflect.New(decoder.elemType)
decoder.elemDecoder.Decode(unsafe.Pointer(elem.Pointer()), iter)
// to put into map, we have to use reflection
keyType := decoder.keyType
// TODO: remove this from loop
switch {
case keyType.Kind() == reflect.String:
realVal.SetMapIndex(reflect.ValueOf(keyStr).Convert(keyType), elem.Elem())
return true
case keyType.Implements(textUnmarshalerType):
textUnmarshaler := reflect.New(keyType.Elem()).Interface().(encoding.TextUnmarshaler)
err := textUnmarshaler.UnmarshalText([]byte(keyStr))
if err != nil {
iter.ReportError("read map key as TextUnmarshaler", err.Error())
return false
}
realVal.SetMapIndex(reflect.ValueOf(textUnmarshaler), elem.Elem())
return true
case reflect.PtrTo(keyType).Implements(textUnmarshalerType):
textUnmarshaler := reflect.New(keyType).Interface().(encoding.TextUnmarshaler)
err := textUnmarshaler.UnmarshalText([]byte(keyStr))
if err != nil {
iter.ReportError("read map key as TextUnmarshaler", err.Error())
return false
}
realVal.SetMapIndex(reflect.ValueOf(textUnmarshaler).Elem(), elem.Elem())
return true
default:
switch keyType.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
n, err := strconv.ParseInt(keyStr, 10, 64)
if err != nil || reflect.Zero(keyType).OverflowInt(n) {
iter.ReportError("read map key as int64", "read int64 failed")
return false
}
realVal.SetMapIndex(reflect.ValueOf(n).Convert(keyType), elem.Elem())
return true
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
n, err := strconv.ParseUint(keyStr, 10, 64)
if err != nil || reflect.Zero(keyType).OverflowUint(n) {
iter.ReportError("read map key as uint64", "read uint64 failed")
return false
}
realVal.SetMapIndex(reflect.ValueOf(n).Convert(keyType), elem.Elem())
return true
}
}
iter.ReportError("read map key", "unexpected map key type "+keyType.String())
return true
})
}
type mapEncoder struct {
mapType reflect.Type
elemType reflect.Type
elemEncoder ValEncoder
mapInterface emptyInterface
}
func (encoder *mapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
mapInterface := encoder.mapInterface
mapInterface.word = ptr
realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
realVal := reflect.ValueOf(*realInterface)
stream.WriteObjectStart()
for i, key := range realVal.MapKeys() {
if i != 0 {
stream.WriteMore()
}
encodeMapKey(key, stream)
if stream.indention > 0 {
stream.writeTwoBytes(byte(':'), byte(' '))
} else {
stream.writeByte(':')
}
val := realVal.MapIndex(key).Interface()
encoder.elemEncoder.EncodeInterface(val, stream)
}
stream.WriteObjectEnd()
}
func encodeMapKey(key reflect.Value, stream *Stream) {
if key.Kind() == reflect.String {
stream.WriteString(key.String())
return
}
if tm, ok := key.Interface().(encoding.TextMarshaler); ok {
buf, err := tm.MarshalText()
if err != nil {
stream.Error = err
return
}
stream.writeByte('"')
stream.Write(buf)
stream.writeByte('"')
return
}
switch key.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
stream.writeByte('"')
stream.WriteInt64(key.Int())
stream.writeByte('"')
return
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
stream.writeByte('"')
stream.WriteUint64(key.Uint())
stream.writeByte('"')
return
}
stream.Error = &json.UnsupportedTypeError{Type: key.Type()}
}
func (encoder *mapEncoder) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, encoder)
}
func (encoder *mapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
mapInterface := encoder.mapInterface
mapInterface.word = ptr
realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
realVal := reflect.ValueOf(*realInterface)
return realVal.Len() == 0
}
type sortKeysMapEncoder struct {
mapType reflect.Type
elemType reflect.Type
elemEncoder ValEncoder
mapInterface emptyInterface
}
func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
mapInterface := encoder.mapInterface
mapInterface.word = ptr
realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
realVal := reflect.ValueOf(*realInterface)
// Extract and sort the keys.
keys := realVal.MapKeys()
sv := stringValues(make([]reflectWithString, len(keys)))
for i, v := range keys {
sv[i].v = v
if err := sv[i].resolve(); err != nil {
stream.Error = err
return
}
}
sort.Sort(sv)
stream.WriteObjectStart()
for i, key := range sv {
if i != 0 {
stream.WriteMore()
}
stream.WriteVal(key.s) // might need html escape, so can not WriteString directly
if stream.indention > 0 {
stream.writeTwoBytes(byte(':'), byte(' '))
} else {
stream.writeByte(':')
}
val := realVal.MapIndex(key.v).Interface()
encoder.elemEncoder.EncodeInterface(val, stream)
}
stream.WriteObjectEnd()
}
// stringValues is a slice of reflect.Value holding *reflect.StringValue.
// It implements the methods to sort by string.
type stringValues []reflectWithString
type reflectWithString struct {
v reflect.Value
s string
}
func (w *reflectWithString) resolve() error {
if w.v.Kind() == reflect.String {
w.s = w.v.String()
return nil
}
if tm, ok := w.v.Interface().(encoding.TextMarshaler); ok {
buf, err := tm.MarshalText()
w.s = string(buf)
return err
}
switch w.v.Kind() {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
w.s = strconv.FormatInt(w.v.Int(), 10)
return nil
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
w.s = strconv.FormatUint(w.v.Uint(), 10)
return nil
}
return &json.UnsupportedTypeError{Type: w.v.Type()}
}
func (sv stringValues) Len() int { return len(sv) }
func (sv stringValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] }
func (sv stringValues) Less(i, j int) bool { return sv[i].s < sv[j].s }
func (encoder *sortKeysMapEncoder) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, encoder)
}
func (encoder *sortKeysMapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
mapInterface := encoder.mapInterface
mapInterface.word = ptr
realInterface := (*interface{})(unsafe.Pointer(&mapInterface))
realVal := reflect.ValueOf(*realInterface)
return realVal.Len() == 0
}
-672
View File
@@ -1,672 +0,0 @@
package jsoniter
import (
"encoding"
"encoding/base64"
"encoding/json"
"unsafe"
)
type stringCodec struct {
}
func (codec *stringCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
*((*string)(ptr)) = iter.ReadString()
}
func (codec *stringCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
str := *((*string)(ptr))
stream.WriteString(str)
}
func (codec *stringCodec) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, codec)
}
func (codec *stringCodec) IsEmpty(ptr unsafe.Pointer) bool {
return *((*string)(ptr)) == ""
}
type intCodec struct {
}
func (codec *intCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
*((*int)(ptr)) = iter.ReadInt()
}
func (codec *intCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteInt(*((*int)(ptr)))
}
func (codec *intCodec) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, codec)
}
func (codec *intCodec) IsEmpty(ptr unsafe.Pointer) bool {
return *((*int)(ptr)) == 0
}
type uintptrCodec struct {
}
func (codec *uintptrCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
*((*uintptr)(ptr)) = uintptr(iter.ReadUint64())
}
func (codec *uintptrCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteUint64(uint64(*((*uintptr)(ptr))))
}
func (codec *uintptrCodec) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, codec)
}
func (codec *uintptrCodec) IsEmpty(ptr unsafe.Pointer) bool {
return *((*uintptr)(ptr)) == 0
}
type int8Codec struct {
}
func (codec *int8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
*((*int8)(ptr)) = iter.ReadInt8()
}
func (codec *int8Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteInt8(*((*int8)(ptr)))
}
func (codec *int8Codec) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, codec)
}
func (codec *int8Codec) IsEmpty(ptr unsafe.Pointer) bool {
return *((*int8)(ptr)) == 0
}
type int16Codec struct {
}
func (codec *int16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
*((*int16)(ptr)) = iter.ReadInt16()
}
func (codec *int16Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteInt16(*((*int16)(ptr)))
}
func (codec *int16Codec) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, codec)
}
func (codec *int16Codec) IsEmpty(ptr unsafe.Pointer) bool {
return *((*int16)(ptr)) == 0
}
type int32Codec struct {
}
func (codec *int32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
*((*int32)(ptr)) = iter.ReadInt32()
}
func (codec *int32Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteInt32(*((*int32)(ptr)))
}
func (codec *int32Codec) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, codec)
}
func (codec *int32Codec) IsEmpty(ptr unsafe.Pointer) bool {
return *((*int32)(ptr)) == 0
}
type int64Codec struct {
}
func (codec *int64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
*((*int64)(ptr)) = iter.ReadInt64()
}
func (codec *int64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteInt64(*((*int64)(ptr)))
}
func (codec *int64Codec) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, codec)
}
func (codec *int64Codec) IsEmpty(ptr unsafe.Pointer) bool {
return *((*int64)(ptr)) == 0
}
type uintCodec struct {
}
func (codec *uintCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
*((*uint)(ptr)) = iter.ReadUint()
}
func (codec *uintCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteUint(*((*uint)(ptr)))
}
func (codec *uintCodec) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, codec)
}
func (codec *uintCodec) IsEmpty(ptr unsafe.Pointer) bool {
return *((*uint)(ptr)) == 0
}
type uint8Codec struct {
}
func (codec *uint8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
*((*uint8)(ptr)) = iter.ReadUint8()
}
func (codec *uint8Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteUint8(*((*uint8)(ptr)))
}
func (codec *uint8Codec) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, codec)
}
func (codec *uint8Codec) IsEmpty(ptr unsafe.Pointer) bool {
return *((*uint8)(ptr)) == 0
}
type uint16Codec struct {
}
func (codec *uint16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
*((*uint16)(ptr)) = iter.ReadUint16()
}
func (codec *uint16Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteUint16(*((*uint16)(ptr)))
}
func (codec *uint16Codec) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, codec)
}
func (codec *uint16Codec) IsEmpty(ptr unsafe.Pointer) bool {
return *((*uint16)(ptr)) == 0
}
type uint32Codec struct {
}
func (codec *uint32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
*((*uint32)(ptr)) = iter.ReadUint32()
}
func (codec *uint32Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteUint32(*((*uint32)(ptr)))
}
func (codec *uint32Codec) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, codec)
}
func (codec *uint32Codec) IsEmpty(ptr unsafe.Pointer) bool {
return *((*uint32)(ptr)) == 0
}
type uint64Codec struct {
}
func (codec *uint64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
*((*uint64)(ptr)) = iter.ReadUint64()
}
func (codec *uint64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteUint64(*((*uint64)(ptr)))
}
func (codec *uint64Codec) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, codec)
}
func (codec *uint64Codec) IsEmpty(ptr unsafe.Pointer) bool {
return *((*uint64)(ptr)) == 0
}
type float32Codec struct {
}
func (codec *float32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
*((*float32)(ptr)) = iter.ReadFloat32()
}
func (codec *float32Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteFloat32(*((*float32)(ptr)))
}
func (codec *float32Codec) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, codec)
}
func (codec *float32Codec) IsEmpty(ptr unsafe.Pointer) bool {
return *((*float32)(ptr)) == 0
}
type float64Codec struct {
}
func (codec *float64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
*((*float64)(ptr)) = iter.ReadFloat64()
}
func (codec *float64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteFloat64(*((*float64)(ptr)))
}
func (codec *float64Codec) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, codec)
}
func (codec *float64Codec) IsEmpty(ptr unsafe.Pointer) bool {
return *((*float64)(ptr)) == 0
}
type boolCodec struct {
}
func (codec *boolCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
*((*bool)(ptr)) = iter.ReadBool()
}
func (codec *boolCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteBool(*((*bool)(ptr)))
}
func (codec *boolCodec) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, codec)
}
func (codec *boolCodec) IsEmpty(ptr unsafe.Pointer) bool {
return !(*((*bool)(ptr)))
}
type emptyInterfaceCodec struct {
}
func (codec *emptyInterfaceCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
*((*interface{})(ptr)) = iter.Read()
}
func (codec *emptyInterfaceCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteVal(*((*interface{})(ptr)))
}
func (codec *emptyInterfaceCodec) EncodeInterface(val interface{}, stream *Stream) {
stream.WriteVal(val)
}
func (codec *emptyInterfaceCodec) IsEmpty(ptr unsafe.Pointer) bool {
return ptr == nil
}
type nonEmptyInterfaceCodec struct {
}
func (codec *nonEmptyInterfaceCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
nonEmptyInterface := (*nonEmptyInterface)(ptr)
if nonEmptyInterface.itab == nil {
iter.ReportError("read non-empty interface", "do not know which concrete type to decode to")
return
}
var i interface{}
e := (*emptyInterface)(unsafe.Pointer(&i))
e.typ = nonEmptyInterface.itab.typ
e.word = nonEmptyInterface.word
iter.ReadVal(&i)
nonEmptyInterface.word = e.word
}
func (codec *nonEmptyInterfaceCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
nonEmptyInterface := (*nonEmptyInterface)(ptr)
var i interface{}
e := (*emptyInterface)(unsafe.Pointer(&i))
e.typ = nonEmptyInterface.itab.typ
e.word = nonEmptyInterface.word
stream.WriteVal(i)
}
func (codec *nonEmptyInterfaceCodec) EncodeInterface(val interface{}, stream *Stream) {
stream.WriteVal(val)
}
func (codec *nonEmptyInterfaceCodec) IsEmpty(ptr unsafe.Pointer) bool {
nonEmptyInterface := (*nonEmptyInterface)(ptr)
return nonEmptyInterface.word == nil
}
type anyCodec struct {
}
func (codec *anyCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
*((*Any)(ptr)) = iter.ReadAny()
}
func (codec *anyCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
(*((*Any)(ptr))).WriteTo(stream)
}
func (codec *anyCodec) EncodeInterface(val interface{}, stream *Stream) {
(val.(Any)).WriteTo(stream)
}
func (codec *anyCodec) IsEmpty(ptr unsafe.Pointer) bool {
return (*((*Any)(ptr))).Size() == 0
}
type jsonNumberCodec struct {
}
func (codec *jsonNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
*((*json.Number)(ptr)) = json.Number([]byte(iter.readNumberAsString()))
}
func (codec *jsonNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteRaw(string(*((*json.Number)(ptr))))
}
func (codec *jsonNumberCodec) EncodeInterface(val interface{}, stream *Stream) {
stream.WriteRaw(string(val.(json.Number)))
}
func (codec *jsonNumberCodec) IsEmpty(ptr unsafe.Pointer) bool {
return len(*((*json.Number)(ptr))) == 0
}
type jsoniterNumberCodec struct {
}
func (codec *jsoniterNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
*((*Number)(ptr)) = Number([]byte(iter.readNumberAsString()))
}
func (codec *jsoniterNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteRaw(string(*((*Number)(ptr))))
}
func (codec *jsoniterNumberCodec) EncodeInterface(val interface{}, stream *Stream) {
stream.WriteRaw(string(val.(Number)))
}
func (codec *jsoniterNumberCodec) IsEmpty(ptr unsafe.Pointer) bool {
return len(*((*Number)(ptr))) == 0
}
type jsonRawMessageCodec struct {
}
func (codec *jsonRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
*((*json.RawMessage)(ptr)) = json.RawMessage(iter.SkipAndReturnBytes())
}
func (codec *jsonRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteRaw(string(*((*json.RawMessage)(ptr))))
}
func (codec *jsonRawMessageCodec) EncodeInterface(val interface{}, stream *Stream) {
stream.WriteRaw(string(val.(json.RawMessage)))
}
func (codec *jsonRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool {
return len(*((*json.RawMessage)(ptr))) == 0
}
type jsoniterRawMessageCodec struct {
}
func (codec *jsoniterRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
*((*RawMessage)(ptr)) = RawMessage(iter.SkipAndReturnBytes())
}
func (codec *jsoniterRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteRaw(string(*((*RawMessage)(ptr))))
}
func (codec *jsoniterRawMessageCodec) EncodeInterface(val interface{}, stream *Stream) {
stream.WriteRaw(string(val.(RawMessage)))
}
func (codec *jsoniterRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool {
return len(*((*RawMessage)(ptr))) == 0
}
type base64Codec struct {
sliceDecoder ValDecoder
}
func (codec *base64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
if iter.ReadNil() {
ptrSlice := (*sliceHeader)(ptr)
ptrSlice.Len = 0
ptrSlice.Cap = 0
ptrSlice.Data = nil
return
}
switch iter.WhatIsNext() {
case StringValue:
encoding := base64.StdEncoding
src := iter.SkipAndReturnBytes()
src = src[1 : len(src)-1]
decodedLen := encoding.DecodedLen(len(src))
dst := make([]byte, decodedLen)
len, err := encoding.Decode(dst, src)
if err != nil {
iter.ReportError("decode base64", err.Error())
} else {
dst = dst[:len]
dstSlice := (*sliceHeader)(unsafe.Pointer(&dst))
ptrSlice := (*sliceHeader)(ptr)
ptrSlice.Data = dstSlice.Data
ptrSlice.Cap = dstSlice.Cap
ptrSlice.Len = dstSlice.Len
}
case ArrayValue:
codec.sliceDecoder.Decode(ptr, iter)
default:
iter.ReportError("base64Codec", "invalid input")
}
}
func (codec *base64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
src := *((*[]byte)(ptr))
if len(src) == 0 {
stream.WriteNil()
return
}
encoding := base64.StdEncoding
stream.writeByte('"')
toGrow := encoding.EncodedLen(len(src))
stream.ensure(toGrow)
encoding.Encode(stream.buf[stream.n:], src)
stream.n += toGrow
stream.writeByte('"')
}
func (codec *base64Codec) EncodeInterface(val interface{}, stream *Stream) {
ptr := extractInterface(val).word
src := *((*[]byte)(ptr))
if len(src) == 0 {
stream.WriteNil()
return
}
encoding := base64.StdEncoding
stream.writeByte('"')
toGrow := encoding.EncodedLen(len(src))
stream.ensure(toGrow)
encoding.Encode(stream.buf[stream.n:], src)
stream.n += toGrow
stream.writeByte('"')
}
func (codec *base64Codec) IsEmpty(ptr unsafe.Pointer) bool {
return len(*((*[]byte)(ptr))) == 0
}
type stringModeNumberDecoder struct {
elemDecoder ValDecoder
}
func (decoder *stringModeNumberDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
c := iter.nextToken()
if c != '"' {
iter.ReportError("stringModeNumberDecoder", `expect "`)
return
}
decoder.elemDecoder.Decode(ptr, iter)
if iter.Error != nil {
return
}
c = iter.readByte()
if c != '"' {
iter.ReportError("stringModeNumberDecoder", `expect "`)
return
}
}
type stringModeStringDecoder struct {
elemDecoder ValDecoder
cfg *frozenConfig
}
func (decoder *stringModeStringDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
decoder.elemDecoder.Decode(ptr, iter)
str := *((*string)(ptr))
tempIter := decoder.cfg.BorrowIterator([]byte(str))
defer decoder.cfg.ReturnIterator(tempIter)
*((*string)(ptr)) = tempIter.ReadString()
}
type stringModeNumberEncoder struct {
elemEncoder ValEncoder
}
func (encoder *stringModeNumberEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.writeByte('"')
encoder.elemEncoder.Encode(ptr, stream)
stream.writeByte('"')
}
func (encoder *stringModeNumberEncoder) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, encoder)
}
func (encoder *stringModeNumberEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return encoder.elemEncoder.IsEmpty(ptr)
}
type stringModeStringEncoder struct {
elemEncoder ValEncoder
cfg *frozenConfig
}
func (encoder *stringModeStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
tempStream := encoder.cfg.BorrowStream(nil)
defer encoder.cfg.ReturnStream(tempStream)
encoder.elemEncoder.Encode(ptr, tempStream)
stream.WriteString(string(tempStream.Buffer()))
}
func (encoder *stringModeStringEncoder) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, encoder)
}
func (encoder *stringModeStringEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return encoder.elemEncoder.IsEmpty(ptr)
}
type marshalerEncoder struct {
templateInterface emptyInterface
checkIsEmpty checkIsEmpty
}
func (encoder *marshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
templateInterface := encoder.templateInterface
templateInterface.word = ptr
realInterface := (*interface{})(unsafe.Pointer(&templateInterface))
marshaler := (*realInterface).(json.Marshaler)
bytes, err := marshaler.MarshalJSON()
if err != nil {
stream.Error = err
} else {
stream.Write(bytes)
}
}
func (encoder *marshalerEncoder) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, encoder)
}
func (encoder *marshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return encoder.checkIsEmpty.IsEmpty(ptr)
}
type textMarshalerEncoder struct {
templateInterface emptyInterface
checkIsEmpty checkIsEmpty
}
func (encoder *textMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
templateInterface := encoder.templateInterface
templateInterface.word = ptr
realInterface := (*interface{})(unsafe.Pointer(&templateInterface))
marshaler := (*realInterface).(encoding.TextMarshaler)
bytes, err := marshaler.MarshalText()
if err != nil {
stream.Error = err
} else {
stream.WriteString(string(bytes))
}
}
func (encoder *textMarshalerEncoder) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, encoder)
}
func (encoder *textMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return encoder.checkIsEmpty.IsEmpty(ptr)
}
type unmarshalerDecoder struct {
templateInterface emptyInterface
}
func (decoder *unmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
templateInterface := decoder.templateInterface
templateInterface.word = ptr
realInterface := (*interface{})(unsafe.Pointer(&templateInterface))
unmarshaler := (*realInterface).(json.Unmarshaler)
iter.nextToken()
iter.unreadByte() // skip spaces
bytes := iter.SkipAndReturnBytes()
err := unmarshaler.UnmarshalJSON(bytes)
if err != nil {
iter.ReportError("unmarshalerDecoder", err.Error())
}
}
type textUnmarshalerDecoder struct {
templateInterface emptyInterface
}
func (decoder *textUnmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
templateInterface := decoder.templateInterface
templateInterface.word = ptr
realInterface := (*interface{})(unsafe.Pointer(&templateInterface))
unmarshaler := (*realInterface).(encoding.TextUnmarshaler)
str := iter.ReadString()
err := unmarshaler.UnmarshalText([]byte(str))
if err != nil {
iter.ReportError("textUnmarshalerDecoder", err.Error())
}
}
-149
View File
@@ -1,149 +0,0 @@
package jsoniter
import (
"fmt"
"io"
"reflect"
"unsafe"
)
func decoderOfSlice(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
decoder, err := decoderOfType(cfg, typ.Elem())
if err != nil {
return nil, err
}
return &sliceDecoder{typ, typ.Elem(), decoder}, nil
}
func encoderOfSlice(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
encoder, err := encoderOfType(cfg, typ.Elem())
if err != nil {
return nil, err
}
if typ.Elem().Kind() == reflect.Map {
encoder = &optionalEncoder{encoder}
}
return &sliceEncoder{typ, typ.Elem(), encoder}, nil
}
type sliceEncoder struct {
sliceType reflect.Type
elemType reflect.Type
elemEncoder ValEncoder
}
func (encoder *sliceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
slice := (*sliceHeader)(ptr)
if slice.Data == nil {
stream.WriteNil()
return
}
if slice.Len == 0 {
stream.WriteEmptyArray()
return
}
stream.WriteArrayStart()
elemPtr := unsafe.Pointer(slice.Data)
encoder.elemEncoder.Encode(unsafe.Pointer(elemPtr), stream)
for i := 1; i < slice.Len; i++ {
stream.WriteMore()
elemPtr = unsafe.Pointer(uintptr(elemPtr) + encoder.elemType.Size())
encoder.elemEncoder.Encode(unsafe.Pointer(elemPtr), stream)
}
stream.WriteArrayEnd()
if stream.Error != nil && stream.Error != io.EOF {
stream.Error = fmt.Errorf("%v: %s", encoder.sliceType, stream.Error.Error())
}
}
func (encoder *sliceEncoder) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, encoder)
}
func (encoder *sliceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
slice := (*sliceHeader)(ptr)
return slice.Len == 0
}
type sliceDecoder struct {
sliceType reflect.Type
elemType reflect.Type
elemDecoder ValDecoder
}
// sliceHeader is a safe version of SliceHeader used within this package.
type sliceHeader struct {
Data unsafe.Pointer
Len int
Cap int
}
func (decoder *sliceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
decoder.doDecode(ptr, iter)
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.sliceType, iter.Error.Error())
}
}
func (decoder *sliceDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
slice := (*sliceHeader)(ptr)
if iter.ReadNil() {
slice.Len = 0
slice.Cap = 0
slice.Data = nil
return
}
reuseSlice(slice, decoder.sliceType, 4)
slice.Len = 0
offset := uintptr(0)
iter.ReadArrayCB(func(iter *Iterator) bool {
growOne(slice, decoder.sliceType, decoder.elemType)
decoder.elemDecoder.Decode(unsafe.Pointer(uintptr(slice.Data)+offset), iter)
offset += decoder.elemType.Size()
return true
})
}
// grow grows the slice s so that it can hold extra more values, allocating
// more capacity if needed. It also returns the old and new slice lengths.
func growOne(slice *sliceHeader, sliceType reflect.Type, elementType reflect.Type) {
newLen := slice.Len + 1
if newLen <= slice.Cap {
slice.Len = newLen
return
}
newCap := slice.Cap
if newCap == 0 {
newCap = 1
} else {
for newCap < newLen {
if slice.Len < 1024 {
newCap += newCap
} else {
newCap += newCap / 4
}
}
}
newVal := reflect.MakeSlice(sliceType, newLen, newCap)
dst := unsafe.Pointer(newVal.Pointer())
// copy old array into new array
originalBytesCount := uintptr(slice.Len) * elementType.Size()
srcPtr := (*[1 << 30]byte)(slice.Data)
dstPtr := (*[1 << 30]byte)(dst)
for i := uintptr(0); i < originalBytesCount; i++ {
dstPtr[i] = srcPtr[i]
}
slice.Data = dst
slice.Len = newLen
slice.Cap = newCap
}
func reuseSlice(slice *sliceHeader, sliceType reflect.Type, expectedCap int) {
if expectedCap <= slice.Cap {
return
}
newVal := reflect.MakeSlice(sliceType, 0, expectedCap)
dst := unsafe.Pointer(newVal.Pointer())
slice.Data = dst
slice.Cap = expectedCap
}
-320
View File
@@ -1,320 +0,0 @@
package jsoniter
var digits []uint32
func init() {
digits = make([]uint32, 1000)
for i := uint32(0); i < 1000; i++ {
digits[i] = (((i / 100) + '0') << 16) + ((((i / 10) % 10) + '0') << 8) + i%10 + '0'
if i < 10 {
digits[i] += 2 << 24
} else if i < 100 {
digits[i] += 1 << 24
}
}
}
func writeFirstBuf(buf []byte, v uint32, n int) int {
start := v >> 24
if start == 0 {
buf[n] = byte(v >> 16)
n++
buf[n] = byte(v >> 8)
n++
} else if start == 1 {
buf[n] = byte(v >> 8)
n++
}
buf[n] = byte(v)
n++
return n
}
func writeBuf(buf []byte, v uint32, n int) {
buf[n] = byte(v >> 16)
buf[n+1] = byte(v >> 8)
buf[n+2] = byte(v)
}
// WriteUint8 write uint8 to stream
func (stream *Stream) WriteUint8(val uint8) {
stream.ensure(3)
stream.n = writeFirstBuf(stream.buf, digits[val], stream.n)
}
// WriteInt8 write int8 to stream
func (stream *Stream) WriteInt8(nval int8) {
stream.ensure(4)
n := stream.n
var val uint8
if nval < 0 {
val = uint8(-nval)
stream.buf[n] = '-'
n++
} else {
val = uint8(nval)
}
stream.n = writeFirstBuf(stream.buf, digits[val], n)
}
// WriteUint16 write uint16 to stream
func (stream *Stream) WriteUint16(val uint16) {
stream.ensure(5)
q1 := val / 1000
if q1 == 0 {
stream.n = writeFirstBuf(stream.buf, digits[val], stream.n)
return
}
r1 := val - q1*1000
n := writeFirstBuf(stream.buf, digits[q1], stream.n)
writeBuf(stream.buf, digits[r1], n)
stream.n = n + 3
return
}
// WriteInt16 write int16 to stream
func (stream *Stream) WriteInt16(nval int16) {
stream.ensure(6)
n := stream.n
var val uint16
if nval < 0 {
val = uint16(-nval)
stream.buf[n] = '-'
n++
} else {
val = uint16(nval)
}
q1 := val / 1000
if q1 == 0 {
stream.n = writeFirstBuf(stream.buf, digits[val], n)
return
}
r1 := val - q1*1000
n = writeFirstBuf(stream.buf, digits[q1], n)
writeBuf(stream.buf, digits[r1], n)
stream.n = n + 3
return
}
// WriteUint32 write uint32 to stream
func (stream *Stream) WriteUint32(val uint32) {
stream.ensure(10)
n := stream.n
q1 := val / 1000
if q1 == 0 {
stream.n = writeFirstBuf(stream.buf, digits[val], n)
return
}
r1 := val - q1*1000
q2 := q1 / 1000
if q2 == 0 {
n := writeFirstBuf(stream.buf, digits[q1], n)
writeBuf(stream.buf, digits[r1], n)
stream.n = n + 3
return
}
r2 := q1 - q2*1000
q3 := q2 / 1000
if q3 == 0 {
n = writeFirstBuf(stream.buf, digits[q2], n)
} else {
r3 := q2 - q3*1000
stream.buf[n] = byte(q3 + '0')
n++
writeBuf(stream.buf, digits[r3], n)
n += 3
}
writeBuf(stream.buf, digits[r2], n)
writeBuf(stream.buf, digits[r1], n+3)
stream.n = n + 6
}
// WriteInt32 write int32 to stream
func (stream *Stream) WriteInt32(nval int32) {
stream.ensure(11)
n := stream.n
var val uint32
if nval < 0 {
val = uint32(-nval)
stream.buf[n] = '-'
n++
} else {
val = uint32(nval)
}
q1 := val / 1000
if q1 == 0 {
stream.n = writeFirstBuf(stream.buf, digits[val], n)
return
}
r1 := val - q1*1000
q2 := q1 / 1000
if q2 == 0 {
n := writeFirstBuf(stream.buf, digits[q1], n)
writeBuf(stream.buf, digits[r1], n)
stream.n = n + 3
return
}
r2 := q1 - q2*1000
q3 := q2 / 1000
if q3 == 0 {
n = writeFirstBuf(stream.buf, digits[q2], n)
} else {
r3 := q2 - q3*1000
stream.buf[n] = byte(q3 + '0')
n++
writeBuf(stream.buf, digits[r3], n)
n += 3
}
writeBuf(stream.buf, digits[r2], n)
writeBuf(stream.buf, digits[r1], n+3)
stream.n = n + 6
}
// WriteUint64 write uint64 to stream
func (stream *Stream) WriteUint64(val uint64) {
stream.ensure(20)
n := stream.n
q1 := val / 1000
if q1 == 0 {
stream.n = writeFirstBuf(stream.buf, digits[val], n)
return
}
r1 := val - q1*1000
q2 := q1 / 1000
if q2 == 0 {
n := writeFirstBuf(stream.buf, digits[q1], n)
writeBuf(stream.buf, digits[r1], n)
stream.n = n + 3
return
}
r2 := q1 - q2*1000
q3 := q2 / 1000
if q3 == 0 {
n = writeFirstBuf(stream.buf, digits[q2], n)
writeBuf(stream.buf, digits[r2], n)
writeBuf(stream.buf, digits[r1], n+3)
stream.n = n + 6
return
}
r3 := q2 - q3*1000
q4 := q3 / 1000
if q4 == 0 {
n = writeFirstBuf(stream.buf, digits[q3], n)
writeBuf(stream.buf, digits[r3], n)
writeBuf(stream.buf, digits[r2], n+3)
writeBuf(stream.buf, digits[r1], n+6)
stream.n = n + 9
return
}
r4 := q3 - q4*1000
q5 := q4 / 1000
if q5 == 0 {
n = writeFirstBuf(stream.buf, digits[q4], n)
writeBuf(stream.buf, digits[r4], n)
writeBuf(stream.buf, digits[r3], n+3)
writeBuf(stream.buf, digits[r2], n+6)
writeBuf(stream.buf, digits[r1], n+9)
stream.n = n + 12
return
}
r5 := q4 - q5*1000
q6 := q5 / 1000
if q6 == 0 {
n = writeFirstBuf(stream.buf, digits[q5], n)
} else {
n = writeFirstBuf(stream.buf, digits[q6], n)
r6 := q5 - q6*1000
writeBuf(stream.buf, digits[r6], n)
n += 3
}
writeBuf(stream.buf, digits[r5], n)
writeBuf(stream.buf, digits[r4], n+3)
writeBuf(stream.buf, digits[r3], n+6)
writeBuf(stream.buf, digits[r2], n+9)
writeBuf(stream.buf, digits[r1], n+12)
stream.n = n + 15
}
// WriteInt64 write int64 to stream
func (stream *Stream) WriteInt64(nval int64) {
stream.ensure(20)
n := stream.n
var val uint64
if nval < 0 {
val = uint64(-nval)
stream.buf[n] = '-'
n++
} else {
val = uint64(nval)
}
q1 := val / 1000
if q1 == 0 {
stream.n = writeFirstBuf(stream.buf, digits[val], n)
return
}
r1 := val - q1*1000
q2 := q1 / 1000
if q2 == 0 {
n := writeFirstBuf(stream.buf, digits[q1], n)
writeBuf(stream.buf, digits[r1], n)
stream.n = n + 3
return
}
r2 := q1 - q2*1000
q3 := q2 / 1000
if q3 == 0 {
n = writeFirstBuf(stream.buf, digits[q2], n)
writeBuf(stream.buf, digits[r2], n)
writeBuf(stream.buf, digits[r1], n+3)
stream.n = n + 6
return
}
r3 := q2 - q3*1000
q4 := q3 / 1000
if q4 == 0 {
n = writeFirstBuf(stream.buf, digits[q3], n)
writeBuf(stream.buf, digits[r3], n)
writeBuf(stream.buf, digits[r2], n+3)
writeBuf(stream.buf, digits[r1], n+6)
stream.n = n + 9
return
}
r4 := q3 - q4*1000
q5 := q4 / 1000
if q5 == 0 {
n = writeFirstBuf(stream.buf, digits[q4], n)
writeBuf(stream.buf, digits[r4], n)
writeBuf(stream.buf, digits[r3], n+3)
writeBuf(stream.buf, digits[r2], n+6)
writeBuf(stream.buf, digits[r1], n+9)
stream.n = n + 12
return
}
r5 := q4 - q5*1000
q6 := q5 / 1000
if q6 == 0 {
n = writeFirstBuf(stream.buf, digits[q5], n)
} else {
stream.buf[n] = byte(q6 + '0')
n++
r6 := q5 - q6*1000
writeBuf(stream.buf, digits[r6], n)
n += 3
}
writeBuf(stream.buf, digits[r5], n)
writeBuf(stream.buf, digits[r4], n+3)
writeBuf(stream.buf, digits[r3], n+6)
writeBuf(stream.buf, digits[r2], n+9)
writeBuf(stream.buf, digits[r1], n+12)
stream.n = n + 15
}
// WriteInt write int to stream
func (stream *Stream) WriteInt(val int) {
stream.WriteInt64(int64(val))
}
// WriteUint write uint to stream
func (stream *Stream) WriteUint(val uint) {
stream.WriteUint64(uint64(val))
}
@@ -77,6 +77,7 @@ type Iterator struct {
captureStartedAt int
captured []byte
Error error
Attachment interface{} // open for customized decoder
}
// NewIterator creates an empty Iterator instance
@@ -167,7 +168,7 @@ func (iter *Iterator) isObjectEnd() bool {
if c == '}' {
return true
}
iter.ReportError("isObjectEnd", "object ended prematurely")
iter.ReportError("isObjectEnd", "object ended prematurely, unexpected char "+string([]byte{c}))
return true
}
@@ -200,8 +201,22 @@ func (iter *Iterator) ReportError(operation string, msg string) {
if peekStart < 0 {
peekStart = 0
}
iter.Error = fmt.Errorf("%s: %s, parsing %v ...%s... at %s", operation, msg, iter.head,
string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail]))
peekEnd := iter.head + 10
if peekEnd > iter.tail {
peekEnd = iter.tail
}
parsing := string(iter.buf[peekStart:peekEnd])
contextStart := iter.head - 50
if contextStart < 0 {
contextStart = 0
}
contextEnd := iter.head + 50
if contextEnd > iter.tail {
contextEnd = iter.tail
}
context := string(iter.buf[contextStart:contextEnd])
iter.Error = fmt.Errorf("%s: %s, error found in #%v byte of ...|%s|..., bigger context ...|%s|...",
operation, msg, iter.head-peekStart, parsing, context)
}
// CurrentBuffer gets current buffer as string for debugging purpose
@@ -210,7 +225,7 @@ func (iter *Iterator) CurrentBuffer() string {
if peekStart < 0 {
peekStart = 0
}
return fmt.Sprintf("parsing %v ...|%s|... at %s", iter.head,
return fmt.Sprintf("parsing #%v byte, around ...|%s|..., whole buffer ...|%s|...", iter.head,
string(iter.buf[peekStart:iter.head]), string(iter.buf[0:iter.tail]))
}
@@ -19,7 +19,7 @@ func (iter *Iterator) ReadArray() (ret bool) {
case ',':
return true
default:
iter.ReportError("ReadArray", "expect [ or , or ] or n, but found: "+string([]byte{c}))
iter.ReportError("ReadArray", "expect [ or , or ] or n, but found "+string([]byte{c}))
return
}
}
@@ -42,7 +42,7 @@ func (iter *Iterator) ReadArrayCB(callback func(*Iterator) bool) (ret bool) {
c = iter.nextToken()
}
if c != ']' {
iter.ReportError("ReadArrayCB", "expect ] in the end")
iter.ReportError("ReadArrayCB", "expect ] in the end, but found "+string([]byte{c}))
return false
}
return true
@@ -53,6 +53,6 @@ func (iter *Iterator) ReadArrayCB(callback func(*Iterator) bool) (ret bool) {
iter.skipThreeBytes('u', 'l', 'l')
return true // null
}
iter.ReportError("ReadArrayCB", "expect [ or n, but found: "+string([]byte{c}))
iter.ReportError("ReadArrayCB", "expect [ or n, but found "+string([]byte{c}))
return false
}
@@ -1,6 +1,7 @@
package jsoniter
import (
"encoding/json"
"io"
"math/big"
"strconv"
@@ -339,3 +340,8 @@ func validateFloat(str string) string {
}
return ""
}
// ReadNumber read json.Number
func (iter *Iterator) ReadNumber() (ret json.Number) {
return json.Number(iter.readNumberAsString())
}
@@ -22,11 +22,17 @@ func init() {
// ReadUint read uint
func (iter *Iterator) ReadUint() uint {
if strconv.IntSize == 32 {
return uint(iter.ReadUint32())
}
return uint(iter.ReadUint64())
}
// ReadInt read int
func (iter *Iterator) ReadInt() int {
if strconv.IntSize == 32 {
return int(iter.ReadInt32())
}
return int(iter.ReadInt64())
}
@@ -115,6 +121,7 @@ func (iter *Iterator) ReadUint32() (ret uint32) {
func (iter *Iterator) readUint32(c byte) (ret uint32) {
ind := intDigits[c]
if ind == 0 {
iter.assertInteger()
return 0 // single zero
}
if ind == invalidCharForNumber {
@@ -127,12 +134,14 @@ func (iter *Iterator) readUint32(c byte) (ret uint32) {
ind2 := intDigits[iter.buf[i]]
if ind2 == invalidCharForNumber {
iter.head = i
iter.assertInteger()
return value
}
i++
ind3 := intDigits[iter.buf[i]]
if ind3 == invalidCharForNumber {
iter.head = i
iter.assertInteger()
return value*10 + uint32(ind2)
}
//iter.head = i + 1
@@ -141,30 +150,35 @@ func (iter *Iterator) readUint32(c byte) (ret uint32) {
ind4 := intDigits[iter.buf[i]]
if ind4 == invalidCharForNumber {
iter.head = i
iter.assertInteger()
return value*100 + uint32(ind2)*10 + uint32(ind3)
}
i++
ind5 := intDigits[iter.buf[i]]
if ind5 == invalidCharForNumber {
iter.head = i
iter.assertInteger()
return value*1000 + uint32(ind2)*100 + uint32(ind3)*10 + uint32(ind4)
}
i++
ind6 := intDigits[iter.buf[i]]
if ind6 == invalidCharForNumber {
iter.head = i
iter.assertInteger()
return value*10000 + uint32(ind2)*1000 + uint32(ind3)*100 + uint32(ind4)*10 + uint32(ind5)
}
i++
ind7 := intDigits[iter.buf[i]]
if ind7 == invalidCharForNumber {
iter.head = i
iter.assertInteger()
return value*100000 + uint32(ind2)*10000 + uint32(ind3)*1000 + uint32(ind4)*100 + uint32(ind5)*10 + uint32(ind6)
}
i++
ind8 := intDigits[iter.buf[i]]
if ind8 == invalidCharForNumber {
iter.head = i
iter.assertInteger()
return value*1000000 + uint32(ind2)*100000 + uint32(ind3)*10000 + uint32(ind4)*1000 + uint32(ind5)*100 + uint32(ind6)*10 + uint32(ind7)
}
i++
@@ -172,6 +186,7 @@ func (iter *Iterator) readUint32(c byte) (ret uint32) {
value = value*10000000 + uint32(ind2)*1000000 + uint32(ind3)*100000 + uint32(ind4)*10000 + uint32(ind5)*1000 + uint32(ind6)*100 + uint32(ind7)*10 + uint32(ind8)
iter.head = i
if ind9 == invalidCharForNumber {
iter.assertInteger()
return value
}
}
@@ -180,6 +195,7 @@ func (iter *Iterator) readUint32(c byte) (ret uint32) {
ind = intDigits[iter.buf[i]]
if ind == invalidCharForNumber {
iter.head = i
iter.assertInteger()
return value
}
if value > uint32SafeToMultiply10 {
@@ -194,6 +210,7 @@ func (iter *Iterator) readUint32(c byte) (ret uint32) {
value = (value << 3) + (value << 1) + uint32(ind)
}
if !iter.loadMore() {
iter.assertInteger()
return value
}
}
@@ -226,6 +243,7 @@ func (iter *Iterator) ReadUint64() uint64 {
func (iter *Iterator) readUint64(c byte) (ret uint64) {
ind := intDigits[c]
if ind == 0 {
iter.assertInteger()
return 0 // single zero
}
if ind == invalidCharForNumber {
@@ -233,11 +251,73 @@ func (iter *Iterator) readUint64(c byte) (ret uint64) {
return
}
value := uint64(ind)
if iter.tail-iter.head > 10 {
i := iter.head
ind2 := intDigits[iter.buf[i]]
if ind2 == invalidCharForNumber {
iter.head = i
iter.assertInteger()
return value
}
i++
ind3 := intDigits[iter.buf[i]]
if ind3 == invalidCharForNumber {
iter.head = i
iter.assertInteger()
return value*10 + uint64(ind2)
}
//iter.head = i + 1
//value = value * 100 + uint32(ind2) * 10 + uint32(ind3)
i++
ind4 := intDigits[iter.buf[i]]
if ind4 == invalidCharForNumber {
iter.head = i
iter.assertInteger()
return value*100 + uint64(ind2)*10 + uint64(ind3)
}
i++
ind5 := intDigits[iter.buf[i]]
if ind5 == invalidCharForNumber {
iter.head = i
iter.assertInteger()
return value*1000 + uint64(ind2)*100 + uint64(ind3)*10 + uint64(ind4)
}
i++
ind6 := intDigits[iter.buf[i]]
if ind6 == invalidCharForNumber {
iter.head = i
iter.assertInteger()
return value*10000 + uint64(ind2)*1000 + uint64(ind3)*100 + uint64(ind4)*10 + uint64(ind5)
}
i++
ind7 := intDigits[iter.buf[i]]
if ind7 == invalidCharForNumber {
iter.head = i
iter.assertInteger()
return value*100000 + uint64(ind2)*10000 + uint64(ind3)*1000 + uint64(ind4)*100 + uint64(ind5)*10 + uint64(ind6)
}
i++
ind8 := intDigits[iter.buf[i]]
if ind8 == invalidCharForNumber {
iter.head = i
iter.assertInteger()
return value*1000000 + uint64(ind2)*100000 + uint64(ind3)*10000 + uint64(ind4)*1000 + uint64(ind5)*100 + uint64(ind6)*10 + uint64(ind7)
}
i++
ind9 := intDigits[iter.buf[i]]
value = value*10000000 + uint64(ind2)*1000000 + uint64(ind3)*100000 + uint64(ind4)*10000 + uint64(ind5)*1000 + uint64(ind6)*100 + uint64(ind7)*10 + uint64(ind8)
iter.head = i
if ind9 == invalidCharForNumber {
iter.assertInteger()
return value
}
}
for {
for i := iter.head; i < iter.tail; i++ {
ind = intDigits[iter.buf[i]]
if ind == invalidCharForNumber {
iter.head = i
iter.assertInteger()
return value
}
if value > uint64SafeToMultiple10 {
@@ -252,7 +332,14 @@ func (iter *Iterator) readUint64(c byte) (ret uint64) {
value = (value << 3) + (value << 1) + uint64(ind)
}
if !iter.loadMore() {
iter.assertInteger()
return value
}
}
}
func (iter *Iterator) assertInteger() {
if iter.head < len(iter.buf) && iter.buf[iter.head] == '.' {
iter.ReportError("assertInteger", "can not decode float as int")
}
}
@@ -3,7 +3,6 @@ package jsoniter
import (
"fmt"
"unicode"
"unsafe"
)
// ReadObject read one field from object.
@@ -19,15 +18,25 @@ func (iter *Iterator) ReadObject() (ret string) {
c = iter.nextToken()
if c == '"' {
iter.unreadByte()
return string(iter.readObjectFieldAsBytes())
field := iter.ReadString()
c = iter.nextToken()
if c != ':' {
iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
}
return field
}
if c == '}' {
return "" // end of object
}
iter.ReportError("ReadObject", `expect " after {`)
iter.ReportError("ReadObject", `expect " after {, but found `+string([]byte{c}))
return
case ',':
return string(iter.readObjectFieldAsBytes())
field := iter.ReadString()
c = iter.nextToken()
if c != ':' {
iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
}
return field
case '}':
return "" // end of object
default:
@@ -36,62 +45,93 @@ func (iter *Iterator) ReadObject() (ret string) {
}
}
func (iter *Iterator) readFieldHash() int32 {
// CaseInsensitive
func (iter *Iterator) readFieldHash() int64 {
hash := int64(0x811c9dc5)
c := iter.nextToken()
if c == '"' {
for {
for i := iter.head; i < iter.tail; i++ {
// require ascii string and no escape
b := iter.buf[i]
if 'A' <= b && b <= 'Z' {
b += 'a' - 'A'
}
if b == '"' {
iter.head = i + 1
c = iter.nextToken()
if c != ':' {
iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c}))
if c != '"' {
iter.ReportError("readFieldHash", `expect ", but found `+string([]byte{c}))
return 0
}
for {
for i := iter.head; i < iter.tail; i++ {
// require ascii string and no escape
b := iter.buf[i]
if b == '\\' {
iter.head = i
for _, b := range iter.readStringSlowPath() {
if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive {
b += 'a' - 'A'
}
return int32(hash)
hash ^= int64(b)
hash *= 0x1000193
}
hash ^= int64(b)
hash *= 0x1000193
c = iter.nextToken()
if c != ':' {
iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c}))
return 0
}
return hash
}
if !iter.loadMore() {
iter.ReportError("readFieldHash", `incomplete field name`)
return 0
if b == '"' {
iter.head = i + 1
c = iter.nextToken()
if c != ':' {
iter.ReportError("readFieldHash", `expect :, but found `+string([]byte{c}))
return 0
}
return hash
}
if 'A' <= b && b <= 'Z' && !iter.cfg.caseSensitive {
b += 'a' - 'A'
}
hash ^= int64(b)
hash *= 0x1000193
}
if !iter.loadMore() {
iter.ReportError("readFieldHash", `incomplete field name`)
return 0
}
}
iter.ReportError("readFieldHash", `expect ", but found `+string([]byte{c}))
return 0
}
func calcHash(str string) int32 {
func calcHash(str string, caseSensitive bool) int64 {
hash := int64(0x811c9dc5)
for _, b := range str {
hash ^= int64(unicode.ToLower(b))
if caseSensitive {
hash ^= int64(b)
} else {
hash ^= int64(unicode.ToLower(b))
}
hash *= 0x1000193
}
return int32(hash)
return int64(hash)
}
// ReadObjectCB read object with callback, the key is ascii only and field name not copied
func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool {
c := iter.nextToken()
var field string
if c == '{' {
c = iter.nextToken()
if c == '"' {
iter.unreadByte()
field := iter.readObjectFieldAsBytes()
if !callback(iter, *(*string)(unsafe.Pointer(&field))) {
field = iter.ReadString()
c = iter.nextToken()
if c != ':' {
iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
}
if !callback(iter, field) {
return false
}
c = iter.nextToken()
for c == ',' {
field = iter.readObjectFieldAsBytes()
if !callback(iter, *(*string)(unsafe.Pointer(&field))) {
field = iter.ReadString()
c = iter.nextToken()
if c != ':' {
iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
}
if !callback(iter, field) {
return false
}
c = iter.nextToken()
@@ -105,14 +145,14 @@ func (iter *Iterator) ReadObjectCB(callback func(*Iterator, string) bool) bool {
if c == '}' {
return true
}
iter.ReportError("ReadObjectCB", `expect " after }`)
iter.ReportError("ReadObjectCB", `expect " after }, but found `+string([]byte{c}))
return false
}
if c == 'n' {
iter.skipThreeBytes('u', 'l', 'l')
return true // null
}
iter.ReportError("ReadObjectCB", `expect { or n`)
iter.ReportError("ReadObjectCB", `expect { or n, but found `+string([]byte{c}))
return false
}
@@ -125,7 +165,7 @@ func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool {
iter.unreadByte()
field := iter.ReadString()
if iter.nextToken() != ':' {
iter.ReportError("ReadMapCB", "expect : after object field")
iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
return false
}
if !callback(iter, field) {
@@ -135,7 +175,7 @@ func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool {
for c == ',' {
field = iter.ReadString()
if iter.nextToken() != ':' {
iter.ReportError("ReadMapCB", "expect : after object field")
iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
return false
}
if !callback(iter, field) {
@@ -152,14 +192,14 @@ func (iter *Iterator) ReadMapCB(callback func(*Iterator, string) bool) bool {
if c == '}' {
return true
}
iter.ReportError("ReadMapCB", `expect " after }`)
iter.ReportError("ReadMapCB", `expect " after }, but found `+string([]byte{c}))
return false
}
if c == 'n' {
iter.skipThreeBytes('u', 'l', 'l')
return true // null
}
iter.ReportError("ReadMapCB", `expect { or n`)
iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c}))
return false
}
@@ -176,7 +216,7 @@ func (iter *Iterator) readObjectStart() bool {
iter.skipThreeBytes('u', 'l', 'l')
return false
}
iter.ReportError("readObjectStart", "expect { or n")
iter.ReportError("readObjectStart", "expect { or n, but found "+string([]byte{c}))
return false
}
@@ -192,7 +232,7 @@ func (iter *Iterator) readObjectFieldAsBytes() (ret []byte) {
}
}
if iter.buf[iter.head] != ':' {
iter.ReportError("readObjectFieldAsBytes", "expect : after object field")
iter.ReportError("readObjectFieldAsBytes", "expect : after object field, but found "+string([]byte{iter.buf[iter.head]}))
return
}
iter.head++
@@ -25,7 +25,7 @@ func (iter *Iterator) ReadBool() (ret bool) {
iter.skipFourBytes('a', 'l', 's', 'e')
return false
}
iter.ReportError("ReadBool", "expect t or f")
iter.ReportError("ReadBool", "expect t or f, but found "+string([]byte{c}))
return
}
@@ -59,7 +59,9 @@ func (iter *Iterator) stopCapture() []byte {
iter.captureStartedAt = -1
iter.captured = nil
if len(captured) == 0 {
return remaining
copied := make([]byte, len(remaining))
copy(copied, remaining)
return copied
}
captured = append(captured, remaining...)
return captured
@@ -1,4 +1,4 @@
//+build jsoniter-sloppy
//+build jsoniter_sloppy
package jsoniter
@@ -1,4 +1,4 @@
//+build !jsoniter-sloppy
//+build !jsoniter_sloppy
package jsoniter
@@ -64,7 +64,7 @@ func (iter *Iterator) trySkipString() bool {
} else if c == '\\' {
return false
} else if c < ' ' {
iter.ReportError("ReadString",
iter.ReportError("trySkipString",
fmt.Sprintf(`invalid control character found: %d`, c))
return true // already failed
}
@@ -28,7 +28,7 @@ func (iter *Iterator) ReadString() (ret string) {
iter.skipThreeBytes('u', 'l', 'l')
return ""
}
iter.ReportError("ReadString", `expects " or n`)
iter.ReportError("ReadString", `expects " or n, but found `+string([]byte{c}))
return
}
@@ -47,7 +47,7 @@ func (iter *Iterator) readStringSlowPath() (ret string) {
str = append(str, c)
}
}
iter.ReportError("ReadString", "unexpected end of input")
iter.ReportError("readStringSlowPath", "unexpected end of input")
return
}
@@ -104,7 +104,7 @@ func (iter *Iterator) readEscapedChar(c byte, str []byte) []byte {
case 't':
str = append(str, '\t')
default:
iter.ReportError("ReadString",
iter.ReportError("readEscapedChar",
`invalid escape char after \`)
return nil
}
@@ -139,7 +139,7 @@ func (iter *Iterator) ReadStringAsSlice() (ret []byte) {
}
return copied
}
iter.ReportError("ReadString", `expects " or n`)
iter.ReportError("ReadStringAsSlice", `expects " or n, but found `+string([]byte{c}))
return
}
@@ -156,7 +156,7 @@ func (iter *Iterator) readU4() (ret rune) {
} else if c >= 'A' && c <= 'F' {
ret = ret*16 + rune(c-'A'+10)
} else {
iter.ReportError("readU4", "expects 0~9 or a~f")
iter.ReportError("readU4", "expects 0~9 or a~f, but found "+string([]byte{c}))
return
}
}
@@ -17,41 +17,26 @@ type StreamPool interface {
}
func (cfg *frozenConfig) BorrowStream(writer io.Writer) *Stream {
select {
case stream := <-cfg.streamPool:
stream.Reset(writer)
return stream
default:
return NewStream(cfg, writer, 512)
}
stream := cfg.streamPool.Get().(*Stream)
stream.Reset(writer)
return stream
}
func (cfg *frozenConfig) ReturnStream(stream *Stream) {
stream.out = nil
stream.Error = nil
select {
case cfg.streamPool <- stream:
return
default:
return
}
stream.Attachment = nil
cfg.streamPool.Put(stream)
}
func (cfg *frozenConfig) BorrowIterator(data []byte) *Iterator {
select {
case iter := <-cfg.iteratorPool:
iter.ResetBytes(data)
return iter
default:
return ParseBytes(cfg, data)
}
iter := cfg.iteratorPool.Get().(*Iterator)
iter.ResetBytes(data)
return iter
}
func (cfg *frozenConfig) ReturnIterator(iter *Iterator) {
iter.Error = nil
select {
case cfg.iteratorPool <- iter:
return
default:
return
}
iter.Attachment = nil
cfg.iteratorPool.Put(iter)
}
+330
View File
@@ -0,0 +1,330 @@
package jsoniter
import (
"fmt"
"reflect"
"unsafe"
"github.com/modern-go/reflect2"
)
// ValDecoder is an internal type registered to cache as needed.
// Don't confuse jsoniter.ValDecoder with json.Decoder.
// For json.Decoder's adapter, refer to jsoniter.AdapterDecoder(todo link).
//
// Reflection on type to create decoders, which is then cached
// Reflection on value is avoided as we can, as the reflect.Value itself will allocate, with following exceptions
// 1. create instance of new value, for example *int will need a int to be allocated
// 2. append to slice, if the existing cap is not enough, allocate will be done using Reflect.New
// 3. assignment to map, both key and value will be reflect.Value
// For a simple struct binding, it will be reflect.Value free and allocation free
type ValDecoder interface {
Decode(ptr unsafe.Pointer, iter *Iterator)
}
// ValEncoder is an internal type registered to cache as needed.
// Don't confuse jsoniter.ValEncoder with json.Encoder.
// For json.Encoder's adapter, refer to jsoniter.AdapterEncoder(todo godoc link).
type ValEncoder interface {
IsEmpty(ptr unsafe.Pointer) bool
Encode(ptr unsafe.Pointer, stream *Stream)
}
type checkIsEmpty interface {
IsEmpty(ptr unsafe.Pointer) bool
}
type ctx struct {
*frozenConfig
prefix string
encoders map[reflect2.Type]ValEncoder
decoders map[reflect2.Type]ValDecoder
}
func (b *ctx) caseSensitive() bool {
if b.frozenConfig == nil {
// default is case-insensitive
return false
}
return b.frozenConfig.caseSensitive
}
func (b *ctx) append(prefix string) *ctx {
return &ctx{
frozenConfig: b.frozenConfig,
prefix: b.prefix + " " + prefix,
encoders: b.encoders,
decoders: b.decoders,
}
}
// ReadVal copy the underlying JSON into go interface, same as json.Unmarshal
func (iter *Iterator) ReadVal(obj interface{}) {
cacheKey := reflect2.RTypeOf(obj)
decoder := iter.cfg.getDecoderFromCache(cacheKey)
if decoder == nil {
typ := reflect2.TypeOf(obj)
if typ.Kind() != reflect.Ptr {
iter.ReportError("ReadVal", "can only unmarshal into pointer")
return
}
decoder = iter.cfg.DecoderOf(typ)
}
ptr := reflect2.PtrOf(obj)
if ptr == nil {
iter.ReportError("ReadVal", "can not read into nil pointer")
return
}
decoder.Decode(ptr, iter)
}
// WriteVal copy the go interface into underlying JSON, same as json.Marshal
func (stream *Stream) WriteVal(val interface{}) {
if nil == val {
stream.WriteNil()
return
}
cacheKey := reflect2.RTypeOf(val)
encoder := stream.cfg.getEncoderFromCache(cacheKey)
if encoder == nil {
typ := reflect2.TypeOf(val)
encoder = stream.cfg.EncoderOf(typ)
}
encoder.Encode(reflect2.PtrOf(val), stream)
}
func (cfg *frozenConfig) DecoderOf(typ reflect2.Type) ValDecoder {
cacheKey := typ.RType()
decoder := cfg.getDecoderFromCache(cacheKey)
if decoder != nil {
return decoder
}
ctx := &ctx{
frozenConfig: cfg,
prefix: "",
decoders: map[reflect2.Type]ValDecoder{},
encoders: map[reflect2.Type]ValEncoder{},
}
ptrType := typ.(*reflect2.UnsafePtrType)
decoder = decoderOfType(ctx, ptrType.Elem())
cfg.addDecoderToCache(cacheKey, decoder)
return decoder
}
func decoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder {
decoder := getTypeDecoderFromExtension(ctx, typ)
if decoder != nil {
return decoder
}
decoder = createDecoderOfType(ctx, typ)
for _, extension := range extensions {
decoder = extension.DecorateDecoder(typ, decoder)
}
for _, extension := range ctx.extensions {
decoder = extension.DecorateDecoder(typ, decoder)
}
return decoder
}
func createDecoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder {
decoder := ctx.decoders[typ]
if decoder != nil {
return decoder
}
placeholder := &placeholderDecoder{}
ctx.decoders[typ] = placeholder
decoder = _createDecoderOfType(ctx, typ)
placeholder.decoder = decoder
return decoder
}
func _createDecoderOfType(ctx *ctx, typ reflect2.Type) ValDecoder {
decoder := createDecoderOfJsonRawMessage(ctx, typ)
if decoder != nil {
return decoder
}
decoder = createDecoderOfJsonNumber(ctx, typ)
if decoder != nil {
return decoder
}
decoder = createDecoderOfMarshaler(ctx, typ)
if decoder != nil {
return decoder
}
decoder = createDecoderOfAny(ctx, typ)
if decoder != nil {
return decoder
}
decoder = createDecoderOfNative(ctx, typ)
if decoder != nil {
return decoder
}
switch typ.Kind() {
case reflect.Interface:
ifaceType, isIFace := typ.(*reflect2.UnsafeIFaceType)
if isIFace {
return &ifaceDecoder{valType: ifaceType}
}
return &efaceDecoder{}
case reflect.Struct:
return decoderOfStruct(ctx, typ)
case reflect.Array:
return decoderOfArray(ctx, typ)
case reflect.Slice:
return decoderOfSlice(ctx, typ)
case reflect.Map:
return decoderOfMap(ctx, typ)
case reflect.Ptr:
return decoderOfOptional(ctx, typ)
default:
return &lazyErrorDecoder{err: fmt.Errorf("%s%s is unsupported type", ctx.prefix, typ.String())}
}
}
func (cfg *frozenConfig) EncoderOf(typ reflect2.Type) ValEncoder {
cacheKey := typ.RType()
encoder := cfg.getEncoderFromCache(cacheKey)
if encoder != nil {
return encoder
}
ctx := &ctx{
frozenConfig: cfg,
prefix: "",
decoders: map[reflect2.Type]ValDecoder{},
encoders: map[reflect2.Type]ValEncoder{},
}
encoder = encoderOfType(ctx, typ)
if typ.LikePtr() {
encoder = &onePtrEncoder{encoder}
}
cfg.addEncoderToCache(cacheKey, encoder)
return encoder
}
type onePtrEncoder struct {
encoder ValEncoder
}
func (encoder *onePtrEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return encoder.encoder.IsEmpty(unsafe.Pointer(&ptr))
}
func (encoder *onePtrEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
encoder.encoder.Encode(unsafe.Pointer(&ptr), stream)
}
func encoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder {
encoder := getTypeEncoderFromExtension(ctx, typ)
if encoder != nil {
return encoder
}
encoder = createEncoderOfType(ctx, typ)
for _, extension := range extensions {
encoder = extension.DecorateEncoder(typ, encoder)
}
for _, extension := range ctx.extensions {
encoder = extension.DecorateEncoder(typ, encoder)
}
return encoder
}
func createEncoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder {
encoder := ctx.encoders[typ]
if encoder != nil {
return encoder
}
placeholder := &placeholderEncoder{}
ctx.encoders[typ] = placeholder
encoder = _createEncoderOfType(ctx, typ)
placeholder.encoder = encoder
return encoder
}
func _createEncoderOfType(ctx *ctx, typ reflect2.Type) ValEncoder {
encoder := createEncoderOfJsonRawMessage(ctx, typ)
if encoder != nil {
return encoder
}
encoder = createEncoderOfJsonNumber(ctx, typ)
if encoder != nil {
return encoder
}
encoder = createEncoderOfMarshaler(ctx, typ)
if encoder != nil {
return encoder
}
encoder = createEncoderOfAny(ctx, typ)
if encoder != nil {
return encoder
}
encoder = createEncoderOfNative(ctx, typ)
if encoder != nil {
return encoder
}
kind := typ.Kind()
switch kind {
case reflect.Interface:
return &dynamicEncoder{typ}
case reflect.Struct:
return encoderOfStruct(ctx, typ)
case reflect.Array:
return encoderOfArray(ctx, typ)
case reflect.Slice:
return encoderOfSlice(ctx, typ)
case reflect.Map:
return encoderOfMap(ctx, typ)
case reflect.Ptr:
return encoderOfOptional(ctx, typ)
default:
return &lazyErrorEncoder{err: fmt.Errorf("%s%s is unsupported type", ctx.prefix, typ.String())}
}
}
type lazyErrorDecoder struct {
err error
}
func (decoder *lazyErrorDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
if iter.WhatIsNext() != NilValue {
if iter.Error == nil {
iter.Error = decoder.err
}
} else {
iter.Skip()
}
}
type lazyErrorEncoder struct {
err error
}
func (encoder *lazyErrorEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
if ptr == nil {
stream.WriteNil()
} else if stream.Error == nil {
stream.Error = encoder.err
}
}
func (encoder *lazyErrorEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return false
}
type placeholderDecoder struct {
decoder ValDecoder
}
func (decoder *placeholderDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
decoder.decoder.Decode(ptr, iter)
}
type placeholderEncoder struct {
encoder ValEncoder
}
func (encoder *placeholderEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
encoder.encoder.Encode(ptr, stream)
}
func (encoder *placeholderEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return encoder.encoder.IsEmpty(ptr)
}
+104
View File
@@ -0,0 +1,104 @@
package jsoniter
import (
"fmt"
"github.com/modern-go/reflect2"
"io"
"unsafe"
)
func decoderOfArray(ctx *ctx, typ reflect2.Type) ValDecoder {
arrayType := typ.(*reflect2.UnsafeArrayType)
decoder := decoderOfType(ctx.append("[arrayElem]"), arrayType.Elem())
return &arrayDecoder{arrayType, decoder}
}
func encoderOfArray(ctx *ctx, typ reflect2.Type) ValEncoder {
arrayType := typ.(*reflect2.UnsafeArrayType)
if arrayType.Len() == 0 {
return emptyArrayEncoder{}
}
encoder := encoderOfType(ctx.append("[arrayElem]"), arrayType.Elem())
return &arrayEncoder{arrayType, encoder}
}
type emptyArrayEncoder struct{}
func (encoder emptyArrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteEmptyArray()
}
func (encoder emptyArrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return true
}
type arrayEncoder struct {
arrayType *reflect2.UnsafeArrayType
elemEncoder ValEncoder
}
func (encoder *arrayEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteArrayStart()
elemPtr := unsafe.Pointer(ptr)
encoder.elemEncoder.Encode(elemPtr, stream)
for i := 1; i < encoder.arrayType.Len(); i++ {
stream.WriteMore()
elemPtr = encoder.arrayType.UnsafeGetIndex(ptr, i)
encoder.elemEncoder.Encode(elemPtr, stream)
}
stream.WriteArrayEnd()
if stream.Error != nil && stream.Error != io.EOF {
stream.Error = fmt.Errorf("%v: %s", encoder.arrayType, stream.Error.Error())
}
}
func (encoder *arrayEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return false
}
type arrayDecoder struct {
arrayType *reflect2.UnsafeArrayType
elemDecoder ValDecoder
}
func (decoder *arrayDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
decoder.doDecode(ptr, iter)
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.arrayType, iter.Error.Error())
}
}
func (decoder *arrayDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
c := iter.nextToken()
arrayType := decoder.arrayType
if c == 'n' {
iter.skipThreeBytes('u', 'l', 'l')
return
}
if c != '[' {
iter.ReportError("decode array", "expect [ or n, but found "+string([]byte{c}))
return
}
c = iter.nextToken()
if c == ']' {
return
}
iter.unreadByte()
elemPtr := arrayType.UnsafeGetIndex(ptr, 0)
decoder.elemDecoder.Decode(elemPtr, iter)
length := 1
for c = iter.nextToken(); c == ','; c = iter.nextToken() {
if length >= arrayType.Len() {
iter.Skip()
continue
}
idx := length
length += 1
elemPtr = arrayType.UnsafeGetIndex(ptr, idx)
decoder.elemDecoder.Decode(elemPtr, iter)
}
if c != ']' {
iter.ReportError("decode array", "expect ], but found "+string([]byte{c}))
return
}
}
+70
View File
@@ -0,0 +1,70 @@
package jsoniter
import (
"github.com/modern-go/reflect2"
"reflect"
"unsafe"
)
type dynamicEncoder struct {
valType reflect2.Type
}
func (encoder *dynamicEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
obj := encoder.valType.UnsafeIndirect(ptr)
stream.WriteVal(obj)
}
func (encoder *dynamicEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return encoder.valType.UnsafeIndirect(ptr) == nil
}
type efaceDecoder struct {
}
func (decoder *efaceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
pObj := (*interface{})(ptr)
obj := *pObj
if obj == nil {
*pObj = iter.Read()
return
}
typ := reflect2.TypeOf(obj)
if typ.Kind() != reflect.Ptr {
*pObj = iter.Read()
return
}
ptrType := typ.(*reflect2.UnsafePtrType)
ptrElemType := ptrType.Elem()
if iter.WhatIsNext() == NilValue {
if ptrElemType.Kind() != reflect.Ptr {
iter.skipFourBytes('n', 'u', 'l', 'l')
*pObj = nil
return
}
}
if reflect2.IsNil(obj) {
obj := ptrElemType.New()
iter.ReadVal(obj)
*pObj = obj
return
}
iter.ReadVal(obj)
}
type ifaceDecoder struct {
valType *reflect2.UnsafeIFaceType
}
func (decoder *ifaceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
if iter.ReadNil() {
decoder.valType.UnsafeSet(ptr, decoder.valType.UnsafeNew())
return
}
obj := decoder.valType.UnsafeIndirect(ptr)
if reflect2.IsNil(obj) {
iter.ReportError("decode non empty interface", "can not unmarshal into nil")
return
}
iter.ReadVal(obj)
}
@@ -2,6 +2,7 @@ package jsoniter
import (
"fmt"
"github.com/modern-go/reflect2"
"reflect"
"sort"
"strings"
@@ -17,17 +18,15 @@ var extensions = []Extension{}
// StructDescriptor describe how should we encode/decode the struct
type StructDescriptor struct {
onePtrEmbedded bool
onePtrOptimization bool
Type reflect.Type
Fields []*Binding
Type reflect2.Type
Fields []*Binding
}
// GetField get one field from the descriptor by its name.
// Can not use map here to keep field orders.
func (structDescriptor *StructDescriptor) GetField(fieldName string) *Binding {
for _, binding := range structDescriptor.Fields {
if binding.Field.Name == fieldName {
if binding.Field.Name() == fieldName {
return binding
}
}
@@ -37,7 +36,7 @@ func (structDescriptor *StructDescriptor) GetField(fieldName string) *Binding {
// Binding describe how should we encode/decode the struct field
type Binding struct {
levels []int
Field *reflect.StructField
Field reflect2.StructField
FromNames []string
ToNames []string
Encoder ValEncoder
@@ -48,10 +47,12 @@ type Binding struct {
// Can also rename fields by UpdateStructDescriptor.
type Extension interface {
UpdateStructDescriptor(structDescriptor *StructDescriptor)
CreateDecoder(typ reflect.Type) ValDecoder
CreateEncoder(typ reflect.Type) ValEncoder
DecorateDecoder(typ reflect.Type, decoder ValDecoder) ValDecoder
DecorateEncoder(typ reflect.Type, encoder ValEncoder) ValEncoder
CreateMapKeyDecoder(typ reflect2.Type) ValDecoder
CreateMapKeyEncoder(typ reflect2.Type) ValEncoder
CreateDecoder(typ reflect2.Type) ValDecoder
CreateEncoder(typ reflect2.Type) ValEncoder
DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder
DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder
}
// DummyExtension embed this type get dummy implementation for all methods of Extension
@@ -62,23 +63,105 @@ type DummyExtension struct {
func (extension *DummyExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) {
}
// CreateMapKeyDecoder No-op
func (extension *DummyExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder {
return nil
}
// CreateMapKeyEncoder No-op
func (extension *DummyExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder {
return nil
}
// CreateDecoder No-op
func (extension *DummyExtension) CreateDecoder(typ reflect.Type) ValDecoder {
func (extension *DummyExtension) CreateDecoder(typ reflect2.Type) ValDecoder {
return nil
}
// CreateEncoder No-op
func (extension *DummyExtension) CreateEncoder(typ reflect.Type) ValEncoder {
func (extension *DummyExtension) CreateEncoder(typ reflect2.Type) ValEncoder {
return nil
}
// DecorateDecoder No-op
func (extension *DummyExtension) DecorateDecoder(typ reflect.Type, decoder ValDecoder) ValDecoder {
func (extension *DummyExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder {
return decoder
}
// DecorateEncoder No-op
func (extension *DummyExtension) DecorateEncoder(typ reflect.Type, encoder ValEncoder) ValEncoder {
func (extension *DummyExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder {
return encoder
}
type EncoderExtension map[reflect2.Type]ValEncoder
// UpdateStructDescriptor No-op
func (extension EncoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) {
}
// CreateDecoder No-op
func (extension EncoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder {
return nil
}
// CreateEncoder get encoder from map
func (extension EncoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder {
return extension[typ]
}
// CreateMapKeyDecoder No-op
func (extension EncoderExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder {
return nil
}
// CreateMapKeyEncoder No-op
func (extension EncoderExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder {
return nil
}
// DecorateDecoder No-op
func (extension EncoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder {
return decoder
}
// DecorateEncoder No-op
func (extension EncoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder {
return encoder
}
type DecoderExtension map[reflect2.Type]ValDecoder
// UpdateStructDescriptor No-op
func (extension DecoderExtension) UpdateStructDescriptor(structDescriptor *StructDescriptor) {
}
// CreateMapKeyDecoder No-op
func (extension DecoderExtension) CreateMapKeyDecoder(typ reflect2.Type) ValDecoder {
return nil
}
// CreateMapKeyEncoder No-op
func (extension DecoderExtension) CreateMapKeyEncoder(typ reflect2.Type) ValEncoder {
return nil
}
// CreateDecoder get decoder from map
func (extension DecoderExtension) CreateDecoder(typ reflect2.Type) ValDecoder {
return extension[typ]
}
// CreateEncoder No-op
func (extension DecoderExtension) CreateEncoder(typ reflect2.Type) ValEncoder {
return nil
}
// DecorateDecoder No-op
func (extension DecoderExtension) DecorateDecoder(typ reflect2.Type, decoder ValDecoder) ValDecoder {
return decoder
}
// DecorateEncoder No-op
func (extension DecoderExtension) DecorateEncoder(typ reflect2.Type, encoder ValEncoder) ValEncoder {
return encoder
}
@@ -99,10 +182,6 @@ func (encoder *funcEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
encoder.fun(ptr, stream)
}
func (encoder *funcEncoder) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, encoder)
}
func (encoder *funcEncoder) IsEmpty(ptr unsafe.Pointer) bool {
if encoder.isEmptyFunc == nil {
return false
@@ -161,132 +240,141 @@ func RegisterExtension(extension Extension) {
extensions = append(extensions, extension)
}
func getTypeDecoderFromExtension(typ reflect.Type) ValDecoder {
decoder := _getTypeDecoderFromExtension(typ)
func getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder {
decoder := _getTypeDecoderFromExtension(ctx, typ)
if decoder != nil {
for _, extension := range extensions {
decoder = extension.DecorateDecoder(typ, decoder)
}
for _, extension := range ctx.extensions {
decoder = extension.DecorateDecoder(typ, decoder)
}
}
return decoder
}
func _getTypeDecoderFromExtension(typ reflect.Type) ValDecoder {
func _getTypeDecoderFromExtension(ctx *ctx, typ reflect2.Type) ValDecoder {
for _, extension := range extensions {
decoder := extension.CreateDecoder(typ)
if decoder != nil {
return decoder
}
}
for _, extension := range ctx.extensions {
decoder := extension.CreateDecoder(typ)
if decoder != nil {
return decoder
}
}
typeName := typ.String()
decoder := typeDecoders[typeName]
if decoder != nil {
return decoder
}
if typ.Kind() == reflect.Ptr {
decoder := typeDecoders[typ.Elem().String()]
ptrType := typ.(*reflect2.UnsafePtrType)
decoder := typeDecoders[ptrType.Elem().String()]
if decoder != nil {
return &optionalDecoder{typ.Elem(), decoder}
return &OptionalDecoder{ptrType.Elem(), decoder}
}
}
return nil
}
func getTypeEncoderFromExtension(typ reflect.Type) ValEncoder {
encoder := _getTypeEncoderFromExtension(typ)
func getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder {
encoder := _getTypeEncoderFromExtension(ctx, typ)
if encoder != nil {
for _, extension := range extensions {
encoder = extension.DecorateEncoder(typ, encoder)
}
for _, extension := range ctx.extensions {
encoder = extension.DecorateEncoder(typ, encoder)
}
}
return encoder
}
func _getTypeEncoderFromExtension(typ reflect.Type) ValEncoder {
func _getTypeEncoderFromExtension(ctx *ctx, typ reflect2.Type) ValEncoder {
for _, extension := range extensions {
encoder := extension.CreateEncoder(typ)
if encoder != nil {
return encoder
}
}
for _, extension := range ctx.extensions {
encoder := extension.CreateEncoder(typ)
if encoder != nil {
return encoder
}
}
typeName := typ.String()
encoder := typeEncoders[typeName]
if encoder != nil {
return encoder
}
if typ.Kind() == reflect.Ptr {
encoder := typeEncoders[typ.Elem().String()]
typePtr := typ.(*reflect2.UnsafePtrType)
encoder := typeEncoders[typePtr.Elem().String()]
if encoder != nil {
return &optionalEncoder{encoder}
return &OptionalEncoder{encoder}
}
}
return nil
}
func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, error) {
func describeStruct(ctx *ctx, typ reflect2.Type) *StructDescriptor {
structType := typ.(*reflect2.UnsafeStructType)
embeddedBindings := []*Binding{}
bindings := []*Binding{}
for i := 0; i < typ.NumField(); i++ {
field := typ.Field(i)
tag := field.Tag.Get(cfg.getTagKey())
for i := 0; i < structType.NumField(); i++ {
field := structType.Field(i)
tag, hastag := field.Tag().Lookup(ctx.getTagKey())
if ctx.onlyTaggedField && !hastag {
continue
}
tagParts := strings.Split(tag, ",")
if tag == "-" {
continue
}
if field.Anonymous && (tag == "" || tagParts[0] == "") {
if field.Type.Kind() == reflect.Struct {
structDescriptor, err := describeStruct(cfg, field.Type)
if err != nil {
return nil, err
}
if field.Anonymous() && (tag == "" || tagParts[0] == "") {
if field.Type().Kind() == reflect.Struct {
structDescriptor := describeStruct(ctx, field.Type())
for _, binding := range structDescriptor.Fields {
binding.levels = append([]int{i}, binding.levels...)
omitempty := binding.Encoder.(*structFieldEncoder).omitempty
binding.Encoder = &structFieldEncoder{&field, binding.Encoder, omitempty}
binding.Decoder = &structFieldDecoder{&field, binding.Decoder}
binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty}
binding.Decoder = &structFieldDecoder{field, binding.Decoder}
embeddedBindings = append(embeddedBindings, binding)
}
continue
} else if field.Type.Kind() == reflect.Ptr && field.Type.Elem().Kind() == reflect.Struct {
structDescriptor, err := describeStruct(cfg, field.Type.Elem())
if err != nil {
return nil, err
} else if field.Type().Kind() == reflect.Ptr {
ptrType := field.Type().(*reflect2.UnsafePtrType)
if ptrType.Elem().Kind() == reflect.Struct {
structDescriptor := describeStruct(ctx, ptrType.Elem())
for _, binding := range structDescriptor.Fields {
binding.levels = append([]int{i}, binding.levels...)
omitempty := binding.Encoder.(*structFieldEncoder).omitempty
binding.Encoder = &dereferenceEncoder{binding.Encoder}
binding.Encoder = &structFieldEncoder{field, binding.Encoder, omitempty}
binding.Decoder = &dereferenceDecoder{ptrType.Elem(), binding.Decoder}
binding.Decoder = &structFieldDecoder{field, binding.Decoder}
embeddedBindings = append(embeddedBindings, binding)
}
continue
}
for _, binding := range structDescriptor.Fields {
binding.levels = append([]int{i}, binding.levels...)
omitempty := binding.Encoder.(*structFieldEncoder).omitempty
binding.Encoder = &optionalEncoder{binding.Encoder}
binding.Encoder = &structFieldEncoder{&field, binding.Encoder, omitempty}
binding.Decoder = &deferenceDecoder{field.Type.Elem(), binding.Decoder}
binding.Decoder = &structFieldDecoder{&field, binding.Decoder}
embeddedBindings = append(embeddedBindings, binding)
}
continue
}
}
fieldNames := calcFieldNames(field.Name, tagParts[0], tag)
fieldCacheKey := fmt.Sprintf("%s/%s", typ.String(), field.Name)
fieldNames := calcFieldNames(field.Name(), tagParts[0], tag)
fieldCacheKey := fmt.Sprintf("%s/%s", typ.String(), field.Name())
decoder := fieldDecoders[fieldCacheKey]
if decoder == nil {
var err error
decoder, err = decoderOfType(cfg, field.Type)
if err != nil {
return nil, err
}
decoder = decoderOfType(ctx.append(field.Name()), field.Type())
}
encoder := fieldEncoders[fieldCacheKey]
if encoder == nil {
var err error
encoder, err = encoderOfType(cfg, field.Type)
if err != nil {
return nil, err
}
// map is stored as pointer in the struct
if field.Type.Kind() == reflect.Map {
encoder = &optionalEncoder{encoder}
}
encoder = encoderOfType(ctx.append(field.Name()), field.Type())
}
binding := &Binding{
Field: &field,
Field: field,
FromNames: fieldNames,
ToNames: fieldNames,
Decoder: decoder,
@@ -295,35 +383,20 @@ func describeStruct(cfg *frozenConfig, typ reflect.Type) (*StructDescriptor, err
binding.levels = []int{i}
bindings = append(bindings, binding)
}
return createStructDescriptor(cfg, typ, bindings, embeddedBindings), nil
return createStructDescriptor(ctx, typ, bindings, embeddedBindings)
}
func createStructDescriptor(cfg *frozenConfig, typ reflect.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor {
onePtrEmbedded := false
onePtrOptimization := false
if typ.NumField() == 1 {
firstField := typ.Field(0)
switch firstField.Type.Kind() {
case reflect.Ptr:
if firstField.Anonymous && firstField.Type.Elem().Kind() == reflect.Struct {
onePtrEmbedded = true
}
fallthrough
case reflect.Map:
onePtrOptimization = true
case reflect.Struct:
onePtrOptimization = isStructOnePtr(firstField.Type)
}
}
func createStructDescriptor(ctx *ctx, typ reflect2.Type, bindings []*Binding, embeddedBindings []*Binding) *StructDescriptor {
structDescriptor := &StructDescriptor{
onePtrEmbedded: onePtrEmbedded,
onePtrOptimization: onePtrOptimization,
Type: typ,
Fields: bindings,
Type: typ,
Fields: bindings,
}
for _, extension := range extensions {
extension.UpdateStructDescriptor(structDescriptor)
}
processTags(structDescriptor, cfg)
for _, extension := range ctx.extensions {
extension.UpdateStructDescriptor(structDescriptor)
}
processTags(structDescriptor, ctx.frozenConfig)
// merge normal & embedded bindings & sort with original order
allBindings := sortableBindings(append(embeddedBindings, structDescriptor.Fields...))
sort.Sort(allBindings)
@@ -331,21 +404,6 @@ func createStructDescriptor(cfg *frozenConfig, typ reflect.Type, bindings []*Bin
return structDescriptor
}
func isStructOnePtr(typ reflect.Type) bool {
if typ.NumField() == 1 {
firstField := typ.Field(0)
switch firstField.Type.Kind() {
case reflect.Ptr:
return true
case reflect.Map:
return true
case reflect.Struct:
return isStructOnePtr(firstField.Type)
}
}
return false
}
type sortableBindings []*Binding
func (bindings sortableBindings) Len() int {
@@ -373,12 +431,12 @@ func (bindings sortableBindings) Swap(i, j int) {
func processTags(structDescriptor *StructDescriptor, cfg *frozenConfig) {
for _, binding := range structDescriptor.Fields {
shouldOmitEmpty := false
tagParts := strings.Split(binding.Field.Tag.Get(cfg.getTagKey()), ",")
tagParts := strings.Split(binding.Field.Tag().Get(cfg.getTagKey()), ",")
for _, tagPart := range tagParts[1:] {
if tagPart == "omitempty" {
shouldOmitEmpty = true
} else if tagPart == "string" {
if binding.Field.Type.Kind() == reflect.String {
if binding.Field.Type().Kind() == reflect.String {
binding.Decoder = &stringModeStringDecoder{binding.Decoder, cfg}
binding.Encoder = &stringModeStringEncoder{binding.Encoder, cfg}
} else {
+112
View File
@@ -0,0 +1,112 @@
package jsoniter
import (
"encoding/json"
"github.com/modern-go/reflect2"
"strconv"
"unsafe"
)
type Number string
// String returns the literal text of the number.
func (n Number) String() string { return string(n) }
// Float64 returns the number as a float64.
func (n Number) Float64() (float64, error) {
return strconv.ParseFloat(string(n), 64)
}
// Int64 returns the number as an int64.
func (n Number) Int64() (int64, error) {
return strconv.ParseInt(string(n), 10, 64)
}
func CastJsonNumber(val interface{}) (string, bool) {
switch typedVal := val.(type) {
case json.Number:
return string(typedVal), true
case Number:
return string(typedVal), true
}
return "", false
}
var jsonNumberType = reflect2.TypeOfPtr((*json.Number)(nil)).Elem()
var jsoniterNumberType = reflect2.TypeOfPtr((*Number)(nil)).Elem()
func createDecoderOfJsonNumber(ctx *ctx, typ reflect2.Type) ValDecoder {
if typ.AssignableTo(jsonNumberType) {
return &jsonNumberCodec{}
}
if typ.AssignableTo(jsoniterNumberType) {
return &jsoniterNumberCodec{}
}
return nil
}
func createEncoderOfJsonNumber(ctx *ctx, typ reflect2.Type) ValEncoder {
if typ.AssignableTo(jsonNumberType) {
return &jsonNumberCodec{}
}
if typ.AssignableTo(jsoniterNumberType) {
return &jsoniterNumberCodec{}
}
return nil
}
type jsonNumberCodec struct {
}
func (codec *jsonNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
switch iter.WhatIsNext() {
case StringValue:
*((*json.Number)(ptr)) = json.Number(iter.ReadString())
case NilValue:
iter.skipFourBytes('n', 'u', 'l', 'l')
*((*json.Number)(ptr)) = ""
default:
*((*json.Number)(ptr)) = json.Number([]byte(iter.readNumberAsString()))
}
}
func (codec *jsonNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
number := *((*json.Number)(ptr))
if len(number) == 0 {
stream.writeByte('0')
} else {
stream.WriteRaw(string(number))
}
}
func (codec *jsonNumberCodec) IsEmpty(ptr unsafe.Pointer) bool {
return len(*((*json.Number)(ptr))) == 0
}
type jsoniterNumberCodec struct {
}
func (codec *jsoniterNumberCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
switch iter.WhatIsNext() {
case StringValue:
*((*Number)(ptr)) = Number(iter.ReadString())
case NilValue:
iter.skipFourBytes('n', 'u', 'l', 'l')
*((*Number)(ptr)) = ""
default:
*((*Number)(ptr)) = Number([]byte(iter.readNumberAsString()))
}
}
func (codec *jsoniterNumberCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
number := *((*Number)(ptr))
if len(number) == 0 {
stream.writeByte('0')
} else {
stream.WriteRaw(string(number))
}
}
func (codec *jsoniterNumberCodec) IsEmpty(ptr unsafe.Pointer) bool {
return len(*((*Number)(ptr))) == 0
}
+60
View File
@@ -0,0 +1,60 @@
package jsoniter
import (
"encoding/json"
"github.com/modern-go/reflect2"
"unsafe"
)
var jsonRawMessageType = reflect2.TypeOfPtr((*json.RawMessage)(nil)).Elem()
var jsoniterRawMessageType = reflect2.TypeOfPtr((*RawMessage)(nil)).Elem()
func createEncoderOfJsonRawMessage(ctx *ctx, typ reflect2.Type) ValEncoder {
if typ == jsonRawMessageType {
return &jsonRawMessageCodec{}
}
if typ == jsoniterRawMessageType {
return &jsoniterRawMessageCodec{}
}
return nil
}
func createDecoderOfJsonRawMessage(ctx *ctx, typ reflect2.Type) ValDecoder {
if typ == jsonRawMessageType {
return &jsonRawMessageCodec{}
}
if typ == jsoniterRawMessageType {
return &jsoniterRawMessageCodec{}
}
return nil
}
type jsonRawMessageCodec struct {
}
func (codec *jsonRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
*((*json.RawMessage)(ptr)) = json.RawMessage(iter.SkipAndReturnBytes())
}
func (codec *jsonRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteRaw(string(*((*json.RawMessage)(ptr))))
}
func (codec *jsonRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool {
return len(*((*json.RawMessage)(ptr))) == 0
}
type jsoniterRawMessageCodec struct {
}
func (codec *jsoniterRawMessageCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
*((*RawMessage)(ptr)) = RawMessage(iter.SkipAndReturnBytes())
}
func (codec *jsoniterRawMessageCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteRaw(string(*((*RawMessage)(ptr))))
}
func (codec *jsoniterRawMessageCodec) IsEmpty(ptr unsafe.Pointer) bool {
return len(*((*RawMessage)(ptr))) == 0
}
+318
View File
@@ -0,0 +1,318 @@
package jsoniter
import (
"fmt"
"github.com/modern-go/reflect2"
"io"
"reflect"
"sort"
"unsafe"
)
func decoderOfMap(ctx *ctx, typ reflect2.Type) ValDecoder {
mapType := typ.(*reflect2.UnsafeMapType)
keyDecoder := decoderOfMapKey(ctx.append("[mapKey]"), mapType.Key())
elemDecoder := decoderOfType(ctx.append("[mapElem]"), mapType.Elem())
return &mapDecoder{
mapType: mapType,
keyType: mapType.Key(),
elemType: mapType.Elem(),
keyDecoder: keyDecoder,
elemDecoder: elemDecoder,
}
}
func encoderOfMap(ctx *ctx, typ reflect2.Type) ValEncoder {
mapType := typ.(*reflect2.UnsafeMapType)
if ctx.sortMapKeys {
return &sortKeysMapEncoder{
mapType: mapType,
keyEncoder: encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()),
elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()),
}
}
return &mapEncoder{
mapType: mapType,
keyEncoder: encoderOfMapKey(ctx.append("[mapKey]"), mapType.Key()),
elemEncoder: encoderOfType(ctx.append("[mapElem]"), mapType.Elem()),
}
}
func decoderOfMapKey(ctx *ctx, typ reflect2.Type) ValDecoder {
for _, extension := range ctx.extensions {
decoder := extension.CreateMapKeyDecoder(typ)
if decoder != nil {
return decoder
}
}
switch typ.Kind() {
case reflect.String:
return decoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String))
case reflect.Bool,
reflect.Uint8, reflect.Int8,
reflect.Uint16, reflect.Int16,
reflect.Uint32, reflect.Int32,
reflect.Uint64, reflect.Int64,
reflect.Uint, reflect.Int,
reflect.Float32, reflect.Float64,
reflect.Uintptr:
typ = reflect2.DefaultTypeOfKind(typ.Kind())
return &numericMapKeyDecoder{decoderOfType(ctx, typ)}
default:
ptrType := reflect2.PtrTo(typ)
if ptrType.Implements(textMarshalerType) {
return &referenceDecoder{
&textUnmarshalerDecoder{
valType: ptrType,
},
}
}
if typ.Implements(textMarshalerType) {
return &textUnmarshalerDecoder{
valType: typ,
}
}
return &lazyErrorDecoder{err: fmt.Errorf("unsupported map key type: %v", typ)}
}
}
func encoderOfMapKey(ctx *ctx, typ reflect2.Type) ValEncoder {
for _, extension := range ctx.extensions {
encoder := extension.CreateMapKeyEncoder(typ)
if encoder != nil {
return encoder
}
}
switch typ.Kind() {
case reflect.String:
return encoderOfType(ctx, reflect2.DefaultTypeOfKind(reflect.String))
case reflect.Bool,
reflect.Uint8, reflect.Int8,
reflect.Uint16, reflect.Int16,
reflect.Uint32, reflect.Int32,
reflect.Uint64, reflect.Int64,
reflect.Uint, reflect.Int,
reflect.Float32, reflect.Float64,
reflect.Uintptr:
typ = reflect2.DefaultTypeOfKind(typ.Kind())
return &numericMapKeyEncoder{encoderOfType(ctx, typ)}
default:
if typ == textMarshalerType {
return &directTextMarshalerEncoder{
stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
}
}
if typ.Implements(textMarshalerType) {
return &textMarshalerEncoder{
valType: typ,
stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
}
}
if typ.Kind() == reflect.Interface {
return &dynamicMapKeyEncoder{ctx, typ}
}
return &lazyErrorEncoder{err: fmt.Errorf("unsupported map key type: %v", typ)}
}
}
type mapDecoder struct {
mapType *reflect2.UnsafeMapType
keyType reflect2.Type
elemType reflect2.Type
keyDecoder ValDecoder
elemDecoder ValDecoder
}
func (decoder *mapDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
mapType := decoder.mapType
c := iter.nextToken()
if c == 'n' {
iter.skipThreeBytes('u', 'l', 'l')
*(*unsafe.Pointer)(ptr) = nil
mapType.UnsafeSet(ptr, mapType.UnsafeNew())
return
}
if mapType.UnsafeIsNil(ptr) {
mapType.UnsafeSet(ptr, mapType.UnsafeMakeMap(0))
}
if c != '{' {
iter.ReportError("ReadMapCB", `expect { or n, but found `+string([]byte{c}))
return
}
c = iter.nextToken()
if c == '}' {
return
}
if c != '"' {
iter.ReportError("ReadMapCB", `expect " after }, but found `+string([]byte{c}))
return
}
iter.unreadByte()
key := decoder.keyType.UnsafeNew()
decoder.keyDecoder.Decode(key, iter)
c = iter.nextToken()
if c != ':' {
iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
return
}
elem := decoder.elemType.UnsafeNew()
decoder.elemDecoder.Decode(elem, iter)
decoder.mapType.UnsafeSetIndex(ptr, key, elem)
for c = iter.nextToken(); c == ','; c = iter.nextToken() {
key := decoder.keyType.UnsafeNew()
decoder.keyDecoder.Decode(key, iter)
c = iter.nextToken()
if c != ':' {
iter.ReportError("ReadMapCB", "expect : after object field, but found "+string([]byte{c}))
return
}
elem := decoder.elemType.UnsafeNew()
decoder.elemDecoder.Decode(elem, iter)
decoder.mapType.UnsafeSetIndex(ptr, key, elem)
}
if c != '}' {
iter.ReportError("ReadMapCB", `expect }, but found `+string([]byte{c}))
}
}
type numericMapKeyDecoder struct {
decoder ValDecoder
}
func (decoder *numericMapKeyDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
c := iter.nextToken()
if c != '"' {
iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c}))
return
}
decoder.decoder.Decode(ptr, iter)
c = iter.nextToken()
if c != '"' {
iter.ReportError("ReadMapCB", `expect ", but found `+string([]byte{c}))
return
}
}
type numericMapKeyEncoder struct {
encoder ValEncoder
}
func (encoder *numericMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.writeByte('"')
encoder.encoder.Encode(ptr, stream)
stream.writeByte('"')
}
func (encoder *numericMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return false
}
type dynamicMapKeyEncoder struct {
ctx *ctx
valType reflect2.Type
}
func (encoder *dynamicMapKeyEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
obj := encoder.valType.UnsafeIndirect(ptr)
encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).Encode(reflect2.PtrOf(obj), stream)
}
func (encoder *dynamicMapKeyEncoder) IsEmpty(ptr unsafe.Pointer) bool {
obj := encoder.valType.UnsafeIndirect(ptr)
return encoderOfMapKey(encoder.ctx, reflect2.TypeOf(obj)).IsEmpty(reflect2.PtrOf(obj))
}
type mapEncoder struct {
mapType *reflect2.UnsafeMapType
keyEncoder ValEncoder
elemEncoder ValEncoder
}
func (encoder *mapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteObjectStart()
iter := encoder.mapType.UnsafeIterate(ptr)
for i := 0; iter.HasNext(); i++ {
if i != 0 {
stream.WriteMore()
}
key, elem := iter.UnsafeNext()
encoder.keyEncoder.Encode(key, stream)
if stream.indention > 0 {
stream.writeTwoBytes(byte(':'), byte(' '))
} else {
stream.writeByte(':')
}
encoder.elemEncoder.Encode(elem, stream)
}
stream.WriteObjectEnd()
}
func (encoder *mapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
iter := encoder.mapType.UnsafeIterate(ptr)
return !iter.HasNext()
}
type sortKeysMapEncoder struct {
mapType *reflect2.UnsafeMapType
keyEncoder ValEncoder
elemEncoder ValEncoder
}
func (encoder *sortKeysMapEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
if *(*unsafe.Pointer)(ptr) == nil {
stream.WriteNil()
return
}
stream.WriteObjectStart()
mapIter := encoder.mapType.UnsafeIterate(ptr)
subStream := stream.cfg.BorrowStream(nil)
subIter := stream.cfg.BorrowIterator(nil)
keyValues := encodedKeyValues{}
for mapIter.HasNext() {
subStream.buf = make([]byte, 0, 64)
key, elem := mapIter.UnsafeNext()
encoder.keyEncoder.Encode(key, subStream)
if subStream.Error != nil && subStream.Error != io.EOF && stream.Error == nil {
stream.Error = subStream.Error
}
encodedKey := subStream.Buffer()
subIter.ResetBytes(encodedKey)
decodedKey := subIter.ReadString()
if stream.indention > 0 {
subStream.writeTwoBytes(byte(':'), byte(' '))
} else {
subStream.writeByte(':')
}
encoder.elemEncoder.Encode(elem, subStream)
keyValues = append(keyValues, encodedKV{
key: decodedKey,
keyValue: subStream.Buffer(),
})
}
sort.Sort(keyValues)
for i, keyValue := range keyValues {
if i != 0 {
stream.WriteMore()
}
stream.Write(keyValue.keyValue)
}
stream.WriteObjectEnd()
stream.cfg.ReturnStream(subStream)
stream.cfg.ReturnIterator(subIter)
}
func (encoder *sortKeysMapEncoder) IsEmpty(ptr unsafe.Pointer) bool {
iter := encoder.mapType.UnsafeIterate(ptr)
return !iter.HasNext()
}
type encodedKeyValues []encodedKV
type encodedKV struct {
key string
keyValue []byte
}
func (sv encodedKeyValues) Len() int { return len(sv) }
func (sv encodedKeyValues) Swap(i, j int) { sv[i], sv[j] = sv[j], sv[i] }
func (sv encodedKeyValues) Less(i, j int) bool { return sv[i].key < sv[j].key }
+218
View File
@@ -0,0 +1,218 @@
package jsoniter
import (
"encoding"
"encoding/json"
"github.com/modern-go/reflect2"
"unsafe"
)
var marshalerType = reflect2.TypeOfPtr((*json.Marshaler)(nil)).Elem()
var unmarshalerType = reflect2.TypeOfPtr((*json.Unmarshaler)(nil)).Elem()
var textMarshalerType = reflect2.TypeOfPtr((*encoding.TextMarshaler)(nil)).Elem()
var textUnmarshalerType = reflect2.TypeOfPtr((*encoding.TextUnmarshaler)(nil)).Elem()
func createDecoderOfMarshaler(ctx *ctx, typ reflect2.Type) ValDecoder {
ptrType := reflect2.PtrTo(typ)
if ptrType.Implements(unmarshalerType) {
return &referenceDecoder{
&unmarshalerDecoder{ptrType},
}
}
if ptrType.Implements(textUnmarshalerType) {
return &referenceDecoder{
&textUnmarshalerDecoder{ptrType},
}
}
return nil
}
func createEncoderOfMarshaler(ctx *ctx, typ reflect2.Type) ValEncoder {
if typ == marshalerType {
checkIsEmpty := createCheckIsEmpty(ctx, typ)
var encoder ValEncoder = &directMarshalerEncoder{
checkIsEmpty: checkIsEmpty,
}
return encoder
}
if typ.Implements(marshalerType) {
checkIsEmpty := createCheckIsEmpty(ctx, typ)
var encoder ValEncoder = &marshalerEncoder{
valType: typ,
checkIsEmpty: checkIsEmpty,
}
return encoder
}
ptrType := reflect2.PtrTo(typ)
if ctx.prefix != "" && ptrType.Implements(marshalerType) {
checkIsEmpty := createCheckIsEmpty(ctx, ptrType)
var encoder ValEncoder = &marshalerEncoder{
valType: ptrType,
checkIsEmpty: checkIsEmpty,
}
return &referenceEncoder{encoder}
}
if typ == textMarshalerType {
checkIsEmpty := createCheckIsEmpty(ctx, typ)
var encoder ValEncoder = &directTextMarshalerEncoder{
checkIsEmpty: checkIsEmpty,
stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
}
return encoder
}
if typ.Implements(textMarshalerType) {
checkIsEmpty := createCheckIsEmpty(ctx, typ)
var encoder ValEncoder = &textMarshalerEncoder{
valType: typ,
stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
checkIsEmpty: checkIsEmpty,
}
return encoder
}
// if prefix is empty, the type is the root type
if ctx.prefix != "" && ptrType.Implements(textMarshalerType) {
checkIsEmpty := createCheckIsEmpty(ctx, ptrType)
var encoder ValEncoder = &textMarshalerEncoder{
valType: ptrType,
stringEncoder: ctx.EncoderOf(reflect2.TypeOf("")),
checkIsEmpty: checkIsEmpty,
}
return &referenceEncoder{encoder}
}
return nil
}
type marshalerEncoder struct {
checkIsEmpty checkIsEmpty
valType reflect2.Type
}
func (encoder *marshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
obj := encoder.valType.UnsafeIndirect(ptr)
if encoder.valType.IsNullable() && reflect2.IsNil(obj) {
stream.WriteNil()
return
}
marshaler := obj.(json.Marshaler)
bytes, err := marshaler.MarshalJSON()
if err != nil {
stream.Error = err
} else {
stream.Write(bytes)
}
}
func (encoder *marshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return encoder.checkIsEmpty.IsEmpty(ptr)
}
type directMarshalerEncoder struct {
checkIsEmpty checkIsEmpty
}
func (encoder *directMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
marshaler := *(*json.Marshaler)(ptr)
if marshaler == nil {
stream.WriteNil()
return
}
bytes, err := marshaler.MarshalJSON()
if err != nil {
stream.Error = err
} else {
stream.Write(bytes)
}
}
func (encoder *directMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return encoder.checkIsEmpty.IsEmpty(ptr)
}
type textMarshalerEncoder struct {
valType reflect2.Type
stringEncoder ValEncoder
checkIsEmpty checkIsEmpty
}
func (encoder *textMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
obj := encoder.valType.UnsafeIndirect(ptr)
if encoder.valType.IsNullable() && reflect2.IsNil(obj) {
stream.WriteNil()
return
}
marshaler := (obj).(encoding.TextMarshaler)
bytes, err := marshaler.MarshalText()
if err != nil {
stream.Error = err
} else {
str := string(bytes)
encoder.stringEncoder.Encode(unsafe.Pointer(&str), stream)
}
}
func (encoder *textMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return encoder.checkIsEmpty.IsEmpty(ptr)
}
type directTextMarshalerEncoder struct {
stringEncoder ValEncoder
checkIsEmpty checkIsEmpty
}
func (encoder *directTextMarshalerEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
marshaler := *(*encoding.TextMarshaler)(ptr)
if marshaler == nil {
stream.WriteNil()
return
}
bytes, err := marshaler.MarshalText()
if err != nil {
stream.Error = err
} else {
str := string(bytes)
encoder.stringEncoder.Encode(unsafe.Pointer(&str), stream)
}
}
func (encoder *directTextMarshalerEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return encoder.checkIsEmpty.IsEmpty(ptr)
}
type unmarshalerDecoder struct {
valType reflect2.Type
}
func (decoder *unmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
valType := decoder.valType
obj := valType.UnsafeIndirect(ptr)
unmarshaler := obj.(json.Unmarshaler)
iter.nextToken()
iter.unreadByte() // skip spaces
bytes := iter.SkipAndReturnBytes()
err := unmarshaler.UnmarshalJSON(bytes)
if err != nil {
iter.ReportError("unmarshalerDecoder", err.Error())
}
}
type textUnmarshalerDecoder struct {
valType reflect2.Type
}
func (decoder *textUnmarshalerDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
valType := decoder.valType
obj := valType.UnsafeIndirect(ptr)
if reflect2.IsNil(obj) {
ptrType := valType.(*reflect2.UnsafePtrType)
elemType := ptrType.Elem()
elem := elemType.UnsafeNew()
ptrType.UnsafeSet(ptr, unsafe.Pointer(&elem))
obj = valType.UnsafeIndirect(ptr)
}
unmarshaler := (obj).(encoding.TextUnmarshaler)
str := iter.ReadString()
err := unmarshaler.UnmarshalText([]byte(str))
if err != nil {
iter.ReportError("textUnmarshalerDecoder", err.Error())
}
}
+451
View File
@@ -0,0 +1,451 @@
package jsoniter
import (
"encoding/base64"
"reflect"
"strconv"
"unsafe"
"github.com/modern-go/reflect2"
)
const ptrSize = 32 << uintptr(^uintptr(0)>>63)
func createEncoderOfNative(ctx *ctx, typ reflect2.Type) ValEncoder {
if typ.Kind() == reflect.Slice && typ.(reflect2.SliceType).Elem().Kind() == reflect.Uint8 {
sliceDecoder := decoderOfSlice(ctx, typ)
return &base64Codec{sliceDecoder: sliceDecoder}
}
typeName := typ.String()
kind := typ.Kind()
switch kind {
case reflect.String:
if typeName != "string" {
return encoderOfType(ctx, reflect2.TypeOfPtr((*string)(nil)).Elem())
}
return &stringCodec{}
case reflect.Int:
if typeName != "int" {
return encoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem())
}
if strconv.IntSize == 32 {
return &int32Codec{}
}
return &int64Codec{}
case reflect.Int8:
if typeName != "int8" {
return encoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem())
}
return &int8Codec{}
case reflect.Int16:
if typeName != "int16" {
return encoderOfType(ctx, reflect2.TypeOfPtr((*int16)(nil)).Elem())
}
return &int16Codec{}
case reflect.Int32:
if typeName != "int32" {
return encoderOfType(ctx, reflect2.TypeOfPtr((*int32)(nil)).Elem())
}
return &int32Codec{}
case reflect.Int64:
if typeName != "int64" {
return encoderOfType(ctx, reflect2.TypeOfPtr((*int64)(nil)).Elem())
}
return &int64Codec{}
case reflect.Uint:
if typeName != "uint" {
return encoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem())
}
if strconv.IntSize == 32 {
return &uint32Codec{}
}
return &uint64Codec{}
case reflect.Uint8:
if typeName != "uint8" {
return encoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem())
}
return &uint8Codec{}
case reflect.Uint16:
if typeName != "uint16" {
return encoderOfType(ctx, reflect2.TypeOfPtr((*uint16)(nil)).Elem())
}
return &uint16Codec{}
case reflect.Uint32:
if typeName != "uint32" {
return encoderOfType(ctx, reflect2.TypeOfPtr((*uint32)(nil)).Elem())
}
return &uint32Codec{}
case reflect.Uintptr:
if typeName != "uintptr" {
return encoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem())
}
if ptrSize == 32 {
return &uint32Codec{}
}
return &uint64Codec{}
case reflect.Uint64:
if typeName != "uint64" {
return encoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem())
}
return &uint64Codec{}
case reflect.Float32:
if typeName != "float32" {
return encoderOfType(ctx, reflect2.TypeOfPtr((*float32)(nil)).Elem())
}
return &float32Codec{}
case reflect.Float64:
if typeName != "float64" {
return encoderOfType(ctx, reflect2.TypeOfPtr((*float64)(nil)).Elem())
}
return &float64Codec{}
case reflect.Bool:
if typeName != "bool" {
return encoderOfType(ctx, reflect2.TypeOfPtr((*bool)(nil)).Elem())
}
return &boolCodec{}
}
return nil
}
func createDecoderOfNative(ctx *ctx, typ reflect2.Type) ValDecoder {
if typ.Kind() == reflect.Slice && typ.(reflect2.SliceType).Elem().Kind() == reflect.Uint8 {
sliceDecoder := decoderOfSlice(ctx, typ)
return &base64Codec{sliceDecoder: sliceDecoder}
}
typeName := typ.String()
switch typ.Kind() {
case reflect.String:
if typeName != "string" {
return decoderOfType(ctx, reflect2.TypeOfPtr((*string)(nil)).Elem())
}
return &stringCodec{}
case reflect.Int:
if typeName != "int" {
return decoderOfType(ctx, reflect2.TypeOfPtr((*int)(nil)).Elem())
}
if strconv.IntSize == 32 {
return &int32Codec{}
}
return &int64Codec{}
case reflect.Int8:
if typeName != "int8" {
return decoderOfType(ctx, reflect2.TypeOfPtr((*int8)(nil)).Elem())
}
return &int8Codec{}
case reflect.Int16:
if typeName != "int16" {
return decoderOfType(ctx, reflect2.TypeOfPtr((*int16)(nil)).Elem())
}
return &int16Codec{}
case reflect.Int32:
if typeName != "int32" {
return decoderOfType(ctx, reflect2.TypeOfPtr((*int32)(nil)).Elem())
}
return &int32Codec{}
case reflect.Int64:
if typeName != "int64" {
return decoderOfType(ctx, reflect2.TypeOfPtr((*int64)(nil)).Elem())
}
return &int64Codec{}
case reflect.Uint:
if typeName != "uint" {
return decoderOfType(ctx, reflect2.TypeOfPtr((*uint)(nil)).Elem())
}
if strconv.IntSize == 32 {
return &uint32Codec{}
}
return &uint64Codec{}
case reflect.Uint8:
if typeName != "uint8" {
return decoderOfType(ctx, reflect2.TypeOfPtr((*uint8)(nil)).Elem())
}
return &uint8Codec{}
case reflect.Uint16:
if typeName != "uint16" {
return decoderOfType(ctx, reflect2.TypeOfPtr((*uint16)(nil)).Elem())
}
return &uint16Codec{}
case reflect.Uint32:
if typeName != "uint32" {
return decoderOfType(ctx, reflect2.TypeOfPtr((*uint32)(nil)).Elem())
}
return &uint32Codec{}
case reflect.Uintptr:
if typeName != "uintptr" {
return decoderOfType(ctx, reflect2.TypeOfPtr((*uintptr)(nil)).Elem())
}
if ptrSize == 32 {
return &uint32Codec{}
}
return &uint64Codec{}
case reflect.Uint64:
if typeName != "uint64" {
return decoderOfType(ctx, reflect2.TypeOfPtr((*uint64)(nil)).Elem())
}
return &uint64Codec{}
case reflect.Float32:
if typeName != "float32" {
return decoderOfType(ctx, reflect2.TypeOfPtr((*float32)(nil)).Elem())
}
return &float32Codec{}
case reflect.Float64:
if typeName != "float64" {
return decoderOfType(ctx, reflect2.TypeOfPtr((*float64)(nil)).Elem())
}
return &float64Codec{}
case reflect.Bool:
if typeName != "bool" {
return decoderOfType(ctx, reflect2.TypeOfPtr((*bool)(nil)).Elem())
}
return &boolCodec{}
}
return nil
}
type stringCodec struct {
}
func (codec *stringCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
*((*string)(ptr)) = iter.ReadString()
}
func (codec *stringCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
str := *((*string)(ptr))
stream.WriteString(str)
}
func (codec *stringCodec) IsEmpty(ptr unsafe.Pointer) bool {
return *((*string)(ptr)) == ""
}
type int8Codec struct {
}
func (codec *int8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
if !iter.ReadNil() {
*((*int8)(ptr)) = iter.ReadInt8()
}
}
func (codec *int8Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteInt8(*((*int8)(ptr)))
}
func (codec *int8Codec) IsEmpty(ptr unsafe.Pointer) bool {
return *((*int8)(ptr)) == 0
}
type int16Codec struct {
}
func (codec *int16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
if !iter.ReadNil() {
*((*int16)(ptr)) = iter.ReadInt16()
}
}
func (codec *int16Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteInt16(*((*int16)(ptr)))
}
func (codec *int16Codec) IsEmpty(ptr unsafe.Pointer) bool {
return *((*int16)(ptr)) == 0
}
type int32Codec struct {
}
func (codec *int32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
if !iter.ReadNil() {
*((*int32)(ptr)) = iter.ReadInt32()
}
}
func (codec *int32Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteInt32(*((*int32)(ptr)))
}
func (codec *int32Codec) IsEmpty(ptr unsafe.Pointer) bool {
return *((*int32)(ptr)) == 0
}
type int64Codec struct {
}
func (codec *int64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
if !iter.ReadNil() {
*((*int64)(ptr)) = iter.ReadInt64()
}
}
func (codec *int64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteInt64(*((*int64)(ptr)))
}
func (codec *int64Codec) IsEmpty(ptr unsafe.Pointer) bool {
return *((*int64)(ptr)) == 0
}
type uint8Codec struct {
}
func (codec *uint8Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
if !iter.ReadNil() {
*((*uint8)(ptr)) = iter.ReadUint8()
}
}
func (codec *uint8Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteUint8(*((*uint8)(ptr)))
}
func (codec *uint8Codec) IsEmpty(ptr unsafe.Pointer) bool {
return *((*uint8)(ptr)) == 0
}
type uint16Codec struct {
}
func (codec *uint16Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
if !iter.ReadNil() {
*((*uint16)(ptr)) = iter.ReadUint16()
}
}
func (codec *uint16Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteUint16(*((*uint16)(ptr)))
}
func (codec *uint16Codec) IsEmpty(ptr unsafe.Pointer) bool {
return *((*uint16)(ptr)) == 0
}
type uint32Codec struct {
}
func (codec *uint32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
if !iter.ReadNil() {
*((*uint32)(ptr)) = iter.ReadUint32()
}
}
func (codec *uint32Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteUint32(*((*uint32)(ptr)))
}
func (codec *uint32Codec) IsEmpty(ptr unsafe.Pointer) bool {
return *((*uint32)(ptr)) == 0
}
type uint64Codec struct {
}
func (codec *uint64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
if !iter.ReadNil() {
*((*uint64)(ptr)) = iter.ReadUint64()
}
}
func (codec *uint64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteUint64(*((*uint64)(ptr)))
}
func (codec *uint64Codec) IsEmpty(ptr unsafe.Pointer) bool {
return *((*uint64)(ptr)) == 0
}
type float32Codec struct {
}
func (codec *float32Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
if !iter.ReadNil() {
*((*float32)(ptr)) = iter.ReadFloat32()
}
}
func (codec *float32Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteFloat32(*((*float32)(ptr)))
}
func (codec *float32Codec) IsEmpty(ptr unsafe.Pointer) bool {
return *((*float32)(ptr)) == 0
}
type float64Codec struct {
}
func (codec *float64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
if !iter.ReadNil() {
*((*float64)(ptr)) = iter.ReadFloat64()
}
}
func (codec *float64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteFloat64(*((*float64)(ptr)))
}
func (codec *float64Codec) IsEmpty(ptr unsafe.Pointer) bool {
return *((*float64)(ptr)) == 0
}
type boolCodec struct {
}
func (codec *boolCodec) Decode(ptr unsafe.Pointer, iter *Iterator) {
if !iter.ReadNil() {
*((*bool)(ptr)) = iter.ReadBool()
}
}
func (codec *boolCodec) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteBool(*((*bool)(ptr)))
}
func (codec *boolCodec) IsEmpty(ptr unsafe.Pointer) bool {
return !(*((*bool)(ptr)))
}
type base64Codec struct {
sliceType *reflect2.UnsafeSliceType
sliceDecoder ValDecoder
}
func (codec *base64Codec) Decode(ptr unsafe.Pointer, iter *Iterator) {
if iter.ReadNil() {
codec.sliceType.UnsafeSetNil(ptr)
return
}
switch iter.WhatIsNext() {
case StringValue:
src := iter.ReadString()
dst, err := base64.StdEncoding.DecodeString(src)
if err != nil {
iter.ReportError("decode base64", err.Error())
} else {
codec.sliceType.UnsafeSet(ptr, unsafe.Pointer(&dst))
}
case ArrayValue:
codec.sliceDecoder.Decode(ptr, iter)
default:
iter.ReportError("base64Codec", "invalid input")
}
}
func (codec *base64Codec) Encode(ptr unsafe.Pointer, stream *Stream) {
src := *((*[]byte)(ptr))
if len(src) == 0 {
stream.WriteNil()
return
}
encoding := base64.StdEncoding
stream.writeByte('"')
size := encoding.EncodedLen(len(src))
buf := make([]byte, size)
encoding.Encode(buf, src)
stream.buf = append(stream.buf, buf...)
stream.writeByte('"')
}
func (codec *base64Codec) IsEmpty(ptr unsafe.Pointer) bool {
return len(*((*[]byte)(ptr))) == 0
}
+133
View File
@@ -0,0 +1,133 @@
package jsoniter
import (
"github.com/modern-go/reflect2"
"reflect"
"unsafe"
)
func decoderOfOptional(ctx *ctx, typ reflect2.Type) ValDecoder {
ptrType := typ.(*reflect2.UnsafePtrType)
elemType := ptrType.Elem()
decoder := decoderOfType(ctx, elemType)
if ctx.prefix == "" && elemType.Kind() == reflect.Ptr {
return &dereferenceDecoder{elemType, decoder}
}
return &OptionalDecoder{elemType, decoder}
}
func encoderOfOptional(ctx *ctx, typ reflect2.Type) ValEncoder {
ptrType := typ.(*reflect2.UnsafePtrType)
elemType := ptrType.Elem()
elemEncoder := encoderOfType(ctx, elemType)
encoder := &OptionalEncoder{elemEncoder}
return encoder
}
type OptionalDecoder struct {
ValueType reflect2.Type
ValueDecoder ValDecoder
}
func (decoder *OptionalDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
if iter.ReadNil() {
*((*unsafe.Pointer)(ptr)) = nil
} else {
if *((*unsafe.Pointer)(ptr)) == nil {
//pointer to null, we have to allocate memory to hold the value
newPtr := decoder.ValueType.UnsafeNew()
decoder.ValueDecoder.Decode(newPtr, iter)
*((*unsafe.Pointer)(ptr)) = newPtr
} else {
//reuse existing instance
decoder.ValueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter)
}
}
}
type dereferenceDecoder struct {
// only to deference a pointer
valueType reflect2.Type
valueDecoder ValDecoder
}
func (decoder *dereferenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
if *((*unsafe.Pointer)(ptr)) == nil {
//pointer to null, we have to allocate memory to hold the value
newPtr := decoder.valueType.UnsafeNew()
decoder.valueDecoder.Decode(newPtr, iter)
*((*unsafe.Pointer)(ptr)) = newPtr
} else {
//reuse existing instance
decoder.valueDecoder.Decode(*((*unsafe.Pointer)(ptr)), iter)
}
}
type OptionalEncoder struct {
ValueEncoder ValEncoder
}
func (encoder *OptionalEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
if *((*unsafe.Pointer)(ptr)) == nil {
stream.WriteNil()
} else {
encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream)
}
}
func (encoder *OptionalEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return *((*unsafe.Pointer)(ptr)) == nil
}
type dereferenceEncoder struct {
ValueEncoder ValEncoder
}
func (encoder *dereferenceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
if *((*unsafe.Pointer)(ptr)) == nil {
stream.WriteNil()
} else {
encoder.ValueEncoder.Encode(*((*unsafe.Pointer)(ptr)), stream)
}
}
func (encoder *dereferenceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
dePtr := *((*unsafe.Pointer)(ptr))
if dePtr == nil {
return true
}
return encoder.ValueEncoder.IsEmpty(dePtr)
}
func (encoder *dereferenceEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool {
deReferenced := *((*unsafe.Pointer)(ptr))
if deReferenced == nil {
return true
}
isEmbeddedPtrNil, converted := encoder.ValueEncoder.(IsEmbeddedPtrNil)
if !converted {
return false
}
fieldPtr := unsafe.Pointer(deReferenced)
return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr)
}
type referenceEncoder struct {
encoder ValEncoder
}
func (encoder *referenceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
encoder.encoder.Encode(unsafe.Pointer(&ptr), stream)
}
func (encoder *referenceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return encoder.encoder.IsEmpty(unsafe.Pointer(&ptr))
}
type referenceDecoder struct {
decoder ValDecoder
}
func (decoder *referenceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
decoder.decoder.Decode(unsafe.Pointer(&ptr), iter)
}
+99
View File
@@ -0,0 +1,99 @@
package jsoniter
import (
"fmt"
"github.com/modern-go/reflect2"
"io"
"unsafe"
)
func decoderOfSlice(ctx *ctx, typ reflect2.Type) ValDecoder {
sliceType := typ.(*reflect2.UnsafeSliceType)
decoder := decoderOfType(ctx.append("[sliceElem]"), sliceType.Elem())
return &sliceDecoder{sliceType, decoder}
}
func encoderOfSlice(ctx *ctx, typ reflect2.Type) ValEncoder {
sliceType := typ.(*reflect2.UnsafeSliceType)
encoder := encoderOfType(ctx.append("[sliceElem]"), sliceType.Elem())
return &sliceEncoder{sliceType, encoder}
}
type sliceEncoder struct {
sliceType *reflect2.UnsafeSliceType
elemEncoder ValEncoder
}
func (encoder *sliceEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
if encoder.sliceType.UnsafeIsNil(ptr) {
stream.WriteNil()
return
}
length := encoder.sliceType.UnsafeLengthOf(ptr)
if length == 0 {
stream.WriteEmptyArray()
return
}
stream.WriteArrayStart()
encoder.elemEncoder.Encode(encoder.sliceType.UnsafeGetIndex(ptr, 0), stream)
for i := 1; i < length; i++ {
stream.WriteMore()
elemPtr := encoder.sliceType.UnsafeGetIndex(ptr, i)
encoder.elemEncoder.Encode(elemPtr, stream)
}
stream.WriteArrayEnd()
if stream.Error != nil && stream.Error != io.EOF {
stream.Error = fmt.Errorf("%v: %s", encoder.sliceType, stream.Error.Error())
}
}
func (encoder *sliceEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return encoder.sliceType.UnsafeLengthOf(ptr) == 0
}
type sliceDecoder struct {
sliceType *reflect2.UnsafeSliceType
elemDecoder ValDecoder
}
func (decoder *sliceDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
decoder.doDecode(ptr, iter)
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.sliceType, iter.Error.Error())
}
}
func (decoder *sliceDecoder) doDecode(ptr unsafe.Pointer, iter *Iterator) {
c := iter.nextToken()
sliceType := decoder.sliceType
if c == 'n' {
iter.skipThreeBytes('u', 'l', 'l')
sliceType.UnsafeSetNil(ptr)
return
}
if c != '[' {
iter.ReportError("decode slice", "expect [ or n, but found "+string([]byte{c}))
return
}
c = iter.nextToken()
if c == ']' {
sliceType.UnsafeSet(ptr, sliceType.UnsafeMakeSlice(0, 0))
return
}
iter.unreadByte()
sliceType.UnsafeGrow(ptr, 1)
elemPtr := sliceType.UnsafeGetIndex(ptr, 0)
decoder.elemDecoder.Decode(elemPtr, iter)
length := 1
for c = iter.nextToken(); c == ','; c = iter.nextToken() {
idx := length
length += 1
sliceType.UnsafeGrow(ptr, length)
elemPtr = sliceType.UnsafeGetIndex(ptr, idx)
decoder.elemDecoder.Decode(elemPtr, iter)
}
if c != ']' {
iter.ReportError("decode slice", "expect ], but found "+string([]byte{c}))
return
}
}
@@ -3,38 +3,78 @@ package jsoniter
import (
"fmt"
"io"
"reflect"
"strings"
"unsafe"
"github.com/modern-go/reflect2"
)
func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder) (ValDecoder, error) {
knownHash := map[int32]struct{}{
func decoderOfStruct(ctx *ctx, typ reflect2.Type) ValDecoder {
bindings := map[string]*Binding{}
structDescriptor := describeStruct(ctx, typ)
for _, binding := range structDescriptor.Fields {
for _, fromName := range binding.FromNames {
old := bindings[fromName]
if old == nil {
bindings[fromName] = binding
continue
}
ignoreOld, ignoreNew := resolveConflictBinding(ctx.frozenConfig, old, binding)
if ignoreOld {
delete(bindings, fromName)
}
if !ignoreNew {
bindings[fromName] = binding
}
}
}
fields := map[string]*structFieldDecoder{}
for k, binding := range bindings {
fields[k] = binding.Decoder.(*structFieldDecoder)
}
if !ctx.caseSensitive() {
for k, binding := range bindings {
if _, found := fields[strings.ToLower(k)]; !found {
fields[strings.ToLower(k)] = binding.Decoder.(*structFieldDecoder)
}
}
}
return createStructDecoder(ctx, typ, fields)
}
func createStructDecoder(ctx *ctx, typ reflect2.Type, fields map[string]*structFieldDecoder) ValDecoder {
if ctx.disallowUnknownFields {
return &generalStructDecoder{typ: typ, fields: fields, disallowUnknownFields: true}
}
knownHash := map[int64]struct{}{
0: {},
}
switch len(fields) {
case 0:
return &skipObjectDecoder{typ}, nil
return &skipObjectDecoder{typ}
case 1:
for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName)
fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields}, nil
return &generalStructDecoder{typ, fields, false}
}
knownHash[fieldHash] = struct{}{}
return &oneFieldStructDecoder{typ, fieldHash, fieldDecoder}, nil
return &oneFieldStructDecoder{typ, fieldHash, fieldDecoder}
}
case 2:
var fieldHash1 int32
var fieldHash2 int32
var fieldHash1 int64
var fieldHash2 int64
var fieldDecoder1 *structFieldDecoder
var fieldDecoder2 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName)
fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields}, nil
return &generalStructDecoder{typ, fields, false}
}
knownHash[fieldHash] = struct{}{}
if fieldHash1 == 0 {
@@ -45,19 +85,19 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
fieldDecoder2 = fieldDecoder
}
}
return &twoFieldsStructDecoder{typ, fieldHash1, fieldDecoder1, fieldHash2, fieldDecoder2}, nil
return &twoFieldsStructDecoder{typ, fieldHash1, fieldDecoder1, fieldHash2, fieldDecoder2}
case 3:
var fieldName1 int32
var fieldName2 int32
var fieldName3 int32
var fieldName1 int64
var fieldName2 int64
var fieldName3 int64
var fieldDecoder1 *structFieldDecoder
var fieldDecoder2 *structFieldDecoder
var fieldDecoder3 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName)
fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields}, nil
return &generalStructDecoder{typ, fields, false}
}
knownHash[fieldHash] = struct{}{}
if fieldName1 == 0 {
@@ -72,21 +112,23 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
}
}
return &threeFieldsStructDecoder{typ,
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3}, nil
fieldName1, fieldDecoder1,
fieldName2, fieldDecoder2,
fieldName3, fieldDecoder3}
case 4:
var fieldName1 int32
var fieldName2 int32
var fieldName3 int32
var fieldName4 int32
var fieldName1 int64
var fieldName2 int64
var fieldName3 int64
var fieldName4 int64
var fieldDecoder1 *structFieldDecoder
var fieldDecoder2 *structFieldDecoder
var fieldDecoder3 *structFieldDecoder
var fieldDecoder4 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName)
fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields}, nil
return &generalStructDecoder{typ, fields, false}
}
knownHash[fieldHash] = struct{}{}
if fieldName1 == 0 {
@@ -104,24 +146,26 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
}
}
return &fourFieldsStructDecoder{typ,
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
fieldName4, fieldDecoder4}, nil
fieldName1, fieldDecoder1,
fieldName2, fieldDecoder2,
fieldName3, fieldDecoder3,
fieldName4, fieldDecoder4}
case 5:
var fieldName1 int32
var fieldName2 int32
var fieldName3 int32
var fieldName4 int32
var fieldName5 int32
var fieldName1 int64
var fieldName2 int64
var fieldName3 int64
var fieldName4 int64
var fieldName5 int64
var fieldDecoder1 *structFieldDecoder
var fieldDecoder2 *structFieldDecoder
var fieldDecoder3 *structFieldDecoder
var fieldDecoder4 *structFieldDecoder
var fieldDecoder5 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName)
fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields}, nil
return &generalStructDecoder{typ, fields, false}
}
knownHash[fieldHash] = struct{}{}
if fieldName1 == 0 {
@@ -142,15 +186,18 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
}
}
return &fiveFieldsStructDecoder{typ,
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
fieldName4, fieldDecoder4, fieldName5, fieldDecoder5}, nil
fieldName1, fieldDecoder1,
fieldName2, fieldDecoder2,
fieldName3, fieldDecoder3,
fieldName4, fieldDecoder4,
fieldName5, fieldDecoder5}
case 6:
var fieldName1 int32
var fieldName2 int32
var fieldName3 int32
var fieldName4 int32
var fieldName5 int32
var fieldName6 int32
var fieldName1 int64
var fieldName2 int64
var fieldName3 int64
var fieldName4 int64
var fieldName5 int64
var fieldName6 int64
var fieldDecoder1 *structFieldDecoder
var fieldDecoder2 *structFieldDecoder
var fieldDecoder3 *structFieldDecoder
@@ -158,10 +205,10 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
var fieldDecoder5 *structFieldDecoder
var fieldDecoder6 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName)
fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields}, nil
return &generalStructDecoder{typ, fields, false}
}
knownHash[fieldHash] = struct{}{}
if fieldName1 == 0 {
@@ -185,16 +232,20 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
}
}
return &sixFieldsStructDecoder{typ,
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6}, nil
fieldName1, fieldDecoder1,
fieldName2, fieldDecoder2,
fieldName3, fieldDecoder3,
fieldName4, fieldDecoder4,
fieldName5, fieldDecoder5,
fieldName6, fieldDecoder6}
case 7:
var fieldName1 int32
var fieldName2 int32
var fieldName3 int32
var fieldName4 int32
var fieldName5 int32
var fieldName6 int32
var fieldName7 int32
var fieldName1 int64
var fieldName2 int64
var fieldName3 int64
var fieldName4 int64
var fieldName5 int64
var fieldName6 int64
var fieldName7 int64
var fieldDecoder1 *structFieldDecoder
var fieldDecoder2 *structFieldDecoder
var fieldDecoder3 *structFieldDecoder
@@ -203,10 +254,10 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
var fieldDecoder6 *structFieldDecoder
var fieldDecoder7 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName)
fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields}, nil
return &generalStructDecoder{typ, fields, false}
}
knownHash[fieldHash] = struct{}{}
if fieldName1 == 0 {
@@ -233,18 +284,22 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
}
}
return &sevenFieldsStructDecoder{typ,
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
fieldName7, fieldDecoder7}, nil
fieldName1, fieldDecoder1,
fieldName2, fieldDecoder2,
fieldName3, fieldDecoder3,
fieldName4, fieldDecoder4,
fieldName5, fieldDecoder5,
fieldName6, fieldDecoder6,
fieldName7, fieldDecoder7}
case 8:
var fieldName1 int32
var fieldName2 int32
var fieldName3 int32
var fieldName4 int32
var fieldName5 int32
var fieldName6 int32
var fieldName7 int32
var fieldName8 int32
var fieldName1 int64
var fieldName2 int64
var fieldName3 int64
var fieldName4 int64
var fieldName5 int64
var fieldName6 int64
var fieldName7 int64
var fieldName8 int64
var fieldDecoder1 *structFieldDecoder
var fieldDecoder2 *structFieldDecoder
var fieldDecoder3 *structFieldDecoder
@@ -254,10 +309,10 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
var fieldDecoder7 *structFieldDecoder
var fieldDecoder8 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName)
fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields}, nil
return &generalStructDecoder{typ, fields, false}
}
knownHash[fieldHash] = struct{}{}
if fieldName1 == 0 {
@@ -287,19 +342,24 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
}
}
return &eightFieldsStructDecoder{typ,
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
fieldName7, fieldDecoder7, fieldName8, fieldDecoder8}, nil
fieldName1, fieldDecoder1,
fieldName2, fieldDecoder2,
fieldName3, fieldDecoder3,
fieldName4, fieldDecoder4,
fieldName5, fieldDecoder5,
fieldName6, fieldDecoder6,
fieldName7, fieldDecoder7,
fieldName8, fieldDecoder8}
case 9:
var fieldName1 int32
var fieldName2 int32
var fieldName3 int32
var fieldName4 int32
var fieldName5 int32
var fieldName6 int32
var fieldName7 int32
var fieldName8 int32
var fieldName9 int32
var fieldName1 int64
var fieldName2 int64
var fieldName3 int64
var fieldName4 int64
var fieldName5 int64
var fieldName6 int64
var fieldName7 int64
var fieldName8 int64
var fieldName9 int64
var fieldDecoder1 *structFieldDecoder
var fieldDecoder2 *structFieldDecoder
var fieldDecoder3 *structFieldDecoder
@@ -310,10 +370,10 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
var fieldDecoder8 *structFieldDecoder
var fieldDecoder9 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName)
fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields}, nil
return &generalStructDecoder{typ, fields, false}
}
knownHash[fieldHash] = struct{}{}
if fieldName1 == 0 {
@@ -346,20 +406,26 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
}
}
return &nineFieldsStructDecoder{typ,
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9}, nil
fieldName1, fieldDecoder1,
fieldName2, fieldDecoder2,
fieldName3, fieldDecoder3,
fieldName4, fieldDecoder4,
fieldName5, fieldDecoder5,
fieldName6, fieldDecoder6,
fieldName7, fieldDecoder7,
fieldName8, fieldDecoder8,
fieldName9, fieldDecoder9}
case 10:
var fieldName1 int32
var fieldName2 int32
var fieldName3 int32
var fieldName4 int32
var fieldName5 int32
var fieldName6 int32
var fieldName7 int32
var fieldName8 int32
var fieldName9 int32
var fieldName10 int32
var fieldName1 int64
var fieldName2 int64
var fieldName3 int64
var fieldName4 int64
var fieldName5 int64
var fieldName6 int64
var fieldName7 int64
var fieldName8 int64
var fieldName9 int64
var fieldName10 int64
var fieldDecoder1 *structFieldDecoder
var fieldDecoder2 *structFieldDecoder
var fieldDecoder3 *structFieldDecoder
@@ -371,10 +437,10 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
var fieldDecoder9 *structFieldDecoder
var fieldDecoder10 *structFieldDecoder
for fieldName, fieldDecoder := range fields {
fieldHash := calcHash(fieldName)
fieldHash := calcHash(fieldName, ctx.caseSensitive())
_, known := knownHash[fieldHash]
if known {
return &generalStructDecoder{typ, fields}, nil
return &generalStructDecoder{typ, fields, false}
}
knownHash[fieldHash] = struct{}{}
if fieldName1 == 0 {
@@ -410,48 +476,80 @@ func createStructDecoder(typ reflect.Type, fields map[string]*structFieldDecoder
}
}
return &tenFieldsStructDecoder{typ,
fieldName1, fieldDecoder1, fieldName2, fieldDecoder2, fieldName3, fieldDecoder3,
fieldName4, fieldDecoder4, fieldName5, fieldDecoder5, fieldName6, fieldDecoder6,
fieldName7, fieldDecoder7, fieldName8, fieldDecoder8, fieldName9, fieldDecoder9,
fieldName10, fieldDecoder10}, nil
fieldName1, fieldDecoder1,
fieldName2, fieldDecoder2,
fieldName3, fieldDecoder3,
fieldName4, fieldDecoder4,
fieldName5, fieldDecoder5,
fieldName6, fieldDecoder6,
fieldName7, fieldDecoder7,
fieldName8, fieldDecoder8,
fieldName9, fieldDecoder9,
fieldName10, fieldDecoder10}
}
return &generalStructDecoder{typ, fields}, nil
return &generalStructDecoder{typ, fields, false}
}
type generalStructDecoder struct {
typ reflect.Type
fields map[string]*structFieldDecoder
typ reflect2.Type
fields map[string]*structFieldDecoder
disallowUnknownFields bool
}
func (decoder *generalStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
if !iter.readObjectStart() {
return
}
fieldBytes := iter.readObjectFieldAsBytes()
field := *(*string)(unsafe.Pointer(&fieldBytes))
fieldDecoder := decoder.fields[strings.ToLower(field)]
if fieldDecoder == nil {
iter.Skip()
} else {
fieldDecoder.Decode(ptr, iter)
}
for iter.nextToken() == ',' {
fieldBytes = iter.readObjectFieldAsBytes()
field = *(*string)(unsafe.Pointer(&fieldBytes))
fieldDecoder = decoder.fields[strings.ToLower(field)]
if fieldDecoder == nil {
iter.Skip()
} else {
fieldDecoder.Decode(ptr, iter)
}
var c byte
for c = ','; c == ','; c = iter.nextToken() {
decoder.decodeOneField(ptr, iter)
}
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
}
if c != '}' {
iter.ReportError("struct Decode", `expect }, but found `+string([]byte{c}))
}
}
func (decoder *generalStructDecoder) decodeOneField(ptr unsafe.Pointer, iter *Iterator) {
var field string
var fieldDecoder *structFieldDecoder
if iter.cfg.objectFieldMustBeSimpleString {
fieldBytes := iter.ReadStringAsSlice()
field = *(*string)(unsafe.Pointer(&fieldBytes))
fieldDecoder = decoder.fields[field]
if fieldDecoder == nil && !iter.cfg.caseSensitive {
fieldDecoder = decoder.fields[strings.ToLower(field)]
}
} else {
field = iter.ReadString()
fieldDecoder = decoder.fields[field]
if fieldDecoder == nil && !iter.cfg.caseSensitive {
fieldDecoder = decoder.fields[strings.ToLower(field)]
}
}
if fieldDecoder == nil {
msg := "found unknown field: " + field
if decoder.disallowUnknownFields {
iter.ReportError("ReadObject", msg)
}
c := iter.nextToken()
if c != ':' {
iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
}
iter.Skip()
return
}
c := iter.nextToken()
if c != ':' {
iter.ReportError("ReadObject", "expect : after object field, but found "+string([]byte{c}))
}
fieldDecoder.Decode(ptr, iter)
}
type skipObjectDecoder struct {
typ reflect.Type
typ reflect2.Type
}
func (decoder *skipObjectDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
@@ -464,8 +562,8 @@ func (decoder *skipObjectDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
}
type oneFieldStructDecoder struct {
typ reflect.Type
fieldHash int32
typ reflect2.Type
fieldHash int64
fieldDecoder *structFieldDecoder
}
@@ -484,15 +582,15 @@ func (decoder *oneFieldStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator)
}
}
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
}
}
type twoFieldsStructDecoder struct {
typ reflect.Type
fieldHash1 int32
typ reflect2.Type
fieldHash1 int64
fieldDecoder1 *structFieldDecoder
fieldHash2 int32
fieldHash2 int64
fieldDecoder2 *structFieldDecoder
}
@@ -514,17 +612,17 @@ func (decoder *twoFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator
}
}
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
}
}
type threeFieldsStructDecoder struct {
typ reflect.Type
fieldHash1 int32
typ reflect2.Type
fieldHash1 int64
fieldDecoder1 *structFieldDecoder
fieldHash2 int32
fieldHash2 int64
fieldDecoder2 *structFieldDecoder
fieldHash3 int32
fieldHash3 int64
fieldDecoder3 *structFieldDecoder
}
@@ -548,19 +646,19 @@ func (decoder *threeFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterat
}
}
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
}
}
type fourFieldsStructDecoder struct {
typ reflect.Type
fieldHash1 int32
typ reflect2.Type
fieldHash1 int64
fieldDecoder1 *structFieldDecoder
fieldHash2 int32
fieldHash2 int64
fieldDecoder2 *structFieldDecoder
fieldHash3 int32
fieldHash3 int64
fieldDecoder3 *structFieldDecoder
fieldHash4 int32
fieldHash4 int64
fieldDecoder4 *structFieldDecoder
}
@@ -586,21 +684,21 @@ func (decoder *fourFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterato
}
}
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
}
}
type fiveFieldsStructDecoder struct {
typ reflect.Type
fieldHash1 int32
typ reflect2.Type
fieldHash1 int64
fieldDecoder1 *structFieldDecoder
fieldHash2 int32
fieldHash2 int64
fieldDecoder2 *structFieldDecoder
fieldHash3 int32
fieldHash3 int64
fieldDecoder3 *structFieldDecoder
fieldHash4 int32
fieldHash4 int64
fieldDecoder4 *structFieldDecoder
fieldHash5 int32
fieldHash5 int64
fieldDecoder5 *structFieldDecoder
}
@@ -628,23 +726,23 @@ func (decoder *fiveFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterato
}
}
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
}
}
type sixFieldsStructDecoder struct {
typ reflect.Type
fieldHash1 int32
typ reflect2.Type
fieldHash1 int64
fieldDecoder1 *structFieldDecoder
fieldHash2 int32
fieldHash2 int64
fieldDecoder2 *structFieldDecoder
fieldHash3 int32
fieldHash3 int64
fieldDecoder3 *structFieldDecoder
fieldHash4 int32
fieldHash4 int64
fieldDecoder4 *structFieldDecoder
fieldHash5 int32
fieldHash5 int64
fieldDecoder5 *structFieldDecoder
fieldHash6 int32
fieldHash6 int64
fieldDecoder6 *structFieldDecoder
}
@@ -674,25 +772,25 @@ func (decoder *sixFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator
}
}
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
}
}
type sevenFieldsStructDecoder struct {
typ reflect.Type
fieldHash1 int32
typ reflect2.Type
fieldHash1 int64
fieldDecoder1 *structFieldDecoder
fieldHash2 int32
fieldHash2 int64
fieldDecoder2 *structFieldDecoder
fieldHash3 int32
fieldHash3 int64
fieldDecoder3 *structFieldDecoder
fieldHash4 int32
fieldHash4 int64
fieldDecoder4 *structFieldDecoder
fieldHash5 int32
fieldHash5 int64
fieldDecoder5 *structFieldDecoder
fieldHash6 int32
fieldHash6 int64
fieldDecoder6 *structFieldDecoder
fieldHash7 int32
fieldHash7 int64
fieldDecoder7 *structFieldDecoder
}
@@ -724,27 +822,27 @@ func (decoder *sevenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterat
}
}
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
}
}
type eightFieldsStructDecoder struct {
typ reflect.Type
fieldHash1 int32
typ reflect2.Type
fieldHash1 int64
fieldDecoder1 *structFieldDecoder
fieldHash2 int32
fieldHash2 int64
fieldDecoder2 *structFieldDecoder
fieldHash3 int32
fieldHash3 int64
fieldDecoder3 *structFieldDecoder
fieldHash4 int32
fieldHash4 int64
fieldDecoder4 *structFieldDecoder
fieldHash5 int32
fieldHash5 int64
fieldDecoder5 *structFieldDecoder
fieldHash6 int32
fieldHash6 int64
fieldDecoder6 *structFieldDecoder
fieldHash7 int32
fieldHash7 int64
fieldDecoder7 *structFieldDecoder
fieldHash8 int32
fieldHash8 int64
fieldDecoder8 *structFieldDecoder
}
@@ -778,29 +876,29 @@ func (decoder *eightFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterat
}
}
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
}
}
type nineFieldsStructDecoder struct {
typ reflect.Type
fieldHash1 int32
typ reflect2.Type
fieldHash1 int64
fieldDecoder1 *structFieldDecoder
fieldHash2 int32
fieldHash2 int64
fieldDecoder2 *structFieldDecoder
fieldHash3 int32
fieldHash3 int64
fieldDecoder3 *structFieldDecoder
fieldHash4 int32
fieldHash4 int64
fieldDecoder4 *structFieldDecoder
fieldHash5 int32
fieldHash5 int64
fieldDecoder5 *structFieldDecoder
fieldHash6 int32
fieldHash6 int64
fieldDecoder6 *structFieldDecoder
fieldHash7 int32
fieldHash7 int64
fieldDecoder7 *structFieldDecoder
fieldHash8 int32
fieldHash8 int64
fieldDecoder8 *structFieldDecoder
fieldHash9 int32
fieldHash9 int64
fieldDecoder9 *structFieldDecoder
}
@@ -836,31 +934,31 @@ func (decoder *nineFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterato
}
}
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
}
}
type tenFieldsStructDecoder struct {
typ reflect.Type
fieldHash1 int32
typ reflect2.Type
fieldHash1 int64
fieldDecoder1 *structFieldDecoder
fieldHash2 int32
fieldHash2 int64
fieldDecoder2 *structFieldDecoder
fieldHash3 int32
fieldHash3 int64
fieldDecoder3 *structFieldDecoder
fieldHash4 int32
fieldHash4 int64
fieldDecoder4 *structFieldDecoder
fieldHash5 int32
fieldHash5 int64
fieldDecoder5 *structFieldDecoder
fieldHash6 int32
fieldHash6 int64
fieldDecoder6 *structFieldDecoder
fieldHash7 int32
fieldHash7 int64
fieldDecoder7 *structFieldDecoder
fieldHash8 int32
fieldHash8 int64
fieldDecoder8 *structFieldDecoder
fieldHash9 int32
fieldHash9 int64
fieldDecoder9 *structFieldDecoder
fieldHash10 int32
fieldHash10 int64
fieldDecoder10 *structFieldDecoder
}
@@ -898,19 +996,53 @@ func (decoder *tenFieldsStructDecoder) Decode(ptr unsafe.Pointer, iter *Iterator
}
}
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%v: %s", decoder.typ, iter.Error.Error())
iter.Error = fmt.Errorf("%v.%s", decoder.typ, iter.Error.Error())
}
}
type structFieldDecoder struct {
field *reflect.StructField
field reflect2.StructField
fieldDecoder ValDecoder
}
func (decoder *structFieldDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
fieldPtr := unsafe.Pointer(uintptr(ptr) + decoder.field.Offset)
fieldPtr := decoder.field.UnsafeGet(ptr)
decoder.fieldDecoder.Decode(fieldPtr, iter)
if iter.Error != nil && iter.Error != io.EOF {
iter.Error = fmt.Errorf("%s: %s", decoder.field.Name, iter.Error.Error())
iter.Error = fmt.Errorf("%s: %s", decoder.field.Name(), iter.Error.Error())
}
}
type stringModeStringDecoder struct {
elemDecoder ValDecoder
cfg *frozenConfig
}
func (decoder *stringModeStringDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
decoder.elemDecoder.Decode(ptr, iter)
str := *((*string)(ptr))
tempIter := decoder.cfg.BorrowIterator([]byte(str))
defer decoder.cfg.ReturnIterator(tempIter)
*((*string)(ptr)) = tempIter.ReadString()
}
type stringModeNumberDecoder struct {
elemDecoder ValDecoder
}
func (decoder *stringModeNumberDecoder) Decode(ptr unsafe.Pointer, iter *Iterator) {
c := iter.nextToken()
if c != '"' {
iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c}))
return
}
decoder.elemDecoder.Decode(ptr, iter)
if iter.Error != nil {
return
}
c = iter.readByte()
if c != '"' {
iter.ReportError("stringModeNumberDecoder", `expect ", but found `+string([]byte{c}))
return
}
}
@@ -2,23 +2,20 @@ package jsoniter
import (
"fmt"
"github.com/modern-go/reflect2"
"io"
"reflect"
"strings"
"unsafe"
)
func encoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
func encoderOfStruct(ctx *ctx, typ reflect2.Type) ValEncoder {
type bindingTo struct {
binding *Binding
toName string
ignored bool
}
orderedBindings := []*bindingTo{}
structDescriptor, err := describeStruct(cfg, typ)
if err != nil {
return nil, err
}
structDescriptor := describeStruct(ctx, typ)
for _, binding := range structDescriptor.Fields {
for _, toName := range binding.ToNames {
new := &bindingTo{
@@ -29,13 +26,13 @@ func encoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
if old.toName != toName {
continue
}
old.ignored, new.ignored = resolveConflictBinding(cfg, old.binding, new.binding)
old.ignored, new.ignored = resolveConflictBinding(ctx.frozenConfig, old.binding, new.binding)
}
orderedBindings = append(orderedBindings, new)
}
}
if len(orderedBindings) == 0 {
return &emptyStructEncoder{}, nil
return &emptyStructEncoder{}
}
finalOrderedFields := []structFieldTo{}
for _, bindingTo := range orderedBindings {
@@ -46,12 +43,36 @@ func encoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValEncoder, error) {
})
}
}
return &structEncoder{structDescriptor.onePtrEmbedded, structDescriptor.onePtrOptimization, finalOrderedFields}, nil
return &structEncoder{typ, finalOrderedFields}
}
func createCheckIsEmpty(ctx *ctx, typ reflect2.Type) checkIsEmpty {
encoder := createEncoderOfNative(ctx, typ)
if encoder != nil {
return encoder
}
kind := typ.Kind()
switch kind {
case reflect.Interface:
return &dynamicEncoder{typ}
case reflect.Struct:
return &structEncoder{typ: typ}
case reflect.Array:
return &arrayEncoder{}
case reflect.Slice:
return &sliceEncoder{}
case reflect.Map:
return encoderOfMap(ctx, typ)
case reflect.Ptr:
return &OptionalEncoder{}
default:
return &lazyErrorEncoder{err: fmt.Errorf("unsupported type: %v", typ)}
}
}
func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ignoreNew bool) {
newTagged := new.Field.Tag.Get(cfg.getTagKey()) != ""
oldTagged := old.Field.Tag.Get(cfg.getTagKey()) != ""
newTagged := new.Field.Tag().Get(cfg.getTagKey()) != ""
oldTagged := old.Field.Tag().Get(cfg.getTagKey()) != ""
if newTagged {
if oldTagged {
if len(old.levels) > len(new.levels) {
@@ -78,62 +99,41 @@ func resolveConflictBinding(cfg *frozenConfig, old, new *Binding) (ignoreOld, ig
}
}
func decoderOfStruct(cfg *frozenConfig, typ reflect.Type) (ValDecoder, error) {
bindings := map[string]*Binding{}
structDescriptor, err := describeStruct(cfg, typ)
if err != nil {
return nil, err
}
for _, binding := range structDescriptor.Fields {
for _, fromName := range binding.FromNames {
old := bindings[fromName]
if old == nil {
bindings[fromName] = binding
continue
}
ignoreOld, ignoreNew := resolveConflictBinding(cfg, old, binding)
if ignoreOld {
delete(bindings, fromName)
}
if !ignoreNew {
bindings[fromName] = binding
}
}
}
fields := map[string]*structFieldDecoder{}
for k, binding := range bindings {
fields[strings.ToLower(k)] = binding.Decoder.(*structFieldDecoder)
}
return createStructDecoder(typ, fields)
}
type structFieldEncoder struct {
field *reflect.StructField
field reflect2.StructField
fieldEncoder ValEncoder
omitempty bool
}
func (encoder *structFieldEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
fieldPtr := unsafe.Pointer(uintptr(ptr) + encoder.field.Offset)
fieldPtr := encoder.field.UnsafeGet(ptr)
encoder.fieldEncoder.Encode(fieldPtr, stream)
if stream.Error != nil && stream.Error != io.EOF {
stream.Error = fmt.Errorf("%s: %s", encoder.field.Name, stream.Error.Error())
stream.Error = fmt.Errorf("%s: %s", encoder.field.Name(), stream.Error.Error())
}
}
func (encoder *structFieldEncoder) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, encoder)
}
func (encoder *structFieldEncoder) IsEmpty(ptr unsafe.Pointer) bool {
fieldPtr := unsafe.Pointer(uintptr(ptr) + encoder.field.Offset)
fieldPtr := encoder.field.UnsafeGet(ptr)
return encoder.fieldEncoder.IsEmpty(fieldPtr)
}
func (encoder *structFieldEncoder) IsEmbeddedPtrNil(ptr unsafe.Pointer) bool {
isEmbeddedPtrNil, converted := encoder.fieldEncoder.(IsEmbeddedPtrNil)
if !converted {
return false
}
fieldPtr := encoder.field.UnsafeGet(ptr)
return isEmbeddedPtrNil.IsEmbeddedPtrNil(fieldPtr)
}
type IsEmbeddedPtrNil interface {
IsEmbeddedPtrNil(ptr unsafe.Pointer) bool
}
type structEncoder struct {
onePtrEmbedded bool
onePtrOptimization bool
fields []structFieldTo
typ reflect2.Type
fields []structFieldTo
}
type structFieldTo struct {
@@ -148,6 +148,9 @@ func (encoder *structEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
if field.encoder.omitempty && field.encoder.IsEmpty(ptr) {
continue
}
if field.encoder.IsEmbeddedPtrNil(ptr) {
continue
}
if isNotFirst {
stream.WriteMore()
}
@@ -156,23 +159,8 @@ func (encoder *structEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
isNotFirst = true
}
stream.WriteObjectEnd()
}
func (encoder *structEncoder) EncodeInterface(val interface{}, stream *Stream) {
e := (*emptyInterface)(unsafe.Pointer(&val))
if encoder.onePtrOptimization {
if e.word == nil && encoder.onePtrEmbedded {
stream.WriteObjectStart()
stream.WriteObjectEnd()
return
}
ptr := uintptr(e.word)
e.word = unsafe.Pointer(&ptr)
}
if reflect.TypeOf(val).Kind() == reflect.Ptr {
encoder.Encode(unsafe.Pointer(&e.word), stream)
} else {
encoder.Encode(e.word, stream)
if stream.Error != nil && stream.Error != io.EOF {
stream.Error = fmt.Errorf("%v.%s", encoder.typ, stream.Error.Error())
}
}
@@ -187,10 +175,36 @@ func (encoder *emptyStructEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.WriteEmptyObject()
}
func (encoder *emptyStructEncoder) EncodeInterface(val interface{}, stream *Stream) {
WriteToStream(val, stream, encoder)
}
func (encoder *emptyStructEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return false
}
type stringModeNumberEncoder struct {
elemEncoder ValEncoder
}
func (encoder *stringModeNumberEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
stream.writeByte('"')
encoder.elemEncoder.Encode(ptr, stream)
stream.writeByte('"')
}
func (encoder *stringModeNumberEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return encoder.elemEncoder.IsEmpty(ptr)
}
type stringModeStringEncoder struct {
elemEncoder ValEncoder
cfg *frozenConfig
}
func (encoder *stringModeStringEncoder) Encode(ptr unsafe.Pointer, stream *Stream) {
tempStream := encoder.cfg.BorrowStream(nil)
defer encoder.cfg.ReturnStream(tempStream)
encoder.elemEncoder.Encode(ptr, tempStream)
stream.WriteString(string(tempStream.Buffer()))
}
func (encoder *stringModeStringEncoder) IsEmpty(ptr unsafe.Pointer) bool {
return encoder.elemEncoder.IsEmpty(ptr)
}
@@ -4,15 +4,15 @@ import (
"io"
)
// Stream is a io.Writer like object, with JSON specific write functions.
// stream is a io.Writer like object, with JSON specific write functions.
// Error is not returned as return value, but stored as Error member on this stream instance.
type Stream struct {
cfg *frozenConfig
out io.Writer
buf []byte
n int
Error error
indention int
cfg *frozenConfig
out io.Writer
buf []byte
Error error
indention int
Attachment interface{} // open for customized encoder
}
// NewStream create new stream instance.
@@ -23,8 +23,7 @@ func NewStream(cfg API, out io.Writer, bufSize int) *Stream {
return &Stream{
cfg: cfg.(*frozenConfig),
out: out,
buf: make([]byte, bufSize),
n: 0,
buf: make([]byte, 0, bufSize),
Error: nil,
indention: 0,
}
@@ -38,22 +37,27 @@ func (stream *Stream) Pool() StreamPool {
// Reset reuse this stream instance by assign a new writer
func (stream *Stream) Reset(out io.Writer) {
stream.out = out
stream.n = 0
stream.buf = stream.buf[:0]
}
// Available returns how many bytes are unused in the buffer.
func (stream *Stream) Available() int {
return len(stream.buf) - stream.n
return cap(stream.buf) - len(stream.buf)
}
// Buffered returns the number of bytes that have been written into the current buffer.
func (stream *Stream) Buffered() int {
return stream.n
return len(stream.buf)
}
// Buffer if writer is nil, use this method to take the result
func (stream *Stream) Buffer() []byte {
return stream.buf[:stream.n]
return stream.buf
}
// SetBuffer allows to append to the internal buffer directly
func (stream *Stream) SetBuffer(buf []byte) {
stream.buf = buf
}
// Write writes the contents of p into the buffer.
@@ -61,97 +65,34 @@ func (stream *Stream) Buffer() []byte {
// If nn < len(p), it also returns an error explaining
// why the write is short.
func (stream *Stream) Write(p []byte) (nn int, err error) {
for len(p) > stream.Available() && stream.Error == nil {
if stream.out == nil {
stream.growAtLeast(len(p))
} else {
var n int
if stream.Buffered() == 0 {
// Large write, empty buffer.
// Write directly from p to avoid copy.
n, stream.Error = stream.out.Write(p)
} else {
n = copy(stream.buf[stream.n:], p)
stream.n += n
stream.Flush()
}
nn += n
p = p[n:]
}
stream.buf = append(stream.buf, p...)
if stream.out != nil {
nn, err = stream.out.Write(stream.buf)
stream.buf = stream.buf[nn:]
return
}
if stream.Error != nil {
return nn, stream.Error
}
n := copy(stream.buf[stream.n:], p)
stream.n += n
nn += n
return nn, nil
return len(p), nil
}
// WriteByte writes a single byte.
func (stream *Stream) writeByte(c byte) {
if stream.Error != nil {
return
}
if stream.Available() < 1 {
stream.growAtLeast(1)
}
stream.buf[stream.n] = c
stream.n++
stream.buf = append(stream.buf, c)
}
func (stream *Stream) writeTwoBytes(c1 byte, c2 byte) {
if stream.Error != nil {
return
}
if stream.Available() < 2 {
stream.growAtLeast(2)
}
stream.buf[stream.n] = c1
stream.buf[stream.n+1] = c2
stream.n += 2
stream.buf = append(stream.buf, c1, c2)
}
func (stream *Stream) writeThreeBytes(c1 byte, c2 byte, c3 byte) {
if stream.Error != nil {
return
}
if stream.Available() < 3 {
stream.growAtLeast(3)
}
stream.buf[stream.n] = c1
stream.buf[stream.n+1] = c2
stream.buf[stream.n+2] = c3
stream.n += 3
stream.buf = append(stream.buf, c1, c2, c3)
}
func (stream *Stream) writeFourBytes(c1 byte, c2 byte, c3 byte, c4 byte) {
if stream.Error != nil {
return
}
if stream.Available() < 4 {
stream.growAtLeast(4)
}
stream.buf[stream.n] = c1
stream.buf[stream.n+1] = c2
stream.buf[stream.n+2] = c3
stream.buf[stream.n+3] = c4
stream.n += 4
stream.buf = append(stream.buf, c1, c2, c3, c4)
}
func (stream *Stream) writeFiveBytes(c1 byte, c2 byte, c3 byte, c4 byte, c5 byte) {
if stream.Error != nil {
return
}
if stream.Available() < 5 {
stream.growAtLeast(5)
}
stream.buf[stream.n] = c1
stream.buf[stream.n+1] = c2
stream.buf[stream.n+2] = c3
stream.buf[stream.n+3] = c4
stream.buf[stream.n+4] = c5
stream.n += 5
stream.buf = append(stream.buf, c1, c2, c3, c4, c5)
}
// Flush writes any buffered data to the underlying io.Writer.
@@ -162,53 +103,20 @@ func (stream *Stream) Flush() error {
if stream.Error != nil {
return stream.Error
}
if stream.n == 0 {
return nil
}
n, err := stream.out.Write(stream.buf[0:stream.n])
if n < stream.n && err == nil {
err = io.ErrShortWrite
}
n, err := stream.out.Write(stream.buf)
if err != nil {
if n > 0 && n < stream.n {
copy(stream.buf[0:stream.n-n], stream.buf[n:stream.n])
if stream.Error == nil {
stream.Error = err
}
stream.n -= n
stream.Error = err
return err
}
stream.n = 0
stream.buf = stream.buf[n:]
return nil
}
func (stream *Stream) ensure(minimal int) {
available := stream.Available()
if available < minimal {
stream.growAtLeast(minimal)
}
}
func (stream *Stream) growAtLeast(minimal int) {
if stream.out != nil {
stream.Flush()
}
toGrow := len(stream.buf)
if toGrow < minimal {
toGrow = minimal
}
newBuf := make([]byte, len(stream.buf)+toGrow)
copy(newBuf, stream.Buffer())
stream.buf = newBuf
}
// WriteRaw write string out without quotes, just like []byte
func (stream *Stream) WriteRaw(s string) {
stream.ensure(len(s))
if stream.Error != nil {
return
}
n := copy(stream.buf[stream.n:], s)
stream.n += n
stream.buf = append(stream.buf, s...)
}
// WriteNil write null to stream
@@ -269,6 +177,7 @@ func (stream *Stream) WriteEmptyObject() {
func (stream *Stream) WriteMore() {
stream.writeByte(',')
stream.writeIndention(0)
stream.Flush()
}
// WriteArrayStart write [ with possible indention
@@ -280,8 +189,7 @@ func (stream *Stream) WriteArrayStart() {
// WriteEmptyArray write []
func (stream *Stream) WriteEmptyArray() {
stream.writeByte('[')
stream.writeByte(']')
stream.writeTwoBytes('[', ']')
}
// WriteArrayEnd write ] with possible indention
@@ -297,9 +205,7 @@ func (stream *Stream) writeIndention(delta int) {
}
stream.writeByte('\n')
toWrite := stream.indention - delta
stream.ensure(toWrite)
for i := 0; i < toWrite && stream.n < len(stream.buf); i++ {
stream.buf[stream.n] = ' '
stream.n++
for i := 0; i < toWrite; i++ {
stream.buf = append(stream.buf, ' ')
}
}
@@ -21,7 +21,7 @@ func (stream *Stream) WriteFloat32(val float32) {
fmt = 'e'
}
}
stream.WriteRaw(strconv.FormatFloat(float64(val), fmt, -1, 32))
stream.buf = strconv.AppendFloat(stream.buf, float64(val), fmt, -1, 32)
}
// WriteFloat32Lossy write float32 to stream with ONLY 6 digits precision although much much faster
@@ -43,13 +43,12 @@ func (stream *Stream) WriteFloat32Lossy(val float32) {
return
}
stream.writeByte('.')
stream.ensure(10)
for p := precision - 1; p > 0 && fval < pow10[p]; p-- {
stream.writeByte('0')
}
stream.WriteUint64(fval)
for stream.buf[stream.n-1] == '0' {
stream.n--
for stream.buf[len(stream.buf)-1] == '0' {
stream.buf = stream.buf[:len(stream.buf)-1]
}
}
@@ -63,7 +62,7 @@ func (stream *Stream) WriteFloat64(val float64) {
fmt = 'e'
}
}
stream.WriteRaw(strconv.FormatFloat(float64(val), fmt, -1, 64))
stream.buf = strconv.AppendFloat(stream.buf, float64(val), fmt, -1, 64)
}
// WriteFloat64Lossy write float64 to stream with ONLY 6 digits precision although much much faster
@@ -85,12 +84,11 @@ func (stream *Stream) WriteFloat64Lossy(val float64) {
return
}
stream.writeByte('.')
stream.ensure(10)
for p := precision - 1; p > 0 && fval < pow10[p]; p-- {
stream.writeByte('0')
}
stream.WriteUint64(fval)
for stream.buf[stream.n-1] == '0' {
stream.n--
for stream.buf[len(stream.buf)-1] == '0' {
stream.buf = stream.buf[:len(stream.buf)-1]
}
}
+190
View File
@@ -0,0 +1,190 @@
package jsoniter
var digits []uint32
func init() {
digits = make([]uint32, 1000)
for i := uint32(0); i < 1000; i++ {
digits[i] = (((i / 100) + '0') << 16) + ((((i / 10) % 10) + '0') << 8) + i%10 + '0'
if i < 10 {
digits[i] += 2 << 24
} else if i < 100 {
digits[i] += 1 << 24
}
}
}
func writeFirstBuf(space []byte, v uint32) []byte {
start := v >> 24
if start == 0 {
space = append(space, byte(v>>16), byte(v>>8))
} else if start == 1 {
space = append(space, byte(v>>8))
}
space = append(space, byte(v))
return space
}
func writeBuf(buf []byte, v uint32) []byte {
return append(buf, byte(v>>16), byte(v>>8), byte(v))
}
// WriteUint8 write uint8 to stream
func (stream *Stream) WriteUint8(val uint8) {
stream.buf = writeFirstBuf(stream.buf, digits[val])
}
// WriteInt8 write int8 to stream
func (stream *Stream) WriteInt8(nval int8) {
var val uint8
if nval < 0 {
val = uint8(-nval)
stream.buf = append(stream.buf, '-')
} else {
val = uint8(nval)
}
stream.buf = writeFirstBuf(stream.buf, digits[val])
}
// WriteUint16 write uint16 to stream
func (stream *Stream) WriteUint16(val uint16) {
q1 := val / 1000
if q1 == 0 {
stream.buf = writeFirstBuf(stream.buf, digits[val])
return
}
r1 := val - q1*1000
stream.buf = writeFirstBuf(stream.buf, digits[q1])
stream.buf = writeBuf(stream.buf, digits[r1])
return
}
// WriteInt16 write int16 to stream
func (stream *Stream) WriteInt16(nval int16) {
var val uint16
if nval < 0 {
val = uint16(-nval)
stream.buf = append(stream.buf, '-')
} else {
val = uint16(nval)
}
stream.WriteUint16(val)
}
// WriteUint32 write uint32 to stream
func (stream *Stream) WriteUint32(val uint32) {
q1 := val / 1000
if q1 == 0 {
stream.buf = writeFirstBuf(stream.buf, digits[val])
return
}
r1 := val - q1*1000
q2 := q1 / 1000
if q2 == 0 {
stream.buf = writeFirstBuf(stream.buf, digits[q1])
stream.buf = writeBuf(stream.buf, digits[r1])
return
}
r2 := q1 - q2*1000
q3 := q2 / 1000
if q3 == 0 {
stream.buf = writeFirstBuf(stream.buf, digits[q2])
} else {
r3 := q2 - q3*1000
stream.buf = append(stream.buf, byte(q3+'0'))
stream.buf = writeBuf(stream.buf, digits[r3])
}
stream.buf = writeBuf(stream.buf, digits[r2])
stream.buf = writeBuf(stream.buf, digits[r1])
}
// WriteInt32 write int32 to stream
func (stream *Stream) WriteInt32(nval int32) {
var val uint32
if nval < 0 {
val = uint32(-nval)
stream.buf = append(stream.buf, '-')
} else {
val = uint32(nval)
}
stream.WriteUint32(val)
}
// WriteUint64 write uint64 to stream
func (stream *Stream) WriteUint64(val uint64) {
q1 := val / 1000
if q1 == 0 {
stream.buf = writeFirstBuf(stream.buf, digits[val])
return
}
r1 := val - q1*1000
q2 := q1 / 1000
if q2 == 0 {
stream.buf = writeFirstBuf(stream.buf, digits[q1])
stream.buf = writeBuf(stream.buf, digits[r1])
return
}
r2 := q1 - q2*1000
q3 := q2 / 1000
if q3 == 0 {
stream.buf = writeFirstBuf(stream.buf, digits[q2])
stream.buf = writeBuf(stream.buf, digits[r2])
stream.buf = writeBuf(stream.buf, digits[r1])
return
}
r3 := q2 - q3*1000
q4 := q3 / 1000
if q4 == 0 {
stream.buf = writeFirstBuf(stream.buf, digits[q3])
stream.buf = writeBuf(stream.buf, digits[r3])
stream.buf = writeBuf(stream.buf, digits[r2])
stream.buf = writeBuf(stream.buf, digits[r1])
return
}
r4 := q3 - q4*1000
q5 := q4 / 1000
if q5 == 0 {
stream.buf = writeFirstBuf(stream.buf, digits[q4])
stream.buf = writeBuf(stream.buf, digits[r4])
stream.buf = writeBuf(stream.buf, digits[r3])
stream.buf = writeBuf(stream.buf, digits[r2])
stream.buf = writeBuf(stream.buf, digits[r1])
return
}
r5 := q4 - q5*1000
q6 := q5 / 1000
if q6 == 0 {
stream.buf = writeFirstBuf(stream.buf, digits[q5])
} else {
stream.buf = writeFirstBuf(stream.buf, digits[q6])
r6 := q5 - q6*1000
stream.buf = writeBuf(stream.buf, digits[r6])
}
stream.buf = writeBuf(stream.buf, digits[r5])
stream.buf = writeBuf(stream.buf, digits[r4])
stream.buf = writeBuf(stream.buf, digits[r3])
stream.buf = writeBuf(stream.buf, digits[r2])
stream.buf = writeBuf(stream.buf, digits[r1])
}
// WriteInt64 write int64 to stream
func (stream *Stream) WriteInt64(nval int64) {
var val uint64
if nval < 0 {
val = uint64(-nval)
stream.buf = append(stream.buf, '-')
} else {
val = uint64(nval)
}
stream.WriteUint64(val)
}
// WriteInt write int to stream
func (stream *Stream) WriteInt(val int) {
stream.WriteInt64(int64(val))
}
// WriteUint write uint to stream
func (stream *Stream) WriteUint(val uint) {
stream.WriteUint64(uint64(val))
}
@@ -219,34 +219,22 @@ var hex = "0123456789abcdef"
// WriteStringWithHTMLEscaped write string to stream with html special characters escaped
func (stream *Stream) WriteStringWithHTMLEscaped(s string) {
stream.ensure(32)
valLen := len(s)
toWriteLen := valLen
bufLengthMinusTwo := len(stream.buf) - 2 // make room for the quotes
if stream.n+toWriteLen > bufLengthMinusTwo {
toWriteLen = bufLengthMinusTwo - stream.n
}
n := stream.n
stream.buf[n] = '"'
n++
stream.buf = append(stream.buf, '"')
// write string, the fast path, without utf8 and escape support
i := 0
for ; i < toWriteLen; i++ {
for ; i < valLen; i++ {
c := s[i]
if c < utf8.RuneSelf && htmlSafeSet[c] {
stream.buf[n] = c
n++
stream.buf = append(stream.buf, c)
} else {
break
}
}
if i == valLen {
stream.buf[n] = '"'
n++
stream.n = n
stream.buf = append(stream.buf, '"')
return
}
stream.n = n
writeStringSlowPathWithHTMLEscaped(stream, i, s, valLen)
}
@@ -321,34 +309,22 @@ func writeStringSlowPathWithHTMLEscaped(stream *Stream, i int, s string, valLen
// WriteString write string to stream without html escape
func (stream *Stream) WriteString(s string) {
stream.ensure(32)
valLen := len(s)
toWriteLen := valLen
bufLengthMinusTwo := len(stream.buf) - 2 // make room for the quotes
if stream.n+toWriteLen > bufLengthMinusTwo {
toWriteLen = bufLengthMinusTwo - stream.n
}
n := stream.n
stream.buf[n] = '"'
n++
stream.buf = append(stream.buf, '"')
// write string, the fast path, without utf8 and escape support
i := 0
for ; i < toWriteLen; i++ {
for ; i < valLen; i++ {
c := s[i]
if c > 31 && c != '"' && c != '\\' {
stream.buf[n] = c
n++
stream.buf = append(stream.buf, c)
} else {
break
}
}
if i == valLen {
stream.buf[n] = '"'
n++
stream.n = n
stream.buf = append(stream.buf, '"')
return
}
stream.n = n
writeStringSlowPath(stream, i, s, valLen)
}
+1 -1
View File
@@ -4,7 +4,7 @@ set -e
echo "" > coverage.txt
for d in $(go list ./... | grep -v vendor); do
go test -coverprofile=profile.out $d
go test -coverprofile=profile.out -coverpkg=github.com/json-iterator/go $d
if [ -f profile.out ]; then
cat profile.out >> coverage.txt
rm profile.out
+1
View File
@@ -0,0 +1 @@
/coverage.txt
+14
View File
@@ -0,0 +1,14 @@
language: go
go:
- 1.8.x
- 1.x
before_install:
- go get -t -v ./...
script:
- ./test.sh
after_success:
- bash <(curl -s https://codecov.io/bash)
+201
View File
@@ -0,0 +1,201 @@
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
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.
+49
View File
@@ -0,0 +1,49 @@
# concurrent
[![Sourcegraph](https://sourcegraph.com/github.com/modern-go/concurrent/-/badge.svg)](https://sourcegraph.com/github.com/modern-go/concurrent?badge)
[![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)](http://godoc.org/github.com/modern-go/concurrent)
[![Build Status](https://travis-ci.org/modern-go/concurrent.svg?branch=master)](https://travis-ci.org/modern-go/concurrent)
[![codecov](https://codecov.io/gh/modern-go/concurrent/branch/master/graph/badge.svg)](https://codecov.io/gh/modern-go/concurrent)
[![rcard](https://goreportcard.com/badge/github.com/modern-go/concurrent)](https://goreportcard.com/report/github.com/modern-go/concurrent)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://raw.githubusercontent.com/modern-go/concurrent/master/LICENSE)
* concurrent.Map: backport sync.Map for go below 1.9
* concurrent.Executor: goroutine with explicit ownership and cancellable
# concurrent.Map
because sync.Map is only available in go 1.9, we can use concurrent.Map to make code portable
```go
m := concurrent.NewMap()
m.Store("hello", "world")
elem, found := m.Load("hello")
// elem will be "world"
// found will be true
```
# concurrent.Executor
```go
executor := concurrent.NewUnboundedExecutor()
executor.Go(func(ctx context.Context) {
everyMillisecond := time.NewTicker(time.Millisecond)
for {
select {
case <-ctx.Done():
fmt.Println("goroutine exited")
return
case <-everyMillisecond.C:
// do something
}
}
})
time.Sleep(time.Second)
executor.StopAndWaitForever()
fmt.Println("executor stopped")
```
attach goroutine to executor instance, so that we can
* cancel it by stop the executor with Stop/StopAndWait/StopAndWaitForever
* handle panic by callback: the default behavior will no longer crash your application

Some files were not shown because too many files have changed in this diff Show More