├── .gitignore
├── LICENSE
├── README.md
├── benchmarks
├── Benchmarks.csproj
├── BenchmarksBase.cs
├── CountStrings.cs
├── CountTokens.cs
├── MinifyBenchmarks.cs
├── Program.cs
└── Report-as-of-3.12.2019.xlsx
├── images
├── logo.ico
└── logo.png
├── jsonexamples
├── apache_builds.json
├── canada.json
├── citm_catalog.json
├── github_events.json
├── gsoc-2018.json
├── instruments.json
├── marine_ik.json
├── mesh.json
├── mesh.pretty.json
├── numbers.json
├── random.json
├── small
│ ├── adversarial.json
│ ├── demo.json
│ ├── flatadversarial.json
│ ├── jsoniter_scala
│ │ ├── README.md
│ │ ├── che-1.geo.json
│ │ ├── che-2.geo.json
│ │ ├── che-3.geo.json
│ │ ├── google_maps_api_compact_response.json
│ │ ├── google_maps_api_response.json
│ │ ├── twitter_api_compact_response.json
│ │ └── twitter_api_response.json
│ ├── repeat.json
│ ├── truenull.json
│ └── twitter_timeline.json
├── twitter.json
├── twitterescaped.json
└── update-center.json
├── samples
├── HelloWorld
│ ├── HelloWorld.csproj
│ └── Program.cs
└── MinifyJson
│ ├── MinifyJson.csproj
│ ├── Program.cs
│ └── sample.json
├── solution.sln
├── src
├── BindingsForNativeLib
│ ├── BindingsGenerator
│ │ ├── BindingsGenerator.csproj
│ │ └── Program.cs
│ ├── SimdJsonNative
│ │ ├── Makefile
│ │ ├── SimdJsonNative.vcxproj
│ │ ├── SimdJsonNative.vcxproj.filters
│ │ ├── bindings.cpp
│ │ ├── simdjson.cpp
│ │ └── simdjson.h
│ └── SimdJsonSharp.Bindings
│ │ ├── Bindings.Generated.cs
│ │ ├── Bindings.cs
│ │ └── SimdJsonSharp.Bindings.csproj
└── FullyManagedImpl
│ ├── Minifier
│ ├── JsonMinifier.cs
│ └── mask128_epi8.cs
│ ├── ParsedJson.cs
│ ├── ParsedJsonIterator.cs
│ ├── SimdJson.cs
│ ├── SimdJsonSharp.Managed.csproj
│ ├── ThrowHelper.cs
│ ├── Utf8Validation.cs
│ ├── Utils
│ ├── Utils.cs
│ ├── numberparsing.cs
│ └── stringparsing.cs
│ ├── stage1_find_marks.cs
│ └── stage2_build_tape.cs
└── tests
├── MinifierTests.cs
├── SimdJsonSharp.Tests.csproj
└── ValidateTestFilesTests.cs
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.suo
8 | *.user
9 | *.userosscache
10 | *.sln.docstates
11 |
12 | # User-specific files (MonoDevelop/Xamarin Studio)
13 | *.userprefs
14 |
15 | # Build results
16 | [Dd]ebug/
17 | [Dd]ebugPublic/
18 | [Rr]elease/
19 | [Rr]eleases/
20 | x64/
21 | x86/
22 | bld/
23 | [Bb]in/
24 | [Oo]bj/
25 | [Ll]og/
26 |
27 | # Visual Studio 2015/2017 cache/options directory
28 | .vs/
29 | # Uncomment if you have tasks that create the project's static files in wwwroot
30 | #wwwroot/
31 |
32 | # Visual Studio 2017 auto generated files
33 | Generated\ Files/
34 |
35 | # MSTest test Results
36 | [Tt]est[Rr]esult*/
37 | [Bb]uild[Ll]og.*
38 |
39 | # NUNIT
40 | *.VisualState.xml
41 | TestResult.xml
42 |
43 | # Build Results of an ATL Project
44 | [Dd]ebugPS/
45 | [Rr]eleasePS/
46 | dlldata.c
47 |
48 | # Benchmark Results
49 | BenchmarkDotNet.Artifacts/
50 |
51 | # .NET Core
52 | project.lock.json
53 | project.fragment.lock.json
54 | artifacts/
55 | **/Properties/launchSettings.json
56 |
57 | # StyleCop
58 | StyleCopReport.xml
59 |
60 | # Files built by Visual Studio
61 | *_i.c
62 | *_p.c
63 | *_i.h
64 | *.ilk
65 | *.meta
66 | *.obj
67 | *.iobj
68 | *.pch
69 | *.pdb
70 | *.ipdb
71 | *.pgc
72 | *.pgd
73 | *.rsp
74 | *.sbr
75 | *.tlb
76 | *.tli
77 | *.tlh
78 | *.tmp
79 | *.tmp_proj
80 | *.log
81 | *.vspscc
82 | *.vssscc
83 | .builds
84 | *.pidb
85 | *.svclog
86 | *.scc
87 |
88 | # Chutzpah Test files
89 | _Chutzpah*
90 |
91 | # Visual C++ cache files
92 | ipch/
93 | *.aps
94 | *.ncb
95 | *.opendb
96 | *.opensdf
97 | *.sdf
98 | *.cachefile
99 | *.VC.db
100 | *.VC.VC.opendb
101 |
102 | # Visual Studio profiler
103 | *.psess
104 | *.vsp
105 | *.vspx
106 | *.sap
107 |
108 | # Visual Studio Trace Files
109 | *.e2e
110 |
111 | # TFS 2012 Local Workspace
112 | $tf/
113 |
114 | # Guidance Automation Toolkit
115 | *.gpState
116 |
117 | # ReSharper is a .NET coding add-in
118 | _ReSharper*/
119 | *.[Rr]e[Ss]harper
120 | *.DotSettings.user
121 |
122 | # JustCode is a .NET coding add-in
123 | .JustCode
124 |
125 | # TeamCity is a build add-in
126 | _TeamCity*
127 |
128 | # DotCover is a Code Coverage Tool
129 | *.dotCover
130 |
131 | # AxoCover is a Code Coverage Tool
132 | .axoCover/*
133 | !.axoCover/settings.json
134 |
135 | # Visual Studio code coverage results
136 | *.coverage
137 | *.coveragexml
138 |
139 | # NCrunch
140 | _NCrunch_*
141 | .*crunch*.local.xml
142 | nCrunchTemp_*
143 |
144 | # MightyMoose
145 | *.mm.*
146 | AutoTest.Net/
147 |
148 | # Web workbench (sass)
149 | .sass-cache/
150 |
151 | # Installshield output folder
152 | [Ee]xpress/
153 |
154 | # DocProject is a documentation generator add-in
155 | DocProject/buildhelp/
156 | DocProject/Help/*.HxT
157 | DocProject/Help/*.HxC
158 | DocProject/Help/*.hhc
159 | DocProject/Help/*.hhk
160 | DocProject/Help/*.hhp
161 | DocProject/Help/Html2
162 | DocProject/Help/html
163 |
164 | # Click-Once directory
165 | publish/
166 |
167 | # Publish Web Output
168 | *.[Pp]ublish.xml
169 | *.azurePubxml
170 | # Note: Comment the next line if you want to checkin your web deploy settings,
171 | # but database connection strings (with potential passwords) will be unencrypted
172 | *.pubxml
173 | *.publishproj
174 |
175 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
176 | # checkin your Azure Web App publish settings, but sensitive information contained
177 | # in these scripts will be unencrypted
178 | PublishScripts/
179 |
180 | # NuGet Packages
181 | *.nupkg
182 | # The packages folder can be ignored because of Package Restore
183 | **/[Pp]ackages/*
184 | # except build/, which is used as an MSBuild target.
185 | !**/[Pp]ackages/build/
186 | # Uncomment if necessary however generally it will be regenerated when needed
187 | #!**/[Pp]ackages/repositories.config
188 | # NuGet v3's project.json files produces more ignorable files
189 | *.nuget.props
190 | *.nuget.targets
191 |
192 | # Microsoft Azure Build Output
193 | csx/
194 | *.build.csdef
195 |
196 | # Microsoft Azure Emulator
197 | ecf/
198 | rcf/
199 |
200 | # Windows Store app package directories and files
201 | AppPackages/
202 | BundleArtifacts/
203 | Package.StoreAssociation.xml
204 | _pkginfo.txt
205 | *.appx
206 |
207 | # Visual Studio cache files
208 | # files ending in .cache can be ignored
209 | *.[Cc]ache
210 | # but keep track of directories ending in .cache
211 | !*.[Cc]ache/
212 |
213 | # Others
214 | ClientBin/
215 | ~$*
216 | *~
217 | *.dbmdl
218 | *.dbproj.schemaview
219 | *.jfm
220 | *.pfx
221 | *.publishsettings
222 | orleans.codegen.cs
223 |
224 | # Including strong name files can present a security risk
225 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
226 | #*.snk
227 |
228 | # Since there are multiple workflows, uncomment next line to ignore bower_components
229 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
230 | #bower_components/
231 |
232 | # RIA/Silverlight projects
233 | Generated_Code/
234 |
235 | # Backup & report files from converting an old project file
236 | # to a newer Visual Studio version. Backup files are not needed,
237 | # because we have git ;-)
238 | _UpgradeReport_Files/
239 | Backup*/
240 | UpgradeLog*.XML
241 | UpgradeLog*.htm
242 | ServiceFabricBackup/
243 | *.rptproj.bak
244 |
245 | # SQL Server files
246 | *.mdf
247 | *.ldf
248 | *.ndf
249 |
250 | # Business Intelligence projects
251 | *.rdl.data
252 | *.bim.layout
253 | *.bim_*.settings
254 | *.rptproj.rsuser
255 |
256 | # Microsoft Fakes
257 | FakesAssemblies/
258 |
259 | # GhostDoc plugin setting file
260 | *.GhostDoc.xml
261 |
262 | # Node.js Tools for Visual Studio
263 | .ntvs_analysis.dat
264 | node_modules/
265 |
266 | # Visual Studio 6 build log
267 | *.plg
268 |
269 | # Visual Studio 6 workspace options file
270 | *.opt
271 |
272 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
273 | *.vbw
274 |
275 | # Visual Studio LightSwitch build output
276 | **/*.HTMLClient/GeneratedArtifacts
277 | **/*.DesktopClient/GeneratedArtifacts
278 | **/*.DesktopClient/ModelManifest.xml
279 | **/*.Server/GeneratedArtifacts
280 | **/*.Server/ModelManifest.xml
281 | _Pvt_Extensions
282 |
283 | # Paket dependency manager
284 | .paket/paket.exe
285 | paket-files/
286 |
287 | # FAKE - F# Make
288 | .fake/
289 |
290 | # JetBrains Rider
291 | .idea/
292 | *.sln.iml
293 |
294 | # CodeRush
295 | .cr/
296 |
297 | # Python Tools for Visual Studio (PTVS)
298 | __pycache__/
299 | *.pyc
300 |
301 | # Cake - Uncomment if you are using it
302 | # tools/**
303 | # !tools/packages.config
304 |
305 | # Tabs Studio
306 | *.tss
307 |
308 | # Telerik's JustMock configuration file
309 | *.jmconfig
310 |
311 | # BizTalk build output
312 | *.btp.cs
313 | *.btm.cs
314 | *.odx.cs
315 | *.xsd.cs
316 |
317 | # OpenCover UI analysis results
318 | OpenCover/
319 |
320 | # Azure Stream Analytics local run output
321 | ASALocalRun/
322 |
323 | # MSBuild Binary and Structured Log
324 | *.binlog
325 |
326 | # NVidia Nsight GPU debugger configuration file
327 | *.nvuser
328 |
329 | # MFractors (Xamarin productivity tool) working folder
330 | .mfractor/
331 |
332 |
333 | # Misc
334 | *.dylib
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright 2018-2019 The simdjson authors
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SimdJsonSharp: Parsing gigabytes of JSON per second
2 | C# version of [lemire/simdjson](https://github.com/lemire/simdjson) (by Daniel Lemire and Geoff Langdale - https://arxiv.org/abs/1902.08318) fully ported from C to C#,
3 | I tried to keep the same format and API). The library accelerates JSON parsing and minification using
4 | SIMD instructions (AVX2). C# version uses `System.Runtime.Intrinsics` API.
5 |
6 | **UPD:** Now it's also available as a set of pinvokes on top of the native lib as a .NETStandard 2.0 library,
7 | thus there are two implementations:
8 | 1) [1.5.0](https://www.nuget.org/packages/SimdJsonSharp.Managed) Fully managed netcoreapp3.0 library (100% port from C to C#)
9 | 2) [1.7.0](https://www.nuget.org/packages/SimdJsonSharp.Bindings) netstandard2.0 library with native lib (bindings are generated via [xoofx/CppAst](https://github.com/xoofx/CppAst))
10 |
11 | ## Benchmarks
12 | The following [benchmark](https://github.com/EgorBo/SimdJsonSharp/blob/master/benchmarks/CountTokens.cs) compares `SimdJsonSharp` with .NET Core 3.0 `Utf8JsonReader`, `Json.NET` and `SpanJson` libraries.
13 | Test json files can be found [here](https://github.com/lemire/simdjson/tree/master/jsonexamples).
14 |
15 | ### 1. Parse doubles
16 | Open [canada.json](https://raw.githubusercontent.com/lemire/simdjson/master/jsonexamples/canada.json) and parse all coordinates as `System.Double`:
17 | ```
18 | | Method | fileName | fileSize | Mean | Ratio |
19 | |---------------- |------------- |-------------|----------:|------:|
20 | | SimdJson | canada.json | 2,251.05 Kb | 4,733 ms | 1.00 |
21 | | Utf8JsonReader | canada.json | 2,251.05 Kb | 56,692 ms | 11.98 |
22 | | JsonNet | canada.json | 2,251.05 Kb | 70,078 ms | 14.81 |
23 | | SpanJsonUtf8 | canada.json | 2,251.05 Kb | 54,878 ms | 11.60 |
24 | ```
25 |
26 | ### 2. Count all tokens
27 | ```
28 | | Method | fileName | fileSize | Mean | Ratio |
29 | |------------------ |------------------- |------------ |-------------:|------:|
30 | | SimdJson | apache_builds.json | 127.28 Kb | 99.28 us | 1.00 |
31 | | Utf8JsonReader | apache_builds.json | 127.28 Kb | 226.42 us | 2.28 |
32 | | JsonNet | apache_builds.json | 127.28 Kb | 461.30 us | 4.64 |
33 | | SpanJsonUtf8 | apache_builds.json | 127.28 Kb | 168.08 us | 1.69 |
34 | | | | | | |
35 | | SimdJson | canada.json | 2,251.05 Kb | 4,494.44 us | 1.00 |
36 | | Utf8JsonReader | canada.json | 2,251.05 Kb | 6,308.01 us | 1.40 |
37 | | JsonNet | canada.json | 2,251.05 Kb | 67,718.12 us | 15.06 |
38 | | SpanJsonUtf8 | canada.json | 2,251.05 Kb | 6,679.82 us | 1.49 |
39 | | | | | | |
40 | | SimdJson | citm_catalog.json | 1,727.20 Kb | 1,572.78 us | 1.00 |
41 | | Utf8JsonReader | citm_catalog.json | 1,727.20 Kb | 3,786.10 us | 2.41 |
42 | | JsonNet | citm_catalog.json | 1,727.20 Kb | 5,903.38 us | 3.75 |
43 | | SpanJsonUtf8 | citm_catalog.json | 1,727.20 Kb | 3,021.13 us | 1.92 |
44 | | | | | | |
45 | | SimdJson | github_events.json | 65.13 Kb | 46.01 us | 1.00 |
46 | | Utf8JsonReader | github_events.json | 65.13 Kb | 113.80 us | 2.47 |
47 | | JsonNet | github_events.json | 65.13 Kb | 214.01 us | 4.65 |
48 | | SpanJsonUtf8 | github_events.json | 65.13 Kb | 89.09 us | 1.94 |
49 | | | | | | |
50 | | SimdJson | gsoc-2018.json | 3,327.83 Kb | 2,209.42 us | 1.00 |
51 | | Utf8JsonReader | gsoc-2018.json | 3,327.83 Kb | 4,010.10 us | 1.82 |
52 | | JsonNet | gsoc-2018.json | 3,327.83 Kb | 6,729.44 us | 3.05 |
53 | | SpanJsonUtf8 | gsoc-2018.json | 3,327.83 Kb | 2,759.59 us | 1.25 |
54 | | | | | | |
55 | | SimdJson | instruments.json | 220.35 Kb | 257.78 us | 1.00 |
56 | | Utf8JsonReader | instruments.json | 220.35 Kb | 594.22 us | 2.31 |
57 | | JsonNet | instruments.json | 220.35 Kb | 980.42 us | 3.80 |
58 | | SpanJsonUtf8 | instruments.json | 220.35 Kb | 409.47 us | 1.59 |
59 | | | | | | |
60 | | SimdJson | truenull.json | 12.00 Kb | 16,032.6 ns | 1.00 |
61 | | Utf8JsonReader | truenull.json | 12.00 Kb | 58,365.2 ns | 3.64 |
62 | | JsonNet | truenull.json | 12.00 Kb | 60,977.3 ns | 3.80 |
63 | | SpanJsonUtf8 | truenull.json | 12.00 Kb | 24,069.2 ns | 1.50 |
64 | ```
65 | ### 3. Json minification:
66 | ```
67 | | Method | fileName | fileSize | Mean | Ratio |
68 | |---------------------- |------------------- |------------ |-------------:|------:|
69 | | SimdJsonNoValidation | apache_builds.json | 127.28 Kb | 186.8 us | 1.00 |
70 | | SimdJson | apache_builds.json | 127.28 Kb | 262.5 us | 1.41 |
71 | | JsonNet | apache_builds.json | 127.28 Kb | 1,802.6 us | 9.65 |
72 | | | | | | |
73 | | SimdJsonNoValidation | canada.json | 2,251.05 Kb | 4,130.7 us | 1.00 |
74 | | SimdJson | canada.json | 2,251.05 Kb | 7,940.7 us | 1.92 |
75 | | JsonNet | canada.json | 2,251.05 Kb | 181,884.0 us | 44.06 |
76 | | | | | | |
77 | | SimdJsonNoValidation | citm_catalog.json | 1,727.20 Kb | 2,346.9 us | 1.00 |
78 | | SimdJson | citm_catalog.json | 1,727.20 Kb | 4,064.0 us | 1.75 |
79 | | JsonNet | citm_catalog.json | 1,727.20 Kb | 34,831.0 us | 14.84 |
80 | ```
81 |
82 | ## Usage
83 | The C# API is not stable yet and currently fully copies the original C-style API
84 | thus it involves some `Unsafe` magic including pointers.
85 |
86 | Add nuget package [SimdJsonSharp.Managed](https://www.nuget.org/packages/SimdJsonSharp.Managed) (for .NET Core 3.0)
87 | or [SimdJsonSharp.Bindings](https://www.nuget.org/packages/SimdJsonSharp.Bindings) for a .NETStandard 2.0 package (.NET 4.x, .NET Core 2.x, etc).
88 | ```
89 | dotnet add package SimdJsonSharp.Bindings
90 | or
91 | dotnet add package SimdJsonSharp.Managed
92 | ```
93 |
94 | The following sample parses a file and iterate numeric tokens
95 | ```csharp
96 | byte[] bytes = File.ReadAllBytes(somefile);
97 | fixed (byte* ptr = bytes) // pin bytes while we are working on them
98 | using (ParsedJson doc = SimdJson.ParseJson(ptr, bytes.Length))
99 | using (var iterator = doc.CreateIterator())
100 | {
101 | while (iterator.MoveForward())
102 | {
103 | if (iterator.GetTokenType() == JsonTokenType.Number)
104 | Console.WriteLine("integer: " + iterator.GetInteger());
105 | }
106 | }
107 | ```
108 | **UPD:** for `SimdJsonSharp.Bindings` types are postfixed with 'N', e.g. `ParsedJsonN`
109 |
110 | As you can see the API looks similiar to `Utf8JsonReader` that was introduced recently in .NET Core 3.0
111 |
112 | Also it's possible to just validate JSON or minify it (remove whitespaces, etc):
113 | ```csharp
114 | string someJson = ...;
115 | string minifiedJson = SimdJson.MinifyJson(someJson);
116 | ```
117 |
118 | ## Requirements
119 | * AVX2 enabled CPU
120 |
--------------------------------------------------------------------------------
/benchmarks/Benchmarks.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.0
5 | latest
6 | Exe
7 | true
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/benchmarks/BenchmarksBase.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using BenchmarkDotNet.Attributes;
6 | using BenchmarkDotNet.Configs;
7 | using BenchmarkDotNet.Jobs;
8 |
9 | namespace Benchmarks
10 | {
11 | [Config(typeof(ConfigWithCustomEnvVars))]
12 | public class BenchmarksBase
13 | {
14 | private class ConfigWithCustomEnvVars : ManualConfig
15 | {
16 | private const string JitTieredCompilation = "COMPlus_TieredCompilation";
17 |
18 | public ConfigWithCustomEnvVars()
19 | {
20 | Add(Job.ShortRun.With(new[] { new EnvironmentVariable(JitTieredCompilation, "1") }));
21 | Add(Job.ShortRun.With(new[] { new EnvironmentVariable(JitTieredCompilation, "0") }));
22 | }
23 | }
24 |
25 | public IEnumerable TestData()
26 | {
27 | string jsonExamples = Environment.GetEnvironmentVariable("pathToJsonExamples");
28 | string[] files = Directory.GetFiles(jsonExamples, "*.json", SearchOption.AllDirectories).ToArray();
29 |
30 | foreach (var file in files)
31 | {
32 | byte[] bytes = File.ReadAllBytes(file);
33 | yield return new object[]
34 | {
35 | bytes,
36 | Path.GetFileName(file),
37 | Math.Round(bytes.Length / 1000.0, 2).ToString("N") + " Kb"
38 | };
39 | }
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/benchmarks/CountStrings.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.Text.Json;
3 | using BenchmarkDotNet.Attributes;
4 | using Newtonsoft.Json;
5 | using SimdJsonSharp;
6 |
7 | namespace Benchmarks
8 | {
9 | public class CountStrings : BenchmarksBase
10 | {
11 | [Benchmark(Baseline = true)]
12 | [ArgumentsSource(nameof(TestData))]
13 | public unsafe ulong SimdJsonUtf16(byte[] data, string fileName, string fileSize)
14 | {
15 | ulong wordsCount = 0;
16 | fixed (byte* dataPtr = data)
17 | {
18 | using (ParsedJson doc = SimdJson.ParseJson(dataPtr, data.Length))
19 | using (var iterator = new ParsedJsonIterator(doc))
20 | {
21 | while (iterator.MoveForward())
22 | {
23 | if (iterator.IsString)
24 | {
25 | if (iterator.GetUtf16String().StartsWith('a'))
26 | wordsCount++;
27 | }
28 | }
29 | }
30 | }
31 |
32 | return wordsCount;
33 | }
34 |
35 | [Benchmark]
36 | [ArgumentsSource(nameof(TestData))]
37 | public unsafe ulong SimdJsonNUtf16(byte[] data, string fileName, string fileSize)
38 | {
39 | ulong wordsCount = 0;
40 | fixed (byte* dataPtr = data)
41 | {
42 | using (ParsedJsonN doc = SimdJsonN.ParseJson(dataPtr, data.Length))
43 | using (var iterator = new ParsedJsonIteratorN(doc))
44 | {
45 | while (iterator.MoveForward())
46 | {
47 | if (iterator.IsString())
48 | {
49 | if (iterator.GetUtf16String().StartsWith('a')) // UTF16 in SimdJsonN is expected to be slow for now (see https://github.com/lemire/simdjson/pull/101)
50 | wordsCount++;
51 | }
52 | }
53 | }
54 | }
55 |
56 | return wordsCount;
57 | }
58 | [Benchmark]
59 | [ArgumentsSource(nameof(TestData))]
60 | public unsafe ulong SimdJsonUtf8(byte[] data, string fileName, string fileSize)
61 | {
62 | ulong wordsCount = 0;
63 | fixed (byte* dataPtr = data)
64 | {
65 | using (ParsedJson doc = SimdJson.ParseJson(dataPtr, data.Length))
66 | using (var iterator = new ParsedJsonIterator(doc))
67 | {
68 | while (iterator.MoveForward())
69 | {
70 | if (iterator.IsString)
71 | {
72 | if (*iterator.GetUtf8String() == (byte)'a')
73 | wordsCount++;
74 | }
75 | }
76 | }
77 | }
78 |
79 | return wordsCount;
80 | }
81 |
82 | //[Benchmark]
83 | [ArgumentsSource(nameof(TestData))]
84 | public unsafe ulong SimdJsonNUtf8(byte[] data, string fileName, string fileSize)
85 | {
86 | ulong wordsCount = 0;
87 | fixed (byte* dataPtr = data)
88 | {
89 | using (ParsedJsonN doc = SimdJsonN.ParseJson(dataPtr, data.Length))
90 | using (var iterator = new ParsedJsonIteratorN(doc))
91 | {
92 | while (iterator.MoveForward())
93 | {
94 | if (iterator.IsString())
95 | {
96 | if (*iterator.GetUtf8String() == (byte)'a')
97 | wordsCount++;
98 | }
99 | }
100 | }
101 | }
102 |
103 | return wordsCount;
104 | }
105 |
106 | [Benchmark]
107 | [ArgumentsSource(nameof(TestData))]
108 | public ulong _Utf8JsonReader(byte[] data, string fileName, string fileSize)
109 | {
110 | ulong wordsCount = 0;
111 | var reader = new Utf8JsonReader(data, true, default);
112 | while (reader.Read())
113 | {
114 | if (reader.TokenType == JsonTokenType.String)
115 | {
116 | // count all strings starting with 'a'
117 | if (reader.GetString().StartsWith('a'))
118 | wordsCount++;
119 | }
120 | }
121 |
122 | return wordsCount;
123 | }
124 |
125 | [Benchmark]
126 | [ArgumentsSource(nameof(TestData))]
127 | public ulong JsonNet(byte[] data, string fileName, string fileSize)
128 | {
129 | ulong wordsCount = 0;
130 | using (var streamReader = new StreamReader(new MemoryStream(data)))
131 | {
132 | JsonTextReader reader = new JsonTextReader(streamReader);
133 | while (reader.Read())
134 | {
135 | if (reader.TokenType == JsonToken.String)
136 | {
137 | // count all strings starting with 'a'
138 | if (reader.ReadAsString().StartsWith('a'))
139 | wordsCount++;
140 | }
141 | }
142 | }
143 |
144 | return wordsCount;
145 | }
146 |
147 | [Benchmark]
148 | [ArgumentsSource(nameof(TestData))]
149 | public ulong SpanJsonUtf8(byte[] data, string fileName, string fileSize)
150 | {
151 | ulong wordsCount = 0;
152 | var reader = new SpanJson.JsonReader(data);
153 | SpanJson.JsonToken token;
154 | while ((token = reader.ReadUtf8NextToken()) != SpanJson.JsonToken.None)
155 | {
156 | if (token == SpanJson.JsonToken.String)
157 | {
158 | // count all strings starting with 'a'
159 | if (reader.ReadString().StartsWith('a'))
160 | wordsCount++;
161 | }
162 | reader.SkipNextUtf8Value(token);
163 | }
164 |
165 | return wordsCount;
166 | }
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/benchmarks/CountTokens.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.Text.Json;
3 | using BenchmarkDotNet.Attributes;
4 | using Newtonsoft.Json;
5 | using SimdJsonSharp;
6 |
7 | namespace Benchmarks
8 | {
9 | public class CountTokens : BenchmarksBase
10 | {
11 | [Benchmark(Baseline = true)]
12 | [ArgumentsSource(nameof(TestData))]
13 | public unsafe ulong _SimdJson(byte[] data, string fileName, string fileSize)
14 | {
15 | ulong numbersCount = 0;
16 | fixed (byte* dataPtr = data)
17 | {
18 | using (ParsedJson doc = SimdJson.ParseJson(dataPtr, data.Length))
19 | using (var iterator = new ParsedJsonIterator(doc))
20 | {
21 | while (iterator.MoveForward())
22 | if (iterator.IsDouble || iterator.IsInteger)
23 | numbersCount++;
24 | }
25 | }
26 |
27 | return numbersCount;
28 | }
29 |
30 | [Benchmark]
31 | [ArgumentsSource(nameof(TestData))]
32 | public unsafe ulong _SimdJsonN(byte[] data, string fileName, string fileSize)
33 | {
34 | ulong numbersCount = 0;
35 | fixed (byte* dataPtr = data)
36 | {
37 | using (ParsedJsonN doc = SimdJsonN.ParseJson(dataPtr, data.Length))
38 | using (var iterator = new ParsedJsonIteratorN(doc))
39 | {
40 | while (iterator.MoveForward())
41 | //if (iterator.IsDouble || iterator.IsInteger)
42 | numbersCount++;
43 | }
44 | }
45 |
46 | return numbersCount;
47 | }
48 |
49 | [Benchmark]
50 | [ArgumentsSource(nameof(TestData))]
51 | public ulong _Utf8JsonReader(byte[] data, string fileName, string fileSize)
52 | {
53 | ulong numbersCount = 0;
54 | var reader = new Utf8JsonReader(data, true, default);
55 | while (reader.Read())
56 | {
57 | if (reader.TokenType == JsonTokenType.Number)
58 | numbersCount++;
59 | }
60 |
61 | return numbersCount;
62 | }
63 |
64 | [Benchmark]
65 | [ArgumentsSource(nameof(TestData))]
66 | public ulong JsonNet(byte[] data, string fileName, string fileSize)
67 | {
68 | ulong numbersCount = 0;
69 | using (var streamReader = new StreamReader(new MemoryStream(data)))
70 | {
71 | JsonTextReader reader = new JsonTextReader(streamReader);
72 | while (reader.Read())
73 | {
74 | if (reader.TokenType == JsonToken.Float ||
75 | reader.TokenType == JsonToken.Integer)
76 | numbersCount++;
77 | }
78 | }
79 |
80 | return numbersCount;
81 | }
82 |
83 | [Benchmark]
84 | [ArgumentsSource(nameof(TestData))]
85 | public ulong SpanJsonUtf8(byte[] data, string fileName, string fileSize)
86 | {
87 | ulong numbersCount = 0;
88 | var reader = new SpanJson.JsonReader(data);
89 | SpanJson.JsonToken token;
90 | while ((token = reader.ReadUtf8NextToken()) != SpanJson.JsonToken.None)
91 | {
92 | if (token == SpanJson.JsonToken.Number)
93 | numbersCount++;
94 | reader.SkipNextUtf8Value(token);
95 | }
96 |
97 | return numbersCount;
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/benchmarks/MinifyBenchmarks.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using BenchmarkDotNet.Attributes;
4 | using Newtonsoft.Json.Linq;
5 | using SimdJsonSharp;
6 |
7 | namespace Benchmarks
8 | {
9 | public class MinifyBenchmarks : BenchmarksBase
10 | {
11 | [Benchmark(Baseline = true)]
12 | [ArgumentsSource(nameof(TestData))]
13 | public string SimdJson_NoValidation(byte[] jsonData, string fileName, string fileSize)
14 | {
15 | string json = Encoding.UTF8.GetString(jsonData);
16 | return SimdJson.MinifyJson(json);
17 | }
18 |
19 | [Benchmark]
20 | [ArgumentsSource(nameof(TestData))]
21 | public string SimdJsonN_NoValidation(byte[] jsonData, string fileName, string fileSize)
22 | {
23 | string json = Encoding.UTF8.GetString(jsonData);
24 | return SimdJsonN.MinifyJson(json);
25 | }
26 |
27 | [Benchmark]
28 | [ArgumentsSource(nameof(TestData))]
29 | public unsafe string SimdJson_Validation(byte[] jsonData, string fileName, string fileSize)
30 | {
31 | string json = Encoding.UTF8.GetString(jsonData);
32 |
33 | // Validate json first
34 | // this step is not required for minification, it's here because JSON.NET also does validation
35 | fixed (byte* dataPtr = jsonData)
36 | {
37 | using (var doc = SimdJson.ParseJson(dataPtr, jsonData.Length))
38 | if (!doc.IsValid)
39 | throw new InvalidOperationException("Json is invalid");
40 | }
41 |
42 | return SimdJson.MinifyJson(json);
43 | }
44 |
45 | [Benchmark]
46 | [ArgumentsSource(nameof(TestData))]
47 | public unsafe string SimdJsonN_Validation(byte[] jsonData, string fileName, string fileSize)
48 | {
49 | string json = Encoding.UTF8.GetString(jsonData);
50 |
51 | // Validate json first
52 | // this step is not required for minification, it's here because JSON.NET also does validation
53 | fixed (byte* dataPtr = jsonData)
54 | {
55 | using (var doc = SimdJsonN.ParseJson(dataPtr, jsonData.Length))
56 | if (!doc.IsValid())
57 | throw new InvalidOperationException("Json is invalid");
58 | }
59 |
60 | return SimdJsonN.MinifyJson(json);
61 | }
62 |
63 | [Benchmark]
64 | [ArgumentsSource(nameof(TestData))]
65 | public string JsonNet(byte[] jsonData, string fileName, string fileSize)
66 | {
67 | string json = Encoding.UTF8.GetString(jsonData);
68 | return JObject.Parse(json).ToString(Newtonsoft.Json.Formatting.None);
69 | }
70 |
71 | [Benchmark]
72 | [ArgumentsSource(nameof(TestData))]
73 | public string SpanJsonUtf16(byte[] jsonData, string fileName, string fileSize)
74 | {
75 | string json = Encoding.UTF8.GetString(jsonData);
76 | return SpanJson.JsonSerializer.Minifier.Minify(json);
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/benchmarks/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Reflection;
4 | using BenchmarkDotNet.Running;
5 |
6 | namespace Benchmarks
7 | {
8 | public class Program
9 | {
10 | public static void Main(string[] args)
11 | {
12 | const string envVariable = "pathToJsonExamples";
13 | if (Environment.GetEnvironmentVariable(envVariable) == null)
14 | {
15 | string root = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
16 | string path = Path.Join(Directory.GetParent(root).Parent.Parent.Parent.FullName, "jsonexamples");
17 | Environment.SetEnvironmentVariable(envVariable, path);
18 | }
19 | BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/benchmarks/Report-as-of-3.12.2019.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EgorBo/SimdJsonSharp/0786341a50919f33c2a86a47d4a1848713c9d60e/benchmarks/Report-as-of-3.12.2019.xlsx
--------------------------------------------------------------------------------
/images/logo.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EgorBo/SimdJsonSharp/0786341a50919f33c2a86a47d4a1848713c9d60e/images/logo.ico
--------------------------------------------------------------------------------
/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/EgorBo/SimdJsonSharp/0786341a50919f33c2a86a47d4a1848713c9d60e/images/logo.png
--------------------------------------------------------------------------------
/jsonexamples/small/adversarial.json:
--------------------------------------------------------------------------------
1 | {
2 | "\"Name rue": [
3 | [ 116,
4 | "\"",
5 | 234,
6 | "true",
7 | false ]
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/jsonexamples/small/demo.json:
--------------------------------------------------------------------------------
1 | {
2 | "Image": {
3 | "Width": 800,
4 | "Height": 600,
5 | "Title": "View from 15th Floor",
6 | "Thumbnail": {
7 | "Url": "http://www.example.com/image/481989943",
8 | "Height": 125,
9 | "Width": 100
10 | },
11 | "Animated" : false,
12 | "IDs": [116, 943, 234, 38793]
13 | }
14 | }
15 |
16 |
--------------------------------------------------------------------------------
/jsonexamples/small/flatadversarial.json:
--------------------------------------------------------------------------------
1 | { "\"Name": [ 116,"\\\"", 234, "true", false ], "t": 1.0e+10}
2 |
--------------------------------------------------------------------------------
/jsonexamples/small/jsoniter_scala/README.md:
--------------------------------------------------------------------------------
1 | Files from https://github.com/plokhotnyuk/jsoniter-scala/tree/master/jsoniter-scala-benchmark/src/main/resources/com/github/plokhotnyuk/jsoniter_scala/benchmark
2 |
3 | See issue "Lower performance on small files":
4 | https://github.com/lemire/simdjson/issues/70
5 |
--------------------------------------------------------------------------------
/jsonexamples/small/jsoniter_scala/che-1.geo.json:
--------------------------------------------------------------------------------
1 | {"type":"FeatureCollection","features":[{"type":"Feature","properties":{"cca2":"ch"},"geometry":{"type":"Polygon","coordinates":[[[7.697223,47.543327],[7.769722,47.553329],[7.906388,47.558052],[7.91361,47.553886],[7.918888,47.552773],[7.931944,47.552216],[8.033333,47.556107],[8.086666,47.560555],[8.092222,47.561661],[8.099722,47.565552],[8.102499,47.568329],[8.103888,47.571938],[8.108055,47.578331],[8.110832,47.581108],[8.185276,47.617218],[8.193333,47.620827],[8.198889,47.621666],[8.205555,47.621666],[8.240833,47.619438],[8.283333,47.613052],[8.288055,47.611664],[8.2925,47.605827],[8.390833,47.579994],[8.435833,47.573608],[8.464998,47.602493],[8.477499,47.612221],[8.51111,47.631104],[8.519999,47.634163],[8.531387,47.632774],[8.558332,47.623329],[8.562222,47.621384],[8.565554,47.614441],[8.56943,47.598537],[8.57642,47.59137],[8.591389,47.599442],[8.594721,47.601662],[8.629166,47.646111],[8.630833,47.649719],[8.629444,47.653328],[8.626944,47.656105],[8.620832,47.66111],[8.610254,47.667732],[8.580555,47.66861],[8.551388,47.668327],[8.545832,47.667496],[8.536943,47.664444],[8.528055,47.656944],[8.525833,47.65361],[8.518332,47.649719],[8.495277,47.647217],[8.475555,47.646942],[8.424721,47.669441],[8.413332,47.678329],[8.407221,47.699715],[8.406666,47.703888],[8.473331,47.767494],[8.47611,47.769997],[8.479443,47.772499],[8.559721,47.806389],[8.566111,47.806938],[8.60861,47.804161],[8.614721,47.803604],[8.661388,47.79805],[8.685555,47.786659],[8.734999,47.761383],[8.736944,47.758049],[8.736944,47.75444],[8.734999,47.713882],[8.734165,47.709717],[8.730698,47.705673],[8.729166,47.703888],[8.720222,47.696625],[8.745277,47.695],[8.761389,47.692215],[8.800133,47.681725],[8.774721,47.710274],[8.772778,47.713333],[8.772221,47.717499],[8.777777,47.722771],[8.799999,47.735275],[8.804165,47.737221],[8.808887,47.735832],[8.835278,47.718048],[8.855833,47.698883],[8.883299,47.654148],[8.892776,47.651382],[8.904999,47.650276],[8.917776,47.650551],[8.934166,47.653053],[8.947777,47.657494],[8.973331,47.667496],[8.985554,47.672775],[8.996666,47.679161],[9.004999,47.682495],[9.024166,47.687775],[9.0425,47.688889],[9.078333,47.685829],[9.086943,47.684998],[9.261095,47.662842],[9.478322,47.575851],[9.566724,47.540451],[9.557772,47.505783],[9.559721,47.499718],[9.562222,47.496666],[9.567499,47.491104],[9.590277,47.470276],[9.594166,47.46833],[9.611666,47.468887],[9.646944,47.460274],[9.65111,47.458328],[9.65361,47.455551],[9.673332,47.398605],[9.673054,47.394997],[9.669998,47.387772],[9.664999,47.381386],[9.650555,47.373055],[9.641666,47.369995],[9.631388,47.36805],[9.625832,47.367218],[9.624422,47.367252],[9.614443,47.367493],[9.605276,47.359993],[9.599722,47.354164],[9.539999,47.284164],[9.533569,47.274544],[9.502222,47.231384],[9.491388,47.215271],[9.485832,47.200272],[9.484165,47.192215],[9.484444,47.179718],[9.489721,47.16555],[9.49861,47.15361],[9.505554,47.139999],[9.511389,47.121666],[9.512777,47.109444],[9.512499,47.100273],[9.510277,47.092499],[9.474637,47.057457],[9.485277,47.061104],[9.506388,47.06472],[9.538055,47.07],[9.544722,47.07],[9.598635,47.063835],[9.6325,47.056664],[9.719444,47.050278],[9.870277,47.023598],[9.875555,47.022491],[9.891943,47.003876],[9.893055,47.000267],[9.889444,46.993324],[9.880833,46.98082],[9.875555,46.970543],[9.873333,46.962769],[9.87361,46.958603],[9.87611,46.941658],[9.879444,46.939156],[9.934999,46.912773],[10.058887,46.866386],[10.109444,46.850273],[10.122776,46.849716],[10.140276,46.851105],[10.141807,46.851341],[10.15111,46.852776],[10.170555,46.857216],[10.22361,46.874992],[10.231388,46.878883],[10.313332,46.933609],[10.323332,46.955551],[10.345833,46.986382],[10.353611,46.994995],[10.357222,46.997215],[10.385555,47.002777],[10.391109,47.003609],[10.400833,47.001106],[10.429998,46.984161],[10.487499,46.937775],[10.488913,46.934212],[10.471235,46.871353],[10.447498,46.763054],[10.470833,46.635826],[10.486387,46.619438],[10.486666,46.615273],[10.486111,46.594719],[10.485277,46.590553],[10.475555,46.562492],[10.471109,46.551666],[10.465277,46.546387],[10.457531,46.542503],[10.44972,46.539162],[10.337221,46.549438],[10.305555,46.553886],[10.301666,46.555832],[10.247499,46.583885],[10.245554,46.587219],[10.245277,46.59111],[10.246944,46.599442],[10.253054,46.613884],[10.254166,46.61805],[10.253611,46.622215],[10.241665,46.636665],[10.238609,46.638885],[10.233332,46.639999],[10.18111,46.632217],[10.119165,46.611382],[10.0525,46.543053],[10.050278,46.539993],[10.044722,46.507217],[10.044167,46.498055],[10.044443,46.453331],[10.044998,46.449165],[10.046665,46.445831],[10.049166,46.443054],[10.055555,46.438332],[10.067221,46.432495],[10.08861,46.424164],[10.092777,46.423332],[10.153889,46.390274],[10.177221,46.272499],[10.176388,46.268326],[10.172499,46.257217],[10.169722,46.25444],[10.140833,46.23333],[10.133888,46.228882],[10.129999,46.227219],[10.078609,46.220551],[10.072777,46.220276],[10.066666,46.221107],[10.063055,46.222771],[10.05722,46.22805],[9.994999,46.291664],[9.982498,46.331383],[9.981943,46.334717],[9.991388,46.346664],[9.99361,46.354439],[9.991943,46.357773],[9.984722,46.361938],[9.949999,46.379166],[9.943888,46.379997],[9.91111,46.383331],[9.904999,46.383049],[9.852777,46.36972],[9.813055,46.35833],[9.770555,46.342209],[9.714998,46.302773],[9.708332,46.298332],[9.696943,46.297218],[9.624722,46.291939],[9.581944,46.296944],[9.547222,46.30555],[9.5425,46.306938],[9.521387,46.319717],[9.458611,46.38472],[9.456665,46.387772],[9.450277,46.426666],[9.455,46.472496],[9.372776,46.5075],[9.360832,46.508606],[9.302221,46.504715],[9.296944,46.503883],[9.288887,46.500275],[9.281944,46.495827],[9.273611,46.487778],[9.249722,46.448051],[9.25,46.440277],[9.253054,46.433327],[9.256943,46.431389],[9.272778,46.428329],[9.280554,46.423332],[9.282221,46.419998],[9.296944,46.35305],[9.297499,46.348885],[9.293333,46.32666],[9.291943,46.323051],[9.276667,46.292496],[9.24341,46.23671],[9.238609,46.230553],[9.189444,46.186661],[9.180555,46.179161],[9.177221,46.176941],[9.158609,46.171661],[9.144439,46.168049],[9.132221,46.160271],[9.083332,46.121109],[9.035831,46.05722],[9.016666,46.022499],[8.998055,45.976944],[8.996666,45.973328],[9.0175,45.94416],[9.025,45.935829],[9.031944,45.931664],[9.066666,45.924164],[9.079443,45.915833],[9.081388,45.912498],[9.085554,45.901939],[9.085554,45.899162],[9.083887,45.895554],[9.036665,45.837776],[8.998333,45.829437],[8.951111,45.845276],[8.93611,45.868889],[8.936666,45.872772],[8.936388,45.876938],[8.926666,45.900833],[8.9,45.949715],[8.895555,45.955826],[8.826666,45.984161],[8.813055,45.988609],[8.816944,46.031662],[8.82361,46.03611],[8.849998,46.054443],[8.852499,46.056938],[8.853333,46.061104],[8.850555,46.072495],[8.846666,46.079163],[8.844166,46.08194],[8.835278,46.089439],[8.826111,46.096664],[8.818333,46.100555],[8.747221,46.121109],[8.728855,46.108589],[8.72361,46.105553],[8.714998,46.102493],[8.701111,46.10083],[8.691944,46.101387],[8.617777,46.120277],[8.613888,46.122215],[8.460554,46.23333],[8.445555,46.245827],[8.444443,46.248604],[8.434166,46.291107],[8.434999,46.295273],[8.443333,46.317215],[8.447498,46.323326],[8.458332,46.33416],[8.465832,46.36805],[8.46611,46.37722],[8.461666,46.444443],[8.459999,46.452217],[8.451666,46.459999],[8.447498,46.461937],[8.436388,46.463333],[8.430277,46.463051],[8.365276,46.453606],[8.357222,46.449997],[8.30611,46.424721],[8.302776,46.422493],[8.299999,46.419716],[8.139999,46.226105],[8.143888,46.219719],[8.158333,46.188889],[8.159443,46.180832],[8.158888,46.176666],[8.150276,46.153053],[8.148888,46.149437],[8.014721,46.013329],[8.00861,46.008331],[7.998055,46.00222],[7.973055,45.996941],[7.95,45.994164],[7.911111,45.994164],[7.902499,45.991104],[7.881944,45.977776],[7.876666,45.972496],[7.866388,45.948326],[7.855742,45.919052],[7.8483,45.918755],[7.783889,45.923607],[7.743333,45.93222],[7.709167,45.943329],[7.653055,45.979996],[7.647499,45.98111],[7.536666,45.981667],[7.458055,45.941109],[7.429722,45.929443],[7.393332,45.916107],[7.378888,45.914719],[7.338888,45.920555],[7.300278,45.923882],[7.295555,45.92305],[7.291111,45.921944],[7.230277,45.898048],[7.196944,45.882217],[7.188611,45.879166],[7.183055,45.879166],[7.117499,45.880829],[7.105,45.882217],[7.099444,45.883606],[7.09111,45.887497],[7.077777,45.896942],[7.062778,45.909164],[7.038054,45.931938],[7.030555,45.961937],[7.008611,45.996666],[7.005833,45.999443],[6.933055,46.055275],[6.873888,46.088051],[6.788055,46.14222],[6.783889,46.148048],[6.781111,46.162498],[6.780833,46.166107],[6.799999,46.378326],[6.807016,46.404228],[6.809444,46.415276],[6.808332,46.41861],[6.803055,46.427773],[6.800278,46.43055],[6.791389,46.434166],[6.737778,46.447495],[6.702777,46.45472],[6.633611,46.464165],[6.52,46.45916],[6.510278,46.457771],[6.491944,46.453049],[6.328333,46.406944],[6.31111,46.401382],[6.295555,46.394165],[6.246388,46.357773],[6.243333,46.354996],[6.236388,46.344719],[6.23,46.333885],[6.225555,46.322495],[6.228055,46.319717],[6.243747,46.31551],[6.271944,46.26194],[6.245555,46.21833],[6.189166,46.173332],[6.185833,46.17083],[6.152222,46.15361],[6.133611,46.149437],[6.12361,46.148048],[5.996388,46.146942],[5.967222,46.201942],[5.96611,46.205276],[5.966666,46.209442],[5.968055,46.212494],[5.981388,46.221939],[6.009166,46.233887],[6.03,46.241386],[6.060833,46.250549],[6.072499,46.249718],[6.0825,46.246666],[6.107778,46.253052],[6.117222,46.260551],[6.119166,46.264442],[6.118055,46.268051],[6.106109,46.297489],[6.115,46.30555],[6.120277,46.311943],[6.154166,46.363052],[6.15861,46.369995],[6.158333,46.373886],[6.157222,46.37722],[6.151667,46.386383],[6.148333,46.388611],[6.111111,46.409721],[6.071111,46.426384],[6.086944,46.44944],[6.135278,46.539719],[6.129722,46.583054],[6.127222,46.585831],[6.127777,46.589996],[6.129999,46.59333],[6.269166,46.682777],[6.346666,46.711388],[6.355,46.714439],[6.366666,46.720551],[6.434999,46.758049],[6.452777,46.774437],[6.4575,46.78083],[6.458611,46.785271],[6.446944,46.839439],[6.460278,46.895828],[6.528333,46.971664],[6.566388,46.979996],[6.620832,46.994438],[6.629722,46.997215],[6.639722,47.004166],[6.678333,47.034164],[6.699444,47.063889],[6.793333,47.130829],[6.849721,47.164989],[6.838888,47.16777],[6.8375,47.171104],[6.839722,47.173607],[6.971666,47.291939],[7.000833,47.364998],[6.980833,47.361664],[6.931389,47.358887],[6.88111,47.356941],[6.879999,47.360275],[6.88111,47.364716],[6.884444,47.372772],[6.990555,47.497215],[7.025,47.508049],[7.14642,47.499054],[7.178333,47.445831],[7.187499,47.442215],[7.241111,47.421944],[7.246944,47.42083],[7.251389,47.421944],[7.275555,47.432495],[7.308332,47.440277],[7.336944,47.439438],[7.343611,47.438606],[7.355897,47.434017],[7.358055,47.433609],[7.3825,47.432495],[7.388333,47.434166],[7.415555,47.445274],[7.433054,47.460548],[7.452777,47.469994],[7.496944,47.494995],[7.502222,47.500549],[7.497222,47.544441],[7.49861,47.54805],[7.501389,47.550552],[7.513055,47.556664],[7.521667,47.559715],[7.546665,47.565552],[7.550833,47.576385],[7.557221,47.581383],[7.567222,47.583611],[7.586944,47.584999],[7.588268,47.58448],[7.640555,47.603882],[7.674444,47.606384],[7.676944,47.603607],[7.671944,47.579437],[7.669999,47.576385],[7.666666,47.574165],[7.621111,47.561104],[7.656111,47.550552],[7.697223,47.543327]],[[8.710255,47.696808],[8.709721,47.70694],[8.708332,47.710548],[8.705,47.713051],[8.698889,47.713608],[8.675278,47.712494],[8.670555,47.711105],[8.670277,47.707497],[8.673298,47.701771],[8.675554,47.697495],[8.678595,47.693344],[8.710255,47.696808]]]}}]}
--------------------------------------------------------------------------------
/jsonexamples/small/jsoniter_scala/che-2.geo.json:
--------------------------------------------------------------------------------
1 | {"features":[{"properties":{"cca2":"ch"},"geometry":{"coordinates":[[[7.697223,47.543327],[7.769722,47.553329],[7.906388,47.558052],[7.91361,47.553886],[7.918888,47.552773],[7.931944,47.552216],[8.033333,47.556107],[8.086666,47.560555],[8.092222,47.561661],[8.099722,47.565552],[8.102499,47.568329],[8.103888,47.571938],[8.108055,47.578331],[8.110832,47.581108],[8.185276,47.617218],[8.193333,47.620827],[8.198889,47.621666],[8.205555,47.621666],[8.240833,47.619438],[8.283333,47.613052],[8.288055,47.611664],[8.2925,47.605827],[8.390833,47.579994],[8.435833,47.573608],[8.464998,47.602493],[8.477499,47.612221],[8.51111,47.631104],[8.519999,47.634163],[8.531387,47.632774],[8.558332,47.623329],[8.562222,47.621384],[8.565554,47.614441],[8.56943,47.598537],[8.57642,47.59137],[8.591389,47.599442],[8.594721,47.601662],[8.629166,47.646111],[8.630833,47.649719],[8.629444,47.653328],[8.626944,47.656105],[8.620832,47.66111],[8.610254,47.667732],[8.580555,47.66861],[8.551388,47.668327],[8.545832,47.667496],[8.536943,47.664444],[8.528055,47.656944],[8.525833,47.65361],[8.518332,47.649719],[8.495277,47.647217],[8.475555,47.646942],[8.424721,47.669441],[8.413332,47.678329],[8.407221,47.699715],[8.406666,47.703888],[8.473331,47.767494],[8.47611,47.769997],[8.479443,47.772499],[8.559721,47.806389],[8.566111,47.806938],[8.60861,47.804161],[8.614721,47.803604],[8.661388,47.79805],[8.685555,47.786659],[8.734999,47.761383],[8.736944,47.758049],[8.736944,47.75444],[8.734999,47.713882],[8.734165,47.709717],[8.730698,47.705673],[8.729166,47.703888],[8.720222,47.696625],[8.745277,47.695],[8.761389,47.692215],[8.800133,47.681725],[8.774721,47.710274],[8.772778,47.713333],[8.772221,47.717499],[8.777777,47.722771],[8.799999,47.735275],[8.804165,47.737221],[8.808887,47.735832],[8.835278,47.718048],[8.855833,47.698883],[8.883299,47.654148],[8.892776,47.651382],[8.904999,47.650276],[8.917776,47.650551],[8.934166,47.653053],[8.947777,47.657494],[8.973331,47.667496],[8.985554,47.672775],[8.996666,47.679161],[9.004999,47.682495],[9.024166,47.687775],[9.0425,47.688889],[9.078333,47.685829],[9.086943,47.684998],[9.261095,47.662842],[9.478322,47.575851],[9.566724,47.540451],[9.557772,47.505783],[9.559721,47.499718],[9.562222,47.496666],[9.567499,47.491104],[9.590277,47.470276],[9.594166,47.46833],[9.611666,47.468887],[9.646944,47.460274],[9.65111,47.458328],[9.65361,47.455551],[9.673332,47.398605],[9.673054,47.394997],[9.669998,47.387772],[9.664999,47.381386],[9.650555,47.373055],[9.641666,47.369995],[9.631388,47.36805],[9.625832,47.367218],[9.624422,47.367252],[9.614443,47.367493],[9.605276,47.359993],[9.599722,47.354164],[9.539999,47.284164],[9.533569,47.274544],[9.502222,47.231384],[9.491388,47.215271],[9.485832,47.200272],[9.484165,47.192215],[9.484444,47.179718],[9.489721,47.16555],[9.49861,47.15361],[9.505554,47.139999],[9.511389,47.121666],[9.512777,47.109444],[9.512499,47.100273],[9.510277,47.092499],[9.474637,47.057457],[9.485277,47.061104],[9.506388,47.06472],[9.538055,47.07],[9.544722,47.07],[9.598635,47.063835],[9.6325,47.056664],[9.719444,47.050278],[9.870277,47.023598],[9.875555,47.022491],[9.891943,47.003876],[9.893055,47.000267],[9.889444,46.993324],[9.880833,46.98082],[9.875555,46.970543],[9.873333,46.962769],[9.87361,46.958603],[9.87611,46.941658],[9.879444,46.939156],[9.934999,46.912773],[10.058887,46.866386],[10.109444,46.850273],[10.122776,46.849716],[10.140276,46.851105],[10.141807,46.851341],[10.15111,46.852776],[10.170555,46.857216],[10.22361,46.874992],[10.231388,46.878883],[10.313332,46.933609],[10.323332,46.955551],[10.345833,46.986382],[10.353611,46.994995],[10.357222,46.997215],[10.385555,47.002777],[10.391109,47.003609],[10.400833,47.001106],[10.429998,46.984161],[10.487499,46.937775],[10.488913,46.934212],[10.471235,46.871353],[10.447498,46.763054],[10.470833,46.635826],[10.486387,46.619438],[10.486666,46.615273],[10.486111,46.594719],[10.485277,46.590553],[10.475555,46.562492],[10.471109,46.551666],[10.465277,46.546387],[10.457531,46.542503],[10.44972,46.539162],[10.337221,46.549438],[10.305555,46.553886],[10.301666,46.555832],[10.247499,46.583885],[10.245554,46.587219],[10.245277,46.59111],[10.246944,46.599442],[10.253054,46.613884],[10.254166,46.61805],[10.253611,46.622215],[10.241665,46.636665],[10.238609,46.638885],[10.233332,46.639999],[10.18111,46.632217],[10.119165,46.611382],[10.0525,46.543053],[10.050278,46.539993],[10.044722,46.507217],[10.044167,46.498055],[10.044443,46.453331],[10.044998,46.449165],[10.046665,46.445831],[10.049166,46.443054],[10.055555,46.438332],[10.067221,46.432495],[10.08861,46.424164],[10.092777,46.423332],[10.153889,46.390274],[10.177221,46.272499],[10.176388,46.268326],[10.172499,46.257217],[10.169722,46.25444],[10.140833,46.23333],[10.133888,46.228882],[10.129999,46.227219],[10.078609,46.220551],[10.072777,46.220276],[10.066666,46.221107],[10.063055,46.222771],[10.05722,46.22805],[9.994999,46.291664],[9.982498,46.331383],[9.981943,46.334717],[9.991388,46.346664],[9.99361,46.354439],[9.991943,46.357773],[9.984722,46.361938],[9.949999,46.379166],[9.943888,46.379997],[9.91111,46.383331],[9.904999,46.383049],[9.852777,46.36972],[9.813055,46.35833],[9.770555,46.342209],[9.714998,46.302773],[9.708332,46.298332],[9.696943,46.297218],[9.624722,46.291939],[9.581944,46.296944],[9.547222,46.30555],[9.5425,46.306938],[9.521387,46.319717],[9.458611,46.38472],[9.456665,46.387772],[9.450277,46.426666],[9.455,46.472496],[9.372776,46.5075],[9.360832,46.508606],[9.302221,46.504715],[9.296944,46.503883],[9.288887,46.500275],[9.281944,46.495827],[9.273611,46.487778],[9.249722,46.448051],[9.25,46.440277],[9.253054,46.433327],[9.256943,46.431389],[9.272778,46.428329],[9.280554,46.423332],[9.282221,46.419998],[9.296944,46.35305],[9.297499,46.348885],[9.293333,46.32666],[9.291943,46.323051],[9.276667,46.292496],[9.24341,46.23671],[9.238609,46.230553],[9.189444,46.186661],[9.180555,46.179161],[9.177221,46.176941],[9.158609,46.171661],[9.144439,46.168049],[9.132221,46.160271],[9.083332,46.121109],[9.035831,46.05722],[9.016666,46.022499],[8.998055,45.976944],[8.996666,45.973328],[9.0175,45.94416],[9.025,45.935829],[9.031944,45.931664],[9.066666,45.924164],[9.079443,45.915833],[9.081388,45.912498],[9.085554,45.901939],[9.085554,45.899162],[9.083887,45.895554],[9.036665,45.837776],[8.998333,45.829437],[8.951111,45.845276],[8.93611,45.868889],[8.936666,45.872772],[8.936388,45.876938],[8.926666,45.900833],[8.9,45.949715],[8.895555,45.955826],[8.826666,45.984161],[8.813055,45.988609],[8.816944,46.031662],[8.82361,46.03611],[8.849998,46.054443],[8.852499,46.056938],[8.853333,46.061104],[8.850555,46.072495],[8.846666,46.079163],[8.844166,46.08194],[8.835278,46.089439],[8.826111,46.096664],[8.818333,46.100555],[8.747221,46.121109],[8.728855,46.108589],[8.72361,46.105553],[8.714998,46.102493],[8.701111,46.10083],[8.691944,46.101387],[8.617777,46.120277],[8.613888,46.122215],[8.460554,46.23333],[8.445555,46.245827],[8.444443,46.248604],[8.434166,46.291107],[8.434999,46.295273],[8.443333,46.317215],[8.447498,46.323326],[8.458332,46.33416],[8.465832,46.36805],[8.46611,46.37722],[8.461666,46.444443],[8.459999,46.452217],[8.451666,46.459999],[8.447498,46.461937],[8.436388,46.463333],[8.430277,46.463051],[8.365276,46.453606],[8.357222,46.449997],[8.30611,46.424721],[8.302776,46.422493],[8.299999,46.419716],[8.139999,46.226105],[8.143888,46.219719],[8.158333,46.188889],[8.159443,46.180832],[8.158888,46.176666],[8.150276,46.153053],[8.148888,46.149437],[8.014721,46.013329],[8.00861,46.008331],[7.998055,46.00222],[7.973055,45.996941],[7.95,45.994164],[7.911111,45.994164],[7.902499,45.991104],[7.881944,45.977776],[7.876666,45.972496],[7.866388,45.948326],[7.855742,45.919052],[7.8483,45.918755],[7.783889,45.923607],[7.743333,45.93222],[7.709167,45.943329],[7.653055,45.979996],[7.647499,45.98111],[7.536666,45.981667],[7.458055,45.941109],[7.429722,45.929443],[7.393332,45.916107],[7.378888,45.914719],[7.338888,45.920555],[7.300278,45.923882],[7.295555,45.92305],[7.291111,45.921944],[7.230277,45.898048],[7.196944,45.882217],[7.188611,45.879166],[7.183055,45.879166],[7.117499,45.880829],[7.105,45.882217],[7.099444,45.883606],[7.09111,45.887497],[7.077777,45.896942],[7.062778,45.909164],[7.038054,45.931938],[7.030555,45.961937],[7.008611,45.996666],[7.005833,45.999443],[6.933055,46.055275],[6.873888,46.088051],[6.788055,46.14222],[6.783889,46.148048],[6.781111,46.162498],[6.780833,46.166107],[6.799999,46.378326],[6.807016,46.404228],[6.809444,46.415276],[6.808332,46.41861],[6.803055,46.427773],[6.800278,46.43055],[6.791389,46.434166],[6.737778,46.447495],[6.702777,46.45472],[6.633611,46.464165],[6.52,46.45916],[6.510278,46.457771],[6.491944,46.453049],[6.328333,46.406944],[6.31111,46.401382],[6.295555,46.394165],[6.246388,46.357773],[6.243333,46.354996],[6.236388,46.344719],[6.23,46.333885],[6.225555,46.322495],[6.228055,46.319717],[6.243747,46.31551],[6.271944,46.26194],[6.245555,46.21833],[6.189166,46.173332],[6.185833,46.17083],[6.152222,46.15361],[6.133611,46.149437],[6.12361,46.148048],[5.996388,46.146942],[5.967222,46.201942],[5.96611,46.205276],[5.966666,46.209442],[5.968055,46.212494],[5.981388,46.221939],[6.009166,46.233887],[6.03,46.241386],[6.060833,46.250549],[6.072499,46.249718],[6.0825,46.246666],[6.107778,46.253052],[6.117222,46.260551],[6.119166,46.264442],[6.118055,46.268051],[6.106109,46.297489],[6.115,46.30555],[6.120277,46.311943],[6.154166,46.363052],[6.15861,46.369995],[6.158333,46.373886],[6.157222,46.37722],[6.151667,46.386383],[6.148333,46.388611],[6.111111,46.409721],[6.071111,46.426384],[6.086944,46.44944],[6.135278,46.539719],[6.129722,46.583054],[6.127222,46.585831],[6.127777,46.589996],[6.129999,46.59333],[6.269166,46.682777],[6.346666,46.711388],[6.355,46.714439],[6.366666,46.720551],[6.434999,46.758049],[6.452777,46.774437],[6.4575,46.78083],[6.458611,46.785271],[6.446944,46.839439],[6.460278,46.895828],[6.528333,46.971664],[6.566388,46.979996],[6.620832,46.994438],[6.629722,46.997215],[6.639722,47.004166],[6.678333,47.034164],[6.699444,47.063889],[6.793333,47.130829],[6.849721,47.164989],[6.838888,47.16777],[6.8375,47.171104],[6.839722,47.173607],[6.971666,47.291939],[7.000833,47.364998],[6.980833,47.361664],[6.931389,47.358887],[6.88111,47.356941],[6.879999,47.360275],[6.88111,47.364716],[6.884444,47.372772],[6.990555,47.497215],[7.025,47.508049],[7.14642,47.499054],[7.178333,47.445831],[7.187499,47.442215],[7.241111,47.421944],[7.246944,47.42083],[7.251389,47.421944],[7.275555,47.432495],[7.308332,47.440277],[7.336944,47.439438],[7.343611,47.438606],[7.355897,47.434017],[7.358055,47.433609],[7.3825,47.432495],[7.388333,47.434166],[7.415555,47.445274],[7.433054,47.460548],[7.452777,47.469994],[7.496944,47.494995],[7.502222,47.500549],[7.497222,47.544441],[7.49861,47.54805],[7.501389,47.550552],[7.513055,47.556664],[7.521667,47.559715],[7.546665,47.565552],[7.550833,47.576385],[7.557221,47.581383],[7.567222,47.583611],[7.586944,47.584999],[7.588268,47.58448],[7.640555,47.603882],[7.674444,47.606384],[7.676944,47.603607],[7.671944,47.579437],[7.669999,47.576385],[7.666666,47.574165],[7.621111,47.561104],[7.656111,47.550552],[7.697223,47.543327]],[[8.710255,47.696808],[8.709721,47.70694],[8.708332,47.710548],[8.705,47.713051],[8.698889,47.713608],[8.675278,47.712494],[8.670555,47.711105],[8.670277,47.707497],[8.673298,47.701771],[8.675554,47.697495],[8.678595,47.693344],[8.710255,47.696808]]],"type":"Polygon"},"type":"Feature"}],"type":"FeatureCollection"}
--------------------------------------------------------------------------------
/jsonexamples/small/jsoniter_scala/che-3.geo.json:
--------------------------------------------------------------------------------
1 | {"features":[{"geometry":{"coordinates":[[[7.697223,47.543327],[7.769722,47.553329],[7.906388,47.558052],[7.91361,47.553886],[7.918888,47.552773],[7.931944,47.552216],[8.033333,47.556107],[8.086666,47.560555],[8.092222,47.561661],[8.099722,47.565552],[8.102499,47.568329],[8.103888,47.571938],[8.108055,47.578331],[8.110832,47.581108],[8.185276,47.617218],[8.193333,47.620827],[8.198889,47.621666],[8.205555,47.621666],[8.240833,47.619438],[8.283333,47.613052],[8.288055,47.611664],[8.2925,47.605827],[8.390833,47.579994],[8.435833,47.573608],[8.464998,47.602493],[8.477499,47.612221],[8.51111,47.631104],[8.519999,47.634163],[8.531387,47.632774],[8.558332,47.623329],[8.562222,47.621384],[8.565554,47.614441],[8.56943,47.598537],[8.57642,47.59137],[8.591389,47.599442],[8.594721,47.601662],[8.629166,47.646111],[8.630833,47.649719],[8.629444,47.653328],[8.626944,47.656105],[8.620832,47.66111],[8.610254,47.667732],[8.580555,47.66861],[8.551388,47.668327],[8.545832,47.667496],[8.536943,47.664444],[8.528055,47.656944],[8.525833,47.65361],[8.518332,47.649719],[8.495277,47.647217],[8.475555,47.646942],[8.424721,47.669441],[8.413332,47.678329],[8.407221,47.699715],[8.406666,47.703888],[8.473331,47.767494],[8.47611,47.769997],[8.479443,47.772499],[8.559721,47.806389],[8.566111,47.806938],[8.60861,47.804161],[8.614721,47.803604],[8.661388,47.79805],[8.685555,47.786659],[8.734999,47.761383],[8.736944,47.758049],[8.736944,47.75444],[8.734999,47.713882],[8.734165,47.709717],[8.730698,47.705673],[8.729166,47.703888],[8.720222,47.696625],[8.745277,47.695],[8.761389,47.692215],[8.800133,47.681725],[8.774721,47.710274],[8.772778,47.713333],[8.772221,47.717499],[8.777777,47.722771],[8.799999,47.735275],[8.804165,47.737221],[8.808887,47.735832],[8.835278,47.718048],[8.855833,47.698883],[8.883299,47.654148],[8.892776,47.651382],[8.904999,47.650276],[8.917776,47.650551],[8.934166,47.653053],[8.947777,47.657494],[8.973331,47.667496],[8.985554,47.672775],[8.996666,47.679161],[9.004999,47.682495],[9.024166,47.687775],[9.0425,47.688889],[9.078333,47.685829],[9.086943,47.684998],[9.261095,47.662842],[9.478322,47.575851],[9.566724,47.540451],[9.557772,47.505783],[9.559721,47.499718],[9.562222,47.496666],[9.567499,47.491104],[9.590277,47.470276],[9.594166,47.46833],[9.611666,47.468887],[9.646944,47.460274],[9.65111,47.458328],[9.65361,47.455551],[9.673332,47.398605],[9.673054,47.394997],[9.669998,47.387772],[9.664999,47.381386],[9.650555,47.373055],[9.641666,47.369995],[9.631388,47.36805],[9.625832,47.367218],[9.624422,47.367252],[9.614443,47.367493],[9.605276,47.359993],[9.599722,47.354164],[9.539999,47.284164],[9.533569,47.274544],[9.502222,47.231384],[9.491388,47.215271],[9.485832,47.200272],[9.484165,47.192215],[9.484444,47.179718],[9.489721,47.16555],[9.49861,47.15361],[9.505554,47.139999],[9.511389,47.121666],[9.512777,47.109444],[9.512499,47.100273],[9.510277,47.092499],[9.474637,47.057457],[9.485277,47.061104],[9.506388,47.06472],[9.538055,47.07],[9.544722,47.07],[9.598635,47.063835],[9.6325,47.056664],[9.719444,47.050278],[9.870277,47.023598],[9.875555,47.022491],[9.891943,47.003876],[9.893055,47.000267],[9.889444,46.993324],[9.880833,46.98082],[9.875555,46.970543],[9.873333,46.962769],[9.87361,46.958603],[9.87611,46.941658],[9.879444,46.939156],[9.934999,46.912773],[10.058887,46.866386],[10.109444,46.850273],[10.122776,46.849716],[10.140276,46.851105],[10.141807,46.851341],[10.15111,46.852776],[10.170555,46.857216],[10.22361,46.874992],[10.231388,46.878883],[10.313332,46.933609],[10.323332,46.955551],[10.345833,46.986382],[10.353611,46.994995],[10.357222,46.997215],[10.385555,47.002777],[10.391109,47.003609],[10.400833,47.001106],[10.429998,46.984161],[10.487499,46.937775],[10.488913,46.934212],[10.471235,46.871353],[10.447498,46.763054],[10.470833,46.635826],[10.486387,46.619438],[10.486666,46.615273],[10.486111,46.594719],[10.485277,46.590553],[10.475555,46.562492],[10.471109,46.551666],[10.465277,46.546387],[10.457531,46.542503],[10.44972,46.539162],[10.337221,46.549438],[10.305555,46.553886],[10.301666,46.555832],[10.247499,46.583885],[10.245554,46.587219],[10.245277,46.59111],[10.246944,46.599442],[10.253054,46.613884],[10.254166,46.61805],[10.253611,46.622215],[10.241665,46.636665],[10.238609,46.638885],[10.233332,46.639999],[10.18111,46.632217],[10.119165,46.611382],[10.0525,46.543053],[10.050278,46.539993],[10.044722,46.507217],[10.044167,46.498055],[10.044443,46.453331],[10.044998,46.449165],[10.046665,46.445831],[10.049166,46.443054],[10.055555,46.438332],[10.067221,46.432495],[10.08861,46.424164],[10.092777,46.423332],[10.153889,46.390274],[10.177221,46.272499],[10.176388,46.268326],[10.172499,46.257217],[10.169722,46.25444],[10.140833,46.23333],[10.133888,46.228882],[10.129999,46.227219],[10.078609,46.220551],[10.072777,46.220276],[10.066666,46.221107],[10.063055,46.222771],[10.05722,46.22805],[9.994999,46.291664],[9.982498,46.331383],[9.981943,46.334717],[9.991388,46.346664],[9.99361,46.354439],[9.991943,46.357773],[9.984722,46.361938],[9.949999,46.379166],[9.943888,46.379997],[9.91111,46.383331],[9.904999,46.383049],[9.852777,46.36972],[9.813055,46.35833],[9.770555,46.342209],[9.714998,46.302773],[9.708332,46.298332],[9.696943,46.297218],[9.624722,46.291939],[9.581944,46.296944],[9.547222,46.30555],[9.5425,46.306938],[9.521387,46.319717],[9.458611,46.38472],[9.456665,46.387772],[9.450277,46.426666],[9.455,46.472496],[9.372776,46.5075],[9.360832,46.508606],[9.302221,46.504715],[9.296944,46.503883],[9.288887,46.500275],[9.281944,46.495827],[9.273611,46.487778],[9.249722,46.448051],[9.25,46.440277],[9.253054,46.433327],[9.256943,46.431389],[9.272778,46.428329],[9.280554,46.423332],[9.282221,46.419998],[9.296944,46.35305],[9.297499,46.348885],[9.293333,46.32666],[9.291943,46.323051],[9.276667,46.292496],[9.24341,46.23671],[9.238609,46.230553],[9.189444,46.186661],[9.180555,46.179161],[9.177221,46.176941],[9.158609,46.171661],[9.144439,46.168049],[9.132221,46.160271],[9.083332,46.121109],[9.035831,46.05722],[9.016666,46.022499],[8.998055,45.976944],[8.996666,45.973328],[9.0175,45.94416],[9.025,45.935829],[9.031944,45.931664],[9.066666,45.924164],[9.079443,45.915833],[9.081388,45.912498],[9.085554,45.901939],[9.085554,45.899162],[9.083887,45.895554],[9.036665,45.837776],[8.998333,45.829437],[8.951111,45.845276],[8.93611,45.868889],[8.936666,45.872772],[8.936388,45.876938],[8.926666,45.900833],[8.9,45.949715],[8.895555,45.955826],[8.826666,45.984161],[8.813055,45.988609],[8.816944,46.031662],[8.82361,46.03611],[8.849998,46.054443],[8.852499,46.056938],[8.853333,46.061104],[8.850555,46.072495],[8.846666,46.079163],[8.844166,46.08194],[8.835278,46.089439],[8.826111,46.096664],[8.818333,46.100555],[8.747221,46.121109],[8.728855,46.108589],[8.72361,46.105553],[8.714998,46.102493],[8.701111,46.10083],[8.691944,46.101387],[8.617777,46.120277],[8.613888,46.122215],[8.460554,46.23333],[8.445555,46.245827],[8.444443,46.248604],[8.434166,46.291107],[8.434999,46.295273],[8.443333,46.317215],[8.447498,46.323326],[8.458332,46.33416],[8.465832,46.36805],[8.46611,46.37722],[8.461666,46.444443],[8.459999,46.452217],[8.451666,46.459999],[8.447498,46.461937],[8.436388,46.463333],[8.430277,46.463051],[8.365276,46.453606],[8.357222,46.449997],[8.30611,46.424721],[8.302776,46.422493],[8.299999,46.419716],[8.139999,46.226105],[8.143888,46.219719],[8.158333,46.188889],[8.159443,46.180832],[8.158888,46.176666],[8.150276,46.153053],[8.148888,46.149437],[8.014721,46.013329],[8.00861,46.008331],[7.998055,46.00222],[7.973055,45.996941],[7.95,45.994164],[7.911111,45.994164],[7.902499,45.991104],[7.881944,45.977776],[7.876666,45.972496],[7.866388,45.948326],[7.855742,45.919052],[7.8483,45.918755],[7.783889,45.923607],[7.743333,45.93222],[7.709167,45.943329],[7.653055,45.979996],[7.647499,45.98111],[7.536666,45.981667],[7.458055,45.941109],[7.429722,45.929443],[7.393332,45.916107],[7.378888,45.914719],[7.338888,45.920555],[7.300278,45.923882],[7.295555,45.92305],[7.291111,45.921944],[7.230277,45.898048],[7.196944,45.882217],[7.188611,45.879166],[7.183055,45.879166],[7.117499,45.880829],[7.105,45.882217],[7.099444,45.883606],[7.09111,45.887497],[7.077777,45.896942],[7.062778,45.909164],[7.038054,45.931938],[7.030555,45.961937],[7.008611,45.996666],[7.005833,45.999443],[6.933055,46.055275],[6.873888,46.088051],[6.788055,46.14222],[6.783889,46.148048],[6.781111,46.162498],[6.780833,46.166107],[6.799999,46.378326],[6.807016,46.404228],[6.809444,46.415276],[6.808332,46.41861],[6.803055,46.427773],[6.800278,46.43055],[6.791389,46.434166],[6.737778,46.447495],[6.702777,46.45472],[6.633611,46.464165],[6.52,46.45916],[6.510278,46.457771],[6.491944,46.453049],[6.328333,46.406944],[6.31111,46.401382],[6.295555,46.394165],[6.246388,46.357773],[6.243333,46.354996],[6.236388,46.344719],[6.23,46.333885],[6.225555,46.322495],[6.228055,46.319717],[6.243747,46.31551],[6.271944,46.26194],[6.245555,46.21833],[6.189166,46.173332],[6.185833,46.17083],[6.152222,46.15361],[6.133611,46.149437],[6.12361,46.148048],[5.996388,46.146942],[5.967222,46.201942],[5.96611,46.205276],[5.966666,46.209442],[5.968055,46.212494],[5.981388,46.221939],[6.009166,46.233887],[6.03,46.241386],[6.060833,46.250549],[6.072499,46.249718],[6.0825,46.246666],[6.107778,46.253052],[6.117222,46.260551],[6.119166,46.264442],[6.118055,46.268051],[6.106109,46.297489],[6.115,46.30555],[6.120277,46.311943],[6.154166,46.363052],[6.15861,46.369995],[6.158333,46.373886],[6.157222,46.37722],[6.151667,46.386383],[6.148333,46.388611],[6.111111,46.409721],[6.071111,46.426384],[6.086944,46.44944],[6.135278,46.539719],[6.129722,46.583054],[6.127222,46.585831],[6.127777,46.589996],[6.129999,46.59333],[6.269166,46.682777],[6.346666,46.711388],[6.355,46.714439],[6.366666,46.720551],[6.434999,46.758049],[6.452777,46.774437],[6.4575,46.78083],[6.458611,46.785271],[6.446944,46.839439],[6.460278,46.895828],[6.528333,46.971664],[6.566388,46.979996],[6.620832,46.994438],[6.629722,46.997215],[6.639722,47.004166],[6.678333,47.034164],[6.699444,47.063889],[6.793333,47.130829],[6.849721,47.164989],[6.838888,47.16777],[6.8375,47.171104],[6.839722,47.173607],[6.971666,47.291939],[7.000833,47.364998],[6.980833,47.361664],[6.931389,47.358887],[6.88111,47.356941],[6.879999,47.360275],[6.88111,47.364716],[6.884444,47.372772],[6.990555,47.497215],[7.025,47.508049],[7.14642,47.499054],[7.178333,47.445831],[7.187499,47.442215],[7.241111,47.421944],[7.246944,47.42083],[7.251389,47.421944],[7.275555,47.432495],[7.308332,47.440277],[7.336944,47.439438],[7.343611,47.438606],[7.355897,47.434017],[7.358055,47.433609],[7.3825,47.432495],[7.388333,47.434166],[7.415555,47.445274],[7.433054,47.460548],[7.452777,47.469994],[7.496944,47.494995],[7.502222,47.500549],[7.497222,47.544441],[7.49861,47.54805],[7.501389,47.550552],[7.513055,47.556664],[7.521667,47.559715],[7.546665,47.565552],[7.550833,47.576385],[7.557221,47.581383],[7.567222,47.583611],[7.586944,47.584999],[7.588268,47.58448],[7.640555,47.603882],[7.674444,47.606384],[7.676944,47.603607],[7.671944,47.579437],[7.669999,47.576385],[7.666666,47.574165],[7.621111,47.561104],[7.656111,47.550552],[7.697223,47.543327]],[[8.710255,47.696808],[8.709721,47.70694],[8.708332,47.710548],[8.705,47.713051],[8.698889,47.713608],[8.675278,47.712494],[8.670555,47.711105],[8.670277,47.707497],[8.673298,47.701771],[8.675554,47.697495],[8.678595,47.693344],[8.710255,47.696808]]],"type":"Polygon"},"type":"Feature","properties":{"cca2":"ch"}}],"type":"FeatureCollection"}
--------------------------------------------------------------------------------
/jsonexamples/small/jsoniter_scala/google_maps_api_compact_response.json:
--------------------------------------------------------------------------------
1 | {"destination_addresses":["New York, NY, USA","Los Angeles, CA, USA","Chicago, IL, USA","Houston, TX, USA","Phoenix, AZ, USA","Philadelphia, PA, USA","San Antonio, TX, USA","San Diego, CA, USA","Dallas, TX, USA","San Jose, CA, USA"],"origin_addresses":["New York, NY, USA","Los Angeles, CA, USA","Chicago, IL, USA","Houston, TX, USA","Phoenix, AZ, USA","Philadelphia, PA, USA","San Antonio, TX, USA","San Diego, CA, USA","Dallas, TX, USA","San Jose, CA, USA"],"rows":[{"elements":[{"distance":{"text":"1 m","value":0},"duration":{"text":"1 min","value":0},"status":"OK"},{"distance":{"text":"4,490 km","value":4489862},"duration":{"text":"1 day 16 hours","value":145589},"status":"OK"},{"distance":{"text":"1,270 km","value":1270445},"duration":{"text":"12 hours 10 mins","value":43773},"status":"OK"},{"distance":{"text":"2,621 km","value":2620658},"duration":{"text":"23 hours 55 mins","value":86073},"status":"OK"},{"distance":{"text":"3,876 km","value":3875676},"duration":{"text":"1 day 12 hours","value":129040},"status":"OK"},{"distance":{"text":"158 km","value":158242},"duration":{"text":"1 hour 55 mins","value":6885},"status":"OK"},{"distance":{"text":"2,935 km","value":2934803},"duration":{"text":"1 day 3 hours","value":96322},"status":"OK"},{"distance":{"text":"4,443 km","value":4443412},"duration":{"text":"1 day 17 hours","value":147406},"status":"OK"},{"distance":{"text":"2,492 km","value":2492302},"duration":{"text":"22 hours 53 mins","value":82371},"status":"OK"},{"distance":{"text":"4,728 km","value":4728294},"duration":{"text":"1 day 19 hours","value":154228},"status":"OK"}]},{"elements":[{"distance":{"text":"4,501 km","value":4501326},"duration":{"text":"1 day 16 hours","value":145282},"status":"OK"},{"distance":{"text":"1 m","value":0},"duration":{"text":"1 min","value":0},"status":"OK"},{"distance":{"text":"3,244 km","value":3243718},"duration":{"text":"1 day 5 hours","value":103355},"status":"OK"},{"distance":{"text":"2,491 km","value":2491140},"duration":{"text":"21 hours 48 mins","value":78485},"status":"OK"},{"distance":{"text":"600 km","value":600314},"duration":{"text":"5 hours 29 mins","value":19738},"status":"OK"},{"distance":{"text":"4,368 km","value":4368094},"duration":{"text":"1 day 15 hours","value":141933},"status":"OK"},{"distance":{"text":"2,177 km","value":2176782},"duration":{"text":"19 hours 3 mins","value":68584},"status":"OK"},{"distance":{"text":"194 km","value":193646},"duration":{"text":"1 hour 57 mins","value":7042},"status":"OK"},{"distance":{"text":"2,312 km","value":2311734},"duration":{"text":"20 hours 25 mins","value":73503},"status":"OK"},{"distance":{"text":"547 km","value":546932},"duration":{"text":"5 hours 11 mins","value":18651},"status":"OK"}]},{"elements":[{"distance":{"text":"1,282 km","value":1281616},"duration":{"text":"12 hours 8 mins","value":43678},"status":"OK"},{"distance":{"text":"3,243 km","value":3242543},"duration":{"text":"1 day 5 hours","value":103349},"status":"OK"},{"distance":{"text":"1 m","value":0},"duration":{"text":"1 min","value":0},"status":"OK"},{"distance":{"text":"1,742 km","value":1741571},"duration":{"text":"16 hours 11 mins","value":58255},"status":"OK"},{"distance":{"text":"2,821 km","value":2821137},"duration":{"text":"1 day 2 hours","value":92449},"status":"OK"},{"distance":{"text":"1,220 km","value":1219825},"duration":{"text":"11 hours 27 mins","value":41212},"status":"OK"},{"distance":{"text":"1,997 km","value":1996514},"duration":{"text":"18 hours 4 mins","value":65059},"status":"OK"},{"distance":{"text":"3,342 km","value":3341754},"duration":{"text":"1 day 6 hours","value":106407},"status":"OK"},{"distance":{"text":"1,490 km","value":1489726},"duration":{"text":"14 hours 2 mins","value":50540},"status":"OK"},{"distance":{"text":"3,481 km","value":3480975},"duration":{"text":"1 day 7 hours","value":111989},"status":"OK"}]},{"elements":[{"distance":{"text":"2,624 km","value":2623641},"duration":{"text":"23 hours 58 mins","value":86258},"status":"OK"},{"distance":{"text":"2,488 km","value":2488117},"duration":{"text":"21 hours 49 mins","value":78547},"status":"OK"},{"distance":{"text":"1,742 km","value":1741761},"duration":{"text":"16 hours 13 mins","value":58360},"status":"OK"},{"distance":{"text":"1 m","value":0},"duration":{"text":"1 min","value":0},"status":"OK"},{"distance":{"text":"1,890 km","value":1889580},"duration":{"text":"16 hours 28 mins","value":59289},"status":"OK"},{"distance":{"text":"2,489 km","value":2489250},"duration":{"text":"22 hours 42 mins","value":81704},"status":"OK"},{"distance":{"text":"317 km","value":317168},"duration":{"text":"2 hours 55 mins","value":10481},"status":"OK"},{"distance":{"text":"2,363 km","value":2362972},"duration":{"text":"20 hours 36 mins","value":74158},"status":"OK"},{"distance":{"text":"385 km","value":384812},"duration":{"text":"3 hours 26 mins","value":12385},"status":"OK"},{"distance":{"text":"3,033 km","value":3033431},"duration":{"text":"1 day 3 hours","value":96387},"status":"OK"}]},{"elements":[{"distance":{"text":"3,885 km","value":3884549},"duration":{"text":"1 day 12 hours","value":128892},"status":"OK"},{"distance":{"text":"599 km","value":598636},"duration":{"text":"5 hours 32 mins","value":19898},"status":"OK"},{"distance":{"text":"2,829 km","value":2828868},"duration":{"text":"1 day 2 hours","value":92370},"status":"OK"},{"distance":{"text":"1,893 km","value":1892718},"duration":{"text":"16 hours 31 mins","value":59432},"status":"OK"},{"distance":{"text":"1 m","value":0},"duration":{"text":"1 min","value":0},"status":"OK"},{"distance":{"text":"3,776 km","value":3776390},"duration":{"text":"1 day 11 hours","value":124555},"status":"OK"},{"distance":{"text":"1,578 km","value":1578360},"duration":{"text":"13 hours 46 mins","value":49532},"status":"OK"},{"distance":{"text":"571 km","value":570657},"duration":{"text":"5 hours 17 mins","value":19041},"status":"OK"},{"distance":{"text":"1,713 km","value":1713312},"duration":{"text":"15 hours 8 mins","value":54450},"status":"OK"},{"distance":{"text":"1,144 km","value":1143951},"duration":{"text":"10 hours 29 mins","value":37738},"status":"OK"}]},{"elements":[{"distance":{"text":"159 km","value":158684},"duration":{"text":"1 hour 53 mins","value":6753},"status":"OK"},{"distance":{"text":"4,363 km","value":4362509},"duration":{"text":"1 day 16 hours","value":142324},"status":"OK"},{"distance":{"text":"1,221 km","value":1220728},"duration":{"text":"11 hours 30 mins","value":41424},"status":"OK"},{"distance":{"text":"2,488 km","value":2487984},"duration":{"text":"22 hours 37 mins","value":81429},"status":"OK"},{"distance":{"text":"3,769 km","value":3769346},"duration":{"text":"1 day 11 hours","value":124752},"status":"OK"},{"distance":{"text":"1 m","value":0},"duration":{"text":"1 min","value":0},"status":"OK"},{"distance":{"text":"2,802 km","value":2802129},"duration":{"text":"1 day 1 hour","value":91677},"status":"OK"},{"distance":{"text":"4,337 km","value":4337082},"duration":{"text":"1 day 16 hours","value":143118},"status":"OK"},{"distance":{"text":"2,360 km","value":2359628},"duration":{"text":"21 hours 35 mins","value":77726},"status":"OK"},{"distance":{"text":"4,679 km","value":4678576},"duration":{"text":"1 day 18 hours","value":151879},"status":"OK"}]},{"elements":[{"distance":{"text":"2,939 km","value":2938513},"duration":{"text":"1 day 3 hours","value":96477},"status":"OK"},{"distance":{"text":"2,178 km","value":2178117},"duration":{"text":"19 hours 6 mins","value":68773},"status":"OK"},{"distance":{"text":"1,996 km","value":1996414},"duration":{"text":"18 hours 3 mins","value":64959},"status":"OK"},{"distance":{"text":"318 km","value":317558},"duration":{"text":"2 hours 54 mins","value":10436},"status":"OK"},{"distance":{"text":"1,580 km","value":1579581},"duration":{"text":"13 hours 45 mins","value":49515},"status":"OK"},{"distance":{"text":"2,804 km","value":2804123},"duration":{"text":"1 day 2 hours","value":91923},"status":"OK"},{"distance":{"text":"1 m","value":0},"duration":{"text":"1 min","value":0},"status":"OK"},{"distance":{"text":"2,053 km","value":2052972},"duration":{"text":"17 hours 53 mins","value":64384},"status":"OK"},{"distance":{"text":"440 km","value":440485},"duration":{"text":"4 hours 7 mins","value":14809},"status":"OK"},{"distance":{"text":"2,723 km","value":2723432},"duration":{"text":"1 day 0 hours","value":86613},"status":"OK"}]},{"elements":[{"distance":{"text":"4,450 km","value":4449804},"duration":{"text":"1 day 17 hours","value":147307},"status":"OK"},{"distance":{"text":"193 km","value":193391},"duration":{"text":"2 hours 1 min","value":7257},"status":"OK"},{"distance":{"text":"3,343 km","value":3342861},"duration":{"text":"1 day 6 hours","value":106618},"status":"OK"},{"distance":{"text":"2,365 km","value":2365196},"duration":{"text":"20 hours 39 mins","value":74342},"status":"OK"},{"distance":{"text":"571 km","value":571299},"duration":{"text":"5 hours 20 mins","value":19183},"status":"OK"},{"distance":{"text":"4,342 km","value":4341645},"duration":{"text":"1 day 16 hours","value":142971},"status":"OK"},{"distance":{"text":"2,051 km","value":2050838},"duration":{"text":"17 hours 54 mins","value":64441},"status":"OK"},{"distance":{"text":"1 m","value":0},"duration":{"text":"1 min","value":0},"status":"OK"},{"distance":{"text":"2,186 km","value":2185790},"duration":{"text":"19 hours 16 mins","value":69360},"status":"OK"},{"distance":{"text":"740 km","value":740005},"duration":{"text":"7 hours 6 mins","value":25541},"status":"OK"}]},{"elements":[{"distance":{"text":"2,493 km","value":2492688},"duration":{"text":"22 hours 52 mins","value":82333},"status":"OK"},{"distance":{"text":"2,311 km","value":2310974},"duration":{"text":"20 hours 27 mins","value":73596},"status":"OK"},{"distance":{"text":"1,557 km","value":1556570},"duration":{"text":"14 hours 3 mins","value":50581},"status":"OK"},{"distance":{"text":"385 km","value":385037},"duration":{"text":"3 hours 28 mins","value":12495},"status":"OK"},{"distance":{"text":"1,712 km","value":1712438},"duration":{"text":"15 hours 6 mins","value":54339},"status":"OK"},{"distance":{"text":"2,358 km","value":2358297},"duration":{"text":"21 hours 36 mins","value":77780},"status":"OK"},{"distance":{"text":"441 km","value":440702},"duration":{"text":"4 hours 7 mins","value":14800},"status":"OK"},{"distance":{"text":"2,186 km","value":2185829},"duration":{"text":"19 hours 13 mins","value":69208},"status":"OK"},{"distance":{"text":"1 m","value":0},"duration":{"text":"1 min","value":0},"status":"OK"},{"distance":{"text":"2,716 km","value":2715614},"duration":{"text":"1 day 1 hour","value":89296},"status":"OK"}]},{"elements":[{"distance":{"text":"4,741 km","value":4740819},"duration":{"text":"1 day 19 hours","value":153881},"status":"OK"},{"distance":{"text":"549 km","value":549030},"duration":{"text":"5 hours 11 mins","value":18643},"status":"OK"},{"distance":{"text":"3,483 km","value":3483210},"duration":{"text":"1 day 7 hours","value":111954},"status":"OK"},{"distance":{"text":"3,037 km","value":3036563},"duration":{"text":"1 day 3 hours","value":96326},"status":"OK"},{"distance":{"text":"1,146 km","value":1145736},"duration":{"text":"10 hours 26 mins","value":37580},"status":"OK"},{"distance":{"text":"4,679 km","value":4679027},"duration":{"text":"1 day 18 hours","value":151414},"status":"OK"},{"distance":{"text":"2,722 km","value":2722204},"duration":{"text":"1 day 0 hours","value":86426},"status":"OK"},{"distance":{"text":"740 km","value":739719},"duration":{"text":"7 hours 2 mins","value":25298},"status":"OK"},{"distance":{"text":"2,717 km","value":2717009},"duration":{"text":"1 day 1 hour","value":89209},"status":"OK"},{"distance":{"text":"1 m","value":0},"duration":{"text":"1 min","value":0},"status":"OK"}]}],"status":"OK"}
--------------------------------------------------------------------------------
/jsonexamples/small/jsoniter_scala/twitter_api_compact_response.json:
--------------------------------------------------------------------------------
1 | [{"created_at":"Thu Apr 06 15:28:43 +0000 2017","id":850007368138018817,"id_str":"850007368138018817","text":"RT @TwitterDev: 1/ Today we’re sharing our vision for the future of the Twitter API platform!\nhttps://t.co/XweGngmxlP","truncated":false,"entities":{"user_mentions":[{"screen_name":"TwitterDev","name":"TwitterDev","id":2244994945,"id_str":"2244994945","indices":[3,14]}],"urls":[{"url":"https://t.co/XweGngmxlP","expanded_url":"https://cards.twitter.com/cards/18ce53wgo4h/3xo1c","display_url":"cards.twitter.com/cards/18ce53wg…","indices":[94,117]}]},"source":"Twitter Web Client ","user":{"id":6253282,"id_str":"6253282","name":"Twitter API","screen_name":"twitterapi","location":"San Francisco, CA","description":"The Real Twitter API. I tweet about API changes, service issues and happily answer questions about Twitter and our API. Don't get an answer? It's on my website.","url":"http://t.co/78pYTvWfJd","entities":{"url":{"urls":[{"url":"http://t.co/78pYTvWfJd","expanded_url":"https://dev.twitter.com","display_url":"dev.twitter.com","indices":[0,22]}]},"description":{}},"protected":false,"followers_count":6172353,"friends_count":46,"listed_count":13091,"created_at":"Wed May 23 06:01:13 +0000 2007","favourites_count":26,"utc_offset":-25200,"time_zone":"Pacific Time (US & Canada)","geo_enabled":true,"verified":true,"statuses_count":3583,"lang":"en","contributors_enabled":false,"is_translator":false,"is_translation_enabled":false,"profile_background_color":"C0DEED","profile_background_image_url":"http://pbs.twimg.com/profile_background_images/656927849/miyt9dpjz77sc0w3d4vj.png","profile_background_image_url_https":"https://pbs.twimg.com/profile_background_images/656927849/miyt9dpjz77sc0w3d4vj.png","profile_background_tile":true,"profile_image_url":"http://pbs.twimg.com/profile_images/2284174872/7df3h38zabcvjylnyfe3_normal.png","profile_image_url_https":"https://pbs.twimg.com/profile_images/2284174872/7df3h38zabcvjylnyfe3_normal.png","profile_banner_url":"https://pbs.twimg.com/profile_banners/6253282/1431474710","profile_link_color":"0084B4","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"has_extended_profile":false,"default_profile":false,"default_profile_image":false,"following":true,"follow_request_sent":false,"notifications":false,"translator_type":"regular"},"retweeted_status":{"created_at":"Thu Apr 06 15:24:15 +0000 2017","id":850006245121695744,"id_str":"850006245121695744","text":"1/ Today we’re sharing our vision for the future of the Twitter API platform!\nhttps://t.co/XweGngmxlP","truncated":false,"entities":{"urls":[{"url":"https://t.co/XweGngmxlP","expanded_url":"https://cards.twitter.com/cards/18ce53wgo4h/3xo1c","display_url":"cards.twitter.com/cards/18ce53wg…","indices":[78,101]}]},"source":"Twitter Web Client ","user":{"id":2244994945,"id_str":"2244994945","name":"TwitterDev","screen_name":"TwitterDev","location":"Internet","description":"Your official source for Twitter Platform news, updates & events. Need technical help? Visit https://t.co/mGHnxZCxkt ⌨️ #TapIntoTwitter","url":"https://t.co/66w26cua1O","entities":{"url":{"urls":[{"url":"https://t.co/66w26cua1O","expanded_url":"https://dev.twitter.com/","display_url":"dev.twitter.com","indices":[0,23]}]},"description":{"urls":[{"url":"https://t.co/mGHnxZCxkt","expanded_url":"https://twittercommunity.com/","display_url":"twittercommunity.com","indices":[93,116]}]}},"protected":false,"followers_count":465425,"friends_count":1523,"listed_count":1168,"created_at":"Sat Dec 14 04:35:55 +0000 2013","favourites_count":2098,"utc_offset":-25200,"time_zone":"Pacific Time (US & Canada)","geo_enabled":true,"verified":true,"statuses_count":3031,"lang":"en","contributors_enabled":false,"is_translator":false,"is_translation_enabled":false,"profile_background_color":"FFFFFF","profile_background_image_url":"http://abs.twimg.com/images/themes/theme1/bg.png","profile_background_image_url_https":"https://abs.twimg.com/images/themes/theme1/bg.png","profile_background_tile":false,"profile_image_url":"http://pbs.twimg.com/profile_images/530814764687949824/npQQVkq8_normal.png","profile_image_url_https":"https://pbs.twimg.com/profile_images/530814764687949824/npQQVkq8_normal.png","profile_banner_url":"https://pbs.twimg.com/profile_banners/2244994945/1396995246","profile_link_color":"0084B4","profile_sidebar_border_color":"FFFFFF","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":false,"has_extended_profile":false,"default_profile":false,"default_profile_image":false,"following":true,"follow_request_sent":false,"notifications":false,"translator_type":"regular"},"is_quote_status":false,"retweet_count":284,"favorite_count":399,"favorited":false,"retweeted":false,"possibly_sensitive":false,"lang":"en"},"is_quote_status":false,"retweet_count":284,"favorite_count":0,"favorited":false,"retweeted":false,"possibly_sensitive":false,"lang":"en"},{"created_at":"Mon Apr 03 16:09:50 +0000 2017","id":848930551989915648,"id_str":"848930551989915648","text":"RT @TwitterMktg: Starting today, businesses can request and share locations when engaging with people in Direct Messages. https://t.co/rpYn…","truncated":false,"entities":{"user_mentions":[{"screen_name":"TwitterMktg","name":"Twitter Marketing","id":357750891,"id_str":"357750891","indices":[3,15]}]},"source":"Twitter Web Client ","user":{"id":6253282,"id_str":"6253282","name":"Twitter API","screen_name":"twitterapi","location":"San Francisco, CA","description":"The Real Twitter API. I tweet about API changes, service issues and happily answer questions about Twitter and our API. Don't get an answer? It's on my website.","url":"http://t.co/78pYTvWfJd","entities":{"url":{"urls":[{"url":"http://t.co/78pYTvWfJd","expanded_url":"https://dev.twitter.com","display_url":"dev.twitter.com","indices":[0,22]}]},"description":{}},"protected":false,"followers_count":6172353,"friends_count":46,"listed_count":13091,"created_at":"Wed May 23 06:01:13 +0000 2007","favourites_count":26,"utc_offset":-25200,"time_zone":"Pacific Time (US & Canada)","geo_enabled":true,"verified":true,"statuses_count":3583,"lang":"en","contributors_enabled":false,"is_translator":false,"is_translation_enabled":false,"profile_background_color":"C0DEED","profile_background_image_url":"http://pbs.twimg.com/profile_background_images/656927849/miyt9dpjz77sc0w3d4vj.png","profile_background_image_url_https":"https://pbs.twimg.com/profile_background_images/656927849/miyt9dpjz77sc0w3d4vj.png","profile_background_tile":true,"profile_image_url":"http://pbs.twimg.com/profile_images/2284174872/7df3h38zabcvjylnyfe3_normal.png","profile_image_url_https":"https://pbs.twimg.com/profile_images/2284174872/7df3h38zabcvjylnyfe3_normal.png","profile_banner_url":"https://pbs.twimg.com/profile_banners/6253282/1431474710","profile_link_color":"0084B4","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"has_extended_profile":false,"default_profile":false,"default_profile_image":false,"following":true,"follow_request_sent":false,"notifications":false,"translator_type":"regular"},"retweeted_status":{"created_at":"Mon Apr 03 16:05:05 +0000 2017","id":848929357519241216,"id_str":"848929357519241216","text":"Starting today, businesses can request and share locations when engaging with people in Direct Messages. https://t.co/rpYndqWfQw","truncated":false,"entities":{"urls":[{"url":"https://t.co/rpYndqWfQw","expanded_url":"https://cards.twitter.com/cards/5wzucr/3x700","display_url":"cards.twitter.com/cards/5wzucr/3…","indices":[105,128]}]},"source":"Twitter Ads ","user":{"id":357750891,"id_str":"357750891","name":"Twitter Marketing","screen_name":"TwitterMktg","location":"Twitter HQ ","description":"Twitter’s place for marketers, agencies, and creative thinkers ⭐ Bringing you insights, news, updates, and inspiration. Visit @TwitterAdsHelp for Ads support.","url":"https://t.co/Tfo4moo92y","entities":{"url":{"urls":[{"url":"https://t.co/Tfo4moo92y","expanded_url":"https://marketing.twitter.com","display_url":"marketing.twitter.com","indices":[0,23]}]},"description":{}},"protected":false,"followers_count":924546,"friends_count":661,"listed_count":3893,"created_at":"Thu Aug 18 21:08:15 +0000 2011","favourites_count":1934,"utc_offset":-25200,"time_zone":"Pacific Time (US & Canada)","geo_enabled":true,"verified":true,"statuses_count":6329,"lang":"en","contributors_enabled":false,"is_translator":false,"is_translation_enabled":false,"profile_background_color":"C0DEED","profile_background_image_url":"http://pbs.twimg.com/profile_background_images/662767273/jvmxdpdrplhxcw8yvkv2.png","profile_background_image_url_https":"https://pbs.twimg.com/profile_background_images/662767273/jvmxdpdrplhxcw8yvkv2.png","profile_background_tile":true,"profile_image_url":"http://pbs.twimg.com/profile_images/800953549697888256/UlXXL5h5_normal.jpg","profile_image_url_https":"https://pbs.twimg.com/profile_images/800953549697888256/UlXXL5h5_normal.jpg","profile_banner_url":"https://pbs.twimg.com/profile_banners/357750891/1487188210","profile_link_color":"19CF86","profile_sidebar_border_color":"FFFFFF","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"has_extended_profile":false,"default_profile":false,"default_profile_image":false,"following":false,"follow_request_sent":false,"notifications":false,"translator_type":"none"},"is_quote_status":false,"retweet_count":111,"favorite_count":162,"favorited":false,"retweeted":false,"possibly_sensitive":false,"lang":"en"},"is_quote_status":false,"retweet_count":111,"favorite_count":0,"favorited":false,"retweeted":false,"possibly_sensitive":false,"lang":"en"}]
--------------------------------------------------------------------------------
/jsonexamples/small/repeat.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": 1,
3 | "jsonrpc": "2.0",
4 | "total": 100,
5 | "result": [
6 | {
7 | "id": 1,
8 | "name": "Юрий Титов"
9 | },
10 | {
11 | "id": 2,
12 | "name": "Валерий Васильев"
13 | },
14 | {
15 | "id": 3,
16 | "name": "Парамон Белов"
17 | },
18 | {
19 | "id": 4,
20 | "name": "Александр Иванов"
21 | },
22 | {
23 | "id": 5,
24 | "name": "Дмитрий Фролов"
25 | },
26 | {
27 | "id": 6,
28 | "name": "Яков Олейник"
29 | },
30 | {
31 | "id": 7,
32 | "name": "Леонтий Зайцев"
33 | },
34 | {
35 | "id": 8,
36 | "name": "Олег Егоров"
37 | },
38 | {
39 | "id": 9,
40 | "name": "Леонтий Зайцев"
41 | },
42 | {
43 | "id": 10,
44 | "name": "Федор Никитин"
45 | },
46 | {
47 | "id": 11,
48 | "name": "Александр Иванов"
49 | },
50 | {
51 | "id": 12,
52 | "name": "Рудольф Логинов"
53 | },
54 | {
55 | "id": 13,
56 | "name": "Анатолий Бондаренко"
57 | },
58 | {
59 | "id": 14,
60 | "name": "Константин Павлов"
61 | },
62 | {
63 | "id": 15,
64 | "name": "Ефим Марченко"
65 | },
66 | {
67 | "id": 16,
68 | "name": "Николай Макаров"
69 | },
70 | {
71 | "id": 17,
72 | "name": "Мирослав Фролов"
73 | },
74 | {
75 | "id": 18,
76 | "name": "Гордей Соколов"
77 | },
78 | {
79 | "id": 19,
80 | "name": "Арсен Попов"
81 | },
82 | {
83 | "id": 20,
84 | "name": "Павел Степанов"
85 | },
86 | {
87 | "id": 21,
88 | "name": "Степан Баранов"
89 | },
90 | {
91 | "id": 22,
92 | "name": "Захар Новиков"
93 | },
94 | {
95 | "id": 23,
96 | "name": "Казимир Макаров"
97 | },
98 | {
99 | "id": 24,
100 | "name": "Оскар Данилов"
101 | },
102 | {
103 | "id": 25,
104 | "name": "Любомир Денисов"
105 | },
106 | {
107 | "id": 26,
108 | "name": "Карл Рябов"
109 | },
110 | {
111 | "id": 27,
112 | "name": "Владимир Смирнов"
113 | },
114 | {
115 | "id": 28,
116 | "name": "Степан Баранов"
117 | },
118 | {
119 | "id": 29,
120 | "name": "Карл Рябов"
121 | },
122 | {
123 | "id": 30,
124 | "name": "Иоан Орлов"
125 | },
126 | {
127 | "id": 31,
128 | "name": "Максим Степанов"
129 | },
130 | {
131 | "id": 32,
132 | "name": "Арсений Кузнецов"
133 | },
134 | {
135 | "id": 33,
136 | "name": "Борис Левченко"
137 | },
138 | {
139 | "id": 34,
140 | "name": "Захар Новиков"
141 | },
142 | {
143 | "id": 35,
144 | "name": "Мирослав Фролов"
145 | },
146 | {
147 | "id": 36,
148 | "name": "Евдоким Демченко"
149 | },
150 | {
151 | "id": 37,
152 | "name": "Осип Григорьев"
153 | },
154 | {
155 | "id": 38,
156 | "name": "Станислав Тарасов"
157 | },
158 | {
159 | "id": 39,
160 | "name": "Вениамин Нестеренко"
161 | },
162 | {
163 | "id": 40,
164 | "name": "Эдуард Лебедев"
165 | },
166 | {
167 | "id": 41,
168 | "name": "Гавриил Мельник"
169 | },
170 | {
171 | "id": 42,
172 | "name": "Мартин Козлов"
173 | },
174 | {
175 | "id": 43,
176 | "name": "Валентин Шевченко"
177 | },
178 | {
179 | "id": 44,
180 | "name": "Артем Смирнов"
181 | },
182 | {
183 | "id": 45,
184 | "name": "Федор Никитин"
185 | },
186 | {
187 | "id": 46,
188 | "name": "Никита Яковлев"
189 | },
190 | {
191 | "id": 47,
192 | "name": "Андрей Петров"
193 | },
194 | {
195 | "id": 48,
196 | "name": "Гарри Морозов"
197 | },
198 | {
199 | "id": 49,
200 | "name": "Егор Мальцев"
201 | },
202 | {
203 | "id": 50,
204 | "name": "Иоан Орлов"
205 | },
206 | {
207 | "id": 51,
208 | "name": "Арсен Попов"
209 | },
210 | {
211 | "id": 52,
212 | "name": "Казимир Макаров"
213 | },
214 | {
215 | "id": 53,
216 | "name": "Герман Морозов"
217 | },
218 | {
219 | "id": 54,
220 | "name": "Тарас Алексеев"
221 | },
222 | {
223 | "id": 55,
224 | "name": "Семен Козлов"
225 | },
226 | {
227 | "id": 56,
228 | "name": "Любомир Денисов"
229 | },
230 | {
231 | "id": 57,
232 | "name": "Даниил Соколов"
233 | },
234 | {
235 | "id": 58,
236 | "name": "Олег Егоров"
237 | },
238 | {
239 | "id": 59,
240 | "name": "Леонид Приходько"
241 | },
242 | {
243 | "id": 60,
244 | "name": "Андрей Петров"
245 | },
246 | {
247 | "id": 61,
248 | "name": "Георгий Василенко"
249 | },
250 | {
251 | "id": 62,
252 | "name": "Лазарь Михайлов"
253 | },
254 | {
255 | "id": 63,
256 | "name": "Станислав Тарасов"
257 | },
258 | {
259 | "id": 64,
260 | "name": "Денис Данилов"
261 | },
262 | {
263 | "id": 65,
264 | "name": "Степан Баранов"
265 | },
266 | {
267 | "id": 66,
268 | "name": "Денис Данилов"
269 | },
270 | {
271 | "id": 67,
272 | "name": "Станислав Тарасов"
273 | },
274 | {
275 | "id": 68,
276 | "name": "Аркадий Кравченко"
277 | },
278 | {
279 | "id": 69,
280 | "name": "Рубен Сорокин"
281 | },
282 | {
283 | "id": 70,
284 | "name": "Мартын Гусев"
285 | },
286 | {
287 | "id": 71,
288 | "name": "Федор Никитин"
289 | },
290 | {
291 | "id": 72,
292 | "name": "Борис Левченко"
293 | },
294 | {
295 | "id": 73,
296 | "name": "Гарри Морозов"
297 | },
298 | {
299 | "id": 74,
300 | "name": "Иоан Орлов"
301 | },
302 | {
303 | "id": 75,
304 | "name": "Максим Степанов"
305 | },
306 | {
307 | "id": 76,
308 | "name": "Рудольф Логинов"
309 | },
310 | {
311 | "id": 77,
312 | "name": "Роман Чернов"
313 | },
314 | {
315 | "id": 78,
316 | "name": "Филипп Литвинов"
317 | },
318 | {
319 | "id": 79,
320 | "name": "Гордей Соколов"
321 | },
322 | {
323 | "id": 80,
324 | "name": "Леонтий Зайцев"
325 | },
326 | {
327 | "id": 81,
328 | "name": "Донат Михайлов"
329 | },
330 | {
331 | "id": 82,
332 | "name": "Александр Иванов"
333 | },
334 | {
335 | "id": 83,
336 | "name": "Арсен Попов"
337 | },
338 | {
339 | "id": 84,
340 | "name": "Валерий Васильев"
341 | },
342 | {
343 | "id": 85,
344 | "name": "Никита Яковлев"
345 | },
346 | {
347 | "id": 86,
348 | "name": "Гарри Морозов"
349 | },
350 | {
351 | "id": 87,
352 | "name": "Любомир Денисов"
353 | },
354 | {
355 | "id": 88,
356 | "name": "Евгений Новиков"
357 | },
358 | {
359 | "id": 89,
360 | "name": "Степан Баранов"
361 | },
362 | {
363 | "id": 90,
364 | "name": "Карл Рябов"
365 | },
366 | {
367 | "id": 91,
368 | "name": "Владислав Бабич"
369 | },
370 | {
371 | "id": 92,
372 | "name": "Филипп Литвинов"
373 | },
374 | {
375 | "id": 93,
376 | "name": "Эдвард Давыдов"
377 | },
378 | {
379 | "id": 94,
380 | "name": "Арнольд Бойко"
381 | },
382 | {
383 | "id": 95,
384 | "name": "Оскар Данилов"
385 | },
386 | {
387 | "id": 96,
388 | "name": "Семен Козлов"
389 | },
390 | {
391 | "id": 97,
392 | "name": "Тарас Алексеев"
393 | },
394 | {
395 | "id": 98,
396 | "name": "Людвиг Сергеев"
397 | },
398 | {
399 | "id": 99,
400 | "name": "Роман Чернов"
401 | },
402 | {
403 | "id": 100,
404 | "name": "Игнат Волков"
405 | }
406 | ]
407 | }
--------------------------------------------------------------------------------
/jsonexamples/small/truenull.json:
--------------------------------------------------------------------------------
1 | [true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null, true, null]
--------------------------------------------------------------------------------
/samples/HelloWorld/HelloWorld.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp3.0
6 | latest
7 | true
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/samples/HelloWorld/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Text;
4 | using SimdJsonSharp;
5 |
6 | namespace ConsoleApp124
7 | {
8 | class Program
9 | {
10 | static unsafe void Main(string[] args)
11 | {
12 | string helloWorldJson = @"{ ""answer"": 42, ""name"": ""Egor"" }";
13 | ReadOnlySpan bytes = Encoding.UTF8.GetBytes(helloWorldJson);
14 |
15 | fixed (byte* ptr = bytes)
16 | {
17 | // SimdJsonN -- N stands for Native, it means we are using Bindings for simdjson native lib
18 | // SimdJson -- fully managed .NET Core 3.0 port
19 | using (ParsedJson doc = SimdJson.ParseJson(ptr, (ulong)bytes.Length))
20 | {
21 | if (!doc.IsValid)
22 | {
23 | Console.WriteLine("Error: " + doc.ErrorCode);
24 | return;
25 | }
26 |
27 | Console.WriteLine("Json is valid!");
28 |
29 | //open iterator:
30 | using (var iterator = new ParsedJsonIterator(doc))
31 | {
32 | while (iterator.MoveForward())
33 | {
34 | if (iterator.IsInteger)
35 | Console.WriteLine("integer: " + iterator.GetInteger());
36 | if (iterator.IsString)
37 | Console.WriteLine("string: " + iterator.GetUtf16String());
38 | }
39 | }
40 | }
41 |
42 | Console.WriteLine("Done");
43 | }
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/samples/MinifyJson/MinifyJson.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp3.0
6 | latest
7 | true
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/samples/MinifyJson/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Reflection;
4 | using System.Text;
5 | using Microsoft.Win32.SafeHandles;
6 | using SimdJsonSharp;
7 |
8 | namespace MinifyJson
9 | {
10 | class Program
11 | {
12 | static void Main(string[] args)
13 | {
14 | ReadOnlySpan beforeData = LoadEmbeddedFile("MinifyJson.sample.json");
15 |
16 | string beforeString = Encoding.UTF8.GetString(beforeData);
17 | Console.WriteLine($"Before:\n{beforeString}\nLength={beforeString.Length}");
18 |
19 | string afterString = SimdJson.MinifyJson(beforeString); // there is also Span API
20 | Console.WriteLine($"\n\nAfter:\n{afterString}.\nLength={afterString.Length}");
21 | }
22 |
23 | private static byte[] LoadEmbeddedFile(string file)
24 | {
25 | using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(file))
26 | using (var ms = new MemoryStream())
27 | {
28 | stream.CopyTo(ms);
29 | return ms.ToArray();
30 | }
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/samples/MinifyJson/sample.json:
--------------------------------------------------------------------------------
1 | {
2 | "Egor": "Bogatov"
3 | }
4 |
--------------------------------------------------------------------------------
/solution.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.28705.295
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimdJsonSharp.Tests", "tests\SimdJsonSharp.Tests.csproj", "{F9759A8C-96A7-4012-8EB6-3F34E89859B3}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloWorld", "samples\HelloWorld\HelloWorld.csproj", "{E85B732E-8A68-4C53-82D2-8F4319A14BB9}"
9 | EndProject
10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{6DD8E0E9-0838-4299-B9B0-E0B75830CCF0}"
11 | EndProject
12 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{0EA09D21-043B-437C-83B5-B400D68DFBE0}"
13 | EndProject
14 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{96B2940D-00A0-488F-B4F4-3936C689C2E2}"
15 | EndProject
16 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimdJsonSharp.Managed", "src\FullyManagedImpl\SimdJsonSharp.Managed.csproj", "{835E9AEC-18FF-4FBB-89F5-0B1AB8A90E4F}"
17 | EndProject
18 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarks", "benchmarks", "{53CBE9B1-22D6-4D6F-A78A-0D6FBA9ED000}"
19 | EndProject
20 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmarks", "benchmarks\Benchmarks.csproj", "{5783067E-D420-462E-943C-4CBA2D74121C}"
21 | EndProject
22 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MinifyJson", "samples\MinifyJson\MinifyJson.csproj", "{D795C37F-D8D3-4B29-ADBA-548C6711D69B}"
23 | EndProject
24 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "1. FullyManaged", "1. FullyManaged", "{3050B7C6-A744-4FAC-925C-75DAB2FFD1C3}"
25 | EndProject
26 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2. BindingsForNativeLib", "2. BindingsForNativeLib", "{5668BADB-B2CF-4E1A-A885-DC10B11D26B2}"
27 | EndProject
28 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimdJsonNative", "src\BindingsForNativeLib\SimdJsonNative\SimdJsonNative.vcxproj", "{B688E099-77FF-46D9-B61B-5C6D718DDBFB}"
29 | EndProject
30 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SimdJsonSharp.Bindings", "src\BindingsForNativeLib\SimdJsonSharp.Bindings\SimdJsonSharp.Bindings.csproj", "{399AA870-D18B-40BB-AAB2-4DFDDB7B8DE6}"
31 | EndProject
32 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BindingsGenerator", "src\BindingsForNativeLib\BindingsGenerator\BindingsGenerator.csproj", "{F6024B33-8886-47AD-A504-24879BFC0A42}"
33 | EndProject
34 | Global
35 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
36 | Debug|Any CPU = Debug|Any CPU
37 | Debug|x64 = Debug|x64
38 | Debug|x86 = Debug|x86
39 | Release|Any CPU = Release|Any CPU
40 | Release|x64 = Release|x64
41 | Release|x86 = Release|x86
42 | EndGlobalSection
43 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
44 | {F9759A8C-96A7-4012-8EB6-3F34E89859B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
45 | {F9759A8C-96A7-4012-8EB6-3F34E89859B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
46 | {F9759A8C-96A7-4012-8EB6-3F34E89859B3}.Debug|x64.ActiveCfg = Debug|Any CPU
47 | {F9759A8C-96A7-4012-8EB6-3F34E89859B3}.Debug|x64.Build.0 = Debug|Any CPU
48 | {F9759A8C-96A7-4012-8EB6-3F34E89859B3}.Debug|x86.ActiveCfg = Debug|Any CPU
49 | {F9759A8C-96A7-4012-8EB6-3F34E89859B3}.Debug|x86.Build.0 = Debug|Any CPU
50 | {F9759A8C-96A7-4012-8EB6-3F34E89859B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
51 | {F9759A8C-96A7-4012-8EB6-3F34E89859B3}.Release|Any CPU.Build.0 = Release|Any CPU
52 | {F9759A8C-96A7-4012-8EB6-3F34E89859B3}.Release|x64.ActiveCfg = Release|Any CPU
53 | {F9759A8C-96A7-4012-8EB6-3F34E89859B3}.Release|x64.Build.0 = Release|Any CPU
54 | {F9759A8C-96A7-4012-8EB6-3F34E89859B3}.Release|x86.ActiveCfg = Release|Any CPU
55 | {F9759A8C-96A7-4012-8EB6-3F34E89859B3}.Release|x86.Build.0 = Release|Any CPU
56 | {E85B732E-8A68-4C53-82D2-8F4319A14BB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
57 | {E85B732E-8A68-4C53-82D2-8F4319A14BB9}.Debug|Any CPU.Build.0 = Debug|Any CPU
58 | {E85B732E-8A68-4C53-82D2-8F4319A14BB9}.Debug|x64.ActiveCfg = Debug|Any CPU
59 | {E85B732E-8A68-4C53-82D2-8F4319A14BB9}.Debug|x64.Build.0 = Debug|Any CPU
60 | {E85B732E-8A68-4C53-82D2-8F4319A14BB9}.Debug|x86.ActiveCfg = Debug|Any CPU
61 | {E85B732E-8A68-4C53-82D2-8F4319A14BB9}.Debug|x86.Build.0 = Debug|Any CPU
62 | {E85B732E-8A68-4C53-82D2-8F4319A14BB9}.Release|Any CPU.ActiveCfg = Release|Any CPU
63 | {E85B732E-8A68-4C53-82D2-8F4319A14BB9}.Release|Any CPU.Build.0 = Release|Any CPU
64 | {E85B732E-8A68-4C53-82D2-8F4319A14BB9}.Release|x64.ActiveCfg = Release|Any CPU
65 | {E85B732E-8A68-4C53-82D2-8F4319A14BB9}.Release|x64.Build.0 = Release|Any CPU
66 | {E85B732E-8A68-4C53-82D2-8F4319A14BB9}.Release|x86.ActiveCfg = Release|Any CPU
67 | {E85B732E-8A68-4C53-82D2-8F4319A14BB9}.Release|x86.Build.0 = Release|Any CPU
68 | {835E9AEC-18FF-4FBB-89F5-0B1AB8A90E4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
69 | {835E9AEC-18FF-4FBB-89F5-0B1AB8A90E4F}.Debug|Any CPU.Build.0 = Debug|Any CPU
70 | {835E9AEC-18FF-4FBB-89F5-0B1AB8A90E4F}.Debug|x64.ActiveCfg = Debug|Any CPU
71 | {835E9AEC-18FF-4FBB-89F5-0B1AB8A90E4F}.Debug|x64.Build.0 = Debug|Any CPU
72 | {835E9AEC-18FF-4FBB-89F5-0B1AB8A90E4F}.Debug|x86.ActiveCfg = Debug|Any CPU
73 | {835E9AEC-18FF-4FBB-89F5-0B1AB8A90E4F}.Debug|x86.Build.0 = Debug|Any CPU
74 | {835E9AEC-18FF-4FBB-89F5-0B1AB8A90E4F}.Release|Any CPU.ActiveCfg = Release|Any CPU
75 | {835E9AEC-18FF-4FBB-89F5-0B1AB8A90E4F}.Release|Any CPU.Build.0 = Release|Any CPU
76 | {835E9AEC-18FF-4FBB-89F5-0B1AB8A90E4F}.Release|x64.ActiveCfg = Release|Any CPU
77 | {835E9AEC-18FF-4FBB-89F5-0B1AB8A90E4F}.Release|x64.Build.0 = Release|Any CPU
78 | {835E9AEC-18FF-4FBB-89F5-0B1AB8A90E4F}.Release|x86.ActiveCfg = Release|Any CPU
79 | {835E9AEC-18FF-4FBB-89F5-0B1AB8A90E4F}.Release|x86.Build.0 = Release|Any CPU
80 | {5783067E-D420-462E-943C-4CBA2D74121C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
81 | {5783067E-D420-462E-943C-4CBA2D74121C}.Debug|Any CPU.Build.0 = Debug|Any CPU
82 | {5783067E-D420-462E-943C-4CBA2D74121C}.Debug|x64.ActiveCfg = Debug|Any CPU
83 | {5783067E-D420-462E-943C-4CBA2D74121C}.Debug|x64.Build.0 = Debug|Any CPU
84 | {5783067E-D420-462E-943C-4CBA2D74121C}.Debug|x86.ActiveCfg = Debug|Any CPU
85 | {5783067E-D420-462E-943C-4CBA2D74121C}.Debug|x86.Build.0 = Debug|Any CPU
86 | {5783067E-D420-462E-943C-4CBA2D74121C}.Release|Any CPU.ActiveCfg = Release|Any CPU
87 | {5783067E-D420-462E-943C-4CBA2D74121C}.Release|Any CPU.Build.0 = Release|Any CPU
88 | {5783067E-D420-462E-943C-4CBA2D74121C}.Release|x64.ActiveCfg = Release|Any CPU
89 | {5783067E-D420-462E-943C-4CBA2D74121C}.Release|x64.Build.0 = Release|Any CPU
90 | {5783067E-D420-462E-943C-4CBA2D74121C}.Release|x86.ActiveCfg = Release|Any CPU
91 | {5783067E-D420-462E-943C-4CBA2D74121C}.Release|x86.Build.0 = Release|Any CPU
92 | {D795C37F-D8D3-4B29-ADBA-548C6711D69B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
93 | {D795C37F-D8D3-4B29-ADBA-548C6711D69B}.Debug|Any CPU.Build.0 = Debug|Any CPU
94 | {D795C37F-D8D3-4B29-ADBA-548C6711D69B}.Debug|x64.ActiveCfg = Debug|Any CPU
95 | {D795C37F-D8D3-4B29-ADBA-548C6711D69B}.Debug|x64.Build.0 = Debug|Any CPU
96 | {D795C37F-D8D3-4B29-ADBA-548C6711D69B}.Debug|x86.ActiveCfg = Debug|Any CPU
97 | {D795C37F-D8D3-4B29-ADBA-548C6711D69B}.Debug|x86.Build.0 = Debug|Any CPU
98 | {D795C37F-D8D3-4B29-ADBA-548C6711D69B}.Release|Any CPU.ActiveCfg = Release|Any CPU
99 | {D795C37F-D8D3-4B29-ADBA-548C6711D69B}.Release|Any CPU.Build.0 = Release|Any CPU
100 | {D795C37F-D8D3-4B29-ADBA-548C6711D69B}.Release|x64.ActiveCfg = Release|Any CPU
101 | {D795C37F-D8D3-4B29-ADBA-548C6711D69B}.Release|x64.Build.0 = Release|Any CPU
102 | {D795C37F-D8D3-4B29-ADBA-548C6711D69B}.Release|x86.ActiveCfg = Release|Any CPU
103 | {D795C37F-D8D3-4B29-ADBA-548C6711D69B}.Release|x86.Build.0 = Release|Any CPU
104 | {B688E099-77FF-46D9-B61B-5C6D718DDBFB}.Debug|Any CPU.ActiveCfg = Debug|x64
105 | {B688E099-77FF-46D9-B61B-5C6D718DDBFB}.Debug|Any CPU.Build.0 = Debug|x64
106 | {B688E099-77FF-46D9-B61B-5C6D718DDBFB}.Debug|x64.ActiveCfg = Debug|x64
107 | {B688E099-77FF-46D9-B61B-5C6D718DDBFB}.Debug|x64.Build.0 = Debug|x64
108 | {B688E099-77FF-46D9-B61B-5C6D718DDBFB}.Debug|x86.ActiveCfg = Debug|Win32
109 | {B688E099-77FF-46D9-B61B-5C6D718DDBFB}.Debug|x86.Build.0 = Debug|Win32
110 | {B688E099-77FF-46D9-B61B-5C6D718DDBFB}.Release|Any CPU.ActiveCfg = Release|Win32
111 | {B688E099-77FF-46D9-B61B-5C6D718DDBFB}.Release|x64.ActiveCfg = Release|x64
112 | {B688E099-77FF-46D9-B61B-5C6D718DDBFB}.Release|x64.Build.0 = Release|x64
113 | {B688E099-77FF-46D9-B61B-5C6D718DDBFB}.Release|x86.ActiveCfg = Release|Win32
114 | {B688E099-77FF-46D9-B61B-5C6D718DDBFB}.Release|x86.Build.0 = Release|Win32
115 | {399AA870-D18B-40BB-AAB2-4DFDDB7B8DE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
116 | {399AA870-D18B-40BB-AAB2-4DFDDB7B8DE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
117 | {399AA870-D18B-40BB-AAB2-4DFDDB7B8DE6}.Debug|x64.ActiveCfg = Debug|Any CPU
118 | {399AA870-D18B-40BB-AAB2-4DFDDB7B8DE6}.Debug|x64.Build.0 = Debug|Any CPU
119 | {399AA870-D18B-40BB-AAB2-4DFDDB7B8DE6}.Debug|x86.ActiveCfg = Debug|Any CPU
120 | {399AA870-D18B-40BB-AAB2-4DFDDB7B8DE6}.Debug|x86.Build.0 = Debug|Any CPU
121 | {399AA870-D18B-40BB-AAB2-4DFDDB7B8DE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
122 | {399AA870-D18B-40BB-AAB2-4DFDDB7B8DE6}.Release|Any CPU.Build.0 = Release|Any CPU
123 | {399AA870-D18B-40BB-AAB2-4DFDDB7B8DE6}.Release|x64.ActiveCfg = Release|Any CPU
124 | {399AA870-D18B-40BB-AAB2-4DFDDB7B8DE6}.Release|x64.Build.0 = Release|Any CPU
125 | {399AA870-D18B-40BB-AAB2-4DFDDB7B8DE6}.Release|x86.ActiveCfg = Release|Any CPU
126 | {399AA870-D18B-40BB-AAB2-4DFDDB7B8DE6}.Release|x86.Build.0 = Release|Any CPU
127 | {F6024B33-8886-47AD-A504-24879BFC0A42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
128 | {F6024B33-8886-47AD-A504-24879BFC0A42}.Debug|Any CPU.Build.0 = Debug|Any CPU
129 | {F6024B33-8886-47AD-A504-24879BFC0A42}.Debug|x64.ActiveCfg = Debug|Any CPU
130 | {F6024B33-8886-47AD-A504-24879BFC0A42}.Debug|x64.Build.0 = Debug|Any CPU
131 | {F6024B33-8886-47AD-A504-24879BFC0A42}.Debug|x86.ActiveCfg = Debug|Any CPU
132 | {F6024B33-8886-47AD-A504-24879BFC0A42}.Debug|x86.Build.0 = Debug|Any CPU
133 | {F6024B33-8886-47AD-A504-24879BFC0A42}.Release|Any CPU.ActiveCfg = Release|Any CPU
134 | {F6024B33-8886-47AD-A504-24879BFC0A42}.Release|Any CPU.Build.0 = Release|Any CPU
135 | {F6024B33-8886-47AD-A504-24879BFC0A42}.Release|x64.ActiveCfg = Release|Any CPU
136 | {F6024B33-8886-47AD-A504-24879BFC0A42}.Release|x64.Build.0 = Release|Any CPU
137 | {F6024B33-8886-47AD-A504-24879BFC0A42}.Release|x86.ActiveCfg = Release|Any CPU
138 | {F6024B33-8886-47AD-A504-24879BFC0A42}.Release|x86.Build.0 = Release|Any CPU
139 | EndGlobalSection
140 | GlobalSection(SolutionProperties) = preSolution
141 | HideSolutionNode = FALSE
142 | EndGlobalSection
143 | GlobalSection(NestedProjects) = preSolution
144 | {F9759A8C-96A7-4012-8EB6-3F34E89859B3} = {96B2940D-00A0-488F-B4F4-3936C689C2E2}
145 | {E85B732E-8A68-4C53-82D2-8F4319A14BB9} = {0EA09D21-043B-437C-83B5-B400D68DFBE0}
146 | {835E9AEC-18FF-4FBB-89F5-0B1AB8A90E4F} = {3050B7C6-A744-4FAC-925C-75DAB2FFD1C3}
147 | {5783067E-D420-462E-943C-4CBA2D74121C} = {53CBE9B1-22D6-4D6F-A78A-0D6FBA9ED000}
148 | {D795C37F-D8D3-4B29-ADBA-548C6711D69B} = {0EA09D21-043B-437C-83B5-B400D68DFBE0}
149 | {3050B7C6-A744-4FAC-925C-75DAB2FFD1C3} = {6DD8E0E9-0838-4299-B9B0-E0B75830CCF0}
150 | {5668BADB-B2CF-4E1A-A885-DC10B11D26B2} = {6DD8E0E9-0838-4299-B9B0-E0B75830CCF0}
151 | {B688E099-77FF-46D9-B61B-5C6D718DDBFB} = {5668BADB-B2CF-4E1A-A885-DC10B11D26B2}
152 | {399AA870-D18B-40BB-AAB2-4DFDDB7B8DE6} = {5668BADB-B2CF-4E1A-A885-DC10B11D26B2}
153 | {F6024B33-8886-47AD-A504-24879BFC0A42} = {5668BADB-B2CF-4E1A-A885-DC10B11D26B2}
154 | EndGlobalSection
155 | GlobalSection(ExtensibilityGlobals) = postSolution
156 | SolutionGuid = {1154050C-AA23-4D3A-80C0-923978F0E163}
157 | EndGlobalSection
158 | EndGlobal
159 |
--------------------------------------------------------------------------------
/src/BindingsForNativeLib/BindingsGenerator/BindingsGenerator.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | netcoreapp3.0
6 | ..\..\..\Bin\
7 | true
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/BindingsForNativeLib/BindingsGenerator/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Net.Http;
4 | using CppAst;
5 | using CppPinvokeGenerator;
6 | using CppPinvokeGenerator.Templates;
7 |
8 | namespace SimdJson
9 | {
10 | public class Program
11 | {
12 | public static void Main(string[] args)
13 | {
14 | // input (single header)
15 | string headerPath = Path.Combine(Environment.CurrentDirectory, "../../src/BindingsForNativeLib/SimdJsonNative/simdjson.h");
16 |
17 | // output
18 | string cgluePath = Path.Combine(Environment.CurrentDirectory, "../../src/BindingsForNativeLib/SimdJsonNative/bindings.cpp");
19 | string bindingsPath = Path.Combine(Environment.CurrentDirectory, "../../src/BindingsForNativeLib/SimdJsonSharp.Bindings/Bindings.Generated.cs");
20 |
21 | var options = new CppParserOptions();
22 | // TODO: test on macOS
23 | options.ConfigureForWindowsMsvc(CppTargetCpu.X86_64);
24 | options.AdditionalArguments.Add("-std=c++17");
25 | CppCompilation compilation = CppParser.ParseFile(headerPath, options);
26 |
27 | if (compilation.DumpErrorsIfAny())
28 | {
29 | Console.ReadKey();
30 | return;
31 | }
32 |
33 | var mapper = new TypeMapper(compilation);
34 | mapper.RenamingForApi += (nativeName, isMethod) =>
35 | {
36 | if (nativeName == "iterator")
37 | return "ParsedJsonIteratorN";
38 | if (!isMethod)
39 | return nativeName + "N"; // SimdJsonSharp has two C# APIs: 1) managed 2) bindings - postfixed with 'N'
40 | if (nativeName == "get_type")
41 | return "GetTokenType";
42 | if (nativeName == "get_string")
43 | return "GetUtf8String";
44 | return nativeName;
45 | };
46 |
47 | // init_state_machine requires external linkage (impl)
48 | mapper.RegisterUnsupportedMethod(null, "init_state_machine");
49 |
50 | // Register native types we don't want to bind (or any method with them in parameters)
51 | mapper.RegisterUnsupportedTypes(
52 | "simdjson", // it's empty - we don't need it
53 | "__m128i",
54 | "simd_input",
55 | "utf8_checking_state",
56 | "basic_string", // TODO:
57 | "basic_string_view", // TODO
58 | "basic_ostream"); // TODO:
59 |
60 | var templateManager = new TemplateManager();
61 |
62 | // Add additional stuff we want to see in the bindings.c
63 | templateManager
64 | .AddToCHeader(@"#include ""simdjson.h""")
65 | .AddToCHeader(@"using namespace simdjson;")
66 | .SetGlobalFunctionsClassName("SimdJsonN");
67 |
68 | PinvokeGenerator.Generate(mapper,
69 | templateManager,
70 | @namespace: "SimdJsonSharp",
71 | dllImportPath: @"SimdJsonN.NativeLib",
72 | outCFile: cgluePath,
73 | outCsFile: bindingsPath);
74 |
75 | Console.WriteLine("Done.");
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/BindingsForNativeLib/SimdJsonNative/Makefile:
--------------------------------------------------------------------------------
1 | OUTPUT_DIR=../../../Bin/
2 |
3 | .PHONY: libSimdJsonNative.dylib
4 |
5 | libSimdJsonNative.dylib:
6 | mkdir -p $(OUTPUT_DIR) && clang simdjson.cpp bindings.cpp -O3 -march=haswell -std=c++17 -dynamiclib -undefined dynamic_lookup -o $(OUTPUT_DIR)libSimdJsonNative.dylib
7 |
--------------------------------------------------------------------------------
/src/BindingsForNativeLib/SimdJsonNative/SimdJsonNative.vcxproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | Win32
7 |
8 |
9 | Release
10 | Win32
11 |
12 |
13 | Debug
14 | x64
15 |
16 |
17 | Release
18 | x64
19 |
20 |
21 |
22 | 15.0
23 | {B688E099-77FF-46D9-B61B-5C6D718DDBFB}
24 | Win32Proj
25 | SimdJsonNative
26 | 10.0
27 |
28 |
29 |
30 | DynamicLibrary
31 | true
32 | v142
33 | Unicode
34 |
35 |
36 | DynamicLibrary
37 | false
38 | v142
39 | true
40 | Unicode
41 |
42 |
43 | DynamicLibrary
44 | true
45 | v142
46 | Unicode
47 |
48 |
49 | DynamicLibrary
50 | false
51 | v142
52 | true
53 | Unicode
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | true
75 | $(SolutionDir)Bin\$(Platform)
76 | $(SolutionDir)Bin\Intermediate
77 |
78 |
79 | true
80 | $(SolutionDir)Bin\$(Platform)
81 | $(SolutionDir)Bin\Intermediate
82 |
83 |
84 | false
85 | $(SolutionDir)Bin\$(Platform)
86 | $(SolutionDir)Bin\Intermediate
87 |
88 |
89 | false
90 | $(SolutionDir)Bin\$(Platform)
91 | $(SolutionDir)Bin\Intermediate
92 |
93 |
94 |
95 | NotUsing
96 | Level3
97 | Disabled
98 | true
99 | WIN32;_DEBUG;SIMDJSONNATIVE_EXPORTS;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_USRDLL;%(PreprocessorDefinitions)
100 | true
101 | true
102 | AdvancedVectorExtensions2
103 | stdcpp17
104 |
105 |
106 | Windows
107 | true
108 |
109 |
110 |
111 |
112 | NotUsing
113 | Level3
114 | Disabled
115 | true
116 | _DEBUG;SIMDJSONNATIVE_EXPORTS;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_USRDLL;%(PreprocessorDefinitions)
117 | true
118 | true
119 | AdvancedVectorExtensions2
120 | stdcpp17
121 |
122 |
123 | Windows
124 | true
125 |
126 |
127 |
128 |
129 | NotUsing
130 | Level3
131 | MaxSpeed
132 | true
133 | true
134 | true
135 | WIN32;NDEBUG;SIMDJSONNATIVE_EXPORTS;_WINDOWS;_CRT_SECURE_NO_WARNINGS;_USRDLL;%(PreprocessorDefinitions)
136 | true
137 | AdvancedVectorExtensions2
138 | stdcpp17
139 |
140 |
141 | Windows
142 | true
143 | true
144 | true
145 |
146 |
147 |
148 |
149 | NotUsing
150 | Level3
151 | MaxSpeed
152 | true
153 | true
154 | true
155 | NDEBUG;SIMDJSONNATIVE_EXPORTS;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
156 | true
157 | AdvancedVectorExtensions2
158 | stdcpp17
159 | Speed
160 | AnySuitable
161 |
162 |
163 | Windows
164 | true
165 | true
166 | true
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
--------------------------------------------------------------------------------
/src/BindingsForNativeLib/SimdJsonNative/SimdJsonNative.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;hm;inl;inc;ipp;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | Source Files
20 |
21 |
22 | Source Files
23 |
24 |
25 |
26 |
27 | Header Files
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/BindingsForNativeLib/SimdJsonSharp.Bindings/Bindings.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 |
4 | namespace SimdJsonSharp
5 | {
6 | public static unsafe partial class SimdJsonN // 'N' stands for Native
7 | {
8 | public const string NativeLib = @"SimdJsonNative";
9 |
10 | public static uint MinifyJson(byte* jsonDataPtr, long jsonDataLength, byte* output) =>
11 | (uint)JsonMinify(jsonDataPtr, jsonDataLength, output);
12 |
13 | public static string MinifyJson(byte[] inputBytes)
14 | {
15 | byte[] outputBytes = new byte[inputBytes.Length]; // no Span and ArrayPool in ns2.0
16 |
17 | fixed (byte* inputBytesPtr = inputBytes)
18 | fixed (byte* outputBytesPtr = outputBytes)
19 | {
20 | uint bytesWritten = MinifyJson(inputBytesPtr, inputBytes.Length, outputBytesPtr);
21 | return Encoding.UTF8.GetString(outputBytes, 0, (int)bytesWritten);
22 | }
23 | }
24 |
25 | public static string MinifyJson(string input)
26 | {
27 | if (string.IsNullOrEmpty(input))
28 | return input;
29 |
30 | byte[] inputBytes = Encoding.UTF8.GetBytes(input);
31 | return MinifyJson(inputBytes);
32 | }
33 |
34 | public static ParsedJsonN ParseJson(byte[] jsonData)
35 | {
36 | fixed (byte* jsonDataPtr = jsonData)
37 | return ParseJson(jsonDataPtr, jsonData.Length);
38 | }
39 |
40 | public static ParsedJsonN ParseJson(byte* jsonDataPtr, long jsonDataLength, bool reallocifneeded = true)
41 | {
42 | ParsedJsonN pj = new ParsedJsonN();
43 | bool ok = pj.AllocateCapacity((uint)jsonDataLength, 1024);
44 | if (ok)
45 | {
46 | JsonParse(jsonDataPtr, jsonDataLength, pj, reallocifneeded);
47 | }
48 | else
49 | {
50 | throw new InvalidOperationException("failure during memory allocation");
51 | }
52 | return pj;
53 | }
54 | }
55 |
56 | // Extend auto-generated stuff here
57 |
58 | public unsafe partial class ParsedJsonIteratorN // 'N' stands for Native
59 | {
60 | internal static readonly UTF8Encoding _utf8Encoding = new UTF8Encoding(false, true);
61 |
62 | public string GetUtf16String() => _utf8Encoding.GetString((byte*)GetUtf8String(), (int)GetStringLength());
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/BindingsForNativeLib/SimdJsonSharp.Bindings/SimdJsonSharp.Bindings.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | netstandard2.0
4 | True
5 | EgorBo
6 |
7 | SimdJson.Bindings: Parsing gigabytes of JSON per second.
8 | C# bindings for lemire/simdjson (written in C++).
9 |
10 | https://github.com/EgorBo/SimdJsonSharp/blob/master/LICENSE
11 | https://github.com/EgorBo/SimdJsonSharp
12 | https://github.com/EgorBo/SimdJsonSharp
13 | simd,json,avx,avx2,sse,ssse3,parsing,minify
14 | (c) lemire, EgorBo
15 | true
16 | https://raw.githubusercontent.com/EgorBo/SimdJsonSharp/master/images/logo.png
17 | 1.8
18 | ..\..\..\Bin\
19 |
20 |
21 |
22 |
23 | runtimes/win-x64/native/SimdJsonNative.dll
24 | true
25 | PreserveNewest
26 |
27 |
28 |
29 |
30 |
37 |
38 |
39 |
40 | runtimes/osx-x64/native/libSimdJsonNative.dylib
41 | true
42 | PreserveNewest
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/src/FullyManagedImpl/Minifier/JsonMinifier.cs:
--------------------------------------------------------------------------------
1 | #if JSON_MINIFY // Adds 500kb to binary because of mask128_epi8 table
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.Intrinsics;
4 | using System.Runtime.Intrinsics.X86;
5 | using System;
6 | using System.Buffers;
7 | using System.Text;
8 |
9 | #region stdint types and friends
10 | // if you change something here please change it in other files too
11 | using size_t = System.UInt64;
12 | using uint8_t = System.Byte;
13 | using uint32_t = System.UInt32;
14 | using uint64_t = System.UInt64;
15 | using int64_t = System.Int64;
16 | using bytechar = System.SByte;
17 | using static SimdJsonSharp.Utils;
18 | #endregion
19 |
20 | namespace SimdJsonSharp
21 | {
22 | internal static unsafe partial class JsonMinifier
23 | {
24 | // a straightforward comparison of a mask against input.
25 | private static uint64_t cmp_mask_against_input_mini(Vector256 input_lo, Vector256 input_hi, Vector256 mask)
26 | {
27 | var cmp_res_0 = Avx2.CompareEqual(input_lo, mask);
28 | uint64_t res_0 = (uint32_t)Avx2.MoveMask(cmp_res_0);
29 | var cmp_res_1 = Avx2.CompareEqual(input_hi, mask);
30 | uint64_t res_1 = (uint64_t)Avx2.MoveMask(cmp_res_1);
31 | return res_0 | (res_1 << 32);
32 | }
33 |
34 | //C#: copied from immintrin.h:
35 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
36 | private static Vector256 _mm256_loadu2_m128i(ulong* hiaddr, ulong* loaddr)
37 | {
38 | var hhi = Sse2.LoadVector128(hiaddr);
39 | var llo = Sse2.LoadVector128(loaddr);
40 | var casted = llo.ToVector256();
41 | return Avx.InsertVector128(casted, hhi, 0x1);
42 | }
43 |
44 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
45 | private static void _mm256_storeu2_m128i(byte* hiaddr, byte* loaddr, Vector256 a)
46 | {
47 | Sse2.Store(loaddr, a.GetLower());
48 | Sse2.Store(hiaddr, Avx.ExtractVector128(a, 0x1));
49 | }
50 |
51 | private static readonly Vector256 s_lut_cntrl = Vector256.Create(
52 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00,
53 | 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54 | 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00);
55 |
56 | private static readonly Vector256 s_low_nibble_mask = Vector256.Create((byte)
57 | // 0 9 a b c d
58 | 16, 0, 0, 0, 0, 0, 0, 0, 0, 8, 12, 1, 2, 9, 0, 0, 16, 0, 0, 0, 0, 0,
59 | 0, 0, 0, 8, 12, 1, 2, 9, 0, 0);
60 |
61 | private static readonly Vector256 s_high_nibble_mask = Vector256.Create((byte)
62 | // 0 2 3 5 7
63 | 8, 0, 18, 4, 0, 1, 0, 1, 0, 0, 0, 3, 2, 1, 0, 0, 8, 0, 18, 4, 0, 1, 0,
64 | 1, 0, 0, 0, 3, 2, 1, 0, 0);
65 |
66 |
67 | // take input from buf and remove useless whitespace, input and output can be
68 | // the same, result is null terminated, return the string length (minus the null termination)
69 | public static size_t Minify(uint8_t* buf, size_t len, uint8_t* @out)
70 | {
71 | if (!Avx2.IsSupported)
72 | throw new NotSupportedException("AVX2 is required form SimdJson");
73 |
74 | //C#: load const vectors once (there is no `const _m256` in C#)
75 | Vector256 lut_cntrl = s_lut_cntrl;
76 | Vector256 low_nibble_mask = s_low_nibble_mask;
77 | Vector256 high_nibble_mask = s_high_nibble_mask;
78 |
79 | fixed (byte* mask128_epi8 = s_mask128_epi8)
80 | {
81 | // Useful constant masks
82 | const uint64_t even_bits = 0x5555555555555555UL;
83 | const uint64_t odd_bits = ~even_bits;
84 | uint8_t* initout = @out;
85 | uint64_t prev_iter_ends_odd_backslash =
86 | 0UL; // either 0 or 1, but a 64-bit value
87 | uint64_t prev_iter_inside_quote = 0UL; // either all zeros or all ones
88 | size_t idx = 0;
89 | if (len >= 64)
90 | {
91 | size_t avxlen = len - 63;
92 |
93 | for (; idx < avxlen; idx += 64)
94 | {
95 | Vector256 input_lo = Avx.LoadVector256((buf + idx + 0));
96 | Vector256 input_hi = Avx.LoadVector256((buf + idx + 32));
97 | uint64_t bs_bits = cmp_mask_against_input_mini(input_lo, input_hi,
98 | Vector256.Create((byte) '\\'));
99 | uint64_t start_edges = bs_bits & ~(bs_bits << 1);
100 | uint64_t even_start_mask = even_bits ^ prev_iter_ends_odd_backslash;
101 | uint64_t even_starts = start_edges & even_start_mask;
102 | uint64_t odd_starts = start_edges & ~even_start_mask;
103 | uint64_t even_carries = bs_bits + even_starts;
104 | uint64_t odd_carries;
105 | bool iter_ends_odd_backslash = add_overflow(
106 | bs_bits, odd_starts, &odd_carries);
107 | odd_carries |= prev_iter_ends_odd_backslash;
108 | prev_iter_ends_odd_backslash = iter_ends_odd_backslash ? 0x1UL : 0x0UL;
109 | uint64_t even_carry_ends = even_carries & ~bs_bits;
110 | uint64_t odd_carry_ends = odd_carries & ~bs_bits;
111 | uint64_t even_start_odd_end = even_carry_ends & odd_bits;
112 | uint64_t odd_start_even_end = odd_carry_ends & even_bits;
113 | uint64_t odd_ends = even_start_odd_end | odd_start_even_end;
114 | uint64_t quote_bits = cmp_mask_against_input_mini(input_lo, input_hi,
115 | Vector256.Create((byte) '"'));
116 | quote_bits = quote_bits & ~odd_ends;
117 | uint64_t quote_mask = Sse2.X64.ConvertToUInt64(Pclmulqdq.CarrylessMultiply(
118 | Vector128.Create(quote_bits, 0UL).AsUInt64(), Vector128.Create((byte) 0xFF).AsUInt64(), 0));
119 | quote_mask ^= prev_iter_inside_quote;
120 | prev_iter_inside_quote =
121 | (uint64_t) ((int64_t) quote_mask >>
122 | 63); // might be undefined behavior, should be fully defined in C++20, ok according to John Regher from Utah University
123 |
124 | Vector256 whitespace_shufti_mask = Vector256.Create((byte) 0x18);
125 | Vector256 v_lo = Avx2.And(
126 | Avx2.Shuffle(low_nibble_mask, input_lo),
127 | Avx2.Shuffle(high_nibble_mask,
128 | Avx2.And(Avx2.ShiftRightLogical(input_lo.AsUInt32(), 4).AsByte(),
129 | Vector256.Create((byte) 0x7f))));
130 |
131 | Vector256 v_hi = Avx2.And(
132 | Avx2.Shuffle(low_nibble_mask, input_hi),
133 | Avx2.Shuffle(high_nibble_mask,
134 | Avx2.And(Avx2.ShiftRightLogical(input_hi.AsUInt32(), 4).AsByte(),
135 | Vector256.Create((byte) 0x7f))));
136 | Vector256 tmp_ws_lo = Avx2.CompareEqual(
137 | Avx2.And(v_lo, whitespace_shufti_mask), Vector256.Create((byte) 0));
138 | Vector256 tmp_ws_hi = Avx2.CompareEqual(
139 | Avx2.And(v_hi, whitespace_shufti_mask), Vector256.Create((byte) 0));
140 |
141 | uint64_t ws_res_0 = (uint32_t) Avx2.MoveMask(tmp_ws_lo);
142 | uint64_t ws_res_1 = (uint64_t) Avx2.MoveMask(tmp_ws_hi);
143 | uint64_t whitespace = ~(ws_res_0 | (ws_res_1 << 32));
144 | whitespace &= ~quote_mask;
145 | int mask1 = (int) (whitespace & 0xFFFF);
146 | int mask2 = (int) ((whitespace >> 16) & 0xFFFF);
147 | int mask3 = (int) ((whitespace >> 32) & 0xFFFF);
148 | int mask4 = (int) ((whitespace >> 48) & 0xFFFF);
149 | int pop1 = (int)hamming((~whitespace) & 0xFFFF);
150 | int pop2 = (int)hamming((~whitespace) & (ulong) (0xFFFFFFFF));
151 | int pop3 = (int)hamming((~whitespace) & (ulong) (0xFFFFFFFFFFFF));
152 | int pop4 = (int)hamming((~whitespace));
153 | var vmask1 =
154 | _mm256_loadu2_m128i((ulong*)mask128_epi8 + (mask2 & 0x7FFF)*2,
155 | (ulong*)mask128_epi8 + (mask1 & 0x7FFF)*2);
156 | var vmask2 =
157 | _mm256_loadu2_m128i((ulong*)mask128_epi8 + (mask4 & 0x7FFF)*2,
158 | (ulong*)mask128_epi8 + (mask3 & 0x7FFF)*2);
159 | var result1 = Avx2.Shuffle(input_lo, vmask1.AsByte());
160 | var result2 = Avx2.Shuffle(input_hi, vmask2.AsByte());
161 | _mm256_storeu2_m128i((@out + pop1), @out, result1);
162 | _mm256_storeu2_m128i((@out + pop3), (@out + pop2),
163 | result2);
164 | @out += pop4;
165 | }
166 | }
167 |
168 | // we finish off the job... copying and pasting the code is not ideal here,
169 | // but it gets the job done.
170 | if (idx < len)
171 | {
172 | uint8_t* buffer = stackalloc uint8_t[64];
173 | memset(buffer, 0, 64);
174 | memcpy(buffer, buf + idx, len - idx);
175 | var input_lo = Avx.LoadVector256((buffer));
176 | var input_hi = Avx.LoadVector256((buffer + 32));
177 | uint64_t bs_bits =
178 | cmp_mask_against_input_mini(input_lo, input_hi, Vector256.Create((byte) '\\'));
179 | uint64_t start_edges = bs_bits & ~(bs_bits << 1);
180 | uint64_t even_start_mask = even_bits ^ prev_iter_ends_odd_backslash;
181 | uint64_t even_starts = start_edges & even_start_mask;
182 | uint64_t odd_starts = start_edges & ~even_start_mask;
183 | uint64_t even_carries = bs_bits + even_starts;
184 | uint64_t odd_carries;
185 | //bool iter_ends_odd_backslash =
186 | add_overflow(bs_bits, odd_starts, &odd_carries);
187 | odd_carries |= prev_iter_ends_odd_backslash;
188 | //prev_iter_ends_odd_backslash = iter_ends_odd_backslash ? 0x1ULL : 0x0ULL; // we never use it
189 | uint64_t even_carry_ends = even_carries & ~bs_bits;
190 | uint64_t odd_carry_ends = odd_carries & ~bs_bits;
191 | uint64_t even_start_odd_end = even_carry_ends & odd_bits;
192 | uint64_t odd_start_even_end = odd_carry_ends & even_bits;
193 | uint64_t odd_ends = even_start_odd_end | odd_start_even_end;
194 | uint64_t quote_bits =
195 | cmp_mask_against_input_mini(input_lo, input_hi, Vector256.Create((byte) '"'));
196 | quote_bits = quote_bits & ~odd_ends;
197 | uint64_t quote_mask = Sse2.X64.ConvertToUInt64(Pclmulqdq.CarrylessMultiply(
198 | Vector128.Create(quote_bits, 0UL), Vector128.Create((byte) 0xFF).AsUInt64(), 0));
199 | quote_mask ^= prev_iter_inside_quote;
200 | // prev_iter_inside_quote = (uint64_t)((int64_t)quote_mask >> 63);// we don't need this anymore
201 |
202 | Vector256 mask_20 = Vector256.Create((byte) 0x20); // c==32
203 | Vector256 mask_70 =
204 | Vector256.Create((byte) 0x70); // adding 0x70 does not check low 4-bits
205 | // but moves any value >= 16 above 128
206 |
207 | Vector256 tmp_ws_lo = Avx2.Or(
208 | Avx2.CompareEqual(mask_20, input_lo),
209 | Avx2.Shuffle(lut_cntrl, Avx2.AddSaturate(mask_70, input_lo)));
210 | Vector256 tmp_ws_hi = Avx2.Or(
211 | Avx2.CompareEqual(mask_20, input_hi),
212 | Avx2.Shuffle(lut_cntrl, Avx2.AddSaturate(mask_70, input_hi)));
213 | uint64_t ws_res_0 = (uint32_t) Avx2.MoveMask(tmp_ws_lo);
214 | uint64_t ws_res_1 = (uint64_t) Avx2.MoveMask(tmp_ws_hi);
215 | uint64_t whitespace = (ws_res_0 | (ws_res_1 << 32));
216 | whitespace &= ~quote_mask;
217 |
218 | if (len - idx < 64)
219 | {
220 | whitespace |= ((0xFFFFFFFFFFFFFFFF) << (int)(len - idx));
221 | }
222 |
223 | int mask1 = (int) (whitespace & 0xFFFF);
224 | int mask2 = (int) ((whitespace >> 16) & 0xFFFF);
225 | int mask3 = (int) ((whitespace >> 32) & 0xFFFF);
226 | int mask4 = (int) ((whitespace >> 48) & 0xFFFF);
227 | int pop1 = (int)hamming((~whitespace) & 0xFFFF);
228 | int pop2 = (int)hamming((~whitespace) & 0xFFFFFFFF);
229 | int pop3 = (int)hamming((~whitespace) & 0xFFFFFFFFFFFF);
230 | int pop4 = (int)hamming((~whitespace));
231 |
232 | var vmask1 =
233 | _mm256_loadu2_m128i((ulong*)mask128_epi8 + (mask2 & 0x7FFF)*2,
234 | (ulong*)mask128_epi8 + (mask1 & 0x7FFF)*2);
235 | var vmask2 =
236 | _mm256_loadu2_m128i((ulong*)mask128_epi8 + (mask4 & 0x7FFF)*2,
237 | (ulong*)mask128_epi8 + (mask3 & 0x7FFF)*2);
238 | var result1 = Avx2.Shuffle(input_lo, vmask1.AsByte());
239 | var result2 = Avx2.Shuffle(input_hi, vmask2.AsByte());
240 | _mm256_storeu2_m128i((buffer + pop1), buffer,
241 | result1);
242 | _mm256_storeu2_m128i((buffer + pop3), (buffer + pop2),
243 | result2);
244 | memcpy(@out, buffer, (size_t) pop4);
245 | @out += pop4;
246 | }
247 |
248 | *@out = (byte) '\0'; // NULL termination
249 | return (size_t)@out - (size_t)initout;
250 | }
251 | }
252 | }
253 | }
254 | #endif
--------------------------------------------------------------------------------
/src/FullyManagedImpl/ParsedJson.cs:
--------------------------------------------------------------------------------
1 | // This file is a manual port of C code https://github.com/lemire/simdjson to C#
2 | // (c) Daniel Lemire and Geoff Langdale
3 |
4 | using System;
5 | using System.Runtime.CompilerServices;
6 | using System.Runtime.Intrinsics.X86;
7 |
8 | #region stdint types and friends
9 | using size_t = System.UInt64;
10 | using uint8_t = System.Byte;
11 | using uint64_t = System.UInt64;
12 | using uint32_t = System.UInt32;
13 | using int64_t = System.Int64;
14 | using char1 = System.SByte;
15 | using static SimdJsonSharp.Utils;
16 | #endregion
17 |
18 | namespace SimdJsonSharp
19 | {
20 | public unsafe class ParsedJson : IDisposable
21 | {
22 | internal size_t bytecapacity; // indicates how many bits are meant to be supported
23 | internal size_t depthcapacity; // how deep we can go
24 | internal size_t tapecapacity;
25 | internal size_t stringcapacity;
26 | internal uint32_t current_loc;
27 | internal uint32_t n_structural_indexes;
28 | internal uint32_t* structural_indexes;
29 | internal uint64_t* tape;
30 | internal uint32_t* containing_scope_offset;
31 | internal char1* ret_address;
32 | internal uint8_t* string_buf; // should be at least bytecapacity
33 | internal uint8_t* current_string_buf_loc;
34 | internal bool isvalid;
35 | internal bool isDisposed;
36 |
37 | public JsonParseError ErrorCode { get; internal set; }
38 |
39 | public ParsedJson()
40 | {
41 | if (!Sse42.IsSupported || IntPtr.Size == 4)
42 | throw new NotSupportedException("SimdJson requires AVX2 or SSE42 and x64");
43 | }
44 |
45 | // if needed, allocate memory so that the object is able to process JSON
46 | // documents having up to len bytes and maxdepth "depth"
47 | public bool AllocateCapacity(size_t len, size_t maxdepth = DEFAULTMAXDEPTH)
48 | {
49 | if ((maxdepth == 0) || (len == 0))
50 | {
51 | return false;
52 | }
53 | if (len > SIMDJSON_MAXSIZE_BYTES)
54 | {
55 | return false;
56 | }
57 | if ((len <= bytecapacity) && (depthcapacity < maxdepth))
58 | {
59 | return true;
60 | }
61 | Deallocate();
62 | isvalid = false;
63 | bytecapacity = 0; // will only set it to len after allocations are a success
64 | n_structural_indexes = 0;
65 | uint32_t max_structures = (uint32_t)(ROUNDUP_N(len, 64) + 2 + 7);
66 | structural_indexes = allocate(max_structures);
67 | // a pathological input like "[[[[..." would generate len tape elements, so need a capacity of len + 1
68 | size_t localtapecapacity = ROUNDUP_N(len + 1, 64);
69 | // a document with only zero-length strings... could have len/3 string
70 | // and we would need len/3 * 5 bytes on the string buffer
71 | size_t localstringcapacity = ROUNDUP_N(5 * len / 3 + 32, 64);
72 | string_buf = allocate (localstringcapacity);
73 | tape = allocate (localtapecapacity);
74 | containing_scope_offset = allocate (maxdepth);
75 | ret_address = allocate(maxdepth);
76 | if ((string_buf == null) || (tape == null) ||
77 | (containing_scope_offset == null) || (ret_address == null) || (structural_indexes == null))
78 | {
79 | delete(ret_address);
80 | delete(containing_scope_offset);
81 | delete(tape);
82 | delete(string_buf);
83 | delete(structural_indexes);
84 | return false;
85 | }
86 | /*
87 | // We do not need to initialize this content for parsing, though we could
88 | // need to initialize it for safety.
89 | memset(string_buf, 0 , localstringcapacity);
90 | memset(structural_indexes, 0, max_structures * sizeof(uint32_t));
91 | memset(tape, 0, localtapecapacity * sizeof(uint64_t));
92 | */
93 | bytecapacity = len;
94 | depthcapacity = maxdepth;
95 | tapecapacity = localtapecapacity;
96 | stringcapacity = localstringcapacity;
97 | return true;
98 | }
99 |
100 | private void Deallocate()
101 | {
102 | bytecapacity = 0;
103 | depthcapacity = 0;
104 | tapecapacity = 0;
105 | stringcapacity = 0;
106 | delete(ret_address);
107 | delete(containing_scope_offset);
108 | delete(tape);
109 | delete(string_buf);
110 | delete(structural_indexes);
111 | isvalid = false;
112 | }
113 |
114 | public void Dispose() => Dispose(true);
115 |
116 | private void Dispose(bool disposing)
117 | {
118 | if (disposing)
119 | GC.SuppressFinalize(this);
120 |
121 | if (!isDisposed)
122 | {
123 | isDisposed = true;
124 | Deallocate();
125 | }
126 | }
127 |
128 | ~ParsedJson()
129 | {
130 | Dispose(false);
131 | }
132 |
133 | public bool IsValid => isvalid;
134 |
135 | // this should be called when parsing (right before writing the tapes)
136 | public void Init()
137 | {
138 | current_string_buf_loc = string_buf;
139 | current_loc = 0;
140 | isvalid = false;
141 | }
142 |
143 | // all nodes are stored on the tape using a 64-bit word.
144 | //
145 | // strings, double and ints are stored as
146 | // a 64-bit word with a pointer to the actual value
147 | //
148 | //
149 | //
150 | // for objects or arrays, store [ or { at the beginning and } and ] at the
151 | // end. For the openings ([ or {), we annotate them with a reference to the
152 | // location on the tape of the end, and for then closings (} and ]), we
153 | // annotate them with a reference to the location of the opening
154 | //
155 | //
156 |
157 | // this should be considered a private function
158 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
159 | public void WriteTape(uint64_t val, uint8_t c)
160 | {
161 | tape[current_loc++] = val | (((uint64_t) c) << 56);
162 | }
163 |
164 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
165 | public void WriteTapeInt64(int64_t i)
166 | {
167 | WriteTape(0, (uint8_t) 'l');
168 | tape[current_loc++] = *((uint64_t*) &i);
169 | }
170 |
171 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
172 | public void WriteTapeDouble(double d)
173 | {
174 | WriteTape(0, (uint8_t) 'd');
175 | memcpy(&tape[current_loc++], &d, sizeof(double));
176 | //tape[current_loc++] = *((uint64_t *)&d);
177 | }
178 |
179 | public uint32_t CurrentLoc => current_loc;
180 |
181 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
182 | public void AnnotatePreviousLoc(uint32_t saved_loc, uint64_t val) => tape[saved_loc] |= val;
183 |
184 | public ParsedJsonIterator CreateIterator() => new ParsedJsonIterator(this);
185 | }
186 |
187 | internal struct scopeindex_t
188 | {
189 | public size_t start_of_scope;
190 | public uint8_t scope_type;
191 | }
192 | }
193 |
--------------------------------------------------------------------------------
/src/FullyManagedImpl/SimdJson.cs:
--------------------------------------------------------------------------------
1 | // This file is a manual port of C code https://github.com/lemire/simdjson to C#
2 | // (c) Daniel Lemire and Geoff Langdale
3 |
4 | using System;
5 | using System.Buffers;
6 | using System.Text;
7 |
8 | using static SimdJsonSharp.Utils;
9 |
10 | namespace SimdJsonSharp
11 | {
12 | public static unsafe class SimdJson
13 | {
14 | public static ParsedJson ParseJson(byte* jsonData, ulong length, bool reallocIfNeeded = true)
15 | {
16 | var pj = new ParsedJson();
17 | bool ok = pj.AllocateCapacity(length);
18 | if (ok)
19 | JsonParse(jsonData, length, pj, reallocIfNeeded);
20 | else
21 | {
22 | pj.isvalid = false;
23 | pj.ErrorCode = JsonParseError.CAPACITY;
24 | }
25 | return pj;
26 | }
27 |
28 | public static ParsedJson ParseJson(byte* jsonData, int length) => ParseJson(jsonData, (ulong) length, true);
29 |
30 | public static string MinifyJson(string input)
31 | {
32 | if (string.IsNullOrEmpty(input))
33 | return input;
34 |
35 | ReadOnlySpan inputBytes = Encoding.UTF8.GetBytes(input);
36 | var length = inputBytes.Length;
37 | byte[] pool = null;
38 |
39 | try
40 | {
41 | Span span = length <= 2048 ?
42 | stackalloc byte[2048] :
43 | (pool = ArrayPool.Shared.Rent(length));
44 |
45 | MinifyJson(inputBytes, span, out int bytesWritten);
46 | return Encoding.UTF8.GetString(span.Slice(0, bytesWritten));
47 | }
48 | finally
49 | {
50 | if (pool != null)
51 | ArrayPool.Shared.Return(pool);
52 | }
53 | }
54 |
55 | public static void MinifyJson(ReadOnlySpan input, Span output, out int bytesWritten)
56 | {
57 | #if JSON_MINIFY
58 | if ((uint)input.Length < 1)
59 | {
60 | bytesWritten = 0;
61 | return;
62 | }
63 |
64 | if ((uint)output.Length < 1)
65 | throw new ArgumentException("Output is empty");
66 |
67 | //TODO: how to validate output length?
68 |
69 | fixed (byte* inputPtr = input)
70 | fixed (byte* outputPtr = output)
71 | {
72 | bytesWritten = (int)JsonMinifier.Minify(inputPtr, (ulong)input.Length, outputPtr);
73 | }
74 | #else
75 | throw new NotSupportedException("SimdJsonSharp was compiled without `JSON_MINIFY`.");
76 | #endif
77 | }
78 |
79 | private static readonly long pagesize = Environment.SystemPageSize;
80 |
81 | internal static JsonParseError JsonParse(byte* jsonData, UInt64 length, ParsedJson pj, bool reallocIfNeeded = true)
82 | {
83 | if (pj.bytecapacity < length)
84 | return JsonParseError.CAPACITY;
85 |
86 | bool reallocated = false;
87 | if (reallocIfNeeded)
88 | {
89 | byte* tmpbuf = jsonData;
90 | jsonData = (byte*)allocate_padded_buffer(length);
91 | if (jsonData == null) return JsonParseError.MEMALLOC;
92 | memcpy((void*)jsonData, tmpbuf, length);
93 | reallocated = true;
94 | }
95 |
96 | JsonParseError stage1_is_ok = stage1_find_marks.find_structural_bits(jsonData, length, pj);
97 | if (stage1_is_ok != JsonParseError.SUCCESS)
98 | {
99 | pj.ErrorCode = stage1_is_ok;
100 | return pj.ErrorCode;
101 | }
102 | JsonParseError res = stage2_build_tape.unified_machine(jsonData, length, pj);
103 | if (reallocated) { aligned_free((void*)jsonData); }
104 | return res;
105 |
106 | }
107 | }
108 |
109 | public enum JsonParseError
110 | {
111 | SUCCESS = 0,
112 | CAPACITY, // This ParsedJson can't support a document that big
113 | MEMALLOC, // Error allocating memory, most likely out of memory
114 | TAPE_ERROR, // Something went wrong while writing to the tape (stage 2), this is a generic error
115 | DEPTH_ERROR, // Your document exceeds the user-specified depth limitation
116 | STRING_ERROR, // Problem while parsing a string
117 | T_ATOM_ERROR, // Problem while parsing an atom starting with the letter 't'
118 | F_ATOM_ERROR, // Problem while parsing an atom starting with the letter 'f'
119 | N_ATOM_ERROR, // Problem while parsing an atom starting with the letter 'n'
120 | NUMBER_ERROR, // Problem while parsing a number
121 | UTF8_ERROR, // the input is not valid UTF-8
122 | UNITIALIZED, // unknown error, or uninitialized document
123 | EMPTY, // no structural document found
124 | UNESCAPED_CHARS, // found unescaped characters in a string.
125 | UNCLOSED_STRING, // missing quote at the end
126 | UNEXPECTED_ERROR // indicative of a bug in simdjson
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/src/FullyManagedImpl/SimdJsonSharp.Managed.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.0
5 | latest
6 | true
7 | JSON_MINIFY
8 | EgorBo
9 | SimdJson: Parsing gigabytes of JSON per second.
10 | C# version of lemire/simdjdon (written in C++).
11 |
12 | https://github.com/EgorBo/SimdJsonSharp/blob/master/LICENSE
13 | https://github.com/EgorBo/SimdJsonSharp
14 | https://github.com/EgorBo/SimdJsonSharp
15 | simd,json,avx,avx2,sse,ssse3,parsing,minify
16 | (c) lemire, EgorBo
17 | true
18 | https://raw.githubusercontent.com/EgorBo/SimdJsonSharp/master/images/logo.png
19 | 1.5
20 | ..\..\Bin\
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/FullyManagedImpl/ThrowHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace SimdJsonSharp
6 | {
7 | internal static class ThrowHelper
8 | {
9 | public static void ThrowPNSE()
10 | {
11 | throw new PlatformNotSupportedException();
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/FullyManagedImpl/Utf8Validation.cs:
--------------------------------------------------------------------------------
1 | // This file is a manual port of C code https://github.com/lemire/simdjson to C#
2 | // (c) Daniel Lemire and Geoff Langdale
3 |
4 | #if SIMDJSON_UTF8VALIDATE // NOT TESTED YET!
5 | using System;
6 | using System.Runtime.CompilerServices;
7 | using System.Runtime.Intrinsics;
8 | using System.Runtime.Intrinsics.X86;
9 |
10 | #region stdint types and friends
11 | // if you change something here please change it in other files too
12 | using size_t = System.UInt64;
13 | using uint8_t = System.Byte;
14 | using uint64_t = System.UInt64;
15 | using uint32_t = System.UInt32;
16 | using int64_t = System.Int64;
17 | using bytechar = System.SByte;
18 | using unsigned_bytechar = System.Byte;
19 | using uintptr_t = System.UIntPtr;
20 | using static SimdJsonSharp.Utils;
21 | #endregion
22 |
23 | namespace SimdJsonSharp
24 | {
25 | internal unsafe partial class Utf8Validation
26 | {
27 | internal static avx_processed_utf_bytes avxcheckUTF8Bytes(Vector256 current_bytes, ref avx_processed_utf_bytes previous, ref Vector256 has_error)
28 | {
29 | avx_processed_utf_bytes pb = new avx_processed_utf_bytes();
30 | avx_count_nibbles(current_bytes, ref pb);
31 | avxcheckSmallerThan0xF4(current_bytes, ref has_error);
32 | Vector256 initial_lengths = avxcontinuationLengths(pb.high_nibbles);
33 | pb.carried_continuations =
34 | avxcarryContinuations(initial_lengths, previous.carried_continuations);
35 | avxcheckContinuations(initial_lengths, pb.carried_continuations, ref has_error);
36 | Vector256 off1_current_bytes = push_last_byte_of_a_to_b(previous.rawbytes, pb.rawbytes);
37 | avxcheckFirstContinuationMax(current_bytes, off1_current_bytes, ref has_error);
38 | avxcheckOverlong(current_bytes, off1_current_bytes, pb.high_nibbles, previous.high_nibbles, ref has_error);
39 | return pb;
40 | }
41 |
42 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
43 | static Vector256 push_last_byte_of_a_to_b(Vector256 a, Vector256 b)
44 | {
45 | return Avx2.AlignRight(b, Avx2.Permute2x128(a, b, 0x21), 15);
46 | }
47 |
48 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
49 | static Vector256 push_last_2bytes_of_a_to_b(Vector256 a, Vector256 b)
50 | {
51 | return Avx2.AlignRight(b, Avx2.Permute2x128(a, b, 0x21), 14);
52 | }
53 |
54 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
55 | internal static void avx_count_nibbles(Vector256 bytes, ref avx_processed_utf_bytes answer)
56 | {
57 | answer.rawbytes = bytes;
58 | answer.high_nibbles = Avx2.And(Avx2.ShiftRightLogical(bytes.AsUInt16(), 4).AsByte(), Vector256.Create((byte)0x0F));
59 | }
60 |
61 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
62 | static void avxcheckSmallerThan0xF4(Vector256 current_bytes, ref Vector256 has_error)
63 | {
64 | // unsigned, saturates to 0 below max
65 | has_error = Avx2.Or(
66 | has_error, Avx2.SubtractSaturate(current_bytes, Vector256.Create((byte)0xF4)));
67 | }
68 |
69 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
70 | static Vector256 avxcontinuationLengths(Vector256 high_nibbles)
71 | {
72 | return Avx2.Shuffle(
73 | Vector256.Create((byte)1, 1, 1, 1, 1, 1, 1, 1, // 0xxx (ASCII)
74 | 0, 0, 0, 0, // 10xx (continuation)
75 | 2, 2, // 110x
76 | 3, // 1110
77 | 4, // 1111, next should be 0 (not checked here)
78 | 1, 1, 1, 1, 1, 1, 1, 1, // 0xxx (ASCII)
79 | 0, 0, 0, 0, // 10xx (continuation)
80 | 2, 2, // 110x
81 | 3, // 1110
82 | 4 // 1111, next should be 0 (not checked here)
83 | ),
84 | high_nibbles);
85 | }
86 |
87 |
88 | static Vector256 avxcarryContinuations(Vector256 initial_lengths,
89 | Vector256 previous_carries)
90 | {
91 | Vector256 right1 = Avx2.SubtractSaturate(
92 | push_last_byte_of_a_to_b(previous_carries, initial_lengths),
93 | Vector256.Create((byte)1));
94 | Vector256 sum = Avx2.Add(initial_lengths, right1);
95 |
96 | Vector256 right2 = Avx2.SubtractSaturate(
97 | push_last_2bytes_of_a_to_b(previous_carries, sum), Vector256.Create((byte)2));
98 | return Avx2.Add(sum, right2);
99 | }
100 |
101 | static void avxcheckContinuations(Vector256 initial_lengths,
102 | Vector256 carries, ref Vector256 has_error)
103 | {
104 |
105 | // overlap || underlap
106 | // carry > length && length > 0 || !(carry > length) && !(length > 0)
107 | // (carries > length) == (lengths > 0)
108 | Vector256 overunder = Avx2.CompareEqual(
109 | Avx2.CompareGreaterThan(carries.AsSByte(), initial_lengths.AsSByte()).AsByte(),
110 | Avx2.CompareGreaterThan(initial_lengths.AsSByte(), Vector256.Zero).AsByte());
111 |
112 | has_error = Avx2.Or(has_error, overunder);
113 | }
114 |
115 | // when 0xED is found, next byte must be no larger than 0x9F
116 | // when 0xF4 is found, next byte must be no larger than 0x8F
117 | // next byte must be continuation, ie sign bit is set, so signed < is ok
118 | static void avxcheckFirstContinuationMax(Vector256 current_bytes,
119 | Vector256 off1_current_bytes,
120 | ref Vector256 has_error)
121 | {
122 | Vector256 maskED =
123 | Avx2.CompareEqual(off1_current_bytes, Vector256.Create((byte)0xED));
124 | Vector256 maskF4 =
125 | Avx2.CompareEqual(off1_current_bytes, Vector256.Create((byte)0xF4));
126 |
127 | Vector256 badfollowED = Avx2.And(
128 | Avx2.CompareGreaterThan(current_bytes.AsSByte(), Vector256.Create((byte)0x9F).AsSByte()).AsByte(), maskED);
129 | Vector256 badfollowF4 = Avx2.And(
130 | Avx2.CompareGreaterThan(current_bytes.AsSByte(), Vector256.Create((byte)0x8F).AsSByte()).AsByte(), maskF4);
131 |
132 | has_error =
133 | Avx2.Or(has_error, Avx2.Or(badfollowED, badfollowF4));
134 | }
135 |
136 | // map off1_hibits => error condition
137 | // hibits off1 cur
138 | // C => < C2 && true
139 | // E => < E1 && < A0
140 | // F => < F1 && < 90
141 | // else false && false
142 | static void avxcheckOverlong(Vector256 current_bytes,
143 | Vector256 off1_current_bytes, Vector256 hibits,
144 | Vector256 previous_hibits,
145 | ref Vector256 has_error)
146 | {
147 | Vector256 off1_hibits = push_last_byte_of_a_to_b(previous_hibits, hibits);
148 | Vector256 initial_mins = Avx2.Shuffle(
149 | //Vector256.Create(-128, -128, -128, -128, -128, -128, -128, -128, -128,
150 | // -128, -128, -128, // 10xx => false
151 | // 0xC2, -128, // 110x
152 | // 0xE1, // 1110
153 | // 0xF1, -128, -128, -128, -128, -128, -128, -128, -128,
154 | // -128, -128, -128, -128, // 10xx => false
155 | // 0xC2, -128, // 110x
156 | // 0xE1, // 1110
157 | // 0xF1),
158 | Vector256.Create(9259542123273814144, 17429353605768446080, 9259542123273814144, 17429353605768446080).AsByte(),
159 | off1_hibits);
160 |
161 | Vector256 initial_under = Avx2.CompareGreaterThan(initial_mins.AsSByte(), off1_current_bytes.AsSByte()).AsByte();
162 |
163 | Vector256 second_mins = Avx2.Shuffle(
164 | //Vector256.Create(-128, -128, -128, -128, -128, -128, -128, -128, -128,
165 | // -128, -128, -128, // 10xx => false
166 | // 127, 127, // 110x => true
167 | // 0xA0, // 1110
168 | // 0x90, -128, -128, -128, -128, -128, -128, -128, -128,
169 | // -128, -128, -128, -128, // 10xx => false
170 | // 127, 127, // 110x => true
171 | // 0xA0, // 1110
172 | // 0x90),
173 | Vector256.Create(9259542123273814144, 10421469723328807040, 9259542123273814144, 10421469723328807040).AsByte(),
174 | off1_hibits);
175 | Vector256 second_under = Avx2.CompareGreaterThan(second_mins.AsSByte(), current_bytes.AsSByte()).AsByte();
176 | has_error = Avx2.Or(has_error, Avx2.And(initial_under, second_under));
177 | }
178 | }
179 |
180 | internal struct avx_processed_utf_bytes
181 | {
182 | public Vector256 rawbytes;
183 | public Vector256 high_nibbles;
184 | public Vector256 carried_continuations;
185 | };
186 | }
187 | #endif
--------------------------------------------------------------------------------
/src/FullyManagedImpl/Utils/stringparsing.cs:
--------------------------------------------------------------------------------
1 | // This file is a manual port of C code https://github.com/lemire/simdjson to C#
2 | // (c) Daniel Lemire and Geoff Langdale
3 |
4 | using System;
5 | using System.Runtime.CompilerServices;
6 | using System.Runtime.Intrinsics;
7 | using System.Runtime.Intrinsics.X86;
8 |
9 | using static SimdJsonSharp.Utils;
10 |
11 | #region stdint types and friends
12 | using size_t = System.UInt64;
13 | using char1 = System.Byte;
14 | using uint8_t = System.Byte;
15 | using uint32_t = System.UInt32;
16 | #endregion
17 |
18 | namespace SimdJsonSharp
19 | {
20 | internal static unsafe class stringparsing
21 | {
22 | // begin copypasta
23 | // These chars yield themselves: " \ /
24 | // b -> backspace, f -> formfeed, n -> newline, r -> cr, t -> horizontal tab
25 | // u not handled in this table as it's complex
26 | static ReadOnlySpan escape_map => new uint8_t[256] // Roslyn hack
27 | {
28 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x0.
29 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
30 | 0, 0, 0x22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2f,
31 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
32 |
33 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x4.
34 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x5c, 0, 0, 0, // 0x5.
35 | 0, 0, 0x08, 0, 0, 0, 0x0c, 0, 0, 0, 0, 0, 0, 0, 0x0a, 0, // 0x6.
36 | 0, 0, 0x0d, 0, 0x09, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x7.
37 |
38 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
39 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
40 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
41 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
42 |
43 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
44 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
45 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
46 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
47 | };
48 |
49 | // handle a unicode codepoint
50 | // write appropriate values into dest
51 | // src will advance 6 bytes or 12 bytes
52 | // dest will advance a variable amount (return via pointer)
53 | // return true if the unicode codepoint was valid
54 | // We work in little-endian then swap at write time
55 |
56 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
57 | internal static bool handle_unicode_codepoint(uint8_t** src_ptr, uint8_t** dst_ptr)
58 | {
59 | // hex_to_u32_nocheck fills high 16 bits of the return value with 1s if the
60 | // conversion isn't valid; we defer the check for this to inside the
61 | // multilingual plane check
62 | uint32_t code_point = hex_to_u32_nocheck(*src_ptr + 2);
63 | *src_ptr += 6;
64 | // check for low surrogate for characters outside the Basic
65 | // Multilingual Plane.
66 | if (code_point >= 0xd800 && code_point < 0xdc00)
67 | {
68 | if (((*src_ptr)[0] != '\\') || (*src_ptr)[1] != 'u')
69 | {
70 | return false;
71 | }
72 |
73 | uint32_t code_point_2 = hex_to_u32_nocheck(*src_ptr + 2);
74 |
75 | // if the first code point is invalid we will get here, as we will go past
76 | // the check for being outside the Basic Multilingual plane. If we don't
77 | // find a \u immediately afterwards we fail out anyhow, but if we do,
78 | // this check catches both the case of the first code point being invalid
79 | // or the second code point being invalid.
80 | if ((code_point | code_point_2) >> 16 != 0)
81 | {
82 | return false;
83 | }
84 |
85 | code_point = (((code_point - 0xd800) << 10) | (code_point_2 - 0xdc00)) + 0x10000;
86 | *src_ptr += 6;
87 | }
88 |
89 | size_t offset = codepoint_to_utf8(code_point, *dst_ptr);
90 | *dst_ptr += offset;
91 | return offset > 0;
92 | }
93 |
94 | // Holds backslashes and quotes locations.
95 | internal struct parse_string_helper
96 | {
97 | public uint32_t bs_bits;
98 | public uint32_t quote_bits;
99 | };
100 |
101 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
102 | internal static parse_string_helper find_bs_bits_and_quote_bits(uint8_t* src, uint8_t* dst)
103 | {
104 | if (Avx2.IsSupported)
105 | {
106 | // this can read up to 31 bytes beyond the buffer size, but we require
107 | // SIMDJSON_PADDING of padding
108 | var v = Avx.LoadVector256(src);
109 | // store to dest unconditionally - we can overwrite the bits we don't like
110 | // later
111 | Avx.Store((dst), v);
112 | var quote_mask = Avx2.CompareEqual(v, Vector256.Create((uint8_t) '"'));
113 | return new parse_string_helper
114 | {
115 | bs_bits = (uint32_t) Avx2.MoveMask(Avx2.CompareEqual(v, Vector256.Create((uint8_t) '\\'))), // bs_bits
116 | quote_bits = (uint32_t) Avx2.MoveMask(quote_mask) // quote_bits
117 | };
118 | }
119 | else // SSE42
120 | {
121 | // this can read up to 31 bytes beyond the buffer size, but we require
122 | // SIMDJSON_PADDING of padding
123 | var v = Sse2.LoadVector128((src));
124 | // store to dest unconditionally - we can overwrite the bits we don't like
125 | // later
126 | Sse2.Store((dst), v);
127 | var quote_mask = Sse2.CompareEqual(v, Vector128.Create((uint8_t) '"'));
128 | return new parse_string_helper
129 | {
130 | bs_bits = (uint32_t) Sse2.MoveMask(Sse2.CompareEqual(v,
131 | Vector128.Create((uint8_t) '\\'))), // bs_bits
132 | quote_bits = (uint32_t) Sse2.MoveMask(quote_mask) // quote_bits
133 | };
134 | }
135 | }
136 |
137 |
138 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
139 | internal static bool parse_string(uint8_t* buf, size_t len, ParsedJson pj, uint32_t depth, uint32_t offset)
140 | {
141 | pj.WriteTape((ulong) (pj.current_string_buf_loc - pj.string_buf), (char1) '"');
142 | uint8_t* src = &buf[offset + 1]; // we know that buf at offset is a "
143 | uint8_t* dst = pj.current_string_buf_loc + sizeof(uint32_t);
144 | uint8_t* start_of_string = dst;
145 | while (true)
146 | {
147 | parse_string_helper helper = find_bs_bits_and_quote_bits(src, dst);
148 | if (((helper.bs_bits - 1) & helper.quote_bits) != 0)
149 | {
150 | // we encountered quotes first. Move dst to point to quotes and exit
151 | // find out where the quote is...
152 | uint32_t quote_dist = (uint32_t) trailingzeroes(helper.quote_bits);
153 |
154 | // NULL termination is still handy if you expect all your strings to be NULL terminated?
155 | // It comes at a small cost
156 | dst[quote_dist] = 0;
157 |
158 | uint32_t str_length = (uint32_t) ((dst - start_of_string) + quote_dist);
159 | memcpy(pj.current_string_buf_loc, &str_length, sizeof(uint32_t));
160 | ///////////////////////
161 | // Above, check for overflow in case someone has a crazy string (>=4GB?)
162 | // But only add the overflow check when the document itself exceeds 4GB
163 | // Currently unneeded because we refuse to parse docs larger or equal to 4GB.
164 | ////////////////////////
165 |
166 | // we advance the point, accounting for the fact that we have a NULL termination
167 | pj.current_string_buf_loc = dst + quote_dist + 1;
168 |
169 | return true;
170 | }
171 |
172 | if (((helper.quote_bits - 1) & helper.bs_bits) != 0)
173 | {
174 | // find out where the backspace is
175 | uint32_t bs_dist = (uint32_t) trailingzeroes(helper.bs_bits);
176 | uint8_t escape_char = src[bs_dist + 1];
177 | // we encountered backslash first. Handle backslash
178 | if (escape_char == 'u')
179 | {
180 | // move src/dst up to the start; they will be further adjusted
181 | // within the unicode codepoint handling code.
182 | src += bs_dist;
183 | dst += bs_dist;
184 | if (!handle_unicode_codepoint(&src, &dst))
185 | {
186 | return false;
187 | }
188 | }
189 | else
190 | {
191 | // simple 1:1 conversion. Will eat bs_dist+2 characters in input and
192 | // write bs_dist+1 characters to output
193 | // note this may reach beyond the part of the buffer we've actually
194 | // seen. I think this is ok
195 | uint8_t escape_result = escape_map[escape_char]; // TODO: https://github.com/dotnet/coreclr/issues/25894
196 | if (escape_result == 0u)
197 | {
198 | return false; // bogus escape value is an error
199 | }
200 |
201 | dst[bs_dist] = escape_result;
202 | src += bs_dist + 2;
203 | dst += bs_dist + 1;
204 | }
205 | }
206 | else
207 | {
208 | // they are the same. Since they can't co-occur, it means we encountered
209 | // neither.
210 | if (!Avx2.IsSupported)
211 | {
212 | src += 16; // sse42
213 | dst += 16;
214 | }
215 | else
216 | {
217 | src += 32; // avx2
218 | dst += 32;
219 | }
220 | }
221 | }
222 | }
223 | }
224 | }
225 |
--------------------------------------------------------------------------------
/tests/MinifierTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Reflection;
4 | using System.Text;
5 | using Xunit;
6 |
7 | namespace SimdJsonSharp.Tests
8 | {
9 | public class MinifierTests
10 | {
11 | private string testDataDir;
12 |
13 | public MinifierTests()
14 | {
15 | string currentDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
16 | testDataDir = Path.Join(Directory.GetParent(currentDir).Parent.Parent.Parent.FullName, "jsonexamples");
17 | }
18 |
19 | //[Fact]
20 | public void ValidateMinifier()
21 | {
22 | string json = @"{
23 | ""Egor"": ""Bogatov""
24 | }
25 | ";
26 |
27 | string minifiedJson = SimdJson.MinifyJson(json);
28 | Assert.Equal(@"{""Egor"":""Bogatov""}", minifiedJson);
29 | // TODO: more tests
30 | }
31 |
32 | [Fact]
33 | public unsafe void ValidateMinimizedJson()
34 | {
35 | string[] files = Directory.GetFiles(testDataDir, "*.json", SearchOption.AllDirectories);
36 | // 20 files, ~15Mb of JSON
37 | Assert.NotEmpty(files);
38 | foreach (string file in files)
39 | {
40 | ReadOnlySpan fileData = File.ReadAllBytes(file);
41 | Span output = new byte[fileData.Length];
42 | SimdJson.MinifyJson(fileData, output, out int bytesWritten);
43 | output = output.Slice(0, bytesWritten);
44 |
45 | fixed (byte* outPtr = output)
46 | using (ParsedJson doc = SimdJson.ParseJson(outPtr, (ulong)output.Length))
47 | Assert.True(doc.IsValid);
48 | }
49 | }
50 |
51 | [Fact]
52 | public unsafe void ValidateMinimizedJsonN()
53 | {
54 | string[] files = Directory.GetFiles(testDataDir, "*.json", SearchOption.AllDirectories);
55 | // 20 files, ~15Mb of JSON
56 | Assert.NotEmpty(files);
57 | foreach (string file in files)
58 | {
59 | string minifiedJson = SimdJsonN.MinifyJson(File.ReadAllBytes(file));
60 | var output = Encoding.UTF8.GetBytes(minifiedJson);
61 |
62 | fixed (byte* outPtr = output)
63 | using (ParsedJsonN doc = SimdJsonN.ParseJson(outPtr, output.Length))
64 | Assert.True(doc.IsValid());
65 | }
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/tests/SimdJsonSharp.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.0
5 | latest
6 | true
7 |
8 |
9 |
10 |
11 |
12 |
13 | all
14 | runtime; build; native; contentfiles; analyzers; buildtransitive
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/tests/ValidateTestFilesTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Reflection;
4 | using System.Collections.Generic;
5 | using Xunit;
6 | using System.Text.Json;
7 | using System.Text;
8 |
9 | namespace SimdJsonSharp.Tests
10 | {
11 | public class ValidateTestFilesTests
12 | {
13 | private string testDataDir;
14 |
15 | public ValidateTestFilesTests()
16 | {
17 | string currentDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
18 | testDataDir = Path.Join(Directory.GetParent(currentDir).Parent.Parent.Parent.FullName, "jsonexamples");
19 | }
20 |
21 | [Fact]
22 | public unsafe void ValidateAllFiles()
23 | {
24 | string[] files = Directory.GetFiles(testDataDir, "*.json", SearchOption.AllDirectories);
25 | // 20 files, ~15Mb of JSON
26 | Assert.NotEmpty(files);
27 | foreach (string file in files)
28 | {
29 | byte[] fileData = File.ReadAllBytes(file);
30 | fixed (byte* ptr = fileData)
31 | using (ParsedJson doc = SimdJson.ParseJson(ptr, (ulong)fileData.Length))
32 | Assert.True(doc.IsValid);
33 | }
34 | }
35 |
36 | [Fact]
37 | public unsafe void ValidateAllFilesN()
38 | {
39 | string[] files = Directory.GetFiles(testDataDir, "*.json", SearchOption.AllDirectories);
40 | // 20 files, ~15Mb of JSON
41 | Assert.NotEmpty(files);
42 | foreach (string file in files)
43 | {
44 | byte[] fileData = File.ReadAllBytes(file);
45 | fixed (byte* ptr = fileData)
46 | using (ParsedJsonN doc = SimdJsonN.ParseJson(ptr, fileData.Length))
47 | Assert.True(doc.IsValid());
48 | }
49 | }
50 |
51 | [Fact]
52 | public unsafe void ValidateStrings()
53 | {
54 | string invalidJson = @"{ ""name"": ""\udc00\ud800\uggggxy"" }";
55 | var bytes = Encoding.UTF8.GetBytes(invalidJson);
56 |
57 | fixed (byte* ptr = bytes)
58 | {
59 | using (ParsedJson doc = SimdJson.ParseJson(ptr, (ulong)bytes.Length))
60 | {
61 | Assert.False(doc.IsValid);
62 | Assert.Throws(() => doc.CreateIterator());
63 | }
64 | }
65 | }
66 |
67 | [Fact]
68 | public unsafe void ParseDoubles()
69 | {
70 | byte[] fileData = File.ReadAllBytes(Path.Combine(testDataDir, "canada.json"));
71 | var simdDoubles = new List();
72 | var referenceDoubles = new List();
73 |
74 | fixed (byte* ptr = fileData)
75 | {
76 | using (ParsedJson doc = SimdJson.ParseJson(ptr, (ulong)fileData.Length))
77 | {
78 | using (var iterator = doc.CreateIterator())
79 | {
80 | while (iterator.MoveForward())
81 | {
82 | if (iterator.IsDouble || iterator.IsInteger)
83 | {
84 | simdDoubles.Add(iterator.GetDouble());
85 | }
86 | }
87 | }
88 | }
89 | }
90 |
91 | // compare with doubles from Utf8JsonReader
92 | Utf8JsonReader reader = new Utf8JsonReader(fileData, true, default);
93 | while (reader.Read())
94 | {
95 | if (reader.TokenType == JsonTokenType.Number) //Utf8JsonReader doesn't have a token type for Double/Float
96 | {
97 | referenceDoubles.Add(reader.GetDouble());
98 | }
99 | }
100 |
101 | for (int i = 0; i < simdDoubles.Count; i++)
102 | {
103 | var doubleSimd = simdDoubles[i];
104 | var doubleRef = referenceDoubles[i];
105 | // TODO: compare
106 | }
107 | }
108 | }
109 | }
110 |
--------------------------------------------------------------------------------