28 changed files with 4460 additions and 33 deletions
Binary file not shown.
@ -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 @@ |
|||||||
|
fileFormatVersion: 2 |
||||||
|
guid: 24989a04c7189984cb5ec48003446fb6 |
||||||
|
folderAsset: yes |
||||||
|
DefaultImporter: |
||||||
|
externalObjects: {} |
||||||
|
userData: |
||||||
|
assetBundleName: |
||||||
|
assetBundleVariant: |
@ -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 @@ |
|||||||
|
fileFormatVersion: 2 |
||||||
|
guid: 62c5b44632e7f514cbaa9ed6169c0cda |
||||||
|
DefaultImporter: |
||||||
|
externalObjects: {} |
||||||
|
userData: |
||||||
|
assetBundleName: |
||||||
|
assetBundleVariant: |
@ -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 @@ |
|||||||
|
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 @@ |
|||||||
|
fileFormatVersion: 2 |
||||||
|
guid: 6ba9ae4dfe94b3c429e3c53e1c98fb3a |
||||||
|
MonoImporter: |
||||||
|
externalObjects: {} |
||||||
|
serializedVersion: 2 |
||||||
|
defaultReferences: [] |
||||||
|
executionOrder: 0 |
||||||
|
icon: {instanceID: 0} |
||||||
|
userData: |
||||||
|
assetBundleName: |
||||||
|
assetBundleVariant: |
@ -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 @@ |
|||||||
|
fileFormatVersion: 2 |
||||||
|
guid: 9867c685641adf747be0d8e36823cb43 |
||||||
|
MonoImporter: |
||||||
|
externalObjects: {} |
||||||
|
serializedVersion: 2 |
||||||
|
defaultReferences: [] |
||||||
|
executionOrder: 0 |
||||||
|
icon: {instanceID: 0} |
||||||
|
userData: |
||||||
|
assetBundleName: |
||||||
|
assetBundleVariant: |
@ -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 @@ |
|||||||
|
fileFormatVersion: 2 |
||||||
|
guid: 496f84edeb6468045a3c9cfc026b963a |
||||||
|
MonoImporter: |
||||||
|
externalObjects: {} |
||||||
|
serializedVersion: 2 |
||||||
|
defaultReferences: [] |
||||||
|
executionOrder: 0 |
||||||
|
icon: {instanceID: 0} |
||||||
|
userData: |
||||||
|
assetBundleName: |
||||||
|
assetBundleVariant: |
@ -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 @@ |
|||||||
|
fileFormatVersion: 2 |
||||||
|
guid: a6cf14146c882034b8e1e1cf5c467ec1 |
||||||
|
MonoImporter: |
||||||
|
externalObjects: {} |
||||||
|
serializedVersion: 2 |
||||||
|
defaultReferences: [] |
||||||
|
executionOrder: 0 |
||||||
|
icon: {instanceID: 0} |
||||||
|
userData: |
||||||
|
assetBundleName: |
||||||
|
assetBundleVariant: |
@ -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 @@ |
|||||||
|
fileFormatVersion: 2 |
||||||
|
guid: 084113975cf9bfd48a72aa8809c523c9 |
||||||
|
MonoImporter: |
||||||
|
externalObjects: {} |
||||||
|
serializedVersion: 2 |
||||||
|
defaultReferences: [] |
||||||
|
executionOrder: 0 |
||||||
|
icon: {instanceID: 0} |
||||||
|
userData: |
||||||
|
assetBundleName: |
||||||
|
assetBundleVariant: |
@ -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 @@ |
|||||||
|
fileFormatVersion: 2 |
||||||
|
guid: 3cda2caaf9ed41b4f9d2f97f25c70070 |
||||||
|
MonoImporter: |
||||||
|
externalObjects: {} |
||||||
|
serializedVersion: 2 |
||||||
|
defaultReferences: [] |
||||||
|
executionOrder: 0 |
||||||
|
icon: {instanceID: 0} |
||||||
|
userData: |
||||||
|
assetBundleName: |
||||||
|
assetBundleVariant: |
@ -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 @@ |
|||||||
|
fileFormatVersion: 2 |
||||||
|
guid: e5d8fbea5f811044fa786e4f915d339d |
||||||
|
MonoImporter: |
||||||
|
externalObjects: {} |
||||||
|
serializedVersion: 2 |
||||||
|
defaultReferences: [] |
||||||
|
executionOrder: 0 |
||||||
|
icon: {instanceID: 0} |
||||||
|
userData: |
||||||
|
assetBundleName: |
||||||
|
assetBundleVariant: |
@ -0,0 +1,7 @@ |
|||||||
|
fileFormatVersion: 2 |
||||||
|
guid: 3b357981191bd544eae0b5a95b7f6b22 |
||||||
|
DefaultImporter: |
||||||
|
externalObjects: {} |
||||||
|
userData: |
||||||
|
assetBundleName: |
||||||
|
assetBundleVariant: |
@ -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 @@ |
|||||||
|
fileFormatVersion: 2 |
||||||
|
guid: 1ad71d58c21d573439a60de7a867666e |
||||||
|
MonoImporter: |
||||||
|
externalObjects: {} |
||||||
|
serializedVersion: 2 |
||||||
|
defaultReferences: [] |
||||||
|
executionOrder: 0 |
||||||
|
icon: {instanceID: 0} |
||||||
|
userData: |
||||||
|
assetBundleName: |
||||||
|
assetBundleVariant: |
@ -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 @@ |
|||||||
|
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 @@ |
|||||||
|
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