{"id":13431735,"url":"https://github.com/neuecc/Utf8Json","last_synced_at":"2025-03-16T12:31:19.341Z","repository":{"id":38709443,"uuid":"103818079","full_name":"neuecc/Utf8Json","owner":"neuecc","description":"Definitely Fastest and Zero Allocation JSON Serializer for C#(NET, .NET Core, Unity, Xamarin).","archived":true,"fork":false,"pushed_at":"2022-05-16T05:46:16.000Z","size":3380,"stargazers_count":2351,"open_issues_count":174,"forks_count":264,"subscribers_count":87,"default_branch":"master","last_synced_at":"2024-05-28T04:34:19.787Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C#","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/neuecc.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}},"created_at":"2017-09-17T09:40:41.000Z","updated_at":"2024-05-27T11:18:33.000Z","dependencies_parsed_at":"2022-09-13T03:10:17.983Z","dependency_job_id":null,"html_url":"https://github.com/neuecc/Utf8Json","commit_stats":null,"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neuecc%2FUtf8Json","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neuecc%2FUtf8Json/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neuecc%2FUtf8Json/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neuecc%2FUtf8Json/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/neuecc","download_url":"https://codeload.github.com/neuecc/Utf8Json/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":221663621,"owners_count":16859867,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2024-07-31T02:01:05.465Z","updated_at":"2024-10-27T10:32:21.578Z","avatar_url":"https://github.com/neuecc.png","language":"C#","readme":"# THIS PROJECT IS ARCHIVED, USE COMMUNITY FORK INSTEAD.\n\nUtf8Json - Fast JSON Serializer for C#\n===\n\n[![Join the chat at https://gitter.im/neuecc/Utf8Json](https://badges.gitter.im/neuecc/Utf8Json.svg)](https://gitter.im/neuecc/Utf8Json?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n [![Releases](https://img.shields.io/github/release/neuecc/Utf8Json.svg)](https://github.com/neuecc/Utf8Json/releases)\n\nDefinitely Fastest and Zero Allocation JSON Serializer for C#(.NET, .NET Core, Unity and Xamarin), this serializer write/read directly to UTF8 binary so boostup performance. And I adopt the same architecture as the fastest binary serializer, [MessagePack for C#](https://github.com/neuecc/MessagePack-CSharp) that I've developed.\n\n![image](https://user-images.githubusercontent.com/46207/30883721-11e0526e-a348-11e7-86f8-efff85a9afe0.png)\n\n\u003e This benchmark is convert object to UTF8 and UTF8 to object benchmark. It is not to string(.NET UTF16), so [Jil](https://github.com/kevin-montrose/Jil/), [NetJSON](https://github.com/rpgmaker/NetJSON/) and [Json.NET](https://github.com/JamesNK/Newtonsoft.Json) contains additional UTF8.GetBytes/UTF8.GetString call. **Definitely** means does not exists encoding/decoding cost. Benchmark code is in [sandbox/PerfBenchmark](https://github.com/neuecc/Utf8Json/tree/master/sandbox/PerfBenchmark) by [BenchmarkDotNet](https://github.com/dotnet/BenchmarkDotNet).\n\n\u003e I've tested more benchmark - [Benchmark of Jil vs Utf8Json](https://github.com/neuecc/Jil) for test many dataset patterns(borrwed from  Jil Benchmark) and three input/output compare(`Object \u003c-\u003e byte[](Utf8), Object \u003c-\u003e Stream(Utf8) and Object \u003c-\u003e String(UTF16)`). If target is UTF8(both `byte[]` and `Stream`), Utf8Json wins and memory allocated is extremely small.\n\nUtf8Json does not beat MessagePack for C#(binary), but shows a similar memory consumption(there is no additional memory allocation) and achieves higher performance than other JSON serializers.\n\nThe crucial difference is that read and write directly to UTF8 binaries means that there is no overhead. Normaly serialization requires serialize to `Stream` or `byte[]`, it requires additional UTF8.GetBytes cost or StreamReader/Writer overhead(it is very slow!).\n\n```csharp\nTargetClass obj1;\n\n// Object to UTF8 byte[]\n[Benchmark]\npublic byte[] Utf8JsonSerializer()\n{\n    return Utf8Json.JsonSerializer.Serialize(obj1, jsonresolver);\n}\n\n// Object to String to UTF8 byte[]\n[Benchmark]\npublic byte[] Jil()\n{\n    return utf8.GetBytes(global::Jil.JSON.Serialize(obj1));\n}\n\n// Object to Stream with StreamWriter\n[Benchmark]\npublic void JilTextWriter()\n{\n    using (var ms = new MemoryStream())\n    using (var sw = new StreamWriter(ms, utf8))\n    {\n        global::Jil.JSON.Serialize(obj1, sw);\n    }\n}\n```\n\nFor example, the `OutputFormatter` of [ASP.NET Core](https://github.com/aspnet/Home) needs to write to Body(`Stream`), but using [Jil](https://github.com/kevin-montrose/Jil)'s TextWriter overload is slow. (This not means Jil is slow, for example `StreamWriter` allocate many memory(`char[1024]` and `byte[3075]`) on constructor ([streamwriter.cs#L203-L204](https://github.com/Microsoft/referencesource/blob/master/mscorlib/system/io/streamwriter.cs#L203-L204)) and other slow features unfortunately).\n\n```csharp\n// ASP.NET Core, OutputFormatter\npublic class JsonOutputFormatter : IOutputFormatter //, IApiResponseTypeMetadataProvider\n{\n    const string ContentType = \"application/json\";\n    static readonly string[] SupportedContentTypes = new[] { ContentType };\n\n    public Task WriteAsync(OutputFormatterWriteContext context)\n    {\n        context.HttpContext.Response.ContentType = ContentType;\n\n        // Jil, normaly JSON Serializer requires serialize to Stream or byte[].\n        using (var writer = new StreamWriter(context.HttpContext.Response.Body))\n        {\n            Jil.JSON.Serialize(context.Object, writer, _options);\n            writer.Flush();\n            return Task.CompletedTask;\n        }\n\n        // Utf8Json\n        // Utf8Json.JsonSerializer.NonGeneric.Serialize(context.ObjectType, context.HttpContext.Response.Body, context.Object, resolver);\n    }\n}\n```\n\nThe approach of directly write/read from JSON binary is similar to [corefxlab/System.Text.Json](https://github.com/dotnet/corefxlab/tree/master/src/System.Text.Json/System/Text/Json) and [corefxlab/System.Text.Formatting](https://github.com/dotnet/corefxlab/wiki/System.Text.Formatting). But it is not yet finished and not be general serializer.\n\nCorefxlab has [UTF8String](https://github.com/dotnet/corefxlab/issues/1751) and C# discussing [UTF8String Constants](https://github.com/dotnet/csharplang/issues/909) but maybe it is far future.\n\nInstall and QuickStart\n---\nThe library provides in NuGet except for Unity. Standard library availables for .NET Framework 4.5 and .NET Standard 2.0.\n\n```\nInstall-Package Utf8Json\n```\n\nAnd official Extension Packages for support other library(ImmutableCollection) or binding for framework(ASP.NET Core MVC).\n\n```\nInstall-Package Utf8Json.ImmutableCollection\nInstall-Package Utf8Json.UnityShims\nInstall-Package Utf8Json.AspNetCoreMvcFormatter\n```\n\nNuGet page links - [Utf8Json](https://www.nuget.org/packages/Utf8Json), [Utf8Json.ImmutableCollection](https://www.nuget.org/packages/Utf8Json.ImmutableCollection), [Utf8Json.UnityShims](https://www.nuget.org/packages/Utf8Json.UnityShims), [Utf8Json.AspNetCoreMvcFormatter](https://www.nuget.org/packages/Utf8Json.AspNetCoreMvcFormatter)\n\nfor Unity, you can download from [releases](https://github.com/neuecc/Utf8Json/releases) page. There providing .unitypackage. Unity support details, see [Unity section](https://github.com/neuecc/Utf8Json#for-unity).\n\nYou can find third-party extension package like [Utf8Json.FSharpExtensions](https://github.com/pocketberserker/Utf8Json.FSharpExtensions) for F# types, [NServiceBus.Utf8Json](https://www.nuget.org/packages/NServiceBus.Utf8Json/) or others.\n\nQuickStart, you can call `Utf8Json.JsonSerializer`.`Serialize/Deserialize`.\n\n```csharp\nvar p = new Person { Age = 99, Name = \"foobar\" };\n\n// Object -\u003e byte[] (UTF8)\nbyte[] result = JsonSerializer.Serialize(p);\n\n// byte[] -\u003e Object\nvar p2 = JsonSerializer.Deserialize\u003cPerson\u003e(result);\n\n// Object -\u003e String\nvar json = JsonSerializer.ToJsonString(p2);\n\n// Write to Stream\nJsonSerializer.Serialize(stream, p2);\n```\n\nIn default, you can serialize all public members. You can customize serialize to private, exclude null, change DateTime format(default is ISO8601), enum handling, etc. see the [Resolver](https://github.com/neuecc/Utf8Json#resolver) section.\n\nPerformance of Serialize\n---\nThis image is what code is generated when object serializing.\n\n![image](https://user-images.githubusercontent.com/46207/30877807-c7f264d8-a335-11e7-91d8-ad1029d4ae86.png)\n\n```csharp\n// Disassemble generated serializer code.\npublic sealed class PersonFormatter : IJsonFormatter\u003cPerson\u003e\n{\n    private readonly byte[][] stringByteKeys;\n    \n    public PersonFormatter()\n    {\n        // pre-encoded escaped string byte with \"{\", \":\" and \",\".\n        this.stringByteKeys = new byte[][]\n        {\n            JsonWriter.GetEncodedPropertyNameWithBeginObject(\"Age\"), // {\\\"Age\\\":\n            JsonWriter.GetEncodedPropertyNameWithPrefixValueSeparator(\"Name\") // ,\\\"Name\\\":\n        };\n    }\n\n    public sealed Serialize(ref JsonWriter writer, Person person, IJsonFormatterResolver jsonFormatterResolver)\n    {\n        if (person == null) { writer.WriteNull(); return; }\n\n        // WriteRawX is optimize byte-\u003ebyte copy when we know src size.\n        UnsafeMemory64.WriteRaw7(ref writer, this.stringByteKeys[0]);\n        writer.WriteInt32(person.Age); // itoa write directly to avoid ToString + UTF8 encode\n        UnsafeMemory64.WriteRaw8(ref writer, this.stringByteKeys[1]);\n        writer.WriteString(person.Name);\n\n        writer.WriteEndObject();\n    }\n\n    // public unsafe Person Deserialize(ref JsonReader reader, IJsonFormatterResolver jsonFormatterResolver)\n}\n```\n\nObject to JSON's main serialization cost is write property name. Utf8Json create cache at first and after that only do memory copy. Optimize part1, concatenate \"{\", \":\" and \".\" to cached  propertyname. Optimize part2, use optimized custom memory copy method(see: [UnsafeMemory.cs](https://github.com/neuecc/Utf8Json/blob/f724c83986d7c919a336c63e55f5a5886cca3575/src/Utf8Json/Internal/UnsafeMemory.cs)). Normally memory copy is used `Buffer.BlockCopy` but it has some overhead when target binary is small enough, releated to [dotnet/coreclr - issue #9786 Optimize Buffer.MemoryCopy](https://github.com/dotnet/coreclr/pull/9786) and [dotnet/coreclr - Add a fast path for byte[] to Buffer.BlockCopy #3118](https://github.com/dotnet/coreclr/pull/3118). Utf8Json don't use `Buffer.BlockCopy` and generates length specialized copy code that can reduce branch cost.\n\nNumber conversion is often high cost. If target encoding is UTF8 only, we can use `itoa` algorithm so avoid `int.ToString` and UTF8 encode cost. Especialy double-conversion, Utf8Json ported [ google/double-conversion](https://github.com/google/double-conversion) algorithm, it is fast `dtoa` and `atod` works.\n\nOther optimize techniques.\n\n* High-level API uses internal memory pool, don't allocate working memory under 64K\n* Struct JsonWriter does not allocate any more and write underlying byte[] directly, don't use TextWriter\n* Avoid boxing all codes, all platforms(include Unity/IL2CPP)\n* Heavyly tuned dynamic IL code generation, it generates per option so reduce option check: see:[DynamicObjectResolver.cs](https://github.com/neuecc/Utf8Json/blob/a8203cb4cfd81a8462105dac5babf5e26fa01ac5/src/Utf8Json/Resolvers/DynamicObjectResolver.cs#L729-L1292)\n* Call Primitive API directly when IL code generation knows target is primitive\n* Getting cached generated formatter on static generic field(don't use dictionary-cache because lookup is overhead)\n* Don't use `IEnumerable\u003cT\u003e` abstraction on iterate collection, specialized each collection types, see:[CollectionFormatter.cs](https://github.com/neuecc/Utf8Json/blob/f724c83986d7c919a336c63e55f5a5886cca3575/src/Utf8Json/Formatters/CollectionFormatters.cs)\n* Uses optimized type key dictionary for non-generic methods, see: [ThreadsafeTypeKeyHashTable.cs](https://github.com/neuecc/Utf8Json/blob/f724c83986d7c919a336c63e55f5a5886cca3575/src/Utf8Json/Internal/ThreadsafeTypeKeyHashTable.cs)\n\nPerformance of Deserialize\n---\nWhen deserializing, requires property name to target member name matching. Utf8Json avoid string key decode for matching, generate [automata](https://en.wikipedia.org/wiki/Automata_theory) based IL inlining code.\n\n![image](https://user-images.githubusercontent.com/46207/29754771-216b40e2-8bc7-11e7-8310-1c3602e80a08.png)\n\nuse raw byte[] slice and try to match each `ulong type` (per 8 character, if it is not enough, pad with 0).\n\n```csharp\n// Disassemble generated serializer code.\npublic sealed class PersonFormatter : IJsonFormatter\u003cPerson\u003e\n{\n    // public sealed Serialize(ref JsonWriter writer, Person person, IJsonFormatterResolver jsonFormatterResolver)\n\n    public unsafe Person Deserialize(ref JsonReader reader, IJsonFormatterResolver jsonFormatterResolver)\n    {\n        if (reader.ReadIsNull()) return null;\n        \n        reader.ReadIsBeginObjectWithVerify(); // \"{\"\n        \n        byte[] bufferUnsafe = reader.GetBufferUnsafe();\n        int age;\n        string name;\n        fixed (byte* ptr2 = \u0026bufferUnsafe[0])\n        {\n            int num;\n            while (!reader.ReadIsEndObjectWithSkipValueSeparator(ref num)) // \"}\" or \",\"\n            {\n                // don't decode string, get raw slice\n                ArraySegment\u003cbyte\u003e arraySegment = reader.ReadPropertyNameSegmentRaw();\n                byte* ptr3 = ptr2 + arraySegment.Offset;\n                int count = arraySegment.Count;\n                if (count != 0)\n                {\n                    // match automata per long\n                    ulong key = AutomataKeyGen.GetKey(ref ptr3, ref count);\n                    if (count == 0)\n                    {\n                        if (key == 6645569uL)\n                        {\n                            age = reader.ReadInt32(); // atoi read directly to avoid GetString + int.Parse\n                            continue;\n                        }\n                        if (key == 1701667150uL)\n                        {\n                            name = reader.ReadString();\n                            continue;\n                        }\n                    }\n                }\n                reader.ReadNextBlock();\n            }\n        }\n\n        return new PersonSample\n        {\n            Age = age,\n            Name = name\n        };\n    }\n}\n```\n\nOf course number conversion(decode to string -\u003e try parse) is high cost. Utf8Json directly convert byte[] to number by atoi/atod algorithm.\n\nBuilt-in support types\n---\nThese types can serialize by default.\n\nPrimitives(`int`, `string`, etc...), `Enum`, `Nullable\u003c\u003e`,  `TimeSpan`,  `DateTime`, `DateTimeOffset`, `Guid`, `Uri`, `Version`, `StringBuilder`, `BitArray`, `Type`, `ArraySegment\u003c\u003e`, `BigInteger`, `Complext`, `ExpandoObject `, `Task`, `Array[]`, `Array[,]`, `Array[,,]`, `Array[,,,]`, `KeyValuePair\u003c,\u003e`, `Tuple\u003c,...\u003e`, `ValueTuple\u003c,...\u003e`, `List\u003c\u003e`, `LinkedList\u003c\u003e`, `Queue\u003c\u003e`, `Stack\u003c\u003e`, `HashSet\u003c\u003e`, `ReadOnlyCollection\u003c\u003e`, `IList\u003c\u003e`, `ICollection\u003c\u003e`, `IEnumerable\u003c\u003e`, `Dictionary\u003c,\u003e`, `IDictionary\u003c,\u003e`, `SortedDictionary\u003c,\u003e`, `SortedList\u003c,\u003e`, `ILookup\u003c,\u003e`, `IGrouping\u003c,\u003e`, `ObservableCollection\u003c\u003e`, `ReadOnlyOnservableCollection\u003c\u003e`, `IReadOnlyList\u003c\u003e`, `IReadOnlyCollection\u003c\u003e`, `ISet\u003c\u003e`, `ConcurrentBag\u003c\u003e`, `ConcurrentQueue\u003c\u003e`, `ConcurrentStack\u003c\u003e`, `ReadOnlyDictionary\u003c,\u003e`, `IReadOnlyDictionary\u003c,\u003e`, `ConcurrentDictionary\u003c,\u003e`, `Lazy\u003c\u003e`, `Task\u003c\u003e`, custom inherited `ICollection\u003c\u003e` or `IDictionary\u003c,\u003e` with paramterless constructor, `IEnumerable`, `ICollection`, `IList`, `IDictionary` and custom inherited `ICollection` or `IDictionary` with paramterless constructor(includes `ArrayList` and `Hashtable`), `Exception` and inherited exception types(serialize only) and your own class or struct(includes anonymous type).\n\nUtf8Json has sufficient extensiblity. You can add custom type support and has some official/third-party extension package. for example  ImmutableCollections(`ImmutableList\u003c\u003e`, etc), [Utf8Json.FSharpExtensions](https://github.com/pocketberserker/Utf8Json.FSharpExtensions)(FSharpOption, FSharpList, etc...). Please see [extensions section](https://github.com/neuecc/Utf8Json#extensions).\n\nObject Serialization\n---\nUtf8Json can serialze your own public `Class` or `Struct`. In default, serializer search all public instance member(field or property) and uses there member name as json property name. If you want to avoid serialization target, you can use `[IgnoreDataMember]` attribute of `System.Runtime.Serialization` to target member. If you want to change property name, you can use `[DataMember(Name = string)]` attribute of `System.Runtime.Serialization`.\n\n```csharp\n// JsonSerializer.Serialize(new FooBar { FooProperty = 99, BarProperty = \"BAR\" });\n// Result : {\"foo\":99}\npublic class FooBar\n{\n    [DataMember(Name = \"foo\")]\n    public int FooProperty { get; set; }\n\n    [IgnoreDataMember]\n    public string BarProperty { get; set; }\n}\n```\n\nUtf8Json has other option, allows private/internal member serialization, convert property name to camelCalse/snake_case, if value is null does not create property. Or you can use a different DateTime format(default is ISO8601). The details, please read [Resolver](https://github.com/neuecc/Utf8Json#resolver) section. Here is sample.\n\n```csharp\n// default serializer change to allow private/exclude null/snake_case serializer.\nJsonSerializer.SetDefaultResolver(StandardResolver.AllowPrivateExcludeNullSnakeCase);\n\nvar json = JsonSerializer.ToJsonString(new Person { Age = 23, FirstName = null, LastName = \"Foo\" });\n\n// {\"age\":23,\"last_name\":\"Foo\"}\nConsole.WriteLine(json);\n```\n\nSerialize ImmutableObject(SerializationConstructor)\n---\nUtf8Json can deserialize immutable object like this.\n\n```\npublic struct CustomPoint\n{\n    public readonly int X;\n    public readonly int Y;\n\n    public CustomPoint(int x, int y)\n    {\n        this.X = x;\n        this.Y = y;\n    }\n}\n```\n\nUtf8Json choose constructor with the most matched argument by name(ignore case).\n\n\u003e MessagePack for C# choose `least` matched argument, please be aware of the opposite. This is design miss of MessagePack for C#.\n\nIf can not match automatically, you can specify to use constructor manually by `[SerializationConstructorAttribute]`.\n\n```csharp\npublic class CustomPoint\n{\n    public readonly int X;\n    public readonly int Y;\n\n    public CustomPoint(int x, int y)\n    {\n        this.X = x;\n        this.Y = y;\n    }\n\n    // used this constructor.\n    [SerializationConstructor]\n    public CustomPoint(int x)\n    {\n        this.X = x;\n    }\n}\n```\n\nShouldSerializeXXX pattern\n---\nUtfJson supports [ShouldSerialize feature of Json.NET](https://www.newtonsoft.com/json/help/html/ConditionalProperties.htm). If defined `public bool ShouldMemberName()` method, call method before serialize member value and if false does not output member.\n\n```csharp\npublic class MyPerson\n{\n    public string Name { get; set; }\n    public string[] Addresses { get; set; }\n\n    // ShouldSerialize*membername**\n    // method must be `public` and return `bool` and parameter less.\n    public bool ShouldSerializeAddresses()\n    {\n        if (Addresses != null \u0026\u0026 Addresses.Length != 0)\n        {\n            return true;\n        }\n        else\n        {\n            return false;\n        }\n    }\n}\n\n--\n\n// {\"Name\":\"foo\"}\nJsonSerializer.ToJsonString(new MyPerson { Name = \"foo\", Addresses = new string[0] });\n        \n// {\"Name\":\"bar\",\"Addresses\":[\"tokyo\",\"kyoto\"]}\nJsonSerializer.ToJsonString(new MyPerson { Name = \"bar\", Addresses = new[] { \"tokyo\", \"kyoto\" } });\n```\n\nDynamic Deserialization\n---\nIf use JsonSerializer.Deserialize\u003cobject\u003e or JsonSerializer.Deserialize\u003cdynamic\u003e, convert json to `bool`, `double`, `string`, `IDictionary\u003cstring, object\u003e`, `List\u003cobject\u003e`.\n\n```csharp\n// dynamic json deserialize\nvar json = JsonSerializer.Deserialize\u003cdynamic\u003e(@\"{\"\"foo\"\":\"\"json\"\",\"\"bar\"\":100,\"\"nest\"\":{\"\"foobar\"\":true}}\");\n\nvar r1 = json[\"foo\"]; // \"json\" - dynamic(string)\nvar r2 = json[\"bar\"]; // 100 - dynamic(double), it can cast to int or other number.\nvar r3 = json[\"nest\"][\"foobar\"]; // true\n```\n\nIf target is object, you access by string indexer.\n\nJSON Comments\n---\nJSON Comments is invalid JSON Format but used widely(for example, [VSCode - settings.json](https://code.visualstudio.com/docs/languages/json#_json-comments)) and also supports JSON.NET. Utf8Json suports both single-line comment and multi-line comment.\n\n```js\n{\n    // allow single line comment\n    \"foo\": true, // trailing\n    /*\n      allow\n      multi\n      line\n      comment\n    */\n    \"bar\": 999 /* trailing */\n}\n```\n\nEncoding\n---\nUtf8Json only supports UTF-8 but it is valid on latest JSON Spec - [RFC8259 The JavaScript Object Notation (JSON) Data Interchange Format](https://www.rfc-editor.org/info/rfc8259), DECEMBER 2017.\n\nIt mentions about encoding.\n\n\u003e 8.1. Character Encoding\n JSON text exchanged between systems that are not part of a closed\n ecosystem MUST be encoded using UTF-8 [RFC3629].\n \n\u003e Previous specifications of JSON have not required the use of UTF-8\n when transmitting JSON text. However, the vast majority of JSON\nbased software implementations have chosen to use the UTF-8 encoding,\n to the extent that it is the only encoding that achieves\n interoperability.\n\nWhich serializer should be used\n---\nThe performance of binary(protobuf, msgpack, avro, etc...) vs text(json, xml, yaml, etc...) depends on the implementation. However, binary has advantage basically. Utf8Json write directly to `byte[]` it is close to the binary serializer. But especialy `double` is still slower than binary write(Utf8Json uses [google/double-conversion](https://github.com/google/double-conversion/) algorithm, it is good but there are many processes, it can not be the fastest), write `string` requires escape and large payload must pay copy cost.\n\nI recommend use [MessagePack for C#](https://github.com/neuecc/MessagePack-CSharp/) for general use serializer, C# to C#, C# to NoSQL, Save to File, communicate internal cross platform(multi-language), etc. MessagePack for C# has many options(Union ,Typeless, Compression) and definitely fastest.\n\nBut JSON is still better on web, for public Web API, send for JavaScript and  easy to integrate between multi-language communication. For example, use Utf8Json for Web API formatter and use MessagePack for C# for Redis. It is perfect.\n\nFor that reason Utf8Json is focusing performance and cross-platform compatibility. I don't implement original format(like Union, Typeless, Cyclic-Reference) if you want to use it should be use binary serializer. But customizability for serialize/deserialize JSON is important for cross-platform communication. IJsonFormatterResolver can serialize/deserialize all patterns and you can create own pattern.\n\nHigh-Level API(JsonSerializer)\n---\n`JsonSerializer` is the entry point of Utf8Json. Its static methods are main API of Utf8Json.\n\n| API | Description |\n| --- | --- |\n| `DefaultResolver` | FormatterResolver that used resolver less overloads. If does not set it, used StandardResolver.Default. |\n| `SetDefaultResolver` | Set default resolver of JsonSerializer APIs. |\n| `Serialize\u003cT\u003e` | Convert object to byte[] or write to stream. There has IJsonFormatterResolver overload, used specified resolver. |\n| `SerializeUnsafe\u003cT\u003e` | Same as `Serialize\u003cT\u003e` but return `ArraySegement\u003cbyte\u003e`. The result of ArraySegment is contains internal buffer pool, it can not share across thread and can not hold, so use quickly. |\n| `SerializeAsync\u003cT\u003e` | Convert object to byte[] and write to stream async. |\n| `ToJsonString\u003cT\u003e` | Convert object to string. |\n| `Deserialize\u003cT\u003e` | Convert byte[] or `ArraySegment\u003cbyte\u003e` or stream to object. There has IFormatterResolver overload, used specified resolver. |\n| `DeserializeAsync\u003cT\u003e` | Convert stream(read async to buffer byte[]) to object. |\n| `PrettyPrint` | Output indented json string. |\n| `PrettyPrintByteArray` | Output indented json string(UTF8 `byte[]`). |\n| `NonGeneric.*` | NonGeneric APIs of Serialize/Deserialize. There accept type parameter at first argument. This API is bit slower than generic API but useful for framework integration such as ASP.NET formatter. |\n\nUtf8Json operates at the byte[] level, so `Deserialize\u003cT\u003e(Stream)` read to end at first, it is not truly streaming deserialize.\n\nHigh-Level API uses memory pool internaly to avoid unnecessary memory allocation. If result size is under 64K, allocates GC memory only for the return bytes.\n\nLow-Level API(IJsonFormatter)\n---\nIJsonFormatter is serializer by each type. For example `Int32Formatter : IJsonFormatter\u003cInt32\u003e` represents Int32 JSON serializer.\n\n```csharp\npublic interface IJsonFormatter\u003cT\u003e : IJsonFormatter\n{\n    void Serialize(ref JsonWriter writer, T value, IJsonFormatterResolver formatterResolver);\n    T Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterResolver);\n}\n```\n\nMany builtin formatters exists under Utf8Json.Formatters. You can get sub type serializer by `formatterResolver.GetFormatter\u003cT\u003e`. Here is sample of write own formatter.\n\n```csharp\n// serialize fileinfo as string fullpath.\npublic class FileInfoFormatter\u003cT\u003e : IJsonFormatter\u003cFileInfo\u003e\n{\n    public void Serialize(ref JsonWriter writer, FileInfo value, IJsonFormatterResolver formatterResolver)\n    {\n        if (value == null) { writer.WriteNull(); return; }\n\n        // if target type is primitive, you can also use writer.Write***.\n        formatterResolver.GetFormatterWithVerify\u003cstring\u003e().Serialize(ref writer, value.FullName, formatterResolver);\n    }\n\n    public FileInfo Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterResolver)\n    {\n        if (reader.ReadIsNull()) return null;\n\n        // if target type is primitive, you can also use reader.Read***.\n        var path = formatterResolver.GetFormatterWithVerify\u003cstring\u003e().Deserialize(ref reader, formatterResolver);\n        return new FileInfo(path);\n    }\n}\n```\n\nCreated formatter needs to register to IFormatterResolver. Please see [Resolver](https://github.com/neuecc/Utf8Json#resolver) section.\n\nYou can see many other samples from [builtin formatters](https://github.com/neuecc/Utf8Json/tree/master/src/Utf8Json/Formatters).\n\n\u003e If target type requires support dictionary key, you need to implements `IObjectPropertyNameFormatter\u003cT\u003e`, too.\n\nPrimitive API(JsonReader/JsonWriter)\n---\n`JsonReader` and `JsonWriter` is most low-level API. It is mutable struct so it must pass by ref and must does not store to field. C# 7.2 supports ref-like types(see: [csharp-7.2/span-safety.md](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.2/span-safety.md)) and readonly-ref(see: [csharp-7.2/Readonly references](https://github.com/dotnet/csharplang/blob/master/proposals/csharp-7.2/readonly-ref.md)) but not yet implements in C#, be careful to use.\n\n`JsonReader` and `JsonWriter` is too primitive(performance reason), slightly odd. Internal state manages only int offset. You should manage other state(in array, in object...) manualy in outer.\n\n**JsonReader**\n\n| Method | Description |\n| --- | --- |\n| AdvanceOffset | Advance offset manually. |\n| SkipWhiteSpace | Skip whitespace. |\n| ReadNext | Skip JSON token. |\n| ReadNextBlock | Skip JSON token with sub structures(array/object). This is useful for create deserializer. |\n| ReadNextBlockSegment | Read next block and returns there array-segment.\n| ReadIsNull | If is null return true. |\n| ReadIsBeginArray | If is '[' return true. |\n| ReadIsBeginArrayWithVerify | If is '[' return true. |\n| ReadIsEndArray | If is ']' return true. |\n| ReadIsEndArrayWithVerify | If is not ']' throws exception. |\n| ReadIsEndArrayWithSkipValueSeparator | check reached ']' or advance ',' when (ref int count) is not zero. |\n| ReadIsInArray | Convinient pattern of ReadIsBeginArrayWithVerify + while(!ReadIsEndArrayWithSkipValueSeparator) |\n| ReadIsBeginObject | If is '{' return true. |\n| ReadIsBeginObjectWithVerify | If is not '{' throws exception. |\n| ReadIsEndObject | If is '}' return true. |\n| ReadIsEndObjectWithVerify | If is not '}' throws exception. |\n| ReadIsEndObjectWithSkipValueSeparator | check reached '}' or advance ',' when (ref int count) is not zero. |\n| ReadIsInObject | Convinient pattern of ReadIsBeginObjectWithVerify + while(!ReadIsEndObjectWithSkipValueSeparator). |\n| ReadIsValueSeparator |  If is ',' return true. |\n| ReadIsValueSeparatorWithVerify | If is not ',' throws exception. |\n| ReadIsNameSeparator |  If is ':' return true. |\n| ReadIsNameSeparatorWithVerify | If is not ':' throws exception. |\n| ReadString | ReadString, unescaped. |\n| ReadStringSegmentUnsafe | ReadString block but does not decode string. Return buffer is in internal buffer pool, be careful to use.  |\n| ReadNumberSegment | Read number as buffer slice. |\n| ReadPropertyName | ReadString + ReadIsNameSeparatorWithVerify. |\n| ReadPropertyNameSegmentRaw | Get raw string-span(do not unescape) + ReadIsNameSeparatorWithVerify. |\n| ReadBoolean | ReadBoolean. |\n| ReadSByte | atoi.  |\n| ReadInt16 | atoi. |\n| ReadInt32 | atoi.  |\n| ReadInt64 | atoi.  |\n| ReadByte | atoi. |\n| ReadUInt16 | atoi. |\n| ReadUInt32 | atoi. |\n| ReadUInt64 | atoi. |\n| ReadUInt16 | atoi. |\n| ReadSingle | atod. |\n| ReadDouble | atod. |\n| GetBufferUnsafe | return underlying buffer. |\n| GetCurrentOffsetUnsafe | return underlying offset. |\n| GetCurrentJsonToken | Get current token(skip whitespace), do not advance. |\n\n`Read***` methods advance next token when called. JsonReader reads utf8 byte[] to primitive directly.\n\nHow to use, see the List formatter.\n\n```csharp\n// JsonReader is struct, always pass ref and do not set local variable.\npublic List\u003cT\u003e Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterResolver)\n{\n    // check current state is null. when null, advanced offset. if not, do not.\n    if (reader.ReadIsNull()) return null;\n\n    var formatter = formatterResolver.GetFormatterWithVerify\u003cT\u003e();\n    var list = new List\u003cT\u003e();\n\n    var count = 0; // managing array-count state in outer(this is count, not index(index is always count - 1)\n\n    // loop helper for Array or Object, you can use ReadIsInArray/ReadIsInObject.\n    while (reader.ReadIsInArray(ref count)) // read '[' or ',' when until reached ']'\n    {\n        list.Add(formatter.Deserialize(ref reader, formatterResolver));\n    }\n\n    return list;\n}\n```\n\n**JsonWriter**\n\n| Method | Description |\n| --- | --- |\n| static GetEncodedPropertyName | Get JSON Encoded byte[]. |\n| static GetEncodedPropertyNameWithPrefixValueSeparator | Get JSON Encoded byte[] with ',' on prefix. |\n| static GetEncodedPropertyNameWithBeginObject | Get JSON Encoded byte[] with '{' on prefix. |\n| static GetEncodedPropertyNameWithoutQuotation | Get JSON Encoded byte[] without pre/post '\"'. |\n| CurrentOffset | Get current offset. |\n| AdvanceOffset | Advance offset manually. |\n| GetBuffer | Get current buffer. |\n| ToUtf8ByteArray | Finish current buffer to byte[]. |\n| ToString | Finish current buffer to json stirng. |\n| EnsureCapacity | Ensure inner buffer capacity. |\n| WriteRaw | Write byte/byte[] directly. |\n| WriteRawUnsafe | WriteRaw but don't check and ensure capacity. |\n| WriteBeginArray | Write '['. |\n| WriteEndArray | Write ']'. |\n| WriteBeginObject | Write '{'. |\n| WriteEndObject | Write '}'. |\n| WriteValueSeparator | Write ','. |\n| WriteNameSeparator | Write ':'. |\n| WritePropertyName | WriteString + WriteNameSeparator. |\n| WriteQuotation | Write '\"'. |\n| WriteNull | Write 'null'. |\n| WriteBoolean | Write 'true' or 'false'. |\n| WriteTrue | Write 'true'. |\n| WriteFalse | Write 'false'. |\n| WriteSByte | itoa.  |\n| WriteInt16 | itoa. |\n| WriteInt32 | itoa.  |\n| WriteInt64 | itoa.  |\n| WriteByte | itoa. |\n| WriteUInt16 | itoa. |\n| WriteUInt32 | itoa. |\n| WriteUInt64 | itoa. |\n| WriteUInt16 | itoa. |\n| WriteSingle | dtoa. |\n| WriteDouble | dtoa. |\n\n`GetBuffer`, `ToUtf8ByteArray`, `ToString` get the wrote result. JsonWriter writes primitive to utf8 bytes directly.\n\nHow to use, see the List formatter.\n\n```csharp\n// JsonWriter is struct, always pass ref and do not set local variable.\npublic void Serialize(ref JsonWriter writer, List\u003cT\u003e value, IJsonFormatterResolver formatterResolver)\n{\n    if (value == null) { writer.WriteNull(); return; }\n\n    var formatter = formatterResolver.GetFormatterWithVerify\u003cT\u003e();\n\n    writer.WriteBeginArray(); // \"[\"\n    if (value.Count != 0)\n    {\n        formatter.Serialize(ref writer, value[0], formatterResolver);\n    }\n    for (int i = 1; i \u003c value.Count; i++)\n    {\n        writer.WriteValueSeparator(); // write \",\" manually\n        formatter.Serialize(ref writer, value[i], formatterResolver);\n    }\n    writer.WriteEndArray(); // \"]\"\n}\n```\n\nHow to write complex type formatter, you can refer [KeyValuePairFormatter](https://github.com/neuecc/Utf8Json/blob/4a45700219ffe20a9d0dac75ddbf3a99d86f488c/src/Utf8Json/Formatters/StandardClassLibraryFormatters.cs#L369-L418), it caches string table for serialize and automata dictionary for deserialize in [outer helper class](https://github.com/neuecc/Utf8Json/blob/4a45700219ffe20a9d0dac75ddbf3a99d86f488c/src/Utf8Json/Formatters/StandardClassLibraryFormatters.cs#L644-L665). How to add the custom formatter to custom resolver, you can see [DynamicGenericResolver](https://github.com/neuecc/Utf8Json/blob/4a457002/src/Utf8Json/Resolvers/DynamicGenericResolver.cs#L122-L129) for generic formatter, [BuiltinResolver](https://github.com/neuecc/Utf8Json/blob/4a457002/src/Utf8Json/Resolvers/BuiltinResolver.cs) for nongeneric formatter.\n\nResolver\n---\n`IJsonFormatterResolver` is storage of typed serializers. Serializer api accepts resolver and can customize serialization.\n\n| Resovler Name | Description |\n| --- | --- |\n| BuiltinResolver | Builtin primitive and standard classes resolver. It includes primitive(int, bool, string...) and there nullable, array and list. and some extra builtin types(Guid, Uri, BigInteger, etc...). |\n| DynamicGenericResolver | Resolver of generic type(`Tuple\u003c\u003e`, `List\u003c\u003e`, `Dictionary\u003c,\u003e`, `Array`, etc). It uses reflection call for resolve generic argument at first time. |\n| AttributeFormatterResolver | Get formatter from `[JsonFormatter]` attribute. |\n| EnumResolver | `EnumResolver.Default` serialize as name, `EnumResolver.UnderlyingValue` serialize as underlying value. Deserialize, can be both. |\n| StandardResolver | Composited resolver. It resolves in the following order `object fallback -\u003e (builtin -\u003e enum -\u003e dynamic generic -\u003e attribute -\u003e  dynamic object)`. `StandardResolver.Default` is default resolver of JsonSerialzier and has many option resolvers, see below. |\n| CompositeResolver | Singleton custom composite resolver.  |\n\nStandardResolver has 12 option resolvers it combinate\n\n* AllowPrivate = true/false\n* ExcludeNull = true/false\n* NameMutate = Original/CamelCase/SnakeCase.\n\nfor example `StandardResolver.SnakeCase`, `StandardResolver.ExcludeNullCamelCase`, `StandardResolver.AllowPrivateExcludeNullSnakeCase`. `StandardResolver.Default` is AllowPrivate:False, ExcludeNull:False, NameMutate:Original.\n\nIf AllowPrivate = true and does not match any constructor, deserializer uses [FormatterServices.GetUninitializedObject](https://msdn.microsoft.com/en-us/library/system.runtime.serialization.formatterservices.getuninitializedobject(v=vs.110).aspx) to create new instance so AllowPrivate = true can deserialize all concrete types.\n\nAssemble the resolver's priority is the only configuration point of Utf8Json. It is too simple but well works. In most cases, it is sufficient to have one custom resolver globally. CompositeResolver will be its helper. It is also necessary to use extension resolver like `Utf8Json.ImmutableCollection` that add support for for System.Collections.Immutable library. It adds `ImmutableArray\u003c\u003e`, `ImmutableList\u003c\u003e`, `ImmutableDictionary\u003c,\u003e`, `ImmutableHashSet\u003c\u003e`, `ImmutableSortedDictionary\u003c,\u003e`, `ImmutableSortedSet\u003c\u003e`, `ImmutableQueue\u003c\u003e`, `ImmutableStack\u003c\u003e`, `IImmutableList\u003c\u003e`, `IImmutableDictionary\u003c,\u003e`, `IImmutableQueue\u003c\u003e`, `IImmutableSet\u003c\u003e`, `IImmutableStack\u003c\u003e` serialization support.\n\n```csharp\n// use global-singleton CompositeResolver.\n// This method initialize CompositeResolver and set to default JsonSerializer\nCompositeResolver.RegisterAndSetAsDefault(new IJsonFormatter[] {\n    // add custome formatters, use other DateTime format.\n    // if target type is struct, requires add nullable formatter too(use NullableXxxFormatter or StaticNullableFormatter(innerFormatter))\n    new DateTimeFormatter(\"yyyy-MM-dd HH:mm:ss\"),\n    new NullableDateTimeFormatter(\"yyyy-MM-dd HH:mm:ss\")\n}, new[] {\n    // resolver custom types first\n    ImmutableCollectionResolver.Instance,\n    EnumResolver.UnderlyingValue,\n\n    // finaly choose standard resolver\n    StandardResolver.AllowPrivateExcludeNullSnakeCase\n});\n```\n\n```csharp\n// select resolver per invoke.\nJsonSerializer.Serialize(value, StandardResolver.Default);\nJsonSerializer.Serialize(value, StandardResolver.SnakeCase);\nJsonSerializer.Serialize(value, CompositeResolver.Instance);\n```\n\nYou can also build own custom composite resolver.\n\n```csharp\n// create custom composite resolver per project is recommended way.\n// let's try to copy and paste:)\npublic class ProjectDefaultResolver : IJsonFormatterResolver\n{\n    public static IJsonFormatterResolver Instance = new ProjectDefaultResolver();\n\n    // configure your resolver and formatters.\n    static IJsonFormatter[] formatters = new IJsonFormatter[]{\n        new DateTimeFormatter(\"yyyy-MM-dd HH:mm:ss\"),\n        new NullableDateTimeFormatter(\"yyyy-MM-dd HH:mm:ss\")\n    };\n\n    static readonly IJsonFormatterResolver[] resolvers = new[]\n    {\n        ImmutableCollectionResolver.Instance,\n        EnumResolver.UnderlyingValue,\n        StandardResolver.AllowPrivateExcludeNullSnakeCase\n    };\n\n    ProjectDefaultResolver()\n    {\n    }\n\n    public IJsonFormatter\u003cT\u003e GetFormatter\u003cT\u003e()\n    {\n        return FormatterCache\u003cT\u003e.formatter;\n    }\n\n    static class FormatterCache\u003cT\u003e\n    {\n        public static readonly IJsonFormatter\u003cT\u003e formatter;\n\n        static FormatterCache()\n        {\n            foreach (var item in formatters)\n            {\n                foreach (var implInterface in item.GetType().GetTypeInfo().ImplementedInterfaces)\n                {\n                    var ti = implInterface.GetTypeInfo();\n                    if (ti.IsGenericType \u0026\u0026 ti.GenericTypeArguments[0] == typeof(T))\n                    {\n                        formatter = (IJsonFormatter\u003cT\u003e)item;\n                        return;\n                    }\n                }\n            }\n\n            foreach (var item in resolvers)\n            {\n                var f = item.GetFormatter\u003cT\u003e();\n                if (f != null)\n                {\n                    formatter = f;\n                    return;\n                }\n            }\n        }\n    }\n}\n```\n\nOr you can create and store dynamic CompositeResolver.\n\n```csharp\npublic static MyOwnProjectResolver\n{\n    // CompositeResolver.Create can create dynamic composite resolver.\n    // It can `not` garbage collect and create is slightly high cost.\n    // so you should store to static field.\n    public static readonly IJsonFormatterResolver Instance = CompositeResolver.Create(\n        /* IJsonFormatter[] */,\n        /* IJsonFormatterResolver[] */\n    );\n}\n```\n\nJsonFormatterAttribute\n---\nJsonFormatterAttribute is lightweight extension point. This is like JSON.NET's JsonConverterAttribute. You can change to use formatter per type and member.\n\n```csharp\n// if serializing, choosed CustomObjectFormatter.\n[JsonFormatter(typeof(CustomObjectFormatter))]\npublic class CustomObject\n{\n    string internalId;\n\n    public CustomObject()\n    {\n        this.internalId = Guid.NewGuid().ToString();\n    }\n\n    class CustomObjectFormatter : IJsonFormatter\u003cCustomObject\u003e\n    {\n        public void Serialize(ref JsonWriter writer, CustomObject value, IJsonFormatterResolver formatterResolver)\n        {\n            formatterResolver.GetFormatterWithVerify\u003cstring\u003e().Serialize(ref writer, value.internalId, formatterResolver);\n        }\n\n        public CustomObject Deserialize(ref JsonReader reader, IJsonFormatterResolver formatterResolver)\n        {\n            var id = formatterResolver.GetFormatterWithVerify\u003cstring\u003e().Deserialize(ref reader, formatterResolver);\n            return new CustomObject { internalId = id };\n        }\n    }\n}\n```\n\nJsonFormatter can receive parameter and can attach to member. For example, configure DateTime format.\n\n```csharp\npublic class Person\n{\n    public int Age { get; set; }\n    public string Name { get; set; }\n\n    [JsonFormatter(typeof(DateTimeFormatter), \"yyyy-MM-dd\")]\n    public DateTime Birth { get; set; }\n}\n```\n\n`DateTime`, `DateTimeOffset`, `TimeSpan` is used ISO8601 format in default by `ISO8601DateTimeFormatter`, `ISO8601DateTimeOffsetFormatter`, `ISO8601TimeSpanFormatter` but if you want to configure format, you can use `DateTimeFormatter`, `DateTimeOffsetFormatter`, `TimeSpanFormatter` with format string argument.\n\nFramework Integration\n--- \nThe guide of provide integrate other framework with Utf8Json. For provides customizability of serialization, can be pass the `IJsonFormatterResolver` by user and does not use `CompositeResolver` on provided library. For example, [AWS Lambda Function](http://docs.aws.amazon.com/en_us/lambda/latest/dg/dotnet-programming-model-handler-types.html)'s custom serializer.\n\n```csharp\n// with `Amazon.Lambda.Core package`\npublic class Utf8JsonLambdaSerializer : Amazon.Lambda.Core.ILambdaSerializer\n{\n    // Note: Default AWS Lambda's JSON.NET Serializer uses special resolver for handle below types.\n    // Amazon.S3.Util.S3EventNotification+ResponseElementsEntity\n    // Amazon.Lambda.KinesisEvents.KinesisEvent+Record\n    // Amazon.DynamoDBv2.Model.StreamRecord\n    // Amazon.DynamoDBv2.Model.AttributeValue\n    // If you want to serialize these types, create there custom formatter and setup custom resolver.\n\n    readonly IJsonFormatterResolver resolver;\n\n    public Utf8JsonLambdaSerializer()\n    {\n        // if you want to customize other configuration change your own choose resolver directly\n        // (Lambda uses default constructor and does not exists configure chance of DefaultResolver)\n        this.resolver = JsonSerializer.DefaultResolver;\n    }\n\n    public Utf8JsonLambdaSerializer(IJsonFormatterResolver resolver)\n    {\n        this.resolver = resolver;\n    }\n\n    public void Serialize\u003cT\u003e(T response, Stream responseStream)\n    {\n        Utf8Json.JsonSerializer.Serialize\u003cT\u003e(responseStream, response, resolver);\n    }\n\n    public T Deserialize\u003cT\u003e(Stream requestStream)\n    {\n        return Utf8Json.JsonSerializer.Deserialize\u003cT\u003e(requestStream, resolver);\n    }\n}\n```\n\nUtf8Json provides for ASP.NET Core MVC formatter. [Utf8Json.AspNetCoreMvcFormatter](https://www.nuget.org/packages/Utf8Json.AspNetCoreMvcFormatter). This is sample of use it.\n\n```csharp\npublic void ConfigureServices(IServiceCollection services)\n{\n    services.AddMvc().AddMvcOptions(option =\u003e\n    {\n        option.OutputFormatters.Clear();\n        // can pass IJsonFormatterResolver for customize.\n        option.OutputFormatters.Add(new JsonOutputFormatter(StandardResolver.Default));\n        option.InputFormatters.Clear();\n        // if does not pass, library should use JsonSerializer.DefaultResolver.\n        option.InputFormatters.Add(new JsonInputFormatter());\n    });\n}\n```\n\nHTML encodoing only requires UTF8, [whatwg/html](https://github.com/whatwg/html/pull/3091) accepts on 2017-10-06. So don't worry about other encoding:)\n\nText Protocol Foundation\n---\nUtf8Json implements fast itoa/atoi, dtoa/atod. It can be useful for text protocol serialization. For example I'm implementing [MySqlSharp](https://github.com/neuecc/MySqlSharp/) that aims fastest MySQL Driver on C#(work in progress yet), MySQL protocol is noramlly text so requires fast parser for text protocol.\n\n`Utf8Json.Internal.NumberConverter` is Read/Write primitive to bytes. It is `public` API so you can use if requires itoa/atoi, dtoa/atod algorithm.\n\n```csharp\nbyte[] buffer = null; // buffer is automatically ensure.\nvar offset = 0;\nvar writeSize = NumberConverter.WriteInt64(ref buffer, offset, 99999);\n\nint readCount;\nvar value = NumberConverter.ReadInt64(buffer, 0, out readCount);\n```\n\nfor Unity\n---\nUnity has the [JsonUtility](https://docs.unity3d.com/2017.2/Documentation/Manual/JSONSerialization.html). It is well fast but has many limitations, can not serialize/deserialize dictionary or other collections and nullable, can not root array, can not handle null correctly, etc... Utf8Json has no limitation and performance is same or better especialy convert to/from byte[], Utf8Json achieves true no zero-allocation.\n\nIn Unity version, added `UnityResolver` to StandardResolver in default. It enables serialize `Vector2`, `Vector3`, `Vector4`, `Quaternion`, `Color`, `Bounds`, `Rect`.\n\n`.unitypackage` is exists in [releases](https://github.com/neuecc/Utf8Json/releases) page. If you are using IL2CPP environment, requires code generator too, see following section.\n\nPre Code Generation(Unity/Xamarin Supports)\n---\nUtf8Json generates object formatter dynamically by [ILGenerator](https://msdn.microsoft.com/en-us/library/system.reflection.emit.ilgenerator.aspx). It is fast and transparently generated at run time. But it does not work on AOT environment(Xamarin, Unity IL2CPP, etc.).\n\nIf you want to run on IL2CPP(or other AOT env), you need pre-code generation. `Utf8Json.UniversalCodeGenerator.exe` is code generator of Utf8Json. It is exists in releases page's `Utf8Json.UniversalCodeGenerator.zip` that run on win/mac/linux. It is using [Roslyn](https://github.com/dotnet/roslyn) so analyze source code and created by [.NET Core](https://www.microsoft.com/net/) for cross platform application.\n\n```\narguments help:\n  -i, --inputFiles=VALUE        [optional]Input path of cs files(',' separated)\n  -d, --inputDirs=VALUE         [optional]Input path of dirs(',' separated)\n  -o, --output=VALUE            [required]Output file path\n  -f, --allowInternal           [optional, default=false]Allow generate internal(friend)\n  -c, --conditionalsymbol=VALUE [optional, default=empty]conditional compiler symbol\n  -r, --resolvername=VALUE      [optional, default=GeneratedResolver]Set resolver name\n  -n, --namespace=VALUE         [optional, default=Utf8Json]Set namespace root name\n```\n\n```csharp\n// Simple usage(directory)\nUtf8Json.UniversalCodeGenerator.exe -d \"..\\src\\Shared\\Request,..\\src\\Shared\\Response\" -o \"Utf8JsonGenerated.cs\"\n```\n\nIf you create DLL by msbuild project, you can use Pre/Post build event or hook your Unity's post/pre process.\n\n```xml\n\u003cPropertyGroup\u003e\n    \u003cPreBuildEvent\u003e\n        Utf8Json.UniversalCodeGenerator.exe, here is useful for analyze/generate target is self project.\n    \u003c/PreBuildEvent\u003e\n    \u003cPostBuildEvent\u003e\n        Utf8Json.UniversalCodeGenerator.exe, here is useful for analyze target is another project.\n    \u003c/PostBuildEvent\u003e\n\u003c/PropertyGroup\u003e\n```\n\nIn default, generates resolver to Utf8Json.Resolvers.GeneratedResolver and formatters generates to Utf8Json.Formatters.***. And application launch, you need to set Resolver at first.\n\n```csharp\n// CompositeResolver is singleton helper for use custom resolver.\n// Ofcourse you can also make custom resolver.\nUtf8Json.Resolvers.CompositeResolver.RegisterAndSetAsDefault(\n    // use generated resolver first, and combine many other generated/custom resolvers\n    Utf8Json.Resolvers.GeneratedResolver.Instance,\n\n    // set StandardResolver or your use resolver chain\n    Utf8Json.Resolvers.StandardResolver.Default,\n);\n```\n\nHow to Build\n---\nOpen `Utf8Json.sln` on Visual Studio 2017(latest) and install .NET Core 2.0 SDK.\n\nUnity Project is using symbolic link. At first, run `make_unity_symlink.bat` so linked under Unity project. You can open `src\\Utf8Json.UnityClient` on Unity Editor.\n\nAuthor Info\n---\nYoshifumi Kawai(a.k.a. neuecc) is a software developer in Japan.  \nHe is the Director/CTO at Grani, Inc.  \nGrani is a mobile game developer company in Japan and well known for using C#.  \nHe is awarding Microsoft MVP for Visual C# since 2011.  \nHe is known as the creator of [UniRx](http://github.com/neuecc/UniRx/)(Reactive Extensions for Unity)  \n\nBlog: [https://medium.com/@neuecc](https://medium.com/@neuecc) (English)  \nBlog: [http://neue.cc/](http://neue.cc/) (Japanese)  \nTwitter: [https://twitter.com/neuecc](https://twitter.com/neuecc) (Japanese)  \n\nLicense\n---\nThis library is under the MIT License.\n","funding_links":[],"categories":["Frameworks, Libraries and Tools","C#","Serializer and Deserializer","C# #","框架, 库和工具","Serialization","C\\#","Serializers","序列化"],"sub_categories":["Serialization","序列化"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneuecc%2FUtf8Json","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fneuecc%2FUtf8Json","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneuecc%2FUtf8Json/lists"}