Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Initial commit

  • Loading branch information...
commit 4c91d28d3683316f552442c5bf3128be66efad67 0 parents
@ysharplanguage authored
22 .gitattributes
@@ -0,0 +1,22 @@
+# Auto detect text files and perform LF normalization
+* text=auto
+
+# Custom for Visual Studio
+*.cs diff=csharp
+*.sln merge=union
+*.csproj merge=union
+*.vbproj merge=union
+*.fsproj merge=union
+*.dbproj merge=union
+
+# Standard to msysgit
+*.doc diff=astextplain
+*.DOC diff=astextplain
+*.docx diff=astextplain
+*.DOCX diff=astextplain
+*.dot diff=astextplain
+*.DOT diff=astextplain
+*.pdf diff=astextplain
+*.PDF diff=astextplain
+*.rtf diff=astextplain
+*.RTF diff=astextplain
215 .gitignore
@@ -0,0 +1,215 @@
+#################
+## Eclipse
+#################
+
+*.pydevproject
+.project
+.metadata
+bin/
+tmp/
+*.tmp
+*.bak
+*.swp
+*~.nib
+local.properties
+.classpath
+.settings/
+.loadpath
+
+# External tool builders
+.externalToolBuilders/
+
+# Locally stored "Eclipse launch configurations"
+*.launch
+
+# CDT-specific
+.cproject
+
+# PDT-specific
+.buildpath
+
+
+#################
+## Visual Studio
+#################
+
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.sln.docstates
+
+# Build results
+
+[Dd]ebug/
+[Rr]elease/
+x64/
+build/
+[Bb]in/
+[Oo]bj/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+*_i.c
+*_p.c
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.log
+*.scc
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opensdf
+*.sdf
+*.cachefile
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+*.ncrunch*
+.*crunch*.local.xml
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.Publish.xml
+*.pubxml
+
+# NuGet Packages Directory
+## TODO: If you have NuGet Package Restore enabled, uncomment the next line
+#packages/
+
+# Windows Azure Build Output
+csx
+*.build.csdef
+
+# Windows Store app package directory
+AppPackages/
+
+# Others
+sql/
+*.Cache
+ClientBin/
+[Ss]tyle[Cc]op.*
+~$*
+*~
+*.dbmdl
+*.[Pp]ublish.xml
+*.pfx
+*.publishsettings
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file to a newer
+# Visual Studio version. Backup files are not needed, because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+App_Data/*.mdf
+App_Data/*.ldf
+
+#############
+## Windows detritus
+#############
+
+# Windows image file caches
+Thumbs.db
+ehthumbs.db
+
+# Folder config file
+Desktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Mac crap
+.DS_Store
+
+
+#############
+## Python
+#############
+
+*.py[co]
+
+# Packages
+*.egg
+*.egg-info
+dist/
+build/
+eggs/
+parts/
+var/
+sdist/
+develop-eggs/
+.installed.cfg
+
+# Installer logs
+pip-log.txt
+
+# Unit test / coverage reports
+.coverage
+.tox
+
+#Translations
+*.mo
+
+#Mr Developer
+.mr.developer.cfg
258 JsonTest/Program.cs
@@ -0,0 +1,258 @@
+// On GitHub:
+// https://github.com/ysharplanguage/JSONParser
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+// For the JavaScriptSerializer
+using System.Web.Script.Serialization;
+
+// JSON.NET 5.0 r8
+using Newtonsoft.Json;
+
+// ServiceStack 3.9.59
+using ServiceStack.Text;
+
+// Our stuff
+using System.Text.Json;
+
+namespace Test
+{
+ class Program
+ {
+ const string TINY_TEST_FILE_PATH = @"..\..\TestData\tiny.json.txt";
+ const string SMALL_TEST_FILE_PATH = @"..\..\TestData\small.json.txt";
+ const string FATHERS_TEST_FILE_PATH = @"..\..\TestData\fathers.json.txt";
+ const string HUGE_TEST_FILE_PATH = @"..\..\TestData\huge.json.txt";
+
+ /* Note: "huge.json.txt" is in fact a copy of this file:
+ *
+ * https://github.com/zeMirco/sf-city-lots-json
+ *
+ * "City Lots San Francisco in .json
+ * I needed a really big .json file for testing various code.
+ * The CityLots spatial data layer is a representation of the City and County of San Francisco's Subdivision parcels. The initial file is in the .shp (shapefile) format and as the conversion process is quite cumbersome I uploaded the data as a .json file.
+ * Warning: size is 189,9 MB."
+ */
+
+ /* System.Text.Json.JsonParser's figures vs. JSON.NET's, v5.0 r8:
+
+ (.NET 4.0 target, on Ideapad w/ Intel Core i5 CPU @ 2.50GHz, 6GB RAM, running Win7 64bit)
+
+ "Loop" Test of tiny JSON (deserializing x times the JSON contained in the tiny.json.txt file = 91 bytes):
+ 10,000 iterations: in ~ 75 milliseconds vs. JSON.NET 5.0 r8 in ~ 250 milliseconds
+ 100,000 iterations: in ~ 650 milliseconds vs. JSON.NET 5.0 r8 in ~ 900 milliseconds
+ 1,000,000 iterations: in ~ 6.4 seconds vs. JSON.NET 5.0 r8 in ~ 8.3 seconds
+
+ "Loop" Test of small JSON (deserializing x times the JSON contained in the small.json.txt file ~ 3.5 kb):
+ 10,000 iterations: in ~ 1.2 second vs. JSON.NET 5.0 r8 in ~ 2.2 seconds
+ 100,000 iterations: in ~ 12.4 seconds vs. JSON.NET 5.0 r8... OutOfMemoryException
+
+ Note: fathers.json.txt was generated using:
+ http://experiments.mennovanslooten.nl/2010/mockjson/tryit.html
+
+ "Fathers" Test (12 mb JSON file):
+ Parsed in ~ 290 milliseconds vs. JSON.NET 5.0 r8 in ~ 510 milliseconds
+
+ "Huge" Test (180 mb JSON file):
+ Parsed in ~ 9.75 seconds vs. JSON.NET 5.0 r8... OutOfMemoryException
+ */
+
+ static void LoopTest(string parserName, Func<string, object> parseFunc, string testFile, int count)
+ {
+ Console.Clear();
+ Console.WriteLine("Parser: {0}", parserName);
+ Console.WriteLine();
+ Console.WriteLine("Loop Test File: {0}", testFile);
+ Console.WriteLine("Iterations: {0}", count.ToString("0,0"));
+ Console.WriteLine();
+ Console.WriteLine("Press ESC to skip this test or any other key to start...");
+ Console.WriteLine();
+ if (Console.ReadKey().KeyChar == 27)
+ return;
+
+ System.Threading.Thread.MemoryBarrier();
+ var initialMemory = System.GC.GetTotalMemory(true);
+
+ var json = System.IO.File.ReadAllText(testFile);
+ var st = DateTime.Now;
+ var l = new List<object>();
+ for (var i = 0; i < count; i++)
+ l.Add(parseFunc(json));
+ var tm = (int)DateTime.Now.Subtract(st).TotalMilliseconds;
+
+ System.Threading.Thread.MemoryBarrier();
+ var finalMemory = System.GC.GetTotalMemory(true);
+ var consumption = finalMemory - initialMemory;
+
+ System.Diagnostics.Debug.Assert(l.Count == count);
+
+ Console.WriteLine();
+ Console.WriteLine("... Done, in {0} ms. Throughput: {1} characters / seconds.", tm.ToString("0,0"), (1000 * (decimal)(count * json.Length) / (tm > 0 ? tm : 1)).ToString("0,0.00"));
+ Console.WriteLine();
+ Console.WriteLine("\tMemory used : {0}", ((decimal)finalMemory).ToString("0,0"));
+ Console.WriteLine();
+
+ GC.Collect();
+ Console.WriteLine("Press a key...");
+ Console.WriteLine();
+ Console.ReadKey();
+ }
+
+ static void Test(string parserName, Func<string, object> parseFunc, string testFile)
+ {
+ Console.Clear();
+ Console.WriteLine("Parser: {0}", parserName);
+ Console.WriteLine();
+ Console.WriteLine("Test File: {0}", testFile);
+ Console.WriteLine();
+ Console.WriteLine("Press ESC to skip this test or any other key to start...");
+ Console.WriteLine();
+ if (Console.ReadKey().KeyChar == 27)
+ return;
+
+ System.Threading.Thread.MemoryBarrier();
+ var initialMemory = System.GC.GetTotalMemory(true);
+
+ var json = System.IO.File.ReadAllText(testFile);
+ var st = DateTime.Now;
+ var o = parseFunc(json);
+ var tm = (int)DateTime.Now.Subtract(st).TotalMilliseconds;
+
+ System.Threading.Thread.MemoryBarrier();
+ var finalMemory = System.GC.GetTotalMemory(true);
+ var consumption = finalMemory - initialMemory;
+
+ Console.WriteLine();
+ Console.WriteLine("... Done, in {0} ms. Throughput: {1} characters / seconds.", tm.ToString("0,0"), (1000 * (decimal)json.Length / (tm > 0 ? tm : 1)).ToString("0,0.00"));
+ Console.WriteLine();
+ Console.WriteLine("\tMemory used : {0}", ((decimal)finalMemory).ToString("0,0"));
+ Console.WriteLine();
+
+ if (o is FathersData)
+ {
+ Console.WriteLine("Fathers : {0}", ((FathersData)o).fathers.Length.ToString("0,0"));
+ Console.WriteLine();
+ }
+ GC.Collect();
+ Console.WriteLine("Press a key...");
+ Console.WriteLine();
+ Console.ReadKey();
+ }
+
+ public class Person
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ public bool Married { get; set; }
+ public string Address { get; set; }
+ // Just to be sure we support that one, too:
+ public IEnumerable<int> Scores { get; set; }
+ public object Data { get; set; }
+ }
+
+ public class FathersData
+ {
+ public Father[] fathers { get; set; }
+ }
+
+ public class Father
+ {
+ public int id { get; set; }
+ public string name { get; set; }
+ public bool married { get; set; }
+ // Lists...
+ public List<Son> sons { get; set; }
+ // ... or arrays for collections, that's fine:
+ public Daughter[] daughters { get; set; }
+ }
+
+ public class Son
+ {
+ public int age { get; set; }
+ public string name { get; set; }
+ }
+
+ public class Daughter
+ {
+ public int age { get; set; }
+ public string name { get; set; }
+ }
+
+ static void SpeedTests()
+ {
+ LoopTest(typeof(JavaScriptSerializer).FullName, new JavaScriptSerializer().Deserialize<Person>, TINY_TEST_FILE_PATH, 10000);
+ LoopTest("JSON.NET 5.0 r8", JsonConvert.DeserializeObject<Person>, TINY_TEST_FILE_PATH, 10000);
+ LoopTest("ServiceStack", new JsonSerializer<Person>().DeserializeFromString, TINY_TEST_FILE_PATH, 10000);
+ LoopTest(typeof(JsonParser).FullName, new JsonParser().Parse<Person>, TINY_TEST_FILE_PATH, 10000);
+
+ LoopTest(typeof(JavaScriptSerializer).FullName, new JavaScriptSerializer().Deserialize<Person>, TINY_TEST_FILE_PATH, 100000);
+ LoopTest("JSON.NET 5.0 r8", JsonConvert.DeserializeObject<Person>, TINY_TEST_FILE_PATH, 100000);
+ LoopTest("ServiceStack", new JsonSerializer<Person>().DeserializeFromString, TINY_TEST_FILE_PATH, 100000);
+ LoopTest(typeof(JsonParser).FullName, new JsonParser().Parse<Person>, TINY_TEST_FILE_PATH, 100000);
+
+ LoopTest(typeof(JavaScriptSerializer).FullName, new JavaScriptSerializer().Deserialize<Person>, TINY_TEST_FILE_PATH, 1000000);
+ LoopTest("JSON.NET 5.0 r8", JsonConvert.DeserializeObject<Person>, TINY_TEST_FILE_PATH, 1000000);
+ LoopTest("ServiceStack", new JsonSerializer<Person>().DeserializeFromString, TINY_TEST_FILE_PATH, 1000000);
+ LoopTest(typeof(JsonParser).FullName, new JsonParser().Parse<Person>, TINY_TEST_FILE_PATH, 1000000);
+
+ LoopTest(typeof(JavaScriptSerializer).FullName, new JavaScriptSerializer().DeserializeObject, SMALL_TEST_FILE_PATH, 10000);
+ LoopTest("JSON.NET 5.0 r8", JsonConvert.DeserializeObject, SMALL_TEST_FILE_PATH, 10000);
+ LoopTest("ServiceStack", new JsonSerializer<object>().DeserializeFromString, SMALL_TEST_FILE_PATH, 10000);
+ LoopTest(typeof(JsonParser).FullName, new JsonParser().Parse<object>, SMALL_TEST_FILE_PATH, 10000);
+
+ LoopTest(typeof(JavaScriptSerializer).FullName, new JavaScriptSerializer().DeserializeObject, SMALL_TEST_FILE_PATH, 100000);
+ LoopTest("JSON.NET 5.0 r8", JsonConvert.DeserializeObject, SMALL_TEST_FILE_PATH, 100000);//(JSON.NET: OutOfMemoryException)
+ LoopTest("ServiceStack", new JsonSerializer<object>().DeserializeFromString, SMALL_TEST_FILE_PATH, 100000);
+ LoopTest(typeof(JsonParser).FullName, new JsonParser().Parse<object>, SMALL_TEST_FILE_PATH, 100000);
+
+ var msJss = new JavaScriptSerializer() { MaxJsonLength = int.MaxValue };
+ Test(typeof(JavaScriptSerializer).FullName, msJss.Deserialize<FathersData>, FATHERS_TEST_FILE_PATH);
+ Test("JSON.NET 5.0 r8", JsonConvert.DeserializeObject<FathersData>, FATHERS_TEST_FILE_PATH);
+ Test("ServiceStack", new JsonSerializer<FathersData>().DeserializeFromString, FATHERS_TEST_FILE_PATH);
+ Test(typeof(JsonParser).FullName, new JsonParser().Parse<FathersData>, FATHERS_TEST_FILE_PATH);
+
+ Test(typeof(JavaScriptSerializer).FullName, msJss.DeserializeObject, HUGE_TEST_FILE_PATH);
+ Test("JSON.NET 5.0 r8", JsonConvert.DeserializeObject, HUGE_TEST_FILE_PATH);//(JSON.NET: OutOfMemoryException)
+ Test("ServiceStack", new JsonSerializer<object>().DeserializeFromString, HUGE_TEST_FILE_PATH);
+ Test(typeof(JsonParser).FullName, new JsonParser().Parse<object>, HUGE_TEST_FILE_PATH);
+
+ StreamTest();
+ }
+
+ static void StreamTest()
+ {
+ Console.Clear();
+
+ System.Threading.Thread.MemoryBarrier();
+ var initialMemory = System.GC.GetTotalMemory(true);
+
+ var stream = new System.IO.FileStream(FATHERS_TEST_FILE_PATH, System.IO.FileMode.Open);
+ Console.WriteLine("\"Fathers\" Test... streamed (press a key)");
+ Console.WriteLine();
+ Console.ReadKey();
+ var st = DateTime.Now;
+ var o = new JsonParser().Parse<FathersData>(stream);
+ var tm = (int)DateTime.Now.Subtract(st).TotalMilliseconds;
+
+ System.Threading.Thread.MemoryBarrier();
+ var finalMemory = System.GC.GetTotalMemory(true);
+ var consumption = finalMemory - initialMemory;
+
+ System.Diagnostics.Debug.Assert(o.fathers.Length == 30000);
+ Console.WriteLine();
+ Console.WriteLine("... {0} ms", tm);
+ Console.WriteLine();
+ Console.WriteLine("\tMemory used : {0}", ((decimal)finalMemory).ToString("0,0"));
+ Console.WriteLine();
+ Console.ReadKey();
+ }
+
+ static void Main(string[] args)
+ {
+ SpeedTests();
+ }
+ }
+}
36 JsonTest/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Test")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Quinstreet")]
+[assembly: AssemblyProduct("Test")]
+[assembly: AssemblyCopyright("Copyright © Cyril Jandia 2013")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("456f272d-a405-41c4-982b-f489466b6122")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
631 JsonTest/System.Text.Json/JsonParser.cs
@@ -0,0 +1,631 @@
+/*
+ * Copyright (c) 2013 Cyril Jandia
+ *
+ * http://www.cjandia.com/
+ *
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+``Software''), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL CYRIL JANDIA BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Cyril Jandia shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from Cyril Jandia.
+
+Inquiries : ysharp {dot} design {at} gmail {dot} com
+ *
+ */
+
+// On GitHub:
+// https://github.com/ysharplanguage/JSONParser
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace System.Text.Json
+{
+ public class JsonParser
+ {
+ private static readonly short[] HEX = new short[128];
+ private static readonly bool[] HXD = new bool[128];
+ private static readonly char[] ESC = new char[128];
+ private static readonly bool[] IDF = new bool[128];
+ private static readonly bool[] IDN = new bool[128];
+ private const int EOF = (char.MaxValue + 1);
+ private const int ANY = 0;
+ private const int LBS = 128;
+ private const int TDS = 128;
+ private const int OBJECT = 0;
+ private const int ARRAY = 1;
+ private const int STRING = 2;
+
+ private IDictionary<Type, int> thash = new Dictionary<Type, int>();
+ private TypeInfo[] types = new TypeInfo[TDS];
+
+ private Func<int, object>[] parse = new Func<int, object>[128];
+ private StringBuilder lsb = new StringBuilder();
+ private char[] lbf = new char[LBS];
+ private char[] stc = new char[1];
+ private System.IO.StreamReader str;
+ private Func<int, int> Char;
+ private Action<int> Next;
+ private Func<int> Read;
+ private Func<int> Space;
+ private char[] txt;
+ private int len;
+ private int lln;
+ private int chr;
+ private int at;
+
+ internal class PropInfo
+ {
+ internal Action<JsonParser, int, object> Set;
+ internal Type Type;
+ internal int Outer;
+ internal string Name;
+ }
+
+ internal class TypeInfo
+ {
+ private static readonly HashSet<Type> WellKnown = new HashSet<Type>();
+
+ internal Func<string, object> Convert;
+ internal Func<object> Ctor;
+ internal PropInfo[] Props;
+ internal PropInfo Items;
+ internal Type ElementType;
+ internal Type Type;
+ internal int Outer;
+ internal int Inner;
+
+ static TypeInfo()
+ {
+ WellKnown.Add(typeof(bool));
+ WellKnown.Add(typeof(byte));
+ WellKnown.Add(typeof(short));
+ WellKnown.Add(typeof(int));
+ WellKnown.Add(typeof(long));
+ WellKnown.Add(typeof(float));
+ WellKnown.Add(typeof(double));
+ WellKnown.Add(typeof(decimal));
+ WellKnown.Add(typeof(DateTime));
+ }
+
+ private object DefaultConvert(string s)
+ {
+ return System.Convert.ChangeType(s, Type);
+ }
+
+ private Func<string, object> GetConvert(Type clr, int outer)
+ {
+ if (outer > STRING)
+ {
+ var type = typeof(Func<,>).MakeGenericType(typeof(string), clr);
+ var conv = clr.GetMethod("Parse", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public, null, new Type[] { typeof(string) }, null);
+ if (clr.IsValueType && (conv != null))
+ {
+ var dyn = new System.Reflection.Emit.DynamicMethod("", typeof(object), new Type[] { typeof(string) }, type, true);
+ var il = dyn.GetILGenerator();
+ il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0);
+ il.Emit(System.Reflection.Emit.OpCodes.Call, conv);
+ il.Emit(System.Reflection.Emit.OpCodes.Box, clr);
+ il.Emit(System.Reflection.Emit.OpCodes.Ret);
+ return (Func<string, object>)dyn.CreateDelegate(typeof(Func<string, object>));
+ }
+ return DefaultConvert;
+ }
+ return null;
+ }
+
+ private Func<object> GetCtor(Type clr, int outer, bool list)
+ {
+ var type = (list ? typeof(List<>).MakeGenericType(clr) : clr);
+ var ctor = type.GetConstructor(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.CreateInstance, null, System.Type.EmptyTypes, null);
+ if (ctor != null)
+ {
+ var dyn = new System.Reflection.Emit.DynamicMethod("", typeof(object), null, type, true);
+ var il = dyn.GetILGenerator();
+ il.Emit(System.Reflection.Emit.OpCodes.Newobj, ctor);
+ il.Emit(System.Reflection.Emit.OpCodes.Ret);
+ return (Func<object>)dyn.CreateDelegate(typeof(Func<object>));
+ }
+ return null;
+ }
+
+ private static System.Reflection.MethodInfo GetParseMethod(Type type)
+ {
+ var val = typeof(JsonParser).GetMethod("Val", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
+ if (type.IsEnum)
+ return typeof(JsonParser).GetMethod("Enum", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).MakeGenericMethod(type);
+ else if (WellKnown.Contains(type))
+ return typeof(JsonParser).GetMethod(type.Name, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
+ else
+ return val;
+ }
+
+ private static PropInfo GetPropInfo(Type type, string name, System.Reflection.MethodInfo smethod, System.Reflection.MethodInfo pmethod)
+ {
+ var dyn = new System.Reflection.Emit.DynamicMethod("", null, new Type[] { typeof(JsonParser), typeof(int), typeof(object) }, typeof(PropInfo));
+ var il = dyn.GetILGenerator();
+ il.DeclareLocal(pmethod.ReturnType);
+ il.Emit(System.Reflection.Emit.OpCodes.Ldarg_0);
+ il.Emit(System.Reflection.Emit.OpCodes.Ldarg_1);
+ il.Emit(System.Reflection.Emit.OpCodes.Callvirt, pmethod);
+ if (type.IsValueType && (pmethod.ReturnType == typeof(object)))
+ il.Emit(System.Reflection.Emit.OpCodes.Unbox_Any, type);
+ il.Emit(System.Reflection.Emit.OpCodes.Stloc_0);
+ il.Emit(System.Reflection.Emit.OpCodes.Ldarg_2);
+ il.Emit(System.Reflection.Emit.OpCodes.Ldloc_0);
+ il.Emit(System.Reflection.Emit.OpCodes.Callvirt, smethod);
+ il.Emit(System.Reflection.Emit.OpCodes.Ret);
+ return new PropInfo { Type = type, Name = name, Set = (Action<JsonParser, int, object>)dyn.CreateDelegate(typeof(Action<JsonParser, int, object>)) };
+ }
+
+ internal TypeInfo(Type type, int outer, Type elem)
+ {
+ var infos = type.GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
+ var props = new SortedList<string, PropInfo>();
+ Type = type;
+ Outer = outer;
+ ElementType = elem;
+ Convert = GetConvert(Type, outer);
+ Ctor = GetCtor((ElementType ?? Type), outer, (ElementType != null));
+ for (var i = 0; i < infos.Length; i++)
+ if (infos[i].CanWrite)
+ props.Add(infos[i].Name, GetPropInfo(infos[i].PropertyType, infos[i].Name, infos[i].GetSetMethod(), GetParseMethod(infos[i].PropertyType)));
+ Props = props.Values.ToArray();
+ Items = ((ElementType != null) ? GetPropInfo(ElementType, "", typeof(List<>).MakeGenericType(ElementType).GetMethod("Add", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public), GetParseMethod(ElementType)) : null);
+ }
+ }
+
+ static JsonParser()
+ {
+ for (char c = '0'; c <= '9'; c++) { HXD[c] = true; HEX[c] = (short)(c - 48); }
+ for (char c = 'A'; c <= 'F'; c++) { HXD[c] = HXD[c + 32] = true; HEX[c] = HEX[c + 32] = (short)(c - 55); }
+ ESC['/'] = '/'; ESC['\\'] = '\\';
+ ESC['b'] = '\b'; ESC['f'] = '\f'; ESC['n'] = '\n'; ESC['r'] = '\r'; ESC['t'] = '\t'; ESC['u'] = 'u';
+ for (int c = ANY; c < 128; c++) if (ESC[c] == ANY) ESC[c] = (char)c;
+ for (int c = '0'; c <= '9'; c++) IDN[c] = true;
+ IDF['_'] = IDN['_'] = true;
+ for (int c = 'A'; c <= 'Z'; c++) IDF[c] = IDN[c] = IDF[c + 32] = IDN[c + 32] = true;
+ }
+
+ private Exception Error(string message) { return new Exception(String.Format("{0} at {1} (found: '{2}')", message, at, ((chr < EOF) ? ("\\" + chr) : "EOF"))); }
+ private void Reset(Func<int> read, Action<int> next, Func<int, int> achar, Func<int> space) { at = -1; chr = ANY; Read = read; Next = next; Char = achar; Space = space; }
+
+ private object Error(int outer) { throw Error("Bad value"); }
+ private object Null(int outer) { Next('n'); Next('u'); Next('l'); Next('l'); return null; }
+ private bool F(int outer) { Next('f'); Next('a'); Next('l'); Next('s'); Next('e'); return false; }
+ private bool T(int outer) { Next('t'); Next('r'); Next('u'); Next('e'); return true; }
+ private object False(int outer) { return F(0); }
+ private object True(int outer) { return T(0); }
+
+ private int StreamSpace() { if (chr <= ' ') while ((chr = (str.Read(stc, 0, 1) > 0) ? stc[0] : EOF) <= ' ') ; return chr; }
+ private int StreamRead() { return (chr = (str.Read(stc, 0, 1) > 0) ? stc[0] : EOF); }
+ private void StreamNext(int ch) { if (chr != ch) throw Error("Unexpected character"); chr = ((str.Read(stc, 0, 1) > 0) ? stc[0] : EOF); }
+ private int StreamChar(int ch)
+ {
+ if (lln >= LBS)
+ {
+ if (lsb.Length == 0)
+ lsb.Append(new string(lbf, 0, lln));
+ lsb.Append((char)ch);
+ }
+ else
+ lbf[lln++] = (char)ch;
+ return (chr = (str.Read(stc, 0, 1) > 0) ? stc[0] : EOF);
+ }
+
+ private int StringSpace() { if (chr <= ' ') while ((++at < len) && ((chr = txt[at]) <= ' ')) ; return chr; }
+ private int StringRead() { return (chr = (++at < len) ? txt[at] : EOF); }
+ private void StringNext(int ch) { if (chr != ch) throw Error("Unexpected character"); chr = ((++at < len) ? txt[at] : EOF); }
+ private int StringChar(int ch)
+ {
+ if (lln >= LBS)
+ {
+ if (lsb.Length == 0)
+ lsb.Append(new string(lbf, 0, lln));
+ lsb.Append((char)ch);
+ }
+ else
+ lbf[lln++] = (char)ch;
+ return (chr = (++at < len) ? txt[at] : EOF);
+ }
+
+ private int Esc(int ec)
+ {
+ int ch;
+ if (ec == 'u')
+ {
+ short cp = 0, ic = -1;
+ while ((++ic < 4) && ((ch = Read()) <= 'f') && HXD[ch]) { cp *= 16; cp += HEX[ch]; }
+ if (ic < 4) throw Error("Invalid Unicode character");
+ ch = Convert.ToChar(cp);
+ }
+ else
+ ch = ESC[ec];
+ Char(ch);
+ return ch;
+ }
+
+ private bool Boolean(int outer)
+ {
+ var ch = Space();
+ switch (ch)
+ {
+ case 'f': return F(0);
+ case 't': return T(0);
+ default: throw Error("Bad boolean");
+ }
+ }
+
+ private byte Byte(int outer)
+ {
+ var ch = Space();
+ byte n = 0;
+ while ((ch >= '0') && (ch <= '9')) { n *= 10; n += (byte)(ch - 48); ch = Read(); }
+ return n;
+ }
+
+ private short Int16(int outer)
+ {
+ short it = 1, n = 0;
+ var ch = Space();
+ if (ch == '-') { ch = Read(); it = (short)-it; }
+ while ((ch >= '0') && (ch <= '9')) { n *= 10; n += (short)(ch - 48); ch = Read(); }
+ return (short)(it * n);
+ }
+
+ private int Int32(int outer)
+ {
+ int it = 1, n = 0;
+ var ch = Space();
+ if (ch == '-') { ch = Read(); it = -it; }
+ while ((ch >= '0') && (ch <= '9')) { n *= 10; n += (ch - 48); ch = Read(); }
+ return (it * n);
+ }
+
+ private long Int64(int outer)
+ {
+ long it = 1, n = 0;
+ var ch = Space();
+ if (ch == '-') { ch = Read(); it = -it; }
+ while ((ch >= '0') && (ch <= '9')) { n *= 10; n += (ch - 48); ch = Read(); }
+ return (it * n);
+ }
+
+ private float Single(int outer)
+ {
+ var ch = Space();
+ string s;
+ lsb.Length = 0; lln = 0;
+ if (ch == '-') ch = Char(ch);
+ while ((ch >= '0') && (ch <= '9')) ch = Char(ch);
+ if (ch == '.')
+ {
+ ch = Char(ch);
+ while ((ch >= '0') && (ch <= '9')) ch = Char(ch);
+ }
+ if ((ch == 'e') || (ch == 'E'))
+ {
+ ch = Char(ch);
+ if ((ch == '-') || (ch == '+')) ch = Char(ch);
+ while ((ch >= '0') && (ch <= '9')) ch = Char(ch);
+ }
+ s = ((lsb.Length > 0) ? lsb.ToString() : new string(lbf, 0, lln));
+ return float.Parse(s);
+ }
+
+ private double Double(int outer)
+ {
+ var ch = Space();
+ string s;
+ lsb.Length = 0; lln = 0;
+ if (ch == '-') ch = Char(ch);
+ while ((ch >= '0') && (ch <= '9')) ch = Char(ch);
+ if (ch == '.')
+ {
+ ch = Char(ch);
+ while ((ch >= '0') && (ch <= '9')) ch = Char(ch);
+ }
+ if ((ch == 'e') || (ch == 'E'))
+ {
+ ch = Char(ch);
+ if ((ch == '-') || (ch == '+')) ch = Char(ch);
+ while ((ch >= '0') && (ch <= '9')) ch = Char(ch);
+ }
+ s = ((lsb.Length > 0) ? lsb.ToString() : new string(lbf, 0, lln));
+ return double.Parse(s);
+ }
+
+ private decimal Decimal(int outer)
+ {
+ var ch = Space();
+ string s;
+ lsb.Length = 0; lln = 0;
+ if (ch == '-') ch = Char(ch);
+ while ((ch >= '0') && (ch <= '9')) ch = Char(ch);
+ if (ch == '.')
+ {
+ ch = Char(ch);
+ while ((ch >= '0') && (ch <= '9')) ch = Char(ch);
+ }
+ s = ((lsb.Length > 0) ? lsb.ToString() : new string(lbf, 0, lln));
+ return decimal.Parse(s);
+ }
+
+ private object Num(int outer)
+ {
+ long it = 1, n = 0;
+ var ch = chr;
+ string s;
+ lsb.Length = 0; lln = 0;
+ if (ch == '-') { ch = Char(ch); it = -it; }
+ while ((ch >= '0') && (ch <= '9')) { n *= 10; n += (ch - 48); ch = Char(ch); }
+ if (ch == '.')
+ {
+ it = 0;
+ ch = Char(ch);
+ while ((ch >= '0') && (ch <= '9')) ch = Char(ch);
+ }
+ if ((ch == 'e') || (ch == 'E'))
+ {
+ it = 0;
+ ch = Char(ch);
+ if ((ch == '-') || (ch == '+')) ch = Char(ch);
+ while ((ch >= '0') && (ch <= '9')) ch = Char(ch);
+ }
+ if (it != 0) { n *= it; if ((int.MinValue <= n) && (n <= int.MaxValue)) return (int)n; else return n; }
+ s = ((lsb.Length > 0) ? lsb.ToString() : new string(lbf, 0, lln));
+ return ((outer > STRING) ? types[outer].Convert(s) : s);
+ }
+
+ private DateTime DateTime(int outer)
+ {
+ Space();
+ return System.DateTime.Parse((string)Str(OBJECT));
+ }
+
+ private TEnum Enum<TEnum>(int outer) where TEnum : struct
+ {
+ var ch = Space();
+ return ((ch == '"') ? (TEnum)System.Enum.Parse(typeof(TEnum), (string)Str(OBJECT)) : (TEnum)Num(OBJECT));
+ }
+
+ private object Str(int outer)
+ {
+ var a = ((outer < OBJECT) ? types[-outer].Props : null);
+ int n = ((a != null) ? a.Length : 0), c = 0, i = 0, cc = 0, nc = 0;
+ PropInfo p = null; string s = null; var ec = false; var ch = chr;
+ if (ch == '"')
+ {
+ Read();
+ lsb.Length = 0; lln = 0;
+ while (true)
+ {
+ switch (ch = chr)
+ {
+ case '\\':
+ ch = Read(); ec = true;
+ break;
+ case '"':
+ Read();
+ if (i >= n)
+ {
+ s = ((lsb.Length > 0) ? lsb.ToString() : new string(lbf, 0, lln));
+ return ((outer > STRING) ? types[outer].Convert(s) : s);
+ }
+ return p;
+ default:
+ break;
+ }
+ if (ch < EOF) { if (!ec || (ch >= 128)) Char(nc = ch); else { nc = Esc(ch); ec = false; } } else break;
+ if (i < n)
+ {
+ while ((i < n) && ((c >= (s = (p = a[i]).Name).Length) || (s[c] != nc))) i++;
+ if ((i >= n) && ((c == 0) || (s[c - 1] != cc))) i = n;
+ c++;
+ }
+ cc = nc;
+ }
+ }
+ throw Error((outer > OBJECT) ? "Bad literal" : "Bad key");
+ }
+
+ private object Obj(int outer)
+ {
+ var cached = types[outer];
+ var obj = cached.Ctor();
+ var ch = chr;
+ if (ch == '{')
+ {
+ Read();
+ ch = Space();
+ if (ch == '}')
+ {
+ Read();
+ return obj;
+ }
+ while (ch < EOF)
+ {
+ var key = Str(-outer);
+ Space();
+ Next(':');
+ if (outer > OBJECT)
+ {
+ if (key is PropInfo)
+ {
+ var prop = (PropInfo)key;
+ prop.Set(this, prop.Outer, obj);
+ }
+ else
+ Val(OBJECT);
+ }
+ else
+ ((IDictionary)obj).Add(key, Val(OBJECT));
+ ch = Space();
+ if (ch == '}')
+ {
+ Read();
+ return obj;
+ }
+ Next(',');
+ ch = Space();
+ }
+ }
+ throw Error("Bad object");
+ }
+
+ private object Arr(int outer)
+ {
+ var cached = types[outer = (outer >= ARRAY) ? outer : ARRAY];
+ var ch = chr;
+ if (ch == '[')
+ {
+ IList list;
+ Read();
+ ch = Space();
+ list = (IList)cached.Ctor();
+ if (ch == ']')
+ {
+ Read();
+ if (cached.Type.IsArray)
+ {
+ var array = Array.CreateInstance(cached.ElementType, list.Count);
+ list.CopyTo(array, 0);
+ return array;
+ }
+ return list;
+ }
+ while (ch < EOF)
+ {
+ var items = cached.Items;
+ items.Set(this, cached.Inner, list);
+ ch = Space();
+ if (ch == ']')
+ {
+ Read();
+ if (cached.Type.IsArray)
+ {
+ var array = Array.CreateInstance(cached.ElementType, list.Count);
+ list.CopyTo(array, 0);
+ return array;
+ }
+ return list;
+ }
+ Next(',');
+ ch = Space();
+ }
+ }
+ throw Error("Bad array");
+ }
+
+ private object Val(int outer)
+ {
+ return parse[Space() & 0x7f](outer);
+ }
+
+ private Type GetElementType(Type type)
+ {
+ if (type.IsArray)
+ return type.GetElementType();
+ else if (typeof(System.Collections.IEnumerable).IsAssignableFrom(type))
+ return (type.IsGenericType ? type.GetGenericArguments()[0] : typeof(object));
+ else
+ return null;
+ }
+
+ private object NewObj()
+ {
+ return new Dictionary<string, object>();
+ }
+
+ private int Closure(int outer)
+ {
+ var props = types[outer].Props;
+ for (var i = 0; i < props.Length; i++) props[i].Outer = Entry(props[i].Type);
+ return outer;
+ }
+
+ private int Entry(Type type)
+ {
+ return Entry(type, null);
+ }
+
+ private int Entry(Type type, Type elem)
+ {
+ int outer;
+ if (!thash.TryGetValue(type, out outer))
+ {
+ bool b = (elem != null);
+ outer = thash.Count;
+ elem = (elem ?? GetElementType(type));
+ types[outer] = new TypeInfo(type, outer, elem);
+ types[outer].Ctor = ((outer > OBJECT) ? types[outer].Ctor : NewObj);
+ thash.Add(type, outer);
+ if ((elem != null) && !b) types[outer].Inner = Entry(elem);
+ }
+ return Closure(outer);
+ }
+
+ private T DoParse<T>(System.IO.Stream input)
+ {
+ Reset(StreamRead, StreamNext, StreamChar, StreamSpace);
+ using (str = new System.IO.StreamReader(input))
+ {
+ return (T)Val(Entry(typeof(T)));
+ }
+ }
+
+ private T DoParse<T>(string input)
+ {
+ len = input.Length;
+ txt = new char[len];
+ input.CopyTo(0, txt, 0, len);
+ Reset(StringRead, StringNext, StringChar, StringSpace);
+ return (T)Val(Entry(typeof(T)));
+ }
+
+ public JsonParser()
+ {
+ parse['n'] = Null; parse['f'] = False; parse['t'] = True;
+ parse['0'] = parse['1'] = parse['2'] = parse['3'] = parse['4'] =
+ parse['5'] = parse['6'] = parse['7'] = parse['8'] = parse['9'] =
+ parse['-'] = Num; parse['"'] = Str; parse['{'] = Obj; parse['['] = Arr;
+ for (var input = 0; input < 128; input++) parse[input] = (parse[input] ?? Error);
+ Entry(typeof(object));
+ Entry(typeof(object[]), typeof(object));
+ Entry(typeof(string), typeof(char));
+ }
+
+ public T Parse<T>(System.IO.Stream input)
+ {
+ if (input == null) throw new ArgumentNullException("input", "cannot be null");
+ return DoParse<T>(input);
+ }
+
+ public T Parse<T>(string input)
+ {
+ if (input == null) throw new ArgumentNullException("input", "cannot be null");
+ return DoParse<T>(input);
+ }
+ }
+}
69 JsonTest/Test.csproj
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+ <ProductVersion>8.0.30703</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{C4054A9A-4907-470E-90F7-3DAA6A378518}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Test</RootNamespace>
+ <AssemblyName>Test</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <TargetFrameworkProfile />
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <UseVSHostingProcess>false</UseVSHostingProcess>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+ <PlatformTarget>x86</PlatformTarget>
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <UseVSHostingProcess>false</UseVSHostingProcess>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>bin\Debug\Newtonsoft.Json.dll</HintPath>
+ </Reference>
+ <Reference Include="ServiceStack.Text, Version=3.9.59.0, Culture=neutral, processorArchitecture=MSIL">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>bin\Debug\ServiceStack.Text.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Web.Extensions" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="System.Text.Json\JsonParser.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="app.config" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project>
20 JsonTest/Test.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test", "Test.csproj", "{C4054A9A-4907-470E-90F7-3DAA6A378518}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|x86 = Debug|x86
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C4054A9A-4907-470E-90F7-3DAA6A378518}.Debug|x86.ActiveCfg = Debug|x86
+ {C4054A9A-4907-470E-90F7-3DAA6A378518}.Debug|x86.Build.0 = Debug|x86
+ {C4054A9A-4907-470E-90F7-3DAA6A378518}.Release|x86.ActiveCfg = Release|x86
+ {C4054A9A-4907-470E-90F7-3DAA6A378518}.Release|x86.Build.0 = Release|x86
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
689,400 JsonTest/TestData/fathers.json.txt
689,400 additions, 0 deletions not shown
88 JsonTest/TestData/small.json.txt
@@ -0,0 +1,88 @@
+{"web-app": {
+ "servlet": [
+ {
+ "servlet-name": "cofaxCDS",
+ "servlet-class": "org.cofax.cds.CDSServlet",
+ "init-param": {
+ "configGlossary:installationAt": "Philadelphia, PA",
+ "configGlossary:adminEmail": "ksm@pobox.com",
+ "configGlossary:poweredBy": "Cofax",
+ "configGlossary:poweredByIcon": "/images/cofax.gif",
+ "configGlossary:staticPath": "/content/static",
+ "templateProcessorClass": "org.cofax.WysiwygTemplate",
+ "templateLoaderClass": "org.cofax.FilesTemplateLoader",
+ "templatePath": "templates",
+ "templateOverridePath": "",
+ "defaultListTemplate": "listTemplate.htm",
+ "defaultFileTemplate": "articleTemplate.htm",
+ "useJSP": false,
+ "jspListTemplate": "listTemplate.jsp",
+ "jspFileTemplate": "articleTemplate.jsp",
+ "cachePackageTagsTrack": 200,
+ "cachePackageTagsStore": 200,
+ "cachePackageTagsRefresh": 60,
+ "cacheTemplatesTrack": 100,
+ "cacheTemplatesStore": 50,
+ "cacheTemplatesRefresh": 15,
+ "cachePagesTrack": 200,
+ "cachePagesStore": 100,
+ "cachePagesRefresh": 10,
+ "cachePagesDirtyRead": 10,
+ "searchEngineListTemplate": "forSearchEnginesList.htm",
+ "searchEngineFileTemplate": "forSearchEngines.htm",
+ "searchEngineRobotsDb": "WEB-INF/robots.db",
+ "useDataStore": true,
+ "dataStoreClass": "org.cofax.SqlDataStore",
+ "redirectionClass": "org.cofax.SqlRedirection",
+ "dataStoreName": "cofax",
+ "dataStoreDriver": "com.microsoft.jdbc.sqlserver.SQLServerDriver",
+ "dataStoreUrl": "jdbc:microsoft:sqlserver://LOCALHOST:1433;DatabaseName=goon",
+ "dataStoreUser": "sa",
+ "dataStorePassword": "dataStoreTestQuery",
+ "dataStoreTestQuery": "SET NOCOUNT ON;select test='test';",
+ "dataStoreLogFile": "/usr/local/tomcat/logs/datastore.log",
+ "dataStoreInitConns": 10,
+ "dataStoreMaxConns": 100,
+ "dataStoreConnUsageLimit": 100,
+ "dataStoreLogLevel": "debug",
+ "maxUrlLength": 500}},
+ {
+ "servlet-name": "cofaxEmail",
+ "servlet-class": "org.cofax.cds.EmailServlet",
+ "init-param": {
+ "mailHost": "mail1",
+ "mailHostOverride": "mail2"}},
+ {
+ "servlet-name": "cofaxAdmin",
+ "servlet-class": "org.cofax.cds.AdminServlet"},
+
+ {
+ "servlet-name": "fileServlet",
+ "servlet-class": "org.cofax.cds.FileServlet"},
+ {
+ "servlet-name": "cofaxTools",
+ "servlet-class": "org.cofax.cms.CofaxToolsServlet",
+ "init-param": {
+ "templatePath": "toolstemplates/",
+ "log": 1,
+ "logLocation": "/usr/local/tomcat/logs/CofaxTools.log",
+ "logMaxSize": "",
+ "dataLog": 1,
+ "dataLogLocation": "/usr/local/tomcat/logs/dataLog.log",
+ "dataLogMaxSize": "",
+ "removePageCache": "/content/admin/remove?cache=pages&id=",
+ "removeTemplateCache": "/content/admin/remove?cache=templates&id=",
+ "fileTransferFolder": "/usr/local/tomcat/webapps/content/fileTransferFolder",
+ "lookInContext": 1,
+ "adminGroupID": 4,
+ "betaServer": true}}],
+ "servlet-mapping": {
+ "cofaxCDS": "/",
+ "cofaxEmail": "/cofaxutil/aemail/*",
+ "cofaxAdmin": "/admin/*",
+ "fileServlet": "/static/*",
+ "cofaxTools": "/tools/*"},
+
+ "taglib": {
+ "taglib-uri": "cofax.tld",
+ "taglib-location": "/WEB-INF/tlds/cofax.tld"}}}
1  JsonTest/TestData/tiny.json.txt
@@ -0,0 +1 @@
+ {"Id" :789 ,"Name":"Albert\tSimple", "Married" :true, "Address": "Planet Earth", "Scores":[1,2,3,4,5,6,7,8,9,10],"Data":null}
3  JsonTest/app.config
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<configuration>
+<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>
32 LICENSE.md
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2013 Cyril Jandia
+ *
+ * http://www.cjandia.com/
+ *
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+``Software''), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL CYRIL JANDIA BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Cyril Jandia shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from Cyril Jandia.
+
+Inquiries : ysharp {dot} design {at} gmail {dot} com
+ *
+ */
4 README.md
@@ -0,0 +1,4 @@
+JSONParser
+==========
+
+A minimalistic, and pretty fast JSON parser
Please sign in to comment.
Something went wrong with that request. Please try again.