DESKTOP-B25GA9E\W35
2 years ago
28 changed files with 4460 additions and 33 deletions
Binary file not shown.
@ -1,33 +0,0 @@
@@ -1,33 +0,0 @@
|
||||
fileFormatVersion: 2 |
||||
guid: c1e390103eefc6b428c4a597b86aeb92 |
||||
PluginImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
iconMap: {} |
||||
executionOrder: {} |
||||
defineConstraints: [] |
||||
isPreloaded: 0 |
||||
isOverridable: 0 |
||||
isExplicitlyReferenced: 0 |
||||
validateReferences: 1 |
||||
platformData: |
||||
- first: |
||||
Any: |
||||
second: |
||||
enabled: 1 |
||||
settings: {} |
||||
- first: |
||||
Editor: Editor |
||||
second: |
||||
enabled: 0 |
||||
settings: |
||||
DefaultValueInitialized: true |
||||
- first: |
||||
Windows Store Apps: WindowsStoreApps |
||||
second: |
||||
enabled: 0 |
||||
settings: |
||||
CPU: AnyCPU |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,8 @@
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 24989a04c7189984cb5ec48003446fb6 |
||||
folderAsset: yes |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,18 @@
@@ -0,0 +1,18 @@
|
||||
using System; |
||||
using System.Reflection; |
||||
using System.Runtime.CompilerServices; |
||||
|
||||
|
||||
[assembly: CLSCompliant (true)] |
||||
|
||||
[assembly: AssemblyTitle ("LitJson")] |
||||
[assembly: AssemblyDescription ("LitJSON library")] |
||||
[assembly: AssemblyConfiguration ("")] |
||||
[assembly: AssemblyCompany ("")] |
||||
[assembly: AssemblyProduct ("LitJSON")] |
||||
[assembly: AssemblyCopyright ( |
||||
"The authors disclaim copyright to this source code")] |
||||
[assembly: AssemblyTrademark ("")] |
||||
[assembly: AssemblyCulture ("")] |
||||
|
||||
[assembly: AssemblyVersion ("@ASSEMBLY_VERSION@")] |
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 62c5b44632e7f514cbaa9ed6169c0cda |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,60 @@
@@ -0,0 +1,60 @@
|
||||
#region Header |
||||
/** |
||||
* IJsonWrapper.cs |
||||
* Interface that represents a type capable of handling all kinds of JSON |
||||
* data. This is mainly used when mapping objects through JsonMapper, and |
||||
* it's implemented by JsonData. |
||||
* |
||||
* The authors disclaim copyright to this source code. For more details, see |
||||
* the COPYING file included with this distribution. |
||||
**/ |
||||
#endregion |
||||
|
||||
|
||||
using System.Collections; |
||||
using System.Collections.Specialized; |
||||
|
||||
|
||||
namespace LitJson |
||||
{ |
||||
public enum JsonType |
||||
{ |
||||
None, |
||||
|
||||
Object, |
||||
Array, |
||||
String, |
||||
Int, |
||||
Long, |
||||
Double, |
||||
Boolean |
||||
} |
||||
|
||||
public interface IJsonWrapper : IList, IOrderedDictionary |
||||
{ |
||||
bool IsArray { get; } |
||||
bool IsBoolean { get; } |
||||
bool IsDouble { get; } |
||||
bool IsInt { get; } |
||||
bool IsLong { get; } |
||||
bool IsObject { get; } |
||||
bool IsString { get; } |
||||
|
||||
bool GetBoolean (); |
||||
double GetDouble (); |
||||
int GetInt (); |
||||
JsonType GetJsonType (); |
||||
long GetLong (); |
||||
string GetString (); |
||||
|
||||
void SetBoolean (bool val); |
||||
void SetDouble (double val); |
||||
void SetInt (int val); |
||||
void SetJsonType (JsonType type); |
||||
void SetLong (long val); |
||||
void SetString (string val); |
||||
|
||||
string ToJson (); |
||||
void ToJson (JsonWriter writer); |
||||
} |
||||
} |
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: eb44247cc2867754296abb0cc48fe239 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 6ba9ae4dfe94b3c429e3c53e1c98fb3a |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,65 @@
@@ -0,0 +1,65 @@
|
||||
#region Header |
||||
/** |
||||
* JsonException.cs |
||||
* Base class throwed by LitJSON when a parsing error occurs. |
||||
* |
||||
* The authors disclaim copyright to this source code. For more details, see |
||||
* the COPYING file included with this distribution. |
||||
**/ |
||||
#endregion |
||||
|
||||
|
||||
using System; |
||||
|
||||
|
||||
namespace LitJson |
||||
{ |
||||
public class JsonException : |
||||
#if NETSTANDARD1_5 |
||||
Exception |
||||
#else |
||||
ApplicationException |
||||
#endif |
||||
{ |
||||
public JsonException () : base () |
||||
{ |
||||
} |
||||
|
||||
internal JsonException (ParserToken token) : |
||||
base (String.Format ( |
||||
"Invalid token '{0}' in input string", token)) |
||||
{ |
||||
} |
||||
|
||||
internal JsonException (ParserToken token, |
||||
Exception inner_exception) : |
||||
base (String.Format ( |
||||
"Invalid token '{0}' in input string", token), |
||||
inner_exception) |
||||
{ |
||||
} |
||||
|
||||
internal JsonException (int c) : |
||||
base (String.Format ( |
||||
"Invalid character '{0}' in input string", (char) c)) |
||||
{ |
||||
} |
||||
|
||||
internal JsonException (int c, Exception inner_exception) : |
||||
base (String.Format ( |
||||
"Invalid character '{0}' in input string", (char) c), |
||||
inner_exception) |
||||
{ |
||||
} |
||||
|
||||
|
||||
public JsonException (string message) : base (message) |
||||
{ |
||||
} |
||||
|
||||
public JsonException (string message, Exception inner_exception) : |
||||
base (message, inner_exception) |
||||
{ |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 9867c685641adf747be0d8e36823cb43 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,987 @@
@@ -0,0 +1,987 @@
|
||||
#region Header |
||||
/** |
||||
* JsonMapper.cs |
||||
* JSON to .Net object and object to JSON conversions. |
||||
* |
||||
* The authors disclaim copyright to this source code. For more details, see |
||||
* the COPYING file included with this distribution. |
||||
**/ |
||||
#endregion |
||||
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Collections.Generic; |
||||
using System.Globalization; |
||||
using System.IO; |
||||
using System.Reflection; |
||||
|
||||
|
||||
namespace LitJson |
||||
{ |
||||
internal struct PropertyMetadata |
||||
{ |
||||
public MemberInfo Info; |
||||
public bool IsField; |
||||
public Type Type; |
||||
} |
||||
|
||||
|
||||
internal struct ArrayMetadata |
||||
{ |
||||
private Type element_type; |
||||
private bool is_array; |
||||
private bool is_list; |
||||
|
||||
|
||||
public Type ElementType { |
||||
get { |
||||
if (element_type == null) |
||||
return typeof (JsonData); |
||||
|
||||
return element_type; |
||||
} |
||||
|
||||
set { element_type = value; } |
||||
} |
||||
|
||||
public bool IsArray { |
||||
get { return is_array; } |
||||
set { is_array = value; } |
||||
} |
||||
|
||||
public bool IsList { |
||||
get { return is_list; } |
||||
set { is_list = value; } |
||||
} |
||||
} |
||||
|
||||
|
||||
internal struct ObjectMetadata |
||||
{ |
||||
private Type element_type; |
||||
private bool is_dictionary; |
||||
|
||||
private IDictionary<string, PropertyMetadata> properties; |
||||
|
||||
|
||||
public Type ElementType { |
||||
get { |
||||
if (element_type == null) |
||||
return typeof (JsonData); |
||||
|
||||
return element_type; |
||||
} |
||||
|
||||
set { element_type = value; } |
||||
} |
||||
|
||||
public bool IsDictionary { |
||||
get { return is_dictionary; } |
||||
set { is_dictionary = value; } |
||||
} |
||||
|
||||
public IDictionary<string, PropertyMetadata> Properties { |
||||
get { return properties; } |
||||
set { properties = value; } |
||||
} |
||||
} |
||||
|
||||
|
||||
internal delegate void ExporterFunc (object obj, JsonWriter writer); |
||||
public delegate void ExporterFunc<T> (T obj, JsonWriter writer); |
||||
|
||||
internal delegate object ImporterFunc (object input); |
||||
public delegate TValue ImporterFunc<TJson, TValue> (TJson input); |
||||
|
||||
public delegate IJsonWrapper WrapperFactory (); |
||||
|
||||
|
||||
public class JsonMapper |
||||
{ |
||||
#region Fields |
||||
private static readonly int max_nesting_depth; |
||||
|
||||
private static readonly IFormatProvider datetime_format; |
||||
|
||||
private static readonly IDictionary<Type, ExporterFunc> base_exporters_table; |
||||
private static readonly IDictionary<Type, ExporterFunc> custom_exporters_table; |
||||
|
||||
private static readonly IDictionary<Type, |
||||
IDictionary<Type, ImporterFunc>> base_importers_table; |
||||
private static readonly IDictionary<Type, |
||||
IDictionary<Type, ImporterFunc>> custom_importers_table; |
||||
|
||||
private static readonly IDictionary<Type, ArrayMetadata> array_metadata; |
||||
private static readonly object array_metadata_lock = new Object (); |
||||
|
||||
private static readonly IDictionary<Type, |
||||
IDictionary<Type, MethodInfo>> conv_ops; |
||||
private static readonly object conv_ops_lock = new Object (); |
||||
|
||||
private static readonly IDictionary<Type, ObjectMetadata> object_metadata; |
||||
private static readonly object object_metadata_lock = new Object (); |
||||
|
||||
private static readonly IDictionary<Type, |
||||
IList<PropertyMetadata>> type_properties; |
||||
private static readonly object type_properties_lock = new Object (); |
||||
|
||||
private static readonly JsonWriter static_writer; |
||||
private static readonly object static_writer_lock = new Object (); |
||||
#endregion |
||||
|
||||
|
||||
#region Constructors |
||||
static JsonMapper () |
||||
{ |
||||
max_nesting_depth = 100; |
||||
|
||||
array_metadata = new Dictionary<Type, ArrayMetadata> (); |
||||
conv_ops = new Dictionary<Type, IDictionary<Type, MethodInfo>> (); |
||||
object_metadata = new Dictionary<Type, ObjectMetadata> (); |
||||
type_properties = new Dictionary<Type, |
||||
IList<PropertyMetadata>> (); |
||||
|
||||
static_writer = new JsonWriter (); |
||||
|
||||
datetime_format = DateTimeFormatInfo.InvariantInfo; |
||||
|
||||
base_exporters_table = new Dictionary<Type, ExporterFunc> (); |
||||
custom_exporters_table = new Dictionary<Type, ExporterFunc> (); |
||||
|
||||
base_importers_table = new Dictionary<Type, |
||||
IDictionary<Type, ImporterFunc>> (); |
||||
custom_importers_table = new Dictionary<Type, |
||||
IDictionary<Type, ImporterFunc>> (); |
||||
|
||||
RegisterBaseExporters (); |
||||
RegisterBaseImporters (); |
||||
} |
||||
#endregion |
||||
|
||||
|
||||
#region Private Methods |
||||
private static void AddArrayMetadata (Type type) |
||||
{ |
||||
if (array_metadata.ContainsKey (type)) |
||||
return; |
||||
|
||||
ArrayMetadata data = new ArrayMetadata (); |
||||
|
||||
data.IsArray = type.IsArray; |
||||
|
||||
if (type.GetInterface ("System.Collections.IList") != null) |
||||
data.IsList = true; |
||||
|
||||
foreach (PropertyInfo p_info in type.GetProperties ()) { |
||||
if (p_info.Name != "Item") |
||||
continue; |
||||
|
||||
ParameterInfo[] parameters = p_info.GetIndexParameters (); |
||||
|
||||
if (parameters.Length != 1) |
||||
continue; |
||||
|
||||
if (parameters[0].ParameterType == typeof (int)) |
||||
data.ElementType = p_info.PropertyType; |
||||
} |
||||
|
||||
lock (array_metadata_lock) { |
||||
try { |
||||
array_metadata.Add (type, data); |
||||
} catch (ArgumentException) { |
||||
return; |
||||
} |
||||
} |
||||
} |
||||
|
||||
private static void AddObjectMetadata (Type type) |
||||
{ |
||||
if (object_metadata.ContainsKey (type)) |
||||
return; |
||||
|
||||
ObjectMetadata data = new ObjectMetadata (); |
||||
|
||||
if (type.GetInterface ("System.Collections.IDictionary") != null) |
||||
data.IsDictionary = true; |
||||
|
||||
data.Properties = new Dictionary<string, PropertyMetadata> (); |
||||
|
||||
foreach (PropertyInfo p_info in type.GetProperties ()) { |
||||
if (p_info.Name == "Item") { |
||||
ParameterInfo[] parameters = p_info.GetIndexParameters (); |
||||
|
||||
if (parameters.Length != 1) |
||||
continue; |
||||
|
||||
if (parameters[0].ParameterType == typeof (string)) |
||||
data.ElementType = p_info.PropertyType; |
||||
|
||||
continue; |
||||
} |
||||
|
||||
PropertyMetadata p_data = new PropertyMetadata (); |
||||
p_data.Info = p_info; |
||||
p_data.Type = p_info.PropertyType; |
||||
|
||||
data.Properties.Add (p_info.Name, p_data); |
||||
} |
||||
|
||||
foreach (FieldInfo f_info in type.GetFields ()) { |
||||
PropertyMetadata p_data = new PropertyMetadata (); |
||||
p_data.Info = f_info; |
||||
p_data.IsField = true; |
||||
p_data.Type = f_info.FieldType; |
||||
|
||||
data.Properties.Add (f_info.Name, p_data); |
||||
} |
||||
|
||||
lock (object_metadata_lock) { |
||||
try { |
||||
object_metadata.Add (type, data); |
||||
} catch (ArgumentException) { |
||||
return; |
||||
} |
||||
} |
||||
} |
||||
|
||||
private static void AddTypeProperties (Type type) |
||||
{ |
||||
if (type_properties.ContainsKey (type)) |
||||
return; |
||||
|
||||
IList<PropertyMetadata> props = new List<PropertyMetadata> (); |
||||
|
||||
foreach (PropertyInfo p_info in type.GetProperties ()) { |
||||
if (p_info.Name == "Item") |
||||
continue; |
||||
|
||||
PropertyMetadata p_data = new PropertyMetadata (); |
||||
p_data.Info = p_info; |
||||
p_data.IsField = false; |
||||
props.Add (p_data); |
||||
} |
||||
|
||||
foreach (FieldInfo f_info in type.GetFields ()) { |
||||
PropertyMetadata p_data = new PropertyMetadata (); |
||||
p_data.Info = f_info; |
||||
p_data.IsField = true; |
||||
|
||||
props.Add (p_data); |
||||
} |
||||
|
||||
lock (type_properties_lock) { |
||||
try { |
||||
type_properties.Add (type, props); |
||||
} catch (ArgumentException) { |
||||
return; |
||||
} |
||||
} |
||||
} |
||||
|
||||
private static MethodInfo GetConvOp (Type t1, Type t2) |
||||
{ |
||||
lock (conv_ops_lock) { |
||||
if (! conv_ops.ContainsKey (t1)) |
||||
conv_ops.Add (t1, new Dictionary<Type, MethodInfo> ()); |
||||
} |
||||
|
||||
if (conv_ops[t1].ContainsKey (t2)) |
||||
return conv_ops[t1][t2]; |
||||
|
||||
MethodInfo op = t1.GetMethod ( |
||||
"op_Implicit", new Type[] { t2 }); |
||||
|
||||
lock (conv_ops_lock) { |
||||
try { |
||||
conv_ops[t1].Add (t2, op); |
||||
} catch (ArgumentException) { |
||||
return conv_ops[t1][t2]; |
||||
} |
||||
} |
||||
|
||||
return op; |
||||
} |
||||
|
||||
private static object ReadValue (Type inst_type, JsonReader reader) |
||||
{ |
||||
reader.Read (); |
||||
|
||||
if (reader.Token == JsonToken.ArrayEnd) |
||||
return null; |
||||
|
||||
Type underlying_type = Nullable.GetUnderlyingType(inst_type); |
||||
Type value_type = underlying_type ?? inst_type; |
||||
|
||||
if (reader.Token == JsonToken.Null) { |
||||
#if NETSTANDARD1_5 |
||||
if (inst_type.IsClass() || underlying_type != null) { |
||||
return null; |
||||
} |
||||
#else |
||||
if (inst_type.IsClass || underlying_type != null) { |
||||
return null; |
||||
} |
||||
#endif |
||||
|
||||
throw new JsonException (String.Format ( |
||||
"Can't assign null to an instance of type {0}", |
||||
inst_type)); |
||||
} |
||||
|
||||
if (reader.Token == JsonToken.Double || |
||||
reader.Token == JsonToken.Int || |
||||
reader.Token == JsonToken.Long || |
||||
reader.Token == JsonToken.String || |
||||
reader.Token == JsonToken.Boolean) { |
||||
|
||||
Type json_type = reader.Value.GetType (); |
||||
|
||||
if (value_type.IsAssignableFrom (json_type)) |
||||
return reader.Value; |
||||
|
||||
// If there's a custom importer that fits, use it |
||||
if (custom_importers_table.ContainsKey (json_type) && |
||||
custom_importers_table[json_type].ContainsKey ( |
||||
value_type)) { |
||||
|
||||
ImporterFunc importer = |
||||
custom_importers_table[json_type][value_type]; |
||||
|
||||
return importer (reader.Value); |
||||
} |
||||
|
||||
// Maybe there's a base importer that works |
||||
if (base_importers_table.ContainsKey (json_type) && |
||||
base_importers_table[json_type].ContainsKey ( |
||||
value_type)) { |
||||
|
||||
ImporterFunc importer = |
||||
base_importers_table[json_type][value_type]; |
||||
|
||||
return importer (reader.Value); |
||||
} |
||||
|
||||
// Maybe it's an enum |
||||
#if NETSTANDARD1_5 |
||||
if (value_type.IsEnum()) |
||||
return Enum.ToObject (value_type, reader.Value); |
||||
#else |
||||
if (value_type.IsEnum) |
||||
return Enum.ToObject (value_type, reader.Value); |
||||
#endif |
||||
// Try using an implicit conversion operator |
||||
MethodInfo conv_op = GetConvOp (value_type, json_type); |
||||
|
||||
if (conv_op != null) |
||||
return conv_op.Invoke (null, |
||||
new object[] { reader.Value }); |
||||
|
||||
// No luck |
||||
throw new JsonException (String.Format ( |
||||
"Can't assign value '{0}' (type {1}) to type {2}", |
||||
reader.Value, json_type, inst_type)); |
||||
} |
||||
|
||||
object instance = null; |
||||
|
||||
if (reader.Token == JsonToken.ArrayStart) { |
||||
|
||||
AddArrayMetadata (inst_type); |
||||
ArrayMetadata t_data = array_metadata[inst_type]; |
||||
|
||||
if (! t_data.IsArray && ! t_data.IsList) |
||||
throw new JsonException (String.Format ( |
||||
"Type {0} can't act as an array", |
||||
inst_type)); |
||||
|
||||
IList list; |
||||
Type elem_type; |
||||
|
||||
if (! t_data.IsArray) { |
||||
list = (IList) Activator.CreateInstance (inst_type); |
||||
elem_type = t_data.ElementType; |
||||
} else { |
||||
list = new ArrayList (); |
||||
elem_type = inst_type.GetElementType (); |
||||
} |
||||
|
||||
list.Clear(); |
||||
|
||||
while (true) { |
||||
object item = ReadValue (elem_type, reader); |
||||
if (item == null && reader.Token == JsonToken.ArrayEnd) |
||||
break; |
||||
|
||||
list.Add (item); |
||||
} |
||||
|
||||
if (t_data.IsArray) { |
||||
int n = list.Count; |
||||
instance = Array.CreateInstance (elem_type, n); |
||||
|
||||
for (int i = 0; i < n; i++) |
||||
((Array) instance).SetValue (list[i], i); |
||||
} else |
||||
instance = list; |
||||
|
||||
} else if (reader.Token == JsonToken.ObjectStart) { |
||||
AddObjectMetadata (value_type); |
||||
ObjectMetadata t_data = object_metadata[value_type]; |
||||
|
||||
instance = Activator.CreateInstance (value_type); |
||||
|
||||
while (true) { |
||||
reader.Read (); |
||||
|
||||
if (reader.Token == JsonToken.ObjectEnd) |
||||
break; |
||||
|
||||
string property = (string) reader.Value; |
||||
|
||||
if (t_data.Properties.ContainsKey (property)) { |
||||
PropertyMetadata prop_data = |
||||
t_data.Properties[property]; |
||||
|
||||
if (prop_data.IsField) { |
||||
((FieldInfo) prop_data.Info).SetValue ( |
||||
instance, ReadValue (prop_data.Type, reader)); |
||||
} else { |
||||
PropertyInfo p_info = |
||||
(PropertyInfo) prop_data.Info; |
||||
|
||||
if (p_info.CanWrite) |
||||
p_info.SetValue ( |
||||
instance, |
||||
ReadValue (prop_data.Type, reader), |
||||
null); |
||||
else |
||||
ReadValue (prop_data.Type, reader); |
||||
} |
||||
|
||||
} else { |
||||
if (! t_data.IsDictionary) { |
||||
|
||||
if (! reader.SkipNonMembers) { |
||||
throw new JsonException (String.Format ( |
||||
"The type {0} doesn't have the " + |
||||
"property '{1}'", |
||||
inst_type, property)); |
||||
} else { |
||||
ReadSkip (reader); |
||||
continue; |
||||
} |
||||
} |
||||
|
||||
((IDictionary) instance).Add ( |
||||
property, ReadValue ( |
||||
t_data.ElementType, reader)); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
|
||||
return instance; |
||||
} |
||||
|
||||
private static IJsonWrapper ReadValue (WrapperFactory factory, |
||||
JsonReader reader) |
||||
{ |
||||
reader.Read (); |
||||
|
||||
if (reader.Token == JsonToken.ArrayEnd || |
||||
reader.Token == JsonToken.Null) |
||||
return null; |
||||
|
||||
IJsonWrapper instance = factory (); |
||||
|
||||
if (reader.Token == JsonToken.String) { |
||||
instance.SetString ((string) reader.Value); |
||||
return instance; |
||||
} |
||||
|
||||
if (reader.Token == JsonToken.Double) { |
||||
instance.SetDouble ((double) reader.Value); |
||||
return instance; |
||||
} |
||||
|
||||
if (reader.Token == JsonToken.Int) { |
||||
instance.SetInt ((int) reader.Value); |
||||
return instance; |
||||
} |
||||
|
||||
if (reader.Token == JsonToken.Long) { |
||||
instance.SetLong ((long) reader.Value); |
||||
return instance; |
||||
} |
||||
|
||||
if (reader.Token == JsonToken.Boolean) { |
||||
instance.SetBoolean ((bool) reader.Value); |
||||
return instance; |
||||
} |
||||
|
||||
if (reader.Token == JsonToken.ArrayStart) { |
||||
instance.SetJsonType (JsonType.Array); |
||||
|
||||
while (true) { |
||||
IJsonWrapper item = ReadValue (factory, reader); |
||||
if (item == null && reader.Token == JsonToken.ArrayEnd) |
||||
break; |
||||
|
||||
((IList) instance).Add (item); |
||||
} |
||||
} |
||||
else if (reader.Token == JsonToken.ObjectStart) { |
||||
instance.SetJsonType (JsonType.Object); |
||||
|
||||
while (true) { |
||||
reader.Read (); |
||||
|
||||
if (reader.Token == JsonToken.ObjectEnd) |
||||
break; |
||||
|
||||
string property = (string) reader.Value; |
||||
|
||||
((IDictionary) instance)[property] = ReadValue ( |
||||
factory, reader); |
||||
} |
||||
|
||||
} |
||||
|
||||
return instance; |
||||
} |
||||
|
||||
private static void ReadSkip (JsonReader reader) |
||||
{ |
||||
ToWrapper ( |
||||
delegate { return new JsonMockWrapper (); }, reader); |
||||
} |
||||
|
||||
private static void RegisterBaseExporters () |
||||
{ |
||||
base_exporters_table[typeof (byte)] = |
||||
delegate (object obj, JsonWriter writer) { |
||||
writer.Write (Convert.ToInt32 ((byte) obj)); |
||||
}; |
||||
|
||||
base_exporters_table[typeof (char)] = |
||||
delegate (object obj, JsonWriter writer) { |
||||
writer.Write (Convert.ToString ((char) obj)); |
||||
}; |
||||
|
||||
base_exporters_table[typeof (DateTime)] = |
||||
delegate (object obj, JsonWriter writer) { |
||||
writer.Write (Convert.ToString ((DateTime) obj, |
||||
datetime_format)); |
||||
}; |
||||
|
||||
base_exporters_table[typeof (decimal)] = |
||||
delegate (object obj, JsonWriter writer) { |
||||
writer.Write ((decimal) obj); |
||||
}; |
||||
|
||||
base_exporters_table[typeof (sbyte)] = |
||||
delegate (object obj, JsonWriter writer) { |
||||
writer.Write (Convert.ToInt32 ((sbyte) obj)); |
||||
}; |
||||
|
||||
base_exporters_table[typeof (short)] = |
||||
delegate (object obj, JsonWriter writer) { |
||||
writer.Write (Convert.ToInt32 ((short) obj)); |
||||
}; |
||||
|
||||
base_exporters_table[typeof (ushort)] = |
||||
delegate (object obj, JsonWriter writer) { |
||||
writer.Write (Convert.ToInt32 ((ushort) obj)); |
||||
}; |
||||
|
||||
base_exporters_table[typeof (uint)] = |
||||
delegate (object obj, JsonWriter writer) { |
||||
writer.Write (Convert.ToUInt64 ((uint) obj)); |
||||
}; |
||||
|
||||
base_exporters_table[typeof (ulong)] = |
||||
delegate (object obj, JsonWriter writer) { |
||||
writer.Write ((ulong) obj); |
||||
}; |
||||
|
||||
base_exporters_table[typeof(DateTimeOffset)] = |
||||
delegate (object obj, JsonWriter writer) { |
||||
writer.Write(((DateTimeOffset)obj).ToString("yyyy-MM-ddTHH:mm:ss.fffffffzzz", datetime_format)); |
||||
}; |
||||
} |
||||
|
||||
private static void RegisterBaseImporters () |
||||
{ |
||||
ImporterFunc importer; |
||||
|
||||
importer = delegate (object input) { |
||||
return Convert.ToByte ((int) input); |
||||
}; |
||||
RegisterImporter (base_importers_table, typeof (int), |
||||
typeof (byte), importer); |
||||
|
||||
importer = delegate (object input) { |
||||
return Convert.ToUInt64 ((int) input); |
||||
}; |
||||
RegisterImporter (base_importers_table, typeof (int), |
||||
typeof (ulong), importer); |
||||
|
||||
importer = delegate (object input) { |
||||
return Convert.ToInt64((int)input); |
||||
}; |
||||
RegisterImporter(base_importers_table, typeof(int), |
||||
typeof(long), importer); |
||||
|
||||
importer = delegate (object input) { |
||||
return Convert.ToSByte ((int) input); |
||||
}; |
||||
RegisterImporter (base_importers_table, typeof (int), |
||||
typeof (sbyte), importer); |
||||
|
||||
importer = delegate (object input) { |
||||
return Convert.ToInt16 ((int) input); |
||||
}; |
||||
RegisterImporter (base_importers_table, typeof (int), |
||||
typeof (short), importer); |
||||
|
||||
importer = delegate (object input) { |
||||
return Convert.ToUInt16 ((int) input); |
||||
}; |
||||
RegisterImporter (base_importers_table, typeof (int), |
||||
typeof (ushort), importer); |
||||
|
||||
importer = delegate (object input) { |
||||
return Convert.ToUInt32 ((int) input); |
||||
}; |
||||
RegisterImporter (base_importers_table, typeof (int), |
||||
typeof (uint), importer); |
||||
|
||||
importer = delegate (object input) { |
||||
return Convert.ToSingle ((int) input); |
||||
}; |
||||
RegisterImporter (base_importers_table, typeof (int), |
||||
typeof (float), importer); |
||||
|
||||
importer = delegate (object input) { |
||||
return Convert.ToDouble ((int) input); |
||||
}; |
||||
RegisterImporter (base_importers_table, typeof (int), |
||||
typeof (double), importer); |
||||
|
||||
importer = delegate (object input) { |
||||
return Convert.ToDecimal ((double) input); |
||||
}; |
||||
RegisterImporter (base_importers_table, typeof (double), |
||||
typeof (decimal), importer); |
||||
|
||||
importer = delegate (object input) { |
||||
return Convert.ToSingle((double)input); |
||||
}; |
||||
RegisterImporter(base_importers_table, typeof(double), |
||||
typeof(float), importer); |
||||
|
||||
importer = delegate (object input) { |
||||
return Convert.ToUInt32 ((long) input); |
||||
}; |
||||
RegisterImporter (base_importers_table, typeof (long), |
||||
typeof (uint), importer); |
||||
|
||||
importer = delegate (object input) { |
||||
return Convert.ToChar ((string) input); |
||||
}; |
||||
RegisterImporter (base_importers_table, typeof (string), |
||||
typeof (char), importer); |
||||
|
||||
importer = delegate (object input) { |
||||
return Convert.ToDateTime ((string) input, datetime_format); |
||||
}; |
||||
RegisterImporter (base_importers_table, typeof (string), |
||||
typeof (DateTime), importer); |
||||
|
||||
importer = delegate (object input) { |
||||
return DateTimeOffset.Parse((string)input, datetime_format); |
||||
}; |
||||
RegisterImporter(base_importers_table, typeof(string), |
||||
typeof(DateTimeOffset), importer); |
||||
} |
||||
|
||||
private static void RegisterImporter ( |
||||
IDictionary<Type, IDictionary<Type, ImporterFunc>> table, |
||||
Type json_type, Type value_type, ImporterFunc importer) |
||||
{ |
||||
if (! table.ContainsKey (json_type)) |
||||
table.Add (json_type, new Dictionary<Type, ImporterFunc> ()); |
||||
|
||||
table[json_type][value_type] = importer; |
||||
} |
||||
|
||||
private static void WriteValue (object obj, JsonWriter writer, |
||||
bool writer_is_private, |
||||
int depth) |
||||
{ |
||||
if (depth > max_nesting_depth) |
||||
throw new JsonException ( |
||||
String.Format ("Max allowed object depth reached while " + |
||||
"trying to export from type {0}", |
||||
obj.GetType ())); |
||||
|
||||
if (obj == null) { |
||||
writer.Write (null); |
||||
return; |
||||
} |
||||
|
||||
if (obj is IJsonWrapper) { |
||||
if (writer_is_private) |
||||
writer.TextWriter.Write (((IJsonWrapper) obj).ToJson ()); |
||||
else |
||||
((IJsonWrapper) obj).ToJson (writer); |
||||
|
||||
return; |
||||
} |
||||
|
||||
if (obj is String) { |
||||
writer.Write ((string) obj); |
||||
return; |
||||
} |
||||
|
||||
if (obj is Double) { |
||||
writer.Write ((double) obj); |
||||
return; |
||||
} |
||||
|
||||
if (obj is Single) |
||||
{ |
||||
writer.Write((float)obj); |
||||
return; |
||||
} |
||||
|
||||
if (obj is Int32) { |
||||
writer.Write ((int) obj); |
||||
return; |
||||
} |
||||
|
||||
if (obj is Boolean) { |
||||
writer.Write ((bool) obj); |
||||
return; |
||||
} |
||||
|
||||
if (obj is Int64) { |
||||
writer.Write ((long) obj); |
||||
return; |
||||
} |
||||
|
||||
if (obj is Array) { |
||||
writer.WriteArrayStart (); |
||||
|
||||
foreach (object elem in (Array) obj) |
||||
WriteValue (elem, writer, writer_is_private, depth + 1); |
||||
|
||||
writer.WriteArrayEnd (); |
||||
|
||||
return; |
||||
} |
||||
|
||||
if (obj is IList) { |
||||
writer.WriteArrayStart (); |
||||
foreach (object elem in (IList) obj) |
||||
WriteValue (elem, writer, writer_is_private, depth + 1); |
||||
writer.WriteArrayEnd (); |
||||
|
||||
return; |
||||
} |
||||
|
||||
if (obj is IDictionary dictionary) { |
||||
writer.WriteObjectStart (); |
||||
foreach (DictionaryEntry entry in dictionary) { |
||||
var propertyName = entry.Key is string key ? |
||||
key |
||||
: Convert.ToString(entry.Key, CultureInfo.InvariantCulture); |
||||
writer.WritePropertyName (propertyName); |
||||
WriteValue (entry.Value, writer, writer_is_private, |
||||
depth + 1); |
||||
} |
||||
writer.WriteObjectEnd (); |
||||
|
||||
return; |
||||
} |
||||
|
||||
Type obj_type = obj.GetType (); |
||||
|
||||
// See if there's a custom exporter for the object |
||||
if (custom_exporters_table.ContainsKey (obj_type)) { |
||||
ExporterFunc exporter = custom_exporters_table[obj_type]; |
||||
exporter (obj, writer); |
||||
|
||||
return; |
||||
} |
||||
|
||||
// If not, maybe there's a base exporter |
||||
if (base_exporters_table.ContainsKey (obj_type)) { |
||||
ExporterFunc exporter = base_exporters_table[obj_type]; |
||||
exporter (obj, writer); |
||||
|
||||
return; |
||||
} |
||||
|
||||
// Last option, let's see if it's an enum |
||||
if (obj is Enum) { |
||||
Type e_type = Enum.GetUnderlyingType (obj_type); |
||||
|
||||
if (e_type == typeof (long)) |
||||
writer.Write ((long) obj); |
||||
else if (e_type == typeof (uint)) |
||||
writer.Write ((uint) obj); |
||||
else if (e_type == typeof (ulong)) |
||||
writer.Write ((ulong) obj); |
||||
else if (e_type == typeof(ushort)) |
||||
writer.Write ((ushort)obj); |
||||
else if (e_type == typeof(short)) |
||||
writer.Write ((short)obj); |
||||
else if (e_type == typeof(byte)) |
||||
writer.Write ((byte)obj); |
||||
else if (e_type == typeof(sbyte)) |
||||
writer.Write ((sbyte)obj); |
||||
else |
||||
writer.Write ((int) obj); |
||||
|
||||
return; |
||||
} |
||||
|
||||
// Okay, so it looks like the input should be exported as an |
||||
// object |
||||
AddTypeProperties (obj_type); |
||||
IList<PropertyMetadata> props = type_properties[obj_type]; |
||||
|
||||
writer.WriteObjectStart (); |
||||
foreach (PropertyMetadata p_data in props) { |
||||
if (p_data.IsField) { |
||||
writer.WritePropertyName (p_data.Info.Name); |
||||
WriteValue (((FieldInfo) p_data.Info).GetValue (obj), |
||||
writer, writer_is_private, depth + 1); |
||||
} |
||||
else { |
||||
PropertyInfo p_info = (PropertyInfo) p_data.Info; |
||||
|
||||
if (p_info.CanRead) { |
||||
writer.WritePropertyName (p_data.Info.Name); |
||||
WriteValue (p_info.GetValue (obj, null), |
||||
writer, writer_is_private, depth + 1); |
||||
} |
||||
} |
||||
} |
||||
writer.WriteObjectEnd (); |
||||
} |
||||
#endregion |
||||
|
||||
|
||||
public static string ToJson (object obj) |
||||
{ |
||||
lock (static_writer_lock) { |
||||
static_writer.Reset (); |
||||
|
||||
WriteValue (obj, static_writer, true, 0); |
||||
|
||||
return static_writer.ToString (); |
||||
} |
||||
} |
||||
|
||||
public static void ToJson (object obj, JsonWriter writer) |
||||
{ |
||||
WriteValue (obj, writer, false, 0); |
||||
} |
||||
|
||||
public static JsonData ToObject (JsonReader reader) |
||||
{ |
||||
return (JsonData) ToWrapper ( |
||||
delegate { return new JsonData (); }, reader); |
||||
} |
||||
|
||||
public static JsonData ToObject (TextReader reader) |
||||
{ |
||||
JsonReader json_reader = new JsonReader (reader); |
||||
|
||||
return (JsonData) ToWrapper ( |
||||
delegate { return new JsonData (); }, json_reader); |
||||
} |
||||
|
||||
public static JsonData ToObject (string json) |
||||
{ |
||||
return (JsonData) ToWrapper ( |
||||
delegate { return new JsonData (); }, json); |
||||
} |
||||
|
||||
public static T ToObject<T> (JsonReader reader) |
||||
{ |
||||
return (T) ReadValue (typeof (T), reader); |
||||
} |
||||
|
||||
public static T ToObject<T> (TextReader reader) |
||||
{ |
||||
JsonReader json_reader = new JsonReader (reader); |
||||
|
||||
return (T) ReadValue (typeof (T), json_reader); |
||||
} |
||||
|
||||
public static T ToObject<T> (string json) |
||||
{ |
||||
JsonReader reader = new JsonReader (json); |
||||
|
||||
return (T) ReadValue (typeof (T), reader); |
||||
} |
||||
|
||||
public static object ToObject(string json, Type ConvertType ) |
||||
{ |
||||
JsonReader reader = new JsonReader(json); |
||||
|
||||
return ReadValue(ConvertType, reader); |
||||
} |
||||
|
||||
public static IJsonWrapper ToWrapper (WrapperFactory factory, |
||||
JsonReader reader) |
||||
{ |
||||
return ReadValue (factory, reader); |
||||
} |
||||
|
||||
public static IJsonWrapper ToWrapper (WrapperFactory factory, |
||||
string json) |
||||
{ |
||||
JsonReader reader = new JsonReader (json); |
||||
|
||||
return ReadValue (factory, reader); |
||||
} |
||||
|
||||
public static void RegisterExporter<T> (ExporterFunc<T> exporter) |
||||
{ |
||||
ExporterFunc exporter_wrapper = |
||||
delegate (object obj, JsonWriter writer) { |
||||
exporter ((T) obj, writer); |
||||
}; |
||||
|
||||
custom_exporters_table[typeof (T)] = exporter_wrapper; |
||||
} |
||||
|
||||
public static void RegisterImporter<TJson, TValue> ( |
||||
ImporterFunc<TJson, TValue> importer) |
||||
{ |
||||
ImporterFunc importer_wrapper = |
||||
delegate (object input) { |
||||
return importer ((TJson) input); |
||||
}; |
||||
|
||||
RegisterImporter (custom_importers_table, typeof (TJson), |
||||
typeof (TValue), importer_wrapper); |
||||
} |
||||
|
||||
public static void UnregisterExporters () |
||||
{ |
||||
custom_exporters_table.Clear (); |
||||
} |
||||
|
||||
public static void UnregisterImporters () |
||||
{ |
||||
custom_importers_table.Clear (); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 496f84edeb6468045a3c9cfc026b963a |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,105 @@
@@ -0,0 +1,105 @@
|
||||
#region Header |
||||
/** |
||||
* JsonMockWrapper.cs |
||||
* Mock object implementing IJsonWrapper, to facilitate actions like |
||||
* skipping data more efficiently. |
||||
* |
||||
* The authors disclaim copyright to this source code. For more details, see |
||||
* the COPYING file included with this distribution. |
||||
**/ |
||||
#endregion |
||||
|
||||
|
||||
using System; |
||||
using System.Collections; |
||||
using System.Collections.Specialized; |
||||
|
||||
|
||||
namespace LitJson |
||||
{ |
||||
public class JsonMockWrapper : IJsonWrapper |
||||
{ |
||||
public bool IsArray { get { return false; } } |
||||
public bool IsBoolean { get { return false; } } |
||||
public bool IsDouble { get { return false; } } |
||||
public bool IsInt { get { return false; } } |
||||
public bool IsLong { get { return false; } } |
||||
public bool IsObject { get { return false; } } |
||||
public bool IsString { get { return false; } } |
||||
|
||||
public bool GetBoolean () { return false; } |
||||
public double GetDouble () { return 0.0; } |
||||
public int GetInt () { return 0; } |
||||
public JsonType GetJsonType () { return JsonType.None; } |
||||
public long GetLong () { return 0L; } |
||||
public string GetString () { return ""; } |
||||
|
||||
public void SetBoolean (bool val) {} |
||||
public void SetDouble (double val) {} |
||||
public void SetInt (int val) {} |
||||
public void SetJsonType (JsonType type) {} |
||||
public void SetLong (long val) {} |
||||
public void SetString (string val) {} |
||||
|
||||
public string ToJson () { return ""; } |
||||
public void ToJson (JsonWriter writer) {} |
||||
|
||||
|
||||
bool IList.IsFixedSize { get { return true; } } |
||||
bool IList.IsReadOnly { get { return true; } } |
||||
|
||||
object IList.this[int index] { |
||||
get { return null; } |
||||
set {} |
||||
} |
||||
|
||||
int IList.Add (object value) { return 0; } |
||||
void IList.Clear () {} |
||||
bool IList.Contains (object value) { return false; } |
||||
int IList.IndexOf (object value) { return -1; } |
||||
void IList.Insert (int i, object v) {} |
||||
void IList.Remove (object value) {} |
||||
void IList.RemoveAt (int index) {} |
||||
|
||||
|
||||
int ICollection.Count { get { return 0; } } |
||||
bool ICollection.IsSynchronized { get { return false; } } |
||||
object ICollection.SyncRoot { get { return null; } } |
||||
|
||||
void ICollection.CopyTo (Array array, int index) {} |
||||
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator () { return null; } |
||||
|
||||
|
||||
bool IDictionary.IsFixedSize { get { return true; } } |
||||
bool IDictionary.IsReadOnly { get { return true; } } |
||||
|
||||
ICollection IDictionary.Keys { get { return null; } } |
||||
ICollection IDictionary.Values { get { return null; } } |
||||
|
||||
object IDictionary.this[object key] { |
||||
get { return null; } |
||||
set {} |
||||
} |
||||
|
||||
void IDictionary.Add (object k, object v) {} |
||||
void IDictionary.Clear () {} |
||||
bool IDictionary.Contains (object key) { return false; } |
||||
void IDictionary.Remove (object key) {} |
||||
|
||||
IDictionaryEnumerator IDictionary.GetEnumerator () { return null; } |
||||
|
||||
|
||||
object IOrderedDictionary.this[int idx] { |
||||
get { return null; } |
||||
set {} |
||||
} |
||||
|
||||
IDictionaryEnumerator IOrderedDictionary.GetEnumerator () { |
||||
return null; |
||||
} |
||||
void IOrderedDictionary.Insert (int i, object k, object v) {} |
||||
void IOrderedDictionary.RemoveAt (int i) {} |
||||
} |
||||
} |
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: a6cf14146c882034b8e1e1cf5c467ec1 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,478 @@
@@ -0,0 +1,478 @@
|
||||
#region Header |
||||
/** |
||||
* JsonReader.cs |
||||
* Stream-like access to JSON text. |
||||
* |
||||
* The authors disclaim copyright to this source code. For more details, see |
||||
* the COPYING file included with this distribution. |
||||
**/ |
||||
#endregion |
||||
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Globalization; |
||||
using System.IO; |
||||
using System.Text; |
||||
|
||||
|
||||
namespace LitJson |
||||
{ |
||||
public enum JsonToken |
||||
{ |
||||
None, |
||||
|
||||
ObjectStart, |
||||
PropertyName, |
||||
ObjectEnd, |
||||
|
||||
ArrayStart, |
||||
ArrayEnd, |
||||
|
||||
Int, |
||||
Long, |
||||
Double, |
||||
|
||||
String, |
||||
|
||||
Boolean, |
||||
Null |
||||
} |
||||
|
||||
|
||||
public class JsonReader |
||||
{ |
||||
#region Fields |
||||
private static readonly IDictionary<int, IDictionary<int, int[]>> parse_table; |
||||
|
||||
private Stack<int> automaton_stack; |
||||
private int current_input; |
||||
private int current_symbol; |
||||
private bool end_of_json; |
||||
private bool end_of_input; |
||||
private Lexer lexer; |
||||
private bool parser_in_string; |
||||
private bool parser_return; |
||||
private bool read_started; |
||||
private TextReader reader; |
||||
private bool reader_is_owned; |
||||
private bool skip_non_members; |
||||
private object token_value; |
||||
private JsonToken token; |
||||
#endregion |
||||
|
||||
|
||||
#region Public Properties |
||||
public bool AllowComments { |
||||
get { return lexer.AllowComments; } |
||||
set { lexer.AllowComments = value; } |
||||
} |
||||
|
||||
public bool AllowSingleQuotedStrings { |
||||
get { return lexer.AllowSingleQuotedStrings; } |
||||
set { lexer.AllowSingleQuotedStrings = value; } |
||||
} |
||||
|
||||
public bool SkipNonMembers { |
||||
get { return skip_non_members; } |
||||
set { skip_non_members = value; } |
||||
} |
||||
|
||||
public bool EndOfInput { |
||||
get { return end_of_input; } |
||||
} |
||||
|
||||
public bool EndOfJson { |
||||
get { return end_of_json; } |
||||
} |
||||
|
||||
public JsonToken Token { |
||||
get { return token; } |
||||
} |
||||
|
||||
public object Value { |
||||
get { return token_value; } |
||||
} |
||||
#endregion |
||||
|
||||
|
||||
#region Constructors |
||||
static JsonReader () |
||||
{ |
||||
parse_table = PopulateParseTable (); |
||||
} |
||||
|
||||
public JsonReader (string json_text) : |
||||
this (new StringReader (json_text), true) |
||||
{ |
||||
} |
||||
|
||||
public JsonReader (TextReader reader) : |
||||
this (reader, false) |
||||
{ |
||||
} |
||||
|
||||
private JsonReader (TextReader reader, bool owned) |
||||
{ |
||||
if (reader == null) |
||||
throw new ArgumentNullException ("reader"); |
||||
|
||||
parser_in_string = false; |
||||
parser_return = false; |
||||
|
||||
read_started = false; |
||||
automaton_stack = new Stack<int> (); |
||||
automaton_stack.Push ((int) ParserToken.End); |
||||
automaton_stack.Push ((int) ParserToken.Text); |
||||
|
||||
lexer = new Lexer (reader); |
||||
|
||||
end_of_input = false; |
||||
end_of_json = false; |
||||
|
||||
skip_non_members = true; |
||||
|
||||
this.reader = reader; |
||||
reader_is_owned = owned; |
||||
} |
||||
#endregion |
||||
|
||||
|
||||
#region Static Methods |
||||
private static IDictionary<int, IDictionary<int, int[]>> PopulateParseTable () |
||||
{ |
||||
// See section A.2. of the manual for details |
||||
IDictionary<int, IDictionary<int, int[]>> parse_table = new Dictionary<int, IDictionary<int, int[]>> (); |
||||
|
||||
TableAddRow (parse_table, ParserToken.Array); |
||||
TableAddCol (parse_table, ParserToken.Array, '[', |
||||
'[', |
||||
(int) ParserToken.ArrayPrime); |
||||
|
||||
TableAddRow (parse_table, ParserToken.ArrayPrime); |
||||
TableAddCol (parse_table, ParserToken.ArrayPrime, '"', |
||||
(int) ParserToken.Value, |
||||
|
||||
(int) ParserToken.ValueRest, |
||||
']'); |
||||
TableAddCol (parse_table, ParserToken.ArrayPrime, '[', |
||||
(int) ParserToken.Value, |
||||
(int) ParserToken.ValueRest, |
||||
']'); |
||||
TableAddCol (parse_table, ParserToken.ArrayPrime, ']', |
||||
']'); |
||||
TableAddCol (parse_table, ParserToken.ArrayPrime, '{', |
||||
(int) ParserToken.Value, |
||||
(int) ParserToken.ValueRest, |
||||
']'); |
||||
TableAddCol (parse_table, ParserToken.ArrayPrime, (int) ParserToken.Number, |
||||
(int) ParserToken.Value, |
||||
(int) ParserToken.ValueRest, |
||||
']'); |
||||
TableAddCol (parse_table, ParserToken.ArrayPrime, (int) ParserToken.True, |
||||
(int) ParserToken.Value, |
||||
(int) ParserToken.ValueRest, |
||||
']'); |
||||
TableAddCol (parse_table, ParserToken.ArrayPrime, (int) ParserToken.False, |
||||
(int) ParserToken.Value, |
||||
(int) ParserToken.ValueRest, |
||||
']'); |
||||
TableAddCol (parse_table, ParserToken.ArrayPrime, (int) ParserToken.Null, |
||||
(int) ParserToken.Value, |
||||
(int) ParserToken.ValueRest, |
||||
']'); |
||||
|
||||
TableAddRow (parse_table, ParserToken.Object); |
||||
TableAddCol (parse_table, ParserToken.Object, '{', |
||||
'{', |
||||
(int) ParserToken.ObjectPrime); |
||||
|
||||
TableAddRow (parse_table, ParserToken.ObjectPrime); |
||||
TableAddCol (parse_table, ParserToken.ObjectPrime, '"', |
||||
(int) ParserToken.Pair, |
||||
(int) ParserToken.PairRest, |
||||
'}'); |
||||
TableAddCol (parse_table, ParserToken.ObjectPrime, '}', |
||||
'}'); |
||||
|
||||
TableAddRow (parse_table, ParserToken.Pair); |
||||
TableAddCol (parse_table, ParserToken.Pair, '"', |
||||
(int) ParserToken.String, |
||||
':', |
||||
(int) ParserToken.Value); |
||||
|
||||
TableAddRow (parse_table, ParserToken.PairRest); |
||||
TableAddCol (parse_table, ParserToken.PairRest, ',', |
||||
',', |
||||
(int) ParserToken.Pair, |
||||
(int) ParserToken.PairRest); |
||||
TableAddCol (parse_table, ParserToken.PairRest, '}', |
||||
(int) ParserToken.Epsilon); |
||||
|
||||
TableAddRow (parse_table, ParserToken.String); |
||||
TableAddCol (parse_table, ParserToken.String, '"', |
||||
'"', |
||||
(int) ParserToken.CharSeq, |
||||
'"'); |
||||
|
||||
TableAddRow (parse_table, ParserToken.Text); |
||||
TableAddCol (parse_table, ParserToken.Text, '[', |
||||
(int) ParserToken.Array); |
||||
TableAddCol (parse_table, ParserToken.Text, '{', |
||||
(int) ParserToken.Object); |
||||
|
||||
TableAddRow (parse_table, ParserToken.Value); |
||||
TableAddCol (parse_table, ParserToken.Value, '"', |
||||
(int) ParserToken.String); |
||||
TableAddCol (parse_table, ParserToken.Value, '[', |
||||
(int) ParserToken.Array); |
||||
TableAddCol (parse_table, ParserToken.Value, '{', |
||||
(int) ParserToken.Object); |
||||
TableAddCol (parse_table, ParserToken.Value, (int) ParserToken.Number, |
||||
(int) ParserToken.Number); |
||||
TableAddCol (parse_table, ParserToken.Value, (int) ParserToken.True, |
||||
(int) ParserToken.True); |
||||
TableAddCol (parse_table, ParserToken.Value, (int) ParserToken.False, |
||||
(int) ParserToken.False); |
||||
TableAddCol (parse_table, ParserToken.Value, (int) ParserToken.Null, |
||||
(int) ParserToken.Null); |
||||
|
||||
TableAddRow (parse_table, ParserToken.ValueRest); |
||||
TableAddCol (parse_table, ParserToken.ValueRest, ',', |
||||
',', |
||||
(int) ParserToken.Value, |
||||
(int) ParserToken.ValueRest); |
||||
TableAddCol (parse_table, ParserToken.ValueRest, ']', |
||||
(int) ParserToken.Epsilon); |
||||
|
||||
return parse_table; |
||||
} |
||||
|
||||
private static void TableAddCol (IDictionary<int, IDictionary<int, int[]>> parse_table, ParserToken row, int col, |
||||
params int[] symbols) |
||||
{ |
||||
parse_table[(int) row].Add (col, symbols); |
||||
} |
||||
|
||||
private static void TableAddRow (IDictionary<int, IDictionary<int, int[]>> parse_table, ParserToken rule) |
||||
{ |
||||
parse_table.Add ((int) rule, new Dictionary<int, int[]> ()); |
||||
} |
||||
#endregion |
||||
|
||||
|
||||
#region Private Methods |
||||
private void ProcessNumber (string number) |
||||
{ |
||||
if (number.IndexOf ('.') != -1 || |
||||
number.IndexOf ('e') != -1 || |
||||
number.IndexOf ('E') != -1) { |
||||
|
||||
double n_double; |
||||
if (double.TryParse (number, NumberStyles.Any, CultureInfo.InvariantCulture, out n_double)) { |
||||
token = JsonToken.Double; |
||||
token_value = n_double; |
||||
|
||||
return; |
||||
} |
||||
} |
||||
|
||||
int n_int32; |
||||
if (int.TryParse (number, NumberStyles.Integer, CultureInfo.InvariantCulture, out n_int32)) { |
||||
token = JsonToken.Int; |
||||
token_value = n_int32; |
||||
|
||||
return; |
||||
} |
||||
|
||||
long n_int64; |
||||
if (long.TryParse (number, NumberStyles.Integer, CultureInfo.InvariantCulture, out n_int64)) { |
||||
token = JsonToken.Long; |
||||
token_value = n_int64; |
||||
|
||||
return; |
||||
} |
||||
|
||||
ulong n_uint64; |
||||
if (ulong.TryParse(number, NumberStyles.Integer, CultureInfo.InvariantCulture, out n_uint64)) |
||||
{ |
||||
token = JsonToken.Long; |
||||
token_value = n_uint64; |
||||
|
||||
return; |
||||
} |
||||
|
||||
// Shouldn't happen, but just in case, return something |
||||
token = JsonToken.Int; |
||||
token_value = 0; |
||||
} |
||||
|
||||
private void ProcessSymbol () |
||||
{ |
||||
if (current_symbol == '[') { |
||||
token = JsonToken.ArrayStart; |
||||
parser_return = true; |
||||
|
||||
} else if (current_symbol == ']') { |
||||
token = JsonToken.ArrayEnd; |
||||
parser_return = true; |
||||
|
||||
} else if (current_symbol == '{') { |
||||
token = JsonToken.ObjectStart; |
||||
parser_return = true; |
||||
|
||||
} else if (current_symbol == '}') { |
||||
token = JsonToken.ObjectEnd; |
||||
parser_return = true; |
||||
|
||||
} else if (current_symbol == '"') { |
||||
if (parser_in_string) { |
||||
parser_in_string = false; |
||||
|
||||
parser_return = true; |
||||
|
||||
} else { |
||||
if (token == JsonToken.None) |
||||
token = JsonToken.String; |
||||
|
||||
parser_in_string = true; |
||||
} |
||||
|
||||
} else if (current_symbol == (int) ParserToken.CharSeq) { |
||||
token_value = lexer.StringValue; |
||||
|
||||
} else if (current_symbol == (int) ParserToken.False) { |
||||
token = JsonToken.Boolean; |
||||
token_value = false; |
||||
parser_return = true; |
||||
|
||||
} else if (current_symbol == (int) ParserToken.Null) { |
||||
token = JsonToken.Null; |
||||
parser_return = true; |
||||
|
||||
} else if (current_symbol == (int) ParserToken.Number) { |
||||
ProcessNumber (lexer.StringValue); |
||||
|
||||
parser_return = true; |
||||
|
||||
} else if (current_symbol == (int) ParserToken.Pair) { |
||||
token = JsonToken.PropertyName; |
||||
|
||||
} else if (current_symbol == (int) ParserToken.True) { |
||||
token = JsonToken.Boolean; |
||||
token_value = true; |
||||
parser_return = true; |
||||
|
||||
} |
||||
} |
||||
|
||||
private bool ReadToken () |
||||
{ |
||||
if (end_of_input) |
||||
return false; |
||||
|
||||
lexer.NextToken (); |
||||
|
||||
if (lexer.EndOfInput) { |
||||
Close (); |
||||
|
||||
return false; |
||||
} |
||||
|
||||
current_input = lexer.Token; |
||||
|
||||
return true; |
||||
} |
||||
#endregion |
||||
|
||||
|
||||
public void Close () |
||||
{ |
||||
if (end_of_input) |
||||
return; |
||||
|
||||
end_of_input = true; |
||||
end_of_json = true; |
||||
|
||||
if (reader_is_owned) |
||||
{ |
||||
using(reader){} |
||||
} |
||||
|
||||
reader = null; |
||||
} |
||||
|
||||
public bool Read () |
||||
{ |
||||
if (end_of_input) |
||||
return false; |
||||
|
||||
if (end_of_json) { |
||||
end_of_json = false; |
||||
automaton_stack.Clear (); |
||||
automaton_stack.Push ((int) ParserToken.End); |
||||
automaton_stack.Push ((int) ParserToken.Text); |
||||
} |
||||
|
||||
parser_in_string = false; |
||||
parser_return = false; |
||||
|
||||
token = JsonToken.None; |
||||
token_value = null; |
||||
|
||||
if (! read_started) { |
||||
read_started = true; |
||||
|
||||
if (! ReadToken ()) |
||||
return false; |
||||
} |
||||
|
||||
|
||||
int[] entry_symbols; |
||||
|
||||
while (true) { |
||||
if (parser_return) { |
||||
if (automaton_stack.Peek () == (int) ParserToken.End) |
||||
end_of_json = true; |
||||
|
||||
return true; |
||||
} |
||||
|
||||
current_symbol = automaton_stack.Pop (); |
||||
|
||||
ProcessSymbol (); |
||||
|
||||
if (current_symbol == current_input) { |
||||
if (! ReadToken ()) { |
||||
if (automaton_stack.Peek () != (int) ParserToken.End) |
||||
throw new JsonException ( |
||||
"Input doesn't evaluate to proper JSON text"); |
||||
|
||||
if (parser_return) |
||||
return true; |
||||
|
||||
return false; |
||||
} |
||||
|
||||
continue; |
||||
} |
||||
|
||||
try { |
||||
|
||||
entry_symbols = |
||||
parse_table[current_symbol][current_input]; |
||||
|
||||
} catch (KeyNotFoundException e) { |
||||
throw new JsonException ((ParserToken) current_input, e); |
||||
} |
||||
|
||||
if (entry_symbols[0] == (int) ParserToken.Epsilon) |
||||
continue; |
||||
|
||||
for (int i = entry_symbols.Length - 1; i >= 0; i--) |
||||
automaton_stack.Push (entry_symbols[i]); |
||||
} |
||||
} |
||||
|
||||
} |
||||
} |
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 084113975cf9bfd48a72aa8809c523c9 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,484 @@
@@ -0,0 +1,484 @@
|
||||
#region Header |
||||
/** |
||||
* JsonWriter.cs |
||||
* Stream-like facility to output JSON text. |
||||
* |
||||
* The authors disclaim copyright to this source code. For more details, see |
||||
* the COPYING file included with this distribution. |
||||
**/ |
||||
#endregion |
||||
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Globalization; |
||||
using System.IO; |
||||
using System.Text; |
||||
|
||||
|
||||
namespace LitJson |
||||
{ |
||||
internal enum Condition |
||||
{ |
||||
InArray, |
||||
InObject, |
||||
NotAProperty, |
||||
Property, |
||||
Value |
||||
} |
||||
|
||||
internal class WriterContext |
||||
{ |
||||
public int Count; |
||||
public bool InArray; |
||||
public bool InObject; |
||||
public bool ExpectingValue; |
||||
public int Padding; |
||||
} |
||||
|
||||
public class JsonWriter |
||||
{ |
||||
#region Fields |
||||
private static readonly NumberFormatInfo number_format; |
||||
|
||||
private WriterContext context; |
||||
private Stack<WriterContext> ctx_stack; |
||||
private bool has_reached_end; |
||||
private char[] hex_seq; |
||||
private int indentation; |
||||
private int indent_value; |
||||
private StringBuilder inst_string_builder; |
||||
private bool pretty_print; |
||||
private bool validate; |
||||
private bool lower_case_properties; |
||||
private TextWriter writer; |
||||
#endregion |
||||
|
||||
|
||||
#region Properties |
||||
public int IndentValue { |
||||
get { return indent_value; } |
||||
set { |
||||
indentation = (indentation / indent_value) * value; |
||||
indent_value = value; |
||||
} |
||||
} |
||||
|
||||
public bool PrettyPrint { |
||||
get { return pretty_print; } |
||||
set { pretty_print = value; } |
||||
} |
||||
|
||||
public TextWriter TextWriter { |
||||
get { return writer; } |
||||
} |
||||
|
||||
public bool Validate { |
||||
get { return validate; } |
||||
set { validate = value; } |
||||
} |
||||
|
||||
public bool LowerCaseProperties { |
||||
get { return lower_case_properties; } |
||||
set { lower_case_properties = value; } |
||||
} |
||||
#endregion |
||||
|
||||
|
||||
#region Constructors |
||||
static JsonWriter () |
||||
{ |
||||
number_format = NumberFormatInfo.InvariantInfo; |
||||
} |
||||
|
||||
public JsonWriter () |
||||
{ |
||||
inst_string_builder = new StringBuilder (); |
||||
writer = new StringWriter (inst_string_builder); |
||||
|
||||
Init (); |
||||
} |
||||
|
||||
public JsonWriter (StringBuilder sb) : |
||||
this (new StringWriter (sb)) |
||||
{ |
||||
} |
||||
|
||||
public JsonWriter (TextWriter writer) |
||||
{ |
||||
if (writer == null) |
||||
throw new ArgumentNullException ("writer"); |
||||
|
||||
this.writer = writer; |
||||
|
||||
Init (); |
||||
} |
||||
#endregion |
||||
|
||||
|
||||
#region Private Methods |
||||
private void DoValidation (Condition cond) |
||||
{ |
||||
if (! context.ExpectingValue) |
||||
context.Count++; |
||||
|
||||
if (! validate) |
||||
return; |
||||
|
||||
if (has_reached_end) |
||||
throw new JsonException ( |
||||
"A complete JSON symbol has already been written"); |
||||
|
||||
switch (cond) { |
||||
case Condition.InArray: |
||||
if (! context.InArray) |
||||
throw new JsonException ( |
||||
"Can't close an array here"); |
||||
break; |
||||
|
||||
case Condition.InObject: |
||||
if (! context.InObject || context.ExpectingValue) |
||||
throw new JsonException ( |
||||
"Can't close an object here"); |
||||
break; |
||||
|
||||
case Condition.NotAProperty: |
||||
if (context.InObject && ! context.ExpectingValue) |
||||
throw new JsonException ( |
||||
"Expected a property"); |
||||
break; |
||||
|
||||
case Condition.Property: |
||||
if (! context.InObject || context.ExpectingValue) |
||||
throw new JsonException ( |
||||
"Can't add a property here"); |
||||
break; |
||||
|
||||
case Condition.Value: |
||||
if (! context.InArray && |
||||
(! context.InObject || ! context.ExpectingValue)) |
||||
throw new JsonException ( |
||||
"Can't add a value here"); |
||||
|
||||
break; |
||||
} |
||||
} |
||||
|
||||
private void Init () |
||||
{ |
||||
has_reached_end = false; |
||||
hex_seq = new char[4]; |
||||
indentation = 0; |
||||
indent_value = 4; |
||||
pretty_print = false; |
||||
validate = true; |
||||
lower_case_properties = false; |
||||
|
||||
ctx_stack = new Stack<WriterContext> (); |
||||
context = new WriterContext (); |
||||
ctx_stack.Push (context); |
||||
} |
||||
|
||||
private static void IntToHex (int n, char[] hex) |
||||
{ |
||||
int num; |
||||
|
||||
for (int i = 0; i < 4; i++) { |
||||
num = n % 16; |
||||
|
||||
if (num < 10) |
||||
hex[3 - i] = (char) ('0' + num); |
||||
else |
||||
hex[3 - i] = (char) ('A' + (num - 10)); |
||||
|
||||
n >>= 4; |
||||
} |
||||
} |
||||
|
||||
private void Indent () |
||||
{ |
||||
if (pretty_print) |
||||
indentation += indent_value; |
||||
} |
||||
|
||||
|
||||
private void Put (string str) |
||||
{ |
||||
if (pretty_print && ! context.ExpectingValue) |
||||
for (int i = 0; i < indentation; i++) |
||||
writer.Write (' '); |
||||
|
||||
writer.Write (str); |
||||
} |
||||
|
||||
private void PutNewline () |
||||
{ |
||||
PutNewline (true); |
||||
} |
||||
|
||||
private void PutNewline (bool add_comma) |
||||
{ |
||||
if (add_comma && ! context.ExpectingValue && |
||||
context.Count > 1) |
||||
writer.Write (','); |
||||
|
||||
if (pretty_print && ! context.ExpectingValue) |
||||
writer.Write (Environment.NewLine); |
||||
} |
||||
|
||||
private void PutString (string str) |
||||
{ |
||||
Put (String.Empty); |
||||
|
||||
writer.Write ('"'); |
||||
|
||||
int n = str.Length; |
||||
for (int i = 0; i < n; i++) { |
||||
switch (str[i]) { |
||||
case '\n': |
||||
writer.Write ("\\n"); |
||||
continue; |
||||
|
||||
case '\r': |
||||
writer.Write ("\\r"); |
||||
continue; |
||||
|
||||
case '\t': |
||||
writer.Write ("\\t"); |
||||
continue; |
||||
|
||||
case '"': |
||||
case '\\': |
||||
writer.Write ('\\'); |
||||
writer.Write (str[i]); |
||||
continue; |
||||
|
||||
case '\f': |
||||
writer.Write ("\\f"); |
||||
continue; |
||||
|
||||
case '\b': |
||||
writer.Write ("\\b"); |
||||
continue; |
||||
} |
||||
|
||||
if ((int) str[i] >= 32 && (int) str[i] <= 126) { |
||||
writer.Write (str[i]); |
||||
continue; |
||||
} |
||||
|
||||
// Default, turn into a \uXXXX sequence |
||||
IntToHex ((int) str[i], hex_seq); |
||||
writer.Write ("\\u"); |
||||
writer.Write (hex_seq); |
||||
} |
||||
|
||||
writer.Write ('"'); |
||||
} |
||||
|
||||
private void Unindent () |
||||
{ |
||||
if (pretty_print) |
||||
indentation -= indent_value; |
||||
} |
||||
#endregion |
||||
|
||||
|
||||
public override string ToString () |
||||
{ |
||||
if (inst_string_builder == null) |
||||
return String.Empty; |
||||
|
||||
return inst_string_builder.ToString (); |
||||
} |
||||
|
||||
public void Reset () |
||||
{ |
||||
has_reached_end = false; |
||||
|
||||
ctx_stack.Clear (); |
||||
context = new WriterContext (); |
||||
ctx_stack.Push (context); |
||||
|
||||
if (inst_string_builder != null) |
||||
inst_string_builder.Remove (0, inst_string_builder.Length); |
||||
} |
||||
|
||||
public void Write (bool boolean) |
||||
{ |
||||
DoValidation (Condition.Value); |
||||
PutNewline (); |
||||
|
||||
Put (boolean ? "true" : "false"); |
||||
|
||||
context.ExpectingValue = false; |
||||
} |
||||
|
||||
public void Write (decimal number) |
||||
{ |
||||
DoValidation (Condition.Value); |
||||
PutNewline (); |
||||
|
||||
Put (Convert.ToString (number, number_format)); |
||||
|
||||
context.ExpectingValue = false; |
||||
} |
||||
|
||||
public void Write (double number) |
||||
{ |
||||
DoValidation (Condition.Value); |
||||
PutNewline (); |
||||
|
||||
string str = Convert.ToString (number, number_format); |
||||
Put (str); |
||||
|
||||
if (str.IndexOf ('.') == -1 && |
||||
str.IndexOf ('E') == -1) |
||||
writer.Write (".0"); |
||||
|
||||
context.ExpectingValue = false; |
||||
} |
||||
|
||||
public void Write(float number) |
||||
{ |
||||
DoValidation(Condition.Value); |
||||
PutNewline(); |
||||
|
||||
string str = Convert.ToString(number, number_format); |
||||
Put(str); |
||||
|
||||
context.ExpectingValue = false; |
||||
} |
||||
|
||||
public void Write (int number) |
||||
{ |
||||
DoValidation (Condition.Value); |
||||
PutNewline (); |
||||
|
||||
Put (Convert.ToString (number, number_format)); |
||||
|
||||
context.ExpectingValue = false; |
||||
} |
||||
|
||||
public void Write (long number) |
||||
{ |
||||
DoValidation (Condition.Value); |
||||
PutNewline (); |
||||
|
||||
Put (Convert.ToString (number, number_format)); |
||||
|
||||
context.ExpectingValue = false; |
||||
} |
||||
|
||||
public void Write (string str) |
||||
{ |
||||
DoValidation (Condition.Value); |
||||
PutNewline (); |
||||
|
||||
if (str == null) |
||||
Put ("null"); |
||||
else |
||||
PutString (str); |
||||
|
||||
context.ExpectingValue = false; |
||||
} |
||||
|
||||
[CLSCompliant(false)] |
||||
public void Write (ulong number) |
||||
{ |
||||
DoValidation (Condition.Value); |
||||
PutNewline (); |
||||
|
||||
Put (Convert.ToString (number, number_format)); |
||||
|
||||
context.ExpectingValue = false; |
||||
} |
||||
|
||||
public void WriteArrayEnd () |
||||
{ |
||||
DoValidation (Condition.InArray); |
||||
PutNewline (false); |
||||
|
||||
ctx_stack.Pop (); |
||||
if (ctx_stack.Count == 1) |
||||
has_reached_end = true; |
||||
else { |
||||
context = ctx_stack.Peek (); |
||||
context.ExpectingValue = false; |
||||
} |
||||
|
||||
Unindent (); |
||||
Put ("]"); |
||||
} |
||||
|
||||
public void WriteArrayStart () |
||||
{ |
||||
DoValidation (Condition.NotAProperty); |
||||
PutNewline (); |
||||
|
||||
Put ("["); |
||||
|
||||
context = new WriterContext (); |
||||
context.InArray = true; |
||||
ctx_stack.Push (context); |
||||
|
||||
Indent (); |
||||
} |
||||
|
||||
public void WriteObjectEnd () |
||||
{ |
||||
DoValidation (Condition.InObject); |
||||
PutNewline (false); |
||||
|
||||
ctx_stack.Pop (); |
||||
if (ctx_stack.Count == 1) |
||||
has_reached_end = true; |
||||
else { |
||||
context = ctx_stack.Peek (); |
||||
context.ExpectingValue = false; |
||||
} |
||||
|
||||
Unindent (); |
||||
Put ("}"); |
||||
} |
||||
|
||||
public void WriteObjectStart () |
||||
{ |
||||
DoValidation (Condition.NotAProperty); |
||||
PutNewline (); |
||||
|
||||
Put ("{"); |
||||
|
||||
context = new WriterContext (); |
||||
context.InObject = true; |
||||
ctx_stack.Push (context); |
||||
|
||||
Indent (); |
||||
} |
||||
|
||||
public void WritePropertyName (string property_name) |
||||
{ |
||||
DoValidation (Condition.Property); |
||||
PutNewline (); |
||||
string propertyName = (property_name == null || !lower_case_properties) |
||||
? property_name |
||||
: property_name.ToLowerInvariant(); |
||||
|
||||
PutString (propertyName); |
||||
|
||||
if (pretty_print) { |
||||
if (propertyName.Length > context.Padding) |
||||
context.Padding = propertyName.Length; |
||||
|
||||
for (int i = context.Padding - propertyName.Length; |
||||
i >= 0; i--) |
||||
writer.Write (' '); |
||||
|
||||
writer.Write (": "); |
||||
} else |
||||
writer.Write (':'); |
||||
|
||||
context.ExpectingValue = true; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 3cda2caaf9ed41b4f9d2f97f25c70070 |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,912 @@
@@ -0,0 +1,912 @@
|
||||
#region Header |
||||
/** |
||||
* Lexer.cs |
||||
* JSON lexer implementation based on a finite state machine. |
||||
* |
||||
* The authors disclaim copyright to this source code. For more details, see |
||||
* the COPYING file included with this distribution. |
||||
**/ |
||||
#endregion |
||||
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.IO; |
||||
using System.Text; |
||||
|
||||
|
||||
namespace LitJson |
||||
{ |
||||
internal class FsmContext |
||||
{ |
||||
public bool Return; |
||||
public int NextState; |
||||
public Lexer L; |
||||
public int StateStack; |
||||
} |
||||
|
||||
|
||||
internal class Lexer |
||||
{ |
||||
#region Fields |
||||
private delegate bool StateHandler (FsmContext ctx); |
||||
|
||||
private static readonly int[] fsm_return_table; |
||||
private static readonly StateHandler[] fsm_handler_table; |
||||
|
||||
private bool allow_comments; |
||||
private bool allow_single_quoted_strings; |
||||
private bool end_of_input; |
||||
private FsmContext fsm_context; |
||||
private int input_buffer; |
||||
private int input_char; |
||||
private TextReader reader; |
||||
private int state; |
||||
private StringBuilder string_buffer; |
||||
private string string_value; |
||||
private int token; |
||||
private int unichar; |
||||
#endregion |
||||
|
||||
|
||||
#region Properties |
||||
public bool AllowComments { |
||||
get { return allow_comments; } |
||||
set { allow_comments = value; } |
||||
} |
||||
|
||||
public bool AllowSingleQuotedStrings { |
||||
get { return allow_single_quoted_strings; } |
||||
set { allow_single_quoted_strings = value; } |
||||
} |
||||
|
||||
public bool EndOfInput { |
||||
get { return end_of_input; } |
||||
} |
||||
|
||||
public int Token { |
||||
get { return token; } |
||||
} |
||||
|
||||
public string StringValue { |
||||
get { return string_value; } |
||||
} |
||||
#endregion |
||||
|
||||
|
||||
#region Constructors |
||||
static Lexer () |
||||
{ |
||||
PopulateFsmTables (out fsm_handler_table, out fsm_return_table); |
||||
} |
||||
|
||||
public Lexer (TextReader reader) |
||||
{ |
||||
allow_comments = true; |
||||
allow_single_quoted_strings = true; |
||||
|
||||
input_buffer = 0; |
||||
string_buffer = new StringBuilder (128); |
||||
state = 1; |
||||
end_of_input = false; |
||||
this.reader = reader; |
||||
|
||||
fsm_context = new FsmContext (); |
||||
fsm_context.L = this; |
||||
} |
||||
#endregion |
||||
|
||||
|
||||
#region Static Methods |
||||
private static int HexValue (int digit) |
||||
{ |
||||
switch (digit) { |
||||
case 'a': |
||||
case 'A': |
||||
return 10; |
||||
|
||||
case 'b': |
||||
case 'B': |
||||
return 11; |
||||
|
||||
case 'c': |
||||
case 'C': |
||||
return 12; |
||||
|
||||
case 'd': |
||||
case 'D': |
||||
return 13; |
||||
|
||||
case 'e': |
||||
case 'E': |
||||
return 14; |
||||
|
||||
case 'f': |
||||
case 'F': |
||||
return 15; |
||||
|
||||
default: |
||||
return digit - '0'; |
||||
} |
||||
} |
||||
|
||||
private static void PopulateFsmTables (out StateHandler[] fsm_handler_table, out int[] fsm_return_table) |
||||
{ |
||||
// See section A.1. of the manual for details of the finite |
||||
// state machine. |
||||
fsm_handler_table = new StateHandler[28] { |
||||
State1, |
||||
State2, |
||||
State3, |
||||
State4, |
||||
State5, |
||||
State6, |
||||
State7, |
||||
State8, |
||||
State9, |
||||
State10, |
||||
State11, |
||||
State12, |
||||
State13, |
||||
State14, |
||||
State15, |
||||
State16, |
||||
State17, |
||||
State18, |
||||
State19, |
||||
State20, |
||||
State21, |
||||
State22, |
||||
State23, |
||||
State24, |
||||
State25, |
||||
State26, |
||||
State27, |
||||
State28 |
||||
}; |
||||
|
||||
fsm_return_table = new int[28] { |
||||
(int) ParserToken.Char, |
||||
0, |
||||
(int) ParserToken.Number, |
||||
(int) ParserToken.Number, |
||||
0, |
||||
(int) ParserToken.Number, |
||||
0, |
||||
(int) ParserToken.Number, |
||||
0, |
||||
0, |
||||
(int) ParserToken.True, |
||||
0, |
||||
0, |
||||
0, |
||||
(int) ParserToken.False, |
||||
0, |
||||
0, |
||||
(int) ParserToken.Null, |
||||
(int) ParserToken.CharSeq, |
||||
(int) ParserToken.Char, |
||||
0, |
||||
0, |
||||
(int) ParserToken.CharSeq, |
||||
(int) ParserToken.Char, |
||||
0, |
||||
0, |
||||
0, |
||||
0 |
||||
}; |
||||
} |
||||
|
||||
private static char ProcessEscChar (int esc_char) |
||||
{ |
||||
switch (esc_char) { |
||||
case '"': |
||||
case '\'': |
||||
case '\\': |
||||
case '/': |
||||
return Convert.ToChar (esc_char); |
||||
|
||||
case 'n': |
||||
return '\n'; |
||||
|
||||
case 't': |
||||
return '\t'; |
||||
|
||||
case 'r': |
||||
return '\r'; |
||||
|
||||
case 'b': |
||||
return '\b'; |
||||
|
||||
case 'f': |
||||
return '\f'; |
||||
|
||||
default: |
||||
// Unreachable |
||||
return '?'; |
||||
} |
||||
} |
||||
|
||||
private static bool State1 (FsmContext ctx) |
||||
{ |
||||
while (ctx.L.GetChar ()) { |
||||
if (ctx.L.input_char == ' ' || |
||||
ctx.L.input_char >= '\t' && ctx.L.input_char <= '\r') |
||||
continue; |
||||
|
||||
if (ctx.L.input_char >= '1' && ctx.L.input_char <= '9') { |
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char); |
||||
ctx.NextState = 3; |
||||
return true; |
||||
} |
||||
|
||||
switch (ctx.L.input_char) { |
||||
case '"': |
||||
ctx.NextState = 19; |
||||
ctx.Return = true; |
||||
return true; |
||||
|
||||
case ',': |
||||
case ':': |
||||
case '[': |
||||
case ']': |
||||
case '{': |
||||
case '}': |
||||
ctx.NextState = 1; |
||||
ctx.Return = true; |
||||
return true; |
||||
|
||||
case '-': |
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char); |
||||
ctx.NextState = 2; |
||||
return true; |
||||
|
||||
case '0': |
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char); |
||||
ctx.NextState = 4; |
||||
return true; |
||||
|
||||
case 'f': |
||||
ctx.NextState = 12; |
||||
return true; |
||||
|
||||
case 'n': |
||||
ctx.NextState = 16; |
||||
return true; |
||||
|
||||
case 't': |
||||
ctx.NextState = 9; |
||||
return true; |
||||
|
||||
case '\'': |
||||
if (! ctx.L.allow_single_quoted_strings) |
||||
return false; |
||||
|
||||
ctx.L.input_char = '"'; |
||||
ctx.NextState = 23; |
||||
ctx.Return = true; |
||||
return true; |
||||
|
||||
case '/': |
||||
if (! ctx.L.allow_comments) |
||||
return false; |
||||
|
||||
ctx.NextState = 25; |
||||
return true; |
||||
|
||||
default: |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
private static bool State2 (FsmContext ctx) |
||||
{ |
||||
ctx.L.GetChar (); |
||||
|
||||
if (ctx.L.input_char >= '1' && ctx.L.input_char<= '9') { |
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char); |
||||
ctx.NextState = 3; |
||||
return true; |
||||
} |
||||
|
||||
switch (ctx.L.input_char) { |
||||
case '0': |
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char); |
||||
ctx.NextState = 4; |
||||
return true; |
||||
|
||||
default: |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
private static bool State3 (FsmContext ctx) |
||||
{ |
||||
while (ctx.L.GetChar ()) { |
||||
if (ctx.L.input_char >= '0' && ctx.L.input_char <= '9') { |
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char); |
||||
continue; |
||||
} |
||||
|
||||
if (ctx.L.input_char == ' ' || |
||||
ctx.L.input_char >= '\t' && ctx.L.input_char <= '\r') { |
||||
ctx.Return = true; |
||||
ctx.NextState = 1; |
||||
return true; |
||||
} |
||||
|
||||
switch (ctx.L.input_char) { |
||||
case ',': |
||||
case ']': |
||||
case '}': |
||||
ctx.L.UngetChar (); |
||||
ctx.Return = true; |
||||
ctx.NextState = 1; |
||||
return true; |
||||
|
||||
case '.': |
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char); |
||||
ctx.NextState = 5; |
||||
return true; |
||||
|
||||
case 'e': |
||||
case 'E': |
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char); |
||||
ctx.NextState = 7; |
||||
return true; |
||||
|
||||
default: |
||||
return false; |
||||
} |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
private static bool State4 (FsmContext ctx) |
||||
{ |
||||
ctx.L.GetChar (); |
||||
|
||||
if (ctx.L.input_char == ' ' || |
||||
ctx.L.input_char >= '\t' && ctx.L.input_char <= '\r') { |
||||
ctx.Return = true; |
||||
ctx.NextState = 1; |
||||
return true; |
||||
} |
||||
|
||||
switch (ctx.L.input_char) { |
||||
case ',': |
||||
case ']': |
||||
case '}': |
||||
ctx.L.UngetChar (); |
||||
ctx.Return = true; |
||||
ctx.NextState = 1; |
||||
return true; |
||||
|
||||
case '.': |
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char); |
||||
ctx.NextState = 5; |
||||
return true; |
||||
|
||||
case 'e': |
||||
case 'E': |
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char); |
||||
ctx.NextState = 7; |
||||
return true; |
||||
|
||||
default: |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
private static bool State5 (FsmContext ctx) |
||||
{ |
||||
ctx.L.GetChar (); |
||||
|
||||
if (ctx.L.input_char >= '0' && ctx.L.input_char <= '9') { |
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char); |
||||
ctx.NextState = 6; |
||||
return true; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
private static bool State6 (FsmContext ctx) |
||||
{ |
||||
while (ctx.L.GetChar ()) { |
||||
if (ctx.L.input_char >= '0' && ctx.L.input_char <= '9') { |
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char); |
||||
continue; |
||||
} |
||||
|
||||
if (ctx.L.input_char == ' ' || |
||||
ctx.L.input_char >= '\t' && ctx.L.input_char <= '\r') { |
||||
ctx.Return = true; |
||||
ctx.NextState = 1; |
||||
return true; |
||||
} |
||||
|
||||
switch (ctx.L.input_char) { |
||||
case ',': |
||||
case ']': |
||||
case '}': |
||||
ctx.L.UngetChar (); |
||||
ctx.Return = true; |
||||
ctx.NextState = 1; |
||||
return true; |
||||
|
||||
case 'e': |
||||
case 'E': |
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char); |
||||
ctx.NextState = 7; |
||||
return true; |
||||
|
||||
default: |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
private static bool State7 (FsmContext ctx) |
||||
{ |
||||
ctx.L.GetChar (); |
||||
|
||||
if (ctx.L.input_char >= '0' && ctx.L.input_char<= '9') { |
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char); |
||||
ctx.NextState = 8; |
||||
return true; |
||||
} |
||||
|
||||
switch (ctx.L.input_char) { |
||||
case '+': |
||||
case '-': |
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char); |
||||
ctx.NextState = 8; |
||||
return true; |
||||
|
||||
default: |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
private static bool State8 (FsmContext ctx) |
||||
{ |
||||
while (ctx.L.GetChar ()) { |
||||
if (ctx.L.input_char >= '0' && ctx.L.input_char<= '9') { |
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char); |
||||
continue; |
||||
} |
||||
|
||||
if (ctx.L.input_char == ' ' || |
||||
ctx.L.input_char >= '\t' && ctx.L.input_char<= '\r') { |
||||
ctx.Return = true; |
||||
ctx.NextState = 1; |
||||
return true; |
||||
} |
||||
|
||||
switch (ctx.L.input_char) { |
||||
case ',': |
||||
case ']': |
||||
case '}': |
||||
ctx.L.UngetChar (); |
||||
ctx.Return = true; |
||||
ctx.NextState = 1; |
||||
return true; |
||||
|
||||
default: |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
private static bool State9 (FsmContext ctx) |
||||
{ |
||||
ctx.L.GetChar (); |
||||
|
||||
switch (ctx.L.input_char) { |
||||
case 'r': |
||||
ctx.NextState = 10; |
||||
return true; |
||||
|
||||
default: |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
private static bool State10 (FsmContext ctx) |
||||
{ |
||||
ctx.L.GetChar (); |
||||
|
||||
switch (ctx.L.input_char) { |
||||
case 'u': |
||||
ctx.NextState = 11; |
||||
return true; |
||||
|
||||
default: |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
private static bool State11 (FsmContext ctx) |
||||
{ |
||||
ctx.L.GetChar (); |
||||
|
||||
switch (ctx.L.input_char) { |
||||
case 'e': |
||||
ctx.Return = true; |
||||
ctx.NextState = 1; |
||||
return true; |
||||
|
||||
default: |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
private static bool State12 (FsmContext ctx) |
||||
{ |
||||
ctx.L.GetChar (); |
||||
|
||||
switch (ctx.L.input_char) { |
||||
case 'a': |
||||
ctx.NextState = 13; |
||||
return true; |
||||
|
||||
default: |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
private static bool State13 (FsmContext ctx) |
||||
{ |
||||
ctx.L.GetChar (); |
||||
|
||||
switch (ctx.L.input_char) { |
||||
case 'l': |
||||
ctx.NextState = 14; |
||||
return true; |
||||
|
||||
default: |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
private static bool State14 (FsmContext ctx) |
||||
{ |
||||
ctx.L.GetChar (); |
||||
|
||||
switch (ctx.L.input_char) { |
||||
case 's': |
||||
ctx.NextState = 15; |
||||
return true; |
||||
|
||||
default: |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
private static bool State15 (FsmContext ctx) |
||||
{ |
||||
ctx.L.GetChar (); |
||||
|
||||
switch (ctx.L.input_char) { |
||||
case 'e': |
||||
ctx.Return = true; |
||||
ctx.NextState = 1; |
||||
return true; |
||||
|
||||
default: |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
private static bool State16 (FsmContext ctx) |
||||
{ |
||||
ctx.L.GetChar (); |
||||
|
||||
switch (ctx.L.input_char) { |
||||
case 'u': |
||||
ctx.NextState = 17; |
||||
return true; |
||||
|
||||
default: |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
private static bool State17 (FsmContext ctx) |
||||
{ |
||||
ctx.L.GetChar (); |
||||
|
||||
switch (ctx.L.input_char) { |
||||
case 'l': |
||||
ctx.NextState = 18; |
||||
return true; |
||||
|
||||
default: |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
private static bool State18 (FsmContext ctx) |
||||
{ |
||||
ctx.L.GetChar (); |
||||
|
||||
switch (ctx.L.input_char) { |
||||
case 'l': |
||||
ctx.Return = true; |
||||
ctx.NextState = 1; |
||||
return true; |
||||
|
||||
default: |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
private static bool State19 (FsmContext ctx) |
||||
{ |
||||
while (ctx.L.GetChar ()) { |
||||
switch (ctx.L.input_char) { |
||||
case '"': |
||||
ctx.L.UngetChar (); |
||||
ctx.Return = true; |
||||
ctx.NextState = 20; |
||||
return true; |
||||
|
||||
case '\\': |
||||
ctx.StateStack = 19; |
||||
ctx.NextState = 21; |
||||
return true; |
||||
|
||||
default: |
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char); |
||||
continue; |
||||
} |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
private static bool State20 (FsmContext ctx) |
||||
{ |
||||
ctx.L.GetChar (); |
||||
|
||||
switch (ctx.L.input_char) { |
||||
case '"': |
||||
ctx.Return = true; |
||||
ctx.NextState = 1; |
||||
return true; |
||||
|
||||
default: |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
private static bool State21 (FsmContext ctx) |
||||
{ |
||||
ctx.L.GetChar (); |
||||
|
||||
switch (ctx.L.input_char) { |
||||
case 'u': |
||||
ctx.NextState = 22; |
||||
return true; |
||||
|
||||
case '"': |
||||
case '\'': |
||||
case '/': |
||||
case '\\': |
||||
case 'b': |
||||
case 'f': |
||||
case 'n': |
||||
case 'r': |
||||
case 't': |
||||
ctx.L.string_buffer.Append ( |
||||
ProcessEscChar (ctx.L.input_char)); |
||||
ctx.NextState = ctx.StateStack; |
||||
return true; |
||||
|
||||
default: |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
private static bool State22 (FsmContext ctx) |
||||
{ |
||||
int counter = 0; |
||||
int mult = 4096; |
||||
|
||||
ctx.L.unichar = 0; |
||||
|
||||
while (ctx.L.GetChar ()) { |
||||
|
||||
if (ctx.L.input_char >= '0' && ctx.L.input_char <= '9' || |
||||
ctx.L.input_char >= 'A' && ctx.L.input_char <= 'F' || |
||||
ctx.L.input_char >= 'a' && ctx.L.input_char <= 'f') { |
||||
|
||||
ctx.L.unichar += HexValue (ctx.L.input_char) * mult; |
||||
|
||||
counter++; |
||||
mult /= 16; |
||||
|
||||
if (counter == 4) { |
||||
ctx.L.string_buffer.Append ( |
||||
Convert.ToChar (ctx.L.unichar)); |
||||
ctx.NextState = ctx.StateStack; |
||||
return true; |
||||
} |
||||
|
||||
continue; |
||||
} |
||||
|
||||
return false; |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
private static bool State23 (FsmContext ctx) |
||||
{ |
||||
while (ctx.L.GetChar ()) { |
||||
switch (ctx.L.input_char) { |
||||
case '\'': |
||||
ctx.L.UngetChar (); |
||||
ctx.Return = true; |
||||
ctx.NextState = 24; |
||||
return true; |
||||
|
||||
case '\\': |
||||
ctx.StateStack = 23; |
||||
ctx.NextState = 21; |
||||
return true; |
||||
|
||||
default: |
||||
ctx.L.string_buffer.Append ((char) ctx.L.input_char); |
||||
continue; |
||||
} |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
private static bool State24 (FsmContext ctx) |
||||
{ |
||||
ctx.L.GetChar (); |
||||
|
||||
switch (ctx.L.input_char) { |
||||
case '\'': |
||||
ctx.L.input_char = '"'; |
||||
ctx.Return = true; |
||||
ctx.NextState = 1; |
||||
return true; |
||||
|
||||
default: |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
private static bool State25 (FsmContext ctx) |
||||
{ |
||||
ctx.L.GetChar (); |
||||
|
||||
switch (ctx.L.input_char) { |
||||
case '*': |
||||
ctx.NextState = 27; |
||||
return true; |
||||
|
||||
case '/': |
||||
ctx.NextState = 26; |
||||
return true; |
||||
|
||||
default: |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
private static bool State26 (FsmContext ctx) |
||||
{ |
||||
while (ctx.L.GetChar ()) { |
||||
if (ctx.L.input_char == '\n') { |
||||
ctx.NextState = 1; |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
private static bool State27 (FsmContext ctx) |
||||
{ |
||||
while (ctx.L.GetChar ()) { |
||||
if (ctx.L.input_char == '*') { |
||||
ctx.NextState = 28; |
||||
return true; |
||||
} |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
|
||||
private static bool State28 (FsmContext ctx) |
||||
{ |
||||
while (ctx.L.GetChar ()) { |
||||
if (ctx.L.input_char == '*') |
||||
continue; |
||||
|
||||
if (ctx.L.input_char == '/') { |
||||
ctx.NextState = 1; |
||||
return true; |
||||
} |
||||
|
||||
ctx.NextState = 27; |
||||
return true; |
||||
} |
||||
|
||||
return true; |
||||
} |
||||
#endregion |
||||
|
||||
|
||||
private bool GetChar () |
||||
{ |
||||
if ((input_char = NextChar ()) != -1) |
||||
return true; |
||||
|
||||
end_of_input = true; |
||||
return false; |
||||
} |
||||
|
||||
private int NextChar () |
||||
{ |
||||
if (input_buffer != 0) { |
||||
int tmp = input_buffer; |
||||
input_buffer = 0; |
||||
|
||||
return tmp; |
||||
} |
||||
|
||||
return reader.Read (); |
||||
} |
||||
|
||||
public bool NextToken () |
||||
{ |
||||
StateHandler handler; |
||||
fsm_context.Return = false; |
||||
|
||||
while (true) { |
||||
handler = fsm_handler_table[state - 1]; |
||||
|
||||
if (! handler (fsm_context)) |
||||
throw new JsonException (input_char); |
||||
|
||||
if (end_of_input) |
||||
return false; |
||||
|
||||
if (fsm_context.Return) { |
||||
string_value = string_buffer.ToString (); |
||||
string_buffer.Remove (0, string_buffer.Length); |
||||
token = fsm_return_table[state - 1]; |
||||
|
||||
if (token == (int) ParserToken.Char) |
||||
token = input_char; |
||||
|
||||
state = fsm_context.NextState; |
||||
|
||||
return true; |
||||
} |
||||
|
||||
state = fsm_context.NextState; |
||||
} |
||||
} |
||||
|
||||
private void UngetChar () |
||||
{ |
||||
input_buffer = input_char; |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: e5d8fbea5f811044fa786e4f915d339d |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 3b357981191bd544eae0b5a95b7f6b22 |
||||
DefaultImporter: |
||||
externalObjects: {} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
#if NETSTANDARD1_5 |
||||
using System; |
||||
using System.Reflection; |
||||
namespace LitJson |
||||
{ |
||||
internal static class Netstandard15Polyfill |
||||
{ |
||||
internal static Type GetInterface(this Type type, string name) |
||||
{ |
||||
return type.GetTypeInfo().GetInterface(name); |
||||
} |
||||
|
||||
internal static bool IsClass(this Type type) |
||||
{ |
||||
return type.GetTypeInfo().IsClass; |
||||
} |
||||
|
||||
internal static bool IsEnum(this Type type) |
||||
{ |
||||
return type.GetTypeInfo().IsEnum; |
||||
} |
||||
} |
||||
} |
||||
#endif |
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 1ad71d58c21d573439a60de7a867666e |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
@ -0,0 +1,44 @@
@@ -0,0 +1,44 @@
|
||||
#region Header |
||||
/** |
||||
* ParserToken.cs |
||||
* Internal representation of the tokens used by the lexer and the parser. |
||||
* |
||||
* The authors disclaim copyright to this source code. For more details, see |
||||
* the COPYING file included with this distribution. |
||||
**/ |
||||
#endregion |
||||
|
||||
|
||||
namespace LitJson |
||||
{ |
||||
internal enum ParserToken |
||||
{ |
||||
// Lexer tokens (see section A.1.1. of the manual) |
||||
None = System.Char.MaxValue + 1, |
||||
Number, |
||||
True, |
||||
False, |
||||
Null, |
||||
CharSeq, |
||||
// Single char |
||||
Char, |
||||
|
||||
// Parser Rules (see section A.2.1 of the manual) |
||||
Text, |
||||
Object, |
||||
ObjectPrime, |
||||
Pair, |
||||
PairRest, |
||||
Array, |
||||
ArrayPrime, |
||||
Value, |
||||
ValueRest, |
||||
String, |
||||
|
||||
// End of input |
||||
End, |
||||
|
||||
// The empty rule |
||||
Epsilon |
||||
} |
||||
} |
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2 |
||||
guid: daba7ea4f41da0e49a36f9be037bb5ab |
||||
MonoImporter: |
||||
externalObjects: {} |
||||
serializedVersion: 2 |
||||
defaultReferences: [] |
||||
executionOrder: 0 |
||||
icon: {instanceID: 0} |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
After Width: | Height: | Size: 3.3 KiB |
@ -0,0 +1,92 @@
@@ -0,0 +1,92 @@
|
||||
fileFormatVersion: 2 |
||||
guid: 419d1de541c175244883a33bdd6253f9 |
||||
TextureImporter: |
||||
internalIDToNameTable: [] |
||||
externalObjects: {} |
||||
serializedVersion: 11 |
||||
mipmaps: |
||||
mipMapMode: 0 |
||||
enableMipMap: 1 |
||||
sRGBTexture: 1 |
||||
linearTexture: 0 |
||||
fadeOut: 0 |
||||
borderMipMap: 0 |
||||
mipMapsPreserveCoverage: 0 |
||||
alphaTestReferenceValue: 0.5 |
||||
mipMapFadeDistanceStart: 1 |
||||
mipMapFadeDistanceEnd: 3 |
||||
bumpmap: |
||||
convertToNormalMap: 0 |
||||
externalNormalMap: 0 |
||||
heightScale: 0.25 |
||||
normalMapFilter: 0 |
||||
isReadable: 0 |
||||
streamingMipmaps: 0 |
||||
streamingMipmapsPriority: 0 |
||||
grayScaleToAlpha: 0 |
||||
generateCubemap: 6 |
||||
cubemapConvolution: 0 |
||||
seamlessCubemap: 0 |
||||
textureFormat: 1 |
||||
maxTextureSize: 2048 |
||||
textureSettings: |
||||
serializedVersion: 2 |
||||
filterMode: 1 |
||||
aniso: 1 |
||||
mipBias: 0 |
||||
wrapU: 0 |
||||
wrapV: 0 |
||||
wrapW: 0 |
||||
nPOTScale: 1 |
||||
lightmap: 0 |
||||
compressionQuality: 50 |
||||
spriteMode: 0 |
||||
spriteExtrude: 1 |
||||
spriteMeshType: 1 |
||||
alignment: 0 |
||||
spritePivot: {x: 0.5, y: 0.5} |
||||
spritePixelsToUnits: 100 |
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0} |
||||
spriteGenerateFallbackPhysicsShape: 1 |
||||
alphaUsage: 1 |
||||
alphaIsTransparency: 0 |
||||
spriteTessellationDetail: -1 |
||||
textureType: 0 |
||||
textureShape: 1 |
||||
singleChannelComponent: 0 |
||||
maxTextureSizeSet: 0 |
||||
compressionQualitySet: 0 |
||||
textureFormatSet: 0 |
||||
applyGammaDecoding: 0 |
||||
platformSettings: |
||||
- serializedVersion: 3 |
||||
buildTarget: DefaultTexturePlatform |
||||
maxTextureSize: 2048 |
||||
resizeAlgorithm: 0 |
||||
textureFormat: -1 |
||||
textureCompression: 1 |
||||
compressionQuality: 50 |
||||
crunchedCompression: 0 |
||||
allowsAlphaSplitting: 0 |
||||
overridden: 0 |
||||
androidETC2FallbackOverride: 0 |
||||
forceMaximumCompressionQuality_BC6H_BC7: 0 |
||||
spriteSheet: |
||||
serializedVersion: 2 |
||||
sprites: [] |
||||
outline: [] |
||||
physicsShape: [] |
||||
bones: [] |
||||
spriteID: |
||||
internalID: 0 |
||||
vertices: [] |
||||
indices: |
||||
edges: [] |
||||
weights: [] |
||||
secondaryTextures: [] |
||||
spritePackingTag: |
||||
pSDRemoveMatte: 0 |
||||
pSDShowRemoveMatteOption: 0 |
||||
userData: |
||||
assetBundleName: |
||||
assetBundleVariant: |
Loading…
Reference in new issue