using System;
using System.Collections;
using System.Collections.Generic;
#if !SILVERLIGHT
using System.Data;
#endif
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using System.Collections.Specialized;
namespace FastJSON
{
public delegate string Serialize(object data);
public delegate object Deserialize(string data);
public sealed class JSONParameters
{
///
/// Use the optimized fast Dataset Schema format (default = True)
///
public bool UseOptimizedDatasetSchema = true;
///
/// Use the fast GUID format (default = True)
///
public bool UseFastGuid = true;
///
/// Serialize null values to the output (default = True)
///
public bool SerializeNullValues = true;
///
/// Use the UTC date format (default = True)
///
public bool UseUTCDateTime = true;
///
/// Show the readonly properties of types in the output (default = False)
///
public bool ShowReadOnlyProperties = false;
///
/// Use the $types extension to optimise the output json (default = True)
///
public bool UsingGlobalTypes = true;
///
/// Ignore case when processing json and deserializing
///
[Obsolete("Not needed anymore and will always match")]
public bool IgnoreCaseOnDeserialize = false;
///
/// Anonymous types have read only properties
///
public bool EnableAnonymousTypes = false;
///
/// Enable fastJSON extensions $types, $type, $map (default = True)
///
public bool UseExtensions = true;
///
/// Use escaped unicode i.e. \uXXXX format for non ASCII characters (default = True)
///
public bool UseEscapedUnicode = false;
///
/// Output string key dictionaries as "k"/"v" format (default = False)
///
public bool KVStyleStringDictionary = false;
///
/// Output Enum values instead of names (default = False)
///
public bool UseValuesOfEnums = false;
///
/// Ignore attributes to check for (default : XmlIgnoreAttribute)
///
public List IgnoreAttributes = new List { typeof(System.Xml.Serialization.XmlIgnoreAttribute) };
///
/// If you have parametric and no default constructor for you classes (default = False)
///
/// IMPORTANT NOTE : If True then all initial values within the class will be ignored and will be not set
///
public bool ParametricConstructorOverride = false;
///
/// Serialize DateTime milliseconds i.e. yyyy-MM-dd HH:mm:ss.nnn (default = false)
///
public bool DateTimeMilliseconds = false;
///
/// Maximum depth for circular references in inline mode (default = 20)
///
public byte SerializerMaxDepth = 20;
///
/// Inline circular or already seen objects instead of replacement with $i (default = False)
///
public bool InlineCircularReferences = false;
///
/// Save property/field names as lowercase (default = false)
///
public bool SerializeToLowerCaseNames = false;
///
/// Serialize property name with underline style
///
public bool UseApiNamingStyle = false;
public void FixValues()
{
if (UseExtensions == false) // disable conflicting params
{
UsingGlobalTypes = false;
InlineCircularReferences = true;
}
if (EnableAnonymousTypes)
ShowReadOnlyProperties = true;
}
}
public static class JSON
{
///
/// Globally set-able parameters for controlling the serializer
///
public static JSONParameters Parameters = new JSONParameters();
///
/// Create a formatted json string (beautified) from an object
///
///
///
///
public static string ToNiceJSON(object obj, JSONParameters param)
{
string s = ToJSON(obj, param);
return Beautify(s);
}
///
/// Create a json representation for an object
///
///
///
public static string ToJSON(object obj)
{
return ToJSON(obj, JSON.Parameters);
}
///
/// Create a json representation for an object with parameter override on this call
///
///
///
///
public static string ToJSON(object obj, JSONParameters param)
{
param.FixValues();
Type t = null;
if (obj == null)
return "null";
if (obj.GetType().IsGenericType)
t = Reflection.Instance.GetGenericTypeDefinition(obj.GetType());
if (t == typeof(Dictionary<,>) || t == typeof(List<>))
param.UsingGlobalTypes = false;
// FEATURE : enable extensions when you can deserialize anon types
if (param.EnableAnonymousTypes) { param.UseExtensions = false; param.UsingGlobalTypes = false; }
return new JSONSerializer(param).ConvertToJSON(obj);
}
///
/// Parse a json string and generate a Dictionary<string,object> or List<object> structure
///
///
///
public static object Parse(string json)
{
return new JsonParser(json).Decode();
}
#if net4
///
/// Create a .net4 dynamic object from the json string
///
///
///
public static dynamic ToDynamic(string json)
{
return new DynamicJson(json);
}
#endif
///
/// Create a typed generic object from the json
///
///
///
///
public static T ToObject(string json)
{
return new deserializer(Parameters).ToObject(json);
}
///
/// Create a typed generic object from the json with parameter override on this call
///
///
///
///
///
public static T ToObject(string json, JSONParameters param)
{
return new deserializer(param).ToObject(json);
}
///
/// Create an object from the json
///
///
///
public static object ToObject(string json)
{
return new deserializer(Parameters).ToObject(json, null);
}
///
/// Create an object from the json with parameter override on this call
///
///
///
///
public static object ToObject(string json, JSONParameters param)
{
return new deserializer(param).ToObject(json, null);
}
///
/// Create an object of type from the json
///
///
///
///
public static object ToObject(string json, Type type)
{
return new deserializer(Parameters).ToObject(json, type);
}
///
/// Fill a given object with the json represenation
///
///
///
///
public static object FillObject(object input, string json)
{
Dictionary ht = new JsonParser(json).Decode() as Dictionary;
if (ht == null) return null;
return new deserializer(Parameters).ParseDictionary(ht, null, input.GetType(), input);
}
///
/// Deep copy an object i.e. clone to a new object
///
///
///
public static object DeepCopy(object obj)
{
return new deserializer(Parameters).ToObject(ToJSON(obj));
}
///
///
///
///
///
///
public static T DeepCopy(T obj)
{
return new deserializer(Parameters).ToObject(ToJSON(obj));
}
///
/// Create a human readable string from the json
///
///
///
public static string Beautify(string input)
{
return Formatter.PrettyPrint(input);
}
///
/// Register custom type handlers for your own types not natively handled by fastJSON
///
///
///
///
public static void RegisterCustomType(Type type, Serialize serializer, Deserialize deserializer)
{
Reflection.Instance.RegisterCustomType(type, serializer, deserializer);
}
///
/// Clear the internal reflection cache so you can start from new (you will loose performance)
///
public static void ClearReflectionCache()
{
Reflection.Instance.ClearReflectionCache();
}
internal static long CreateLong(out long num, string s, int index, int count)
{
num = 0;
bool neg = false;
for (int x = 0; x < count; x++, index++)
{
char cc = s[index];
if (cc == '-')
neg = true;
else if (cc == '+')
neg = false;
else
{
num *= 10;
num += (int)(cc - '0');
}
}
if (neg) num = -num;
return num;
}
}
internal class deserializer
{
public deserializer(JSONParameters param)
{
_params = param;
}
private JSONParameters _params;
private bool _usingglobals = false;
private Dictionary