{"id":36420965,"url":"https://github.com/green4j/green-jelly","last_synced_at":"2026-01-11T17:35:23.009Z","repository":{"id":52170927,"uuid":"150099566","full_name":"green4j/green-jelly","owner":"green4j","description":"Garbage-free (green), simple and fast stream oriented JSON parser and generator if you need to parse/generate mega(giga)bytes of data with no GC pauses","archived":false,"fork":false,"pushed_at":"2025-04-30T17:11:13.000Z","size":411,"stargazers_count":25,"open_issues_count":2,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-30T18:26:17.785Z","etag":null,"topics":["fast","java","json","json-generator","json-parser","streaming"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/green4j.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-09-24T12:32:41.000Z","updated_at":"2025-04-30T17:11:17.000Z","dependencies_parsed_at":"2024-12-10T18:34:27.536Z","dependency_job_id":"667dce40-306c-4133-9aa6-ffd6524f678e","html_url":"https://github.com/green4j/green-jelly","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/green4j/green-jelly","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/green4j%2Fgreen-jelly","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/green4j%2Fgreen-jelly/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/green4j%2Fgreen-jelly/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/green4j%2Fgreen-jelly/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/green4j","download_url":"https://codeload.github.com/green4j/green-jelly/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/green4j%2Fgreen-jelly/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28315879,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-11T14:58:17.114Z","status":"ssl_error","status_checked_at":"2026-01-11T14:55:53.580Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fast","java","json","json-generator","json-parser","streaming"],"created_at":"2026-01-11T17:35:22.347Z","updated_at":"2026-01-11T17:35:23.004Z","avatar_url":"https://github.com/green4j.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Green Jelly\n\n[![Build CI](https://github.com/green4j/green-jelly/actions/workflows/build.yml/badge.svg)](https://github.com/green4j/green-jelly/actions/workflows/build.yml)\n\nGC-free (green) JSON parser/generator library for Java which isn't an object mapper, but aims to be:\n\n* **minimal**: MIT licensed with no dependencies\n* **reactive styled**: the parser can parse a JSON document part by part (i.e. if you have received the part from a block device), even byte by byte; you don't need to iterate over all the tokens with verbose `if` or `switch`, just handle a callback you are interested in\n* **lightweight**: the code never recurses or allocates more memory than it needs, the Flyweight patern can be used to wrap a receive/send buffer to prevent memory copying\n* **fast**: high performance, more than comparable with other state-of-the-art parsers like Gson and Jackson (see [Performance](#performance)). No additional GC pauses introduced, since the code doesn't allocate new memory in its main/critical path\n* **IO buffering oriented**: the parser can be fed with several parts of one single JSON document, even byte by byte; so it's easy to use it with buffering read\n* **robust**: built according to [Ecma-404](https://www.ecma-international.org/publications/standards/Ecma-404.htm) with some extensions for the number values (see [Numbers](#numbers))\n\n## Binaries\n\nBinaries for Maven, Ivy, Gradle, and others can be found at \n[https://central.sonatype.com/search?q=green-jelly](https://central.sonatype.com/search?q=green-jelly).\n\nExample for Maven:\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.github.green4j\u003c/groupId\u003e\n    \u003cartifactId\u003egreen-jelly\u003c/artifactId\u003e\n    \u003cversion\u003e${greenJelly.version}\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## How to build\n\nJust run the standard Gradle build and install process:\n\n```\n    ./gradlew\n```\n\n## Usage\n\n### JsonParser\n\nThe generic pattern of the usage if the following:\n* create an instance of the JsonParser\n* set a listener (an instance of the `JsonParserListener` interface) to get all parsing events\n* call the `parse` method as many times as many parts of a JSON document you have\n* finish the parsing with a call of the `eoj`(End Of JSON) method (or use `parseAndEoj` method)\n* parse next JSON document with the same instance of the parser\n\n```java\nfinal JsonParser parser = new JsonParser();\nparser.setListener(new JsonParserListener() {\n...\n});\n\nparser.parse(\"\\\"st\");\nparser.parse(\"ring\\\"\");\nparser.eoj();\n\nparser.parseAndEoj(\"[1,2,3]\");\n```\n#### JsonStringBuilder\n\nWhile creating an instance of the `JsonParser`, an instance of the `JsonStringBuilder` can be passed to `JsonParser`'s constructor. The responsibility of the `JsonStringBuilder` is to store characters of a string value. There are two implementations of the interface included to the library:\n\n* **CopyingStringBuilder**: copies the character of string values to internal buffer. Should be used when not the whole JSON document can be parsed at once (i.e. you use reusable/mutable buffer to receive the data via `receive` system call). Also, this builder supports *unescaping* on-the-fly.\n* **FlyweightStringBuilder**: stores the reference to a CharSequence passed to the `parse` method and knows the length of the string value. This builder prevents you from memory copying, but it requires any string value must be fitted into one instance of CharSequence. Also, *unescaping* isn't supported, since the length of the result string value, passed to the `onStringValue(CharSequence data)` callback, must be the same as the length of the original string.\n\n#### JsonParserListener\n\nWhile parsing you can be notified about the following events with an instance of the JsonParserListener:\n\n```\nvoid onJsonStarted();\n\nvoid onError(String error, int position);\n\nvoid onJsonEnded();\n\nboolean onObjectStarted();\n\nboolean onObjectMember(CharSequence name);\n\nboolean onObjectEnded();\n\nboolean onArrayStarted();\n\nboolean onArrayEnded();\n\nboolean onStringValue(CharSequence data);\n\nboolean onNumberValue(JsonNumber number);\n\nboolean onNumberValue(JsonNumber number, boolean overflow); // optional, has a default implementation\n\nboolean onTrueValue();\n\nboolean onFalseValue();\n\nboolean onNullValue();\n```\nIf any of method returns `false`, the parsing stops and can continue then (see [Parsing with steps](#parsing-with-steps)).\nThere is a default implementation of the listener in the library `JsonParserListenerAdapter`. All callbacks of the adaptor are empty and just return `true`.\n\n#### Numbers\n\nSupported format of number values is a bit more relaxed than specified in [Ecma-404](https://www.ecma-international.org/publications/standards/Ecma-404.htm):\n* the numbers can start with both `+` or `-`\n* the leading zeros are allowed for both mantissa and exponent\n* mantissa is presented by java's signed long which is a bit wider than JavaScript numbers [-(2^53)+1, (2^53)-1]\n\nTo prevent memory allocation and unnecessary computations, the library doesn't implement any fixed or floating point arithmetic. Numbers are presented with the following interface:\n```java\npublic interface JsonNumber {\n\n    long mantissa();\n\n    int exp();\n\n}\n```\nFeel free to use any type of arithmetic like [decimal4j](https://github.com/tools4j/decimal4j), which supports GC-free calculations, out-of-the-box `java.math.BigDecimal`, which a bit slow and allocates new memory, etc. An example of `java.math.BigDecimal` using:\n\n```java\nJsonNumber number = ...\nBigDecimal decimal = BigDecimal.valueOf(number.mantissa(), -number.exp());\n```\nSometimes vendor sends numbers as string values. To parse such values you can use static `JsonParser.parseNumber` method:\n```java\nMutableJsonNumber number = new MutableJsonNumber();\nJsonParser.parseNumber(\"134.4455\", number);\nSystem.out.println(number);\n```\n\n#### Error handling\n\nIf the parser detects an error while parsing, you receive a notification with the `onError(String error, int position)` callback. Also, after the control is given back from the `parse` method, you can check the error with the following methods:\n```\nboolean hasError()\n\nString getError()\n    \nint getErrorPosition()\n```\n#### Parsing with steps\nSometimes you may need to split the process of parsing into some steps. In this case you return `false` from any of `JsonEventListener`'s callback. The parsing stops with an instance of the `Next` returned back. You call `Next.next()` until it returns `null`. For example, the following code prints each number on new line:\n\n```java\nfinal var valueHolder = new Object() {\n    long value;\n}; // mutable value with the final reference\n\nfinal JsonParser parser = new JsonParser().setListener(\n   new JsonParserListenerAdaptor() {\n       @Override\n       public boolean onNumberValue(final JsonNumber number) {\n            valueHolder.value = number.mantissa();\n            return false; // stop the parsing after each number\n        }\n    }\n);\n\nJsonParser.Next nextStep = parser.parse(\"[0,10,20,30,40,5\");\nwhile (nextStep != null) {\n    System.out.println(valueHolder.value);\n    nextStep = nextStep.next();\n}\n\nnextStep = parser.parse(\"0,60,70,80,90,100]\");\nwhile (nextStep != null) {\n    System.out.println(valueHolder.value);\n    nextStep = nextStep.next();\n}\nparser.eoj();\n```\n\n### JsonGenerator\n\nAn example:\n```java\nfinal AppendableWriter\u003cStringBuilder\u003e writer = new AppendableWriter\u003c\u003e(new StringBuilder());\nfinal JsonGenerator generator = new JsonGenerator();\ngenerator.setOutput(writer);\n       \ngenerator.startArray();\ngenerator.stringValue(\"\\test1\", true); // the value requires to be escaped\ngenerator.stringValue(\"test2\");\ngenerator.stringValue(\"test3\");\ngenerator.endArray();\ngenerator.eoj();\n\nSystem.out.println(writer.output().toString());\n```\n\n### Encodings\n\nThe library works over character based abstractions, so, it doesn't implement any encoding functionality. As in case of Gson, for instance, the user has to care about correct bytes-to/from-chars transformation if any required.\n\nAt the same time, there are few specific classes to support JSON generation in different encodings if required:\n\n| Json Writer                                    | Buffer Type/Encoding                                                             |\n|------------------------------------------------|----------------------------------------------------------------------------------|\n| `io.github.green4j.jelly.AsciiByteArrayWriter` | Byte array of ASCII encoded data. All characters outside 0-127 range are escaped |\n| `io.github.green4j.jelly.Utf8ByteArrayWriter`  | Byte array of UTF-8 encoded data                                                 |\n| `io.github.green4j.jelly.CharArrayWriter`      | Char array. Can be used as is, or to be converted later to any other encoding    |\n\nEach of the classes has its own internal mutable buffer which can be passed to IO routines after JSON is generated.\n\n## Performance\n\nA JMH test, which sums all numbers in the document in streaming style, compared to Gson (v.2.8.5) and Jackson (v.2.9.7):\n```\nBenchmark                                                   Mode  Cnt      Score     Error  Units\nJsonParserPerformanceComparison.greenJellyFlyweightSumTest  avgt   25  17747.965 ± 257.699  ns/op\nJsonParserPerformanceComparison.gsonJsonReaderSumTest       avgt   25  23442.288 ± 109.931  ns/op\nJsonParserPerformanceComparison.jacksonJsonParserSumTest    avgt   25  18336.310 ± 220.573  ns/op\n```\n\n\u003cdetails\u003e\u003csummary markdown=\"span\"\u003e\u003ccode\u003eSource code of the test\u003c/code\u003e\u003c/summary\u003e\n\u003cp\u003e\n\n```java\nimport com.fasterxml.jackson.core.JsonFactory;\nimport com.google.gson.stream.JsonReader;\nimport com.google.gson.stream.JsonToken;\nimport java.io.IOException;\nimport java.io.StringReader;\nimport java.util.concurrent.TimeUnit;\nimport FlyweightStringBuilder;\nimport JsonNumber;\nimport JsonParser;\nimport JsonParserListenerAdaptor;\nimport org.openjdk.jmh.annotations.Benchmark;\nimport org.openjdk.jmh.annotations.BenchmarkMode;\nimport org.openjdk.jmh.annotations.Level;\nimport org.openjdk.jmh.annotations.Mode;\nimport org.openjdk.jmh.annotations.OutputTimeUnit;\nimport org.openjdk.jmh.annotations.Scope;\nimport org.openjdk.jmh.annotations.Setup;\nimport org.openjdk.jmh.annotations.State;\nimport org.openjdk.jmh.annotations.TearDown;\n\n@BenchmarkMode(Mode.AverageTime)\n@OutputTimeUnit(TimeUnit.NANOSECONDS)\npublic class JsonParserPerformanceComparison {\n\n    public static final String JSON = \"[\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":true},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":false},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":true},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":false},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":true},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":false},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":true},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":false},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":true},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":false},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":true},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":false},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":true},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":false},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":true},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":false},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":true},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":false},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":true},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":false},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":true},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":false},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":true},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":false},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":true},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":false},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":true},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":false},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":true},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":false},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":true},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":false},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":true},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":false},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":true},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":false},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":true},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":false},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":true},\\n\"\n        + \"  {\\\"property1\\\":100,\\\"property2\\\":200,\\\"property3\\\":300,\\\"property4\\\":[400,500,600,700],\\\"property5\\\":false}\\n\"\n        + \"]\";\n\n    @State(Scope.Thread)\n    public static class JellyFlyweightSum extends JsonParserListenerAdaptor {\n\n        public JsonParser parser;\n        public long value;\n\n        @Setup(Level.Invocation)\n        public void doSetup() {\n            value = 0;\n            parser = new JsonParser(new FlyweightStringBuilder());\n            parser.setListener(this);\n        }\n\n        @TearDown(Level.Invocation)\n        public void doTearDown() {\n            parser.eoj();\n        }\n\n        @Override\n        public boolean onNumberValue(final JsonNumber number) {\n            value += number.mantissa();\n            return true;\n        }\n    }\n\n    @State(Scope.Thread)\n    public static class GsonSum {\n        JsonReader reader;\n        long value;\n\n        @Setup(Level.Invocation)\n        public void doSetup() {\n            value = 0;\n            reader = new JsonReader(new StringReader(JSON));\n        }\n\n        @TearDown(Level.Invocation)\n        public void doTearDown() throws IOException {\n            reader.close();\n        }\n    }\n\n    @State(Scope.Thread)\n    public static class JacksonSum {\n        com.fasterxml.jackson.core.JsonParser parser;\n        long value;\n\n        @Setup(Level.Invocation)\n        public void doSetup() throws Exception {\n            value = 0;\n            final JsonFactory factory = new JsonFactory();\n            parser = factory.createParser(JSON);\n        }\n\n        @TearDown(Level.Invocation)\n        public void doTearDown() throws Exception {\n            parser.close();\n        }\n    }\n\n    @Benchmark\n    public void greenJellyFlyweightSumTest(final JellyFlyweightSum sum) {\n        sum.parser.parse(JSON);\n    }\n    \n    @Benchmark\n    public void gsonJsonReaderSumTest(final GsonSum sum) throws IOException {\n        final JsonReader reader = sum.reader;\n        _end:\n        while (true) {\n            final JsonToken token = reader.peek();\n            switch (token) {\n                case BEGIN_ARRAY:\n                    reader.beginArray();\n                    break;\n                case END_ARRAY:\n                    reader.endArray();\n                    break;\n                case BEGIN_OBJECT:\n                    reader.beginObject();\n                    break;\n                case END_OBJECT:\n                    reader.endObject();\n                    break;\n                case NAME:\n                    reader.skipValue();\n                    break;\n                case STRING:\n                    reader.skipValue();\n                    break;\n                case NUMBER:\n                    sum.value += reader.nextLong();\n                    break;\n                case BOOLEAN:\n                    reader.skipValue();\n                    break;\n                case NULL:\n                    reader.skipValue();\n                    break;\n                case END_DOCUMENT:\n                    break _end;\n            }\n        }\n    }\n\n    @Benchmark\n    public void jacksonJsonParserSumTest(final JacksonSum sum) throws IOException {\n        final com.fasterxml.jackson.core.JsonParser parser = sum.parser;\n        com.fasterxml.jackson.core.JsonToken token;\n        while ((token = parser.nextToken()) != null) {\n            if (token == com.fasterxml.jackson.core.JsonToken.VALUE_NUMBER_INT) {\n                sum.value += parser.getLongValue();\n            }\n        }\n    }\n}\n```\n\u003c/p\u003e\n\u003c/details\u003e\n\n## JSON Value\n\nSometimes we don't worry about memory consumption and CPU utilization, but we need a simple way to work \nwith JSON documents. And we would prefer to don't introduce complex POJO structures and involve object mapping. \nA good example of approach like that is the `JSON.simple` library. The `Green-Jelly` also provides similar \npackage `io.github.green4j.jelly.simple`.\n\nThe `io.github.green4j.jelly.simple.JsonValue` class is the main class to construct a representation of a JSON document:\n```\nfinal JsonValue json = JsonValue.newObject();\nfinal JsonObject user = json.asObject();\nuser.putString(\"name\", \"Mike\");\nuser.putInteger(\"age\", 23);\nfinal JsonArray rates = user.putArray(\"rates\");\nrates.addInteger(10);\nrates.addInteger(8);\n```\n\nA `JsonValue` can be serialized with a `io.github.green4j.jelly.simple.JsonWriter` or with a `java.io.Writer`:\n```\nfinal JsonValue json = ...\n\nfinal StringBuilder output = new StringBuilder();\nfinal JsonWriter jsonWriter = new JsonWriterGenerator(new JsonGenerator(output));\njson.toJsonAndEoj(jsonWriter);\nSystem.out.println(output);\n\nfinal StringWriter stringWriter = new StringWriter();\njson.toJsonAndEoj(stringWriter);\nSystem.out.println(stringWriter);\n```\n\nTo parse JSON and build a `JsonValue`, use the `JsonValueParser` class:\n```\nfinal JsonValueParser parser = new JsonValueParser();\nfinal JsonValue json = parser.parseAndEoj(\"{ \\\"name\\\": \\\"Mike\\\", \\\"age\\\": 23 }\");\nSystem.out.println(json);   \n```\n\n## License\nThe code is available under the terms of the [MIT License](http://opensource.org/licenses/MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgreen4j%2Fgreen-jelly","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgreen4j%2Fgreen-jelly","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgreen4j%2Fgreen-jelly/lists"}