forked from ln-dotnet/ln.json
Alpha commit
parent
a9a37de231
commit
659088b90e
|
@ -2,6 +2,7 @@
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using sharp.extensions;
|
using sharp.extensions;
|
||||||
|
using System.Globalization;
|
||||||
|
|
||||||
namespace sharp.json
|
namespace sharp.json
|
||||||
{
|
{
|
||||||
|
@ -20,6 +21,8 @@ namespace sharp.json
|
||||||
System.Tuple.Create('t','\t'),
|
System.Tuple.Create('t','\t'),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static List<char> numberScan = new List<char>(new char[] { '-', '0', '1', '2', '3', '4', '5', '7', '8', '9', '.','E','e' });
|
||||||
|
|
||||||
char[] buffer;
|
char[] buffer;
|
||||||
int position;
|
int position;
|
||||||
|
|
||||||
|
@ -37,7 +40,7 @@ namespace sharp.json
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Peek(int len){
|
public string Peek(int len){
|
||||||
return new String(buffer.Segment(position,len));
|
return new String(buffer.Segment(position,len).Extend(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,7 +52,7 @@ namespace sharp.json
|
||||||
}
|
}
|
||||||
public char[] Read(int len){
|
public char[] Read(int len){
|
||||||
if ((position) < buffer.Length){
|
if ((position) < buffer.Length){
|
||||||
char[] r = buffer.Segment(position,len);
|
char[] r = buffer.Segment(position, len).Extend(len);
|
||||||
position += r.Length;
|
position += r.Length;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -85,22 +88,43 @@ namespace sharp.json
|
||||||
}
|
}
|
||||||
|
|
||||||
public JSON parseNumber(){
|
public JSON parseNumber(){
|
||||||
Int64 i64 = parseInt64();
|
List<char> digits = new List<char>();
|
||||||
|
|
||||||
if (Peek() == '.'){
|
do
|
||||||
Read();
|
{
|
||||||
Int64 dec = parseInt64();
|
char n = (char)Peek();
|
||||||
int lg10 = (int)Math.Log10(dec);
|
if (!numberScan.Contains(n)){
|
||||||
i64 = i64 * lg10;
|
break;
|
||||||
if (i64 < 0){
|
|
||||||
i64 -= dec;
|
|
||||||
} else {
|
|
||||||
i64 += dec;
|
|
||||||
}
|
}
|
||||||
return new JSONNumber(((double)i64) / (double)lg10 );
|
digits.Add(n);
|
||||||
|
Read();
|
||||||
|
} while (true);
|
||||||
|
|
||||||
|
string sv = new String(digits.ToArray());
|
||||||
|
|
||||||
|
if ((sv.IndexOf(".") > 0)||(sv.IndexOf("E") > 0)||(sv.IndexOf("e") > 0))
|
||||||
|
{
|
||||||
|
return new JSONNumber(double.Parse(sv,CultureInfo.InvariantCulture));
|
||||||
} else {
|
} else {
|
||||||
return new JSONNumber(i64);
|
return new JSONNumber(Int64.Parse(sv));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Int64 i64 = parseInt64();
|
||||||
|
|
||||||
|
//if (Peek() == '.'){
|
||||||
|
// Read();
|
||||||
|
// Int64 dec = parseInt64();
|
||||||
|
// int lg10 = (int)Math.Log10(dec);
|
||||||
|
// i64 = i64 * lg10;
|
||||||
|
// if (i64 < 0){
|
||||||
|
// i64 -= dec;
|
||||||
|
// } else {
|
||||||
|
// i64 += dec;
|
||||||
|
// }
|
||||||
|
// return new JSONNumber(((double)i64) / (double)lg10 );
|
||||||
|
//} else {
|
||||||
|
// return new JSONNumber(i64);
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
public JSON parseObject(){
|
public JSON parseObject(){
|
||||||
|
@ -138,7 +162,7 @@ namespace sharp.json
|
||||||
scanWhitespace();
|
scanWhitespace();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
throw new FormatException("parser error: expected ',' or '}' but got '{0}'");
|
throw new FormatException("parser error: expected ',' or '}' but got '"+n+"'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return o;
|
return o;
|
||||||
|
@ -185,20 +209,10 @@ namespace sharp.json
|
||||||
|
|
||||||
while (Peek() != '"'){
|
while (Peek() != '"'){
|
||||||
char ch = Read();
|
char ch = Read();
|
||||||
if (ch == '\\'){
|
sb.Append(ch);
|
||||||
|
if (ch == '\\')
|
||||||
|
{
|
||||||
ch = Read();
|
ch = Read();
|
||||||
foreach (System.Tuple<char,char> repl in escapeCharacters){
|
|
||||||
if (repl.Item1 == ch){
|
|
||||||
sb.Append(repl.Item2);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (ch == 'u'){
|
|
||||||
char[] hex = Read(4);
|
|
||||||
sb.Append("_");
|
|
||||||
Console.WriteLine("JSON WARNING: UNICODE ESCAPE SEQUENCES ARE NOT IMPLEMENTED YET");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
sb.Append(ch);
|
sb.Append(ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
273
JSON.cs
273
JSON.cs
|
@ -2,65 +2,266 @@
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Net;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
namespace sharp.json
|
namespace sharp.json
|
||||||
{
|
{
|
||||||
public abstract class JSON
|
public delegate object JSONActivationDelegate(Type t);
|
||||||
|
|
||||||
|
public abstract class JSON : IEnumerable<JSON>
|
||||||
{
|
{
|
||||||
List<string> keys = new List<string>();
|
public virtual double Double { get { throw new NotImplementedException(); } }
|
||||||
List<JSON> values = new List<JSON>();
|
public virtual long Integer { get { throw new NotImplementedException(); } }
|
||||||
|
public virtual string String { get { throw new NotImplementedException(); } }
|
||||||
|
public virtual bool Boolean { get { throw new NotImplementedException(); } }
|
||||||
|
|
||||||
public JSON this[int n] {
|
public virtual JSON this[int n]
|
||||||
get {
|
{
|
||||||
return values[n];
|
get { throw new NotImplementedException(String.Format("{0} has no numbered elements",GetType().Name)); }
|
||||||
}
|
set { throw new NotImplementedException(String.Format("{0} has no numbered elements",GetType().Name)); }
|
||||||
set{
|
|
||||||
values[n] = value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public JSON this[string name] {
|
public virtual JSON this[string name] {
|
||||||
get {
|
get { throw new NotImplementedException(String.Format("{0} has no named elements", GetType().Name)); }
|
||||||
return values[keys.IndexOf(name)];
|
set { throw new NotImplementedException(String.Format("{0} has no named elements", GetType().Name)); }
|
||||||
}
|
|
||||||
set{
|
|
||||||
if (keys.Contains(name)){
|
|
||||||
values[keys.IndexOf(name)] = value;
|
|
||||||
} else {
|
|
||||||
keys.Add(name);
|
|
||||||
values.Add(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string[] Keys {
|
public virtual int Count { get { return 0; } }
|
||||||
get { return this.keys.ToArray(); }
|
|
||||||
}
|
public virtual bool Contains(object o){
|
||||||
public JSON[] Values {
|
return false;
|
||||||
get { return this.values.ToArray(); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Add(JSON element){
|
public virtual void Add(JSON child)
|
||||||
this.values.Add(element);
|
{
|
||||||
|
throw new NotImplementedException(String.Format("{0} has no numbered elements", GetType().Name));
|
||||||
}
|
}
|
||||||
|
public virtual void Remove(JSON child)
|
||||||
public virtual bool isTrue(){
|
{
|
||||||
return this.JSONType == JSONTypes.True;
|
throw new NotImplementedException(String.Format("{0} has no numbered elements", GetType().Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int Count { get { return values.Count; } }
|
|
||||||
public JSONTypes JSONType { get; private set; }
|
public JSONTypes JSONType { get; private set; }
|
||||||
|
|
||||||
protected JSON(JSONTypes type){
|
protected JSON(JSONTypes type){
|
||||||
JSONType = type;
|
JSONType = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract string prettyPrint(int d);
|
public abstract string[] prettyPrint();
|
||||||
public override abstract string ToString();
|
public override abstract string ToString();
|
||||||
|
|
||||||
public static JSON parse(String jsonSource){
|
|
||||||
return new ByteParser(jsonSource).parse();
|
public string prettyFormat(){
|
||||||
|
return String.Join("\n", prettyPrint());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static implicit operator JSON(Double src)
|
||||||
|
{
|
||||||
|
return new JSONNumber(src);
|
||||||
|
}
|
||||||
|
public static implicit operator JSON(int src)
|
||||||
|
{
|
||||||
|
return new JSONNumber(src);
|
||||||
|
}
|
||||||
|
public static implicit operator JSON(string text)
|
||||||
|
{
|
||||||
|
return new JSONString(text);
|
||||||
|
}
|
||||||
|
public static implicit operator JSON(bool b)
|
||||||
|
{
|
||||||
|
return b ? JSONSpecial.True : JSONSpecial.False;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T To<T>(){
|
||||||
|
object o = Create(typeof(T));
|
||||||
|
return (T)o;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteTo(Stream stream){
|
||||||
|
byte[] data = Encoding.ASCII.GetBytes(ToString());
|
||||||
|
stream.Write(data,0,data.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteTo(String filename)
|
||||||
|
{
|
||||||
|
FileStream fs = new FileStream(filename, FileMode.Create);
|
||||||
|
WriteTo(fs);
|
||||||
|
fs.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JSON ReadFrom(string filename){
|
||||||
|
JSONParser parser = new JSONParser();
|
||||||
|
string source = File.ReadAllText(filename);
|
||||||
|
return parser.Parse(source);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private object Create(Type t)
|
||||||
|
{
|
||||||
|
if (t.IsPrimitive || (t == typeof(string)) )
|
||||||
|
{
|
||||||
|
return CreatePrimitive(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.JSONType == JSONTypes.Object)
|
||||||
|
{
|
||||||
|
return CreateObject(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((this.JSONType == JSONTypes.Array) && (t.IsArray))
|
||||||
|
{
|
||||||
|
return CreateArray(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new InvalidCastException(String.Format("JSON {0} can't be casted to {1}", this.JSONType.ToString(), t.Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
private object CreatePrimitive(Type t){
|
||||||
|
|
||||||
|
if ((this.JSONType == JSONTypes.Null)){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((this.JSONType == JSONTypes.Array) || (this.JSONType == JSONTypes.Object)){
|
||||||
|
throw new InvalidCastException(String.Format("JSON {0} can't be casted to {1}",this.JSONType.ToString(),t.Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t.Equals(typeof(int)) || t.Equals(typeof(long)) || t.Equals(typeof(short))){
|
||||||
|
return (object)this.Integer;
|
||||||
|
}
|
||||||
|
if (t.Equals(typeof(double)) || t.Equals(typeof(float)))
|
||||||
|
{
|
||||||
|
return (object)this.Double;
|
||||||
|
}
|
||||||
|
if (t.Equals(typeof(string)))
|
||||||
|
{
|
||||||
|
return (object)this.String;
|
||||||
|
}
|
||||||
|
if (t.Equals(typeof(Boolean)))
|
||||||
|
{
|
||||||
|
return (object)this.Boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Exception(String.Format("Unsupported primitive type",t.Name));
|
||||||
|
}
|
||||||
|
|
||||||
|
private object CreateObject(Type t){
|
||||||
|
if (t.GetConstructor(new Type[] { typeof(JSON) } ) != null){
|
||||||
|
return Activator.CreateInstance(t, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
object instance = Activator.CreateInstance(t);
|
||||||
|
Dictionary<string, FieldPropertyInfo> assignedFields = new Dictionary<string, FieldPropertyInfo>();
|
||||||
|
|
||||||
|
foreach (FieldInfo fi in t.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
|
||||||
|
{
|
||||||
|
foreach (JSONField f in fi.GetCustomAttributes<JSONField>())
|
||||||
|
{
|
||||||
|
if (this.Contains(f.Alias))
|
||||||
|
{
|
||||||
|
if (!assignedFields.ContainsKey(f.Alias) || assignedFields[f.Alias].IsAutoAssigned){
|
||||||
|
assignedFields[f.Alias] = new FieldPropertyInfo(fi, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!assignedFields.ContainsKey(fi.Name) && this.Contains(fi.Name)){
|
||||||
|
assignedFields[fi.Name] = new FieldPropertyInfo(fi, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (PropertyInfo pi in t.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
|
||||||
|
{
|
||||||
|
foreach (JSONField f in pi.GetCustomAttributes<JSONField>())
|
||||||
|
{
|
||||||
|
if (this.Contains(f.Alias))
|
||||||
|
{
|
||||||
|
if (!assignedFields.ContainsKey(f.Alias) || assignedFields[f.Alias].IsAutoAssigned)
|
||||||
|
{
|
||||||
|
assignedFields[f.Alias] = new FieldPropertyInfo(pi, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!assignedFields.ContainsKey(pi.Name) && this.Contains(pi.Name))
|
||||||
|
{
|
||||||
|
assignedFields[pi.Name] = new FieldPropertyInfo(pi, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (KeyValuePair<string,FieldPropertyInfo> e in assignedFields){
|
||||||
|
e.Value.setValue(instance, this[e.Key].Create(e.Value.ValueType));
|
||||||
|
}
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private object CreateArray(Type t)
|
||||||
|
{
|
||||||
|
Array a = Array.CreateInstance(t.GetElementType(), this.Count);
|
||||||
|
|
||||||
|
for (int n = 0; n < this.Count;n++){
|
||||||
|
a.SetValue(this[n].Create(t.GetElementType()),n);
|
||||||
|
}
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual IEnumerator<JSON> GetEnumerator()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
{
|
||||||
|
return (IEnumerator)GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct FieldPropertyInfo {
|
||||||
|
public bool IsAutoAssigned { get; set; }
|
||||||
|
FieldInfo FieldInfo { get; set; }
|
||||||
|
PropertyInfo PropertyInfo { get; set; }
|
||||||
|
|
||||||
|
public FieldPropertyInfo(PropertyInfo propertyInfo,bool autoAssigned)
|
||||||
|
{
|
||||||
|
this.IsAutoAssigned = autoAssigned;
|
||||||
|
this.PropertyInfo = propertyInfo;
|
||||||
|
this.FieldInfo = null;
|
||||||
|
}
|
||||||
|
public FieldPropertyInfo(FieldInfo fieldInfo,bool autoAssigned)
|
||||||
|
{
|
||||||
|
this.IsAutoAssigned = autoAssigned;
|
||||||
|
this.PropertyInfo = null;
|
||||||
|
this.FieldInfo = fieldInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setValue(object inst,object value){
|
||||||
|
if (PropertyInfo != null){
|
||||||
|
PropertyInfo.SetValue(inst,value);
|
||||||
|
} else if (FieldInfo != null){
|
||||||
|
FieldInfo.SetValue(inst,value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type ValueType {
|
||||||
|
get {
|
||||||
|
if (PropertyInfo != null){
|
||||||
|
return PropertyInfo.PropertyType;
|
||||||
|
} else if (FieldInfo != null){
|
||||||
|
return FieldInfo.FieldType;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
80
JSONArray.cs
80
JSONArray.cs
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
@ -7,31 +7,95 @@ namespace sharp.json
|
||||||
public class JSONArray : JSON
|
public class JSONArray : JSON
|
||||||
{
|
{
|
||||||
public JSONArray()
|
public JSONArray()
|
||||||
:base(JSONTypes.Array){}
|
: base(JSONTypes.Array) { }
|
||||||
|
|
||||||
public override bool isTrue()
|
List<JSON> values = new List<JSON>();
|
||||||
|
|
||||||
|
public override bool Boolean
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
get { return values.Count > 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string prettyPrint(int d = 0)
|
public override JSON this[int n]
|
||||||
{
|
{
|
||||||
return ToString();
|
get
|
||||||
|
{
|
||||||
|
return values[n];
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
values[n] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int Count
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return this.values.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Contains(object o)
|
||||||
|
{
|
||||||
|
return this.values.Contains((JSON)o);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Add(JSON child)
|
||||||
|
{
|
||||||
|
this.values.Add(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Remove(JSON child)
|
||||||
|
{
|
||||||
|
this.values.Remove(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string[] prettyPrint()
|
||||||
|
{
|
||||||
|
List<string> lines = new List<string>();
|
||||||
|
|
||||||
|
lines.Add("[");
|
||||||
|
|
||||||
|
for (int i = 0; i < this.values.Count; i++)
|
||||||
|
{
|
||||||
|
JSON cv = this.values[i];
|
||||||
|
string[] clines = cv.prettyPrint();
|
||||||
|
|
||||||
|
for (int n = 0; n < clines.Length; n++)
|
||||||
|
{
|
||||||
|
lines.Add(String.Format(" {0}{1}", clines[n], (n < clines.Length - 1) || (i == this.values.Count - 1) ? "" : ","));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lines.Add("]");
|
||||||
|
|
||||||
|
return lines.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.Append("[");
|
sb.Append("[");
|
||||||
for (int n=0;n<this.Count;n++)
|
for (int n = 0; n < this.Count; n++)
|
||||||
{
|
{
|
||||||
sb.Append(this[n].ToString());
|
sb.Append(this[n].ToString());
|
||||||
if (n+1 < this.Count){
|
if (n + 1 < this.Count)
|
||||||
|
{
|
||||||
sb.Append(",");
|
sb.Append(",");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sb.Append("]");
|
sb.Append("]");
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public override IEnumerator<JSON> GetEnumerator()
|
||||||
|
{
|
||||||
|
return this.values.GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace sharp.json
|
||||||
|
{
|
||||||
|
public class JSONField : Attribute
|
||||||
|
{
|
||||||
|
public string Alias { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Reflection;
|
||||||
namespace sharp.json
|
namespace sharp.json
|
||||||
{
|
{
|
||||||
public class JSONNumber: JSON
|
public class JSONNumber: JSON
|
||||||
|
@ -25,18 +27,68 @@ namespace sharp.json
|
||||||
doubleValue = d;
|
doubleValue = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string prettyPrint(int d = 0)
|
public override double Double
|
||||||
{
|
{
|
||||||
if (Double.IsNaN(doubleValue)){
|
get
|
||||||
return this.intValue.ToString();
|
{
|
||||||
} else {
|
if (!Double.IsNaN(doubleValue)){
|
||||||
return this.doubleValue.ToString();
|
return doubleValue;
|
||||||
|
} else {
|
||||||
|
return (double)intValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override long Integer
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!Double.IsNaN(doubleValue)){
|
||||||
|
return (int)doubleValue;
|
||||||
|
} else {
|
||||||
|
return intValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string String
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!Double.IsNaN(doubleValue))
|
||||||
|
{
|
||||||
|
return doubleValue.ToString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return intValue.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public override string[] prettyPrint()
|
||||||
|
{
|
||||||
|
return new string[] { ToString() };
|
||||||
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return this.prettyPrint(0);
|
if (Double.IsNaN(doubleValue))
|
||||||
|
{
|
||||||
|
return this.intValue.ToString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return this.doubleValue.ToString(CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsInteger(){
|
||||||
|
return Double.IsNaN(doubleValue);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using sharp.extensions;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace sharp.json
|
namespace sharp.json
|
||||||
{
|
{
|
||||||
|
@ -9,29 +12,53 @@ namespace sharp.json
|
||||||
public JSONObject()
|
public JSONObject()
|
||||||
:base(JSONTypes.Object){}
|
:base(JSONTypes.Object){}
|
||||||
|
|
||||||
public override bool isTrue()
|
private Dictionary<string, JSON> values = new Dictionary<string, JSON>();
|
||||||
|
|
||||||
|
public override JSON this[string name]
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
get { return this.values[name]; }
|
||||||
|
set { this.values[name] = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string prettyPrint(int d = 0)
|
public override int Count
|
||||||
{
|
{
|
||||||
StringBuilder sb = new StringBuilder();
|
get { return this.values.Count; }
|
||||||
sb.Append("{");
|
}
|
||||||
|
|
||||||
string[] keys = Keys;
|
public override bool Boolean
|
||||||
|
{
|
||||||
|
get { return this.values.Count > 0; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Contains(object o)
|
||||||
|
{
|
||||||
|
return this.values.ContainsKey((string)o);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public override string[] prettyPrint()
|
||||||
|
{
|
||||||
|
List<string> lines = new List<string>();
|
||||||
|
lines.Add("{");
|
||||||
|
|
||||||
|
string[] keys = this.values.Keys.ToArray();
|
||||||
|
|
||||||
for (int n=0;n<keys.Length;n++)
|
for (int n=0;n<keys.Length;n++)
|
||||||
{
|
{
|
||||||
sb.Append(new JSONString(keys[n]));
|
string[] clines = this[keys[n]].prettyPrint();
|
||||||
sb.Append(":");
|
|
||||||
sb.Append(this[keys[n]].ToString());
|
lines.Add(String.Format(" {0} : {1}",new JSONString(keys[n]),clines[0]));
|
||||||
if (n+1 < keys.Length){
|
foreach (string cline in clines.Segment(1)){
|
||||||
sb.Append(",");
|
lines.Add(String.Format(" {0}",cline));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n < keys.Length-1){
|
||||||
|
lines[lines.Count - 1] += ",";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sb.Append("}");
|
lines.Add("}");
|
||||||
return sb.ToString();
|
return lines.ToArray();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +67,7 @@ namespace sharp.json
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
sb.Append("{");
|
sb.Append("{");
|
||||||
|
|
||||||
string[] keys = Keys;
|
string[] keys = this.values.Keys.ToArray();
|
||||||
|
|
||||||
for (int n=0;n<keys.Length;n++)
|
for (int n=0;n<keys.Length;n++)
|
||||||
{
|
{
|
||||||
|
@ -54,5 +81,6 @@ namespace sharp.json
|
||||||
sb.Append("}");
|
sb.Append("}");
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,318 @@
|
||||||
|
using System;
|
||||||
|
using sharp.parser;
|
||||||
|
using Microsoft.Win32.SafeHandles;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Net.Mime;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace sharp.json
|
||||||
|
{
|
||||||
|
public class JSONParser : Parser<JSON>
|
||||||
|
{
|
||||||
|
delegate JSON ParseObjectDelegate(TokenQueue tokens);
|
||||||
|
|
||||||
|
Dictionary<TokenDefinition, ParseObjectDelegate> parserDelegates = new Dictionary<TokenDefinition, ParseObjectDelegate>();
|
||||||
|
|
||||||
|
public JSONParser()
|
||||||
|
:base(tokenDefinitions)
|
||||||
|
{
|
||||||
|
parserDelegates.Add(tString,parseString);
|
||||||
|
parserDelegates.Add(tNumber,parseNumber);
|
||||||
|
parserDelegates.Add(tObjectOpen,parseObject);
|
||||||
|
parserDelegates.Add(tArrayOpen,parseArray);
|
||||||
|
parserDelegates.Add(tTrue,parseTrue);
|
||||||
|
parserDelegates.Add(tFalse,parseFalse);
|
||||||
|
parserDelegates.Add(tNull,parseNull);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override JSON ParseTokens(Token[] tokens)
|
||||||
|
{
|
||||||
|
TokenQueue qtoken = new TokenQueue();
|
||||||
|
foreach (Token t in tokens){
|
||||||
|
if (t.Definition != tWhiteSpace){
|
||||||
|
qtoken.Enqueue(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parseValue(qtoken);
|
||||||
|
}
|
||||||
|
|
||||||
|
private JSON parseValue(TokenQueue tokens){
|
||||||
|
foreach (TokenDefinition tdef in this.parserDelegates.Keys){
|
||||||
|
if (tdef == tokens.Peek().Definition){
|
||||||
|
return this.parserDelegates[tokens.Peek().Definition](tokens);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new Exception(String.Format("Parser got unexpected token: {0}", tokens.Peek().ToString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
JSON parseString(TokenQueue tokens){
|
||||||
|
Token t = tokens.Expect(tString);
|
||||||
|
return new JSONString(t.Value.Substring(1, t.Value.Length - 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
JSON parseNumber(TokenQueue tokens)
|
||||||
|
{
|
||||||
|
Token t = tokens.Expect(tNumber);
|
||||||
|
Double dv = double.Parse(t.Value,CultureInfo.InvariantCulture);
|
||||||
|
return new JSONNumber(dv);
|
||||||
|
}
|
||||||
|
|
||||||
|
JSON parseObject(TokenQueue tokens)
|
||||||
|
{
|
||||||
|
Token t = tokens.Expect(tObjectOpen);
|
||||||
|
JSONObject jo = new JSONObject();
|
||||||
|
|
||||||
|
if (tokens.Peek().Definition == tObjectClose){
|
||||||
|
tokens.Dequeue();
|
||||||
|
return jo;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
JSONString js = (JSONString)parseString(tokens);
|
||||||
|
|
||||||
|
tokens.Expect(tColon);
|
||||||
|
|
||||||
|
JSON json = parseValue(tokens);
|
||||||
|
jo[js.String] = json;
|
||||||
|
|
||||||
|
t = tokens.Expect(tObjectClose, tComma);
|
||||||
|
|
||||||
|
if (t.Definition == tObjectClose){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (true);
|
||||||
|
|
||||||
|
return jo;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSON parseArray(TokenQueue tokens)
|
||||||
|
{
|
||||||
|
Token t = tokens.Expect(tArrayOpen);
|
||||||
|
JSONArray ja = new JSONArray();
|
||||||
|
|
||||||
|
if (tokens.Peek().Definition == tArrayClose)
|
||||||
|
{
|
||||||
|
tokens.Dequeue();
|
||||||
|
return ja;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
JSON json = parseValue(tokens);
|
||||||
|
ja.Add(json);
|
||||||
|
|
||||||
|
t = tokens.Expect(tArrayClose, tComma);
|
||||||
|
|
||||||
|
if (t.Definition == tArrayClose)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (true);
|
||||||
|
|
||||||
|
return ja;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSON parseTrue(TokenQueue tokens)
|
||||||
|
{
|
||||||
|
if (tokens.Peek().Definition == tTrue){
|
||||||
|
Token t = tokens.Dequeue();
|
||||||
|
return JSONSpecial.True;
|
||||||
|
}
|
||||||
|
throw new Exception("Unexpected Token: " + tokens.Peek());
|
||||||
|
}
|
||||||
|
JSON parseFalse(TokenQueue tokens)
|
||||||
|
{
|
||||||
|
if (tokens.Peek().Definition == tFalse){
|
||||||
|
Token t = tokens.Dequeue();
|
||||||
|
return JSONSpecial.False;
|
||||||
|
}
|
||||||
|
throw new Exception("Unexpected Token: " + tokens.Peek());
|
||||||
|
}
|
||||||
|
JSON parseNull(TokenQueue tokens)
|
||||||
|
{
|
||||||
|
if (tokens.Peek().Definition == tNull){
|
||||||
|
Token t = tokens.Dequeue();
|
||||||
|
return JSONSpecial.Null;
|
||||||
|
}
|
||||||
|
throw new Exception("Unexpected Token: " + tokens.Peek());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static bool initializer = initialize();
|
||||||
|
|
||||||
|
static TokenDefinition[] tokenDefinitions;
|
||||||
|
|
||||||
|
static CharGroup eE = new CharGroup(new char[] { 'e', 'E' } );
|
||||||
|
|
||||||
|
static LexerPathSegment null_ll;
|
||||||
|
static LexerPathSegment null_l;
|
||||||
|
static LexerPathSegment null_u;
|
||||||
|
static LexerPathSegment null_n;
|
||||||
|
|
||||||
|
static LexerPathSegment true_e;
|
||||||
|
static LexerPathSegment true_u;
|
||||||
|
static LexerPathSegment true_r;
|
||||||
|
static LexerPathSegment true_t;
|
||||||
|
|
||||||
|
static LexerPathSegment false_e;
|
||||||
|
static LexerPathSegment false_s;
|
||||||
|
static LexerPathSegment false_l;
|
||||||
|
static LexerPathSegment false_a;
|
||||||
|
static LexerPathSegment false_f;
|
||||||
|
|
||||||
|
static LexerPathSegment ws;
|
||||||
|
|
||||||
|
static TokenDefinition tNumber;
|
||||||
|
static TokenDefinition tString;
|
||||||
|
static TokenDefinition tColon;
|
||||||
|
static TokenDefinition tComma;
|
||||||
|
static TokenDefinition tObjectOpen;
|
||||||
|
static TokenDefinition tObjectClose;
|
||||||
|
static TokenDefinition tArrayOpen;
|
||||||
|
static TokenDefinition tArrayClose;
|
||||||
|
static TokenDefinition tTrue;
|
||||||
|
static TokenDefinition tFalse;
|
||||||
|
static TokenDefinition tNull;
|
||||||
|
static TokenDefinition tWhiteSpace;
|
||||||
|
|
||||||
|
static private bool initialize(){
|
||||||
|
eE = new CharGroup(new char[] { 'e', 'E' });
|
||||||
|
|
||||||
|
null_ll = new LexerPathSegment('l', true);
|
||||||
|
null_l = new LexerPathSegment('l', null_ll);
|
||||||
|
null_u = new LexerPathSegment('u', null_l);
|
||||||
|
null_n = new LexerPathSegment('n', null_u);
|
||||||
|
|
||||||
|
true_e = new LexerPathSegment('e', true);
|
||||||
|
true_u = new LexerPathSegment('u', true_e);
|
||||||
|
true_r = new LexerPathSegment('r', true_u);
|
||||||
|
true_t = new LexerPathSegment('t', true_r);
|
||||||
|
|
||||||
|
false_e = new LexerPathSegment('e', true);
|
||||||
|
false_s = new LexerPathSegment('s', false_e);
|
||||||
|
false_l = new LexerPathSegment('l', false_s);
|
||||||
|
false_a = new LexerPathSegment('a', false_l);
|
||||||
|
false_f = new LexerPathSegment('f', false_a);
|
||||||
|
|
||||||
|
ws = new LexerPathSegment(CharGroup.WS, true);
|
||||||
|
ws.AddFollower(ws);
|
||||||
|
|
||||||
|
tNumber = new TokenDefinition("JSON.number", initializeNumberHead());
|
||||||
|
tString = new TokenDefinition("JSON.string", initializeStringHead());
|
||||||
|
tColon = new TokenDefinition("JSON.colon", new LexerPathSegment(':',true));
|
||||||
|
tComma = new TokenDefinition("JSON.comma", new LexerPathSegment(',',true));
|
||||||
|
tObjectOpen = new TokenDefinition("JSON.obj.open", new LexerPathSegment('{',true));
|
||||||
|
tObjectClose = new TokenDefinition("JSON.obj.close", new LexerPathSegment('}',true));
|
||||||
|
tArrayOpen = new TokenDefinition("JSON.array.open", new LexerPathSegment('[',true));
|
||||||
|
tArrayClose = new TokenDefinition("JSON.array.close", new LexerPathSegment(']',true));
|
||||||
|
tTrue = new TokenDefinition("JSON.true", true_t);
|
||||||
|
tFalse = new TokenDefinition("JSON.false", false_f);
|
||||||
|
tNull = new TokenDefinition("JSON.null", null_n);
|
||||||
|
tWhiteSpace = new TokenDefinition("JSON.WhiteSpace",ws);
|
||||||
|
|
||||||
|
tokenDefinitions = new TokenDefinition[]{
|
||||||
|
tWhiteSpace,
|
||||||
|
tNumber,
|
||||||
|
tString,
|
||||||
|
tColon,
|
||||||
|
tComma,
|
||||||
|
tObjectOpen,
|
||||||
|
tObjectClose,
|
||||||
|
tArrayOpen,
|
||||||
|
tArrayClose,
|
||||||
|
tTrue,
|
||||||
|
tFalse,
|
||||||
|
tNull
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static private LexerPathSegment initializeStringHead(){
|
||||||
|
LexerPathSegment head = new LexerPathSegment('\"');
|
||||||
|
LexerPathSegment finish = new LexerPathSegment('\"',true);
|
||||||
|
LexerPathSegment backslash = new LexerPathSegment('\\');
|
||||||
|
LexerPathSegment control = new LexerPathSegment(new char[] { '\"','\\','/','b','f','n','r','t'} );
|
||||||
|
LexerPathSegment u4 = new LexerPathSegment(CharGroup.hexdigits);
|
||||||
|
LexerPathSegment u3 = new LexerPathSegment(CharGroup.hexdigits,u4);
|
||||||
|
LexerPathSegment u2 = new LexerPathSegment(CharGroup.hexdigits,u3);
|
||||||
|
LexerPathSegment u1 = new LexerPathSegment(CharGroup.hexdigits,u2);
|
||||||
|
LexerPathSegment ucontrol = new LexerPathSegment('u',u1);
|
||||||
|
|
||||||
|
CharGroup anyChar = new CharGroup((char)0x20, (char)0xff) - backslash.CharGroup - finish.CharGroup;
|
||||||
|
LexerPathSegment any = new LexerPathSegment(anyChar);
|
||||||
|
|
||||||
|
head.AddFollower(finish);
|
||||||
|
head.AddFollower(any);
|
||||||
|
head.AddFollower(backslash);
|
||||||
|
|
||||||
|
any.AddFollower(any);
|
||||||
|
any.AddFollower(backslash);
|
||||||
|
any.AddFollower(finish);
|
||||||
|
|
||||||
|
backslash.AddFollower(control);
|
||||||
|
backslash.AddFollower(ucontrol);
|
||||||
|
|
||||||
|
control.AddFollower(any);
|
||||||
|
control.AddFollower(backslash);
|
||||||
|
control.AddFollower(finish);
|
||||||
|
|
||||||
|
u4.AddFollower(any);
|
||||||
|
u4.AddFollower(backslash);
|
||||||
|
u4.AddFollower(finish);
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
static private LexerPathSegment initializeNumberHead()
|
||||||
|
{
|
||||||
|
LexerPathSegment head = new LexerPathSegment();
|
||||||
|
LexerPathSegment minus = new LexerPathSegment(CharGroup.minus);
|
||||||
|
LexerPathSegment zero = new LexerPathSegment('0',true);
|
||||||
|
LexerPathSegment d19 = new LexerPathSegment('1', '9', true);
|
||||||
|
LexerPathSegment digit_a = new LexerPathSegment(CharGroup.digit,true);
|
||||||
|
LexerPathSegment digit_b = new LexerPathSegment(CharGroup.digit,true);
|
||||||
|
LexerPathSegment digit_c = new LexerPathSegment(CharGroup.digit,true);
|
||||||
|
LexerPathSegment dot = new LexerPathSegment('.');
|
||||||
|
LexerPathSegment ee = new LexerPathSegment(eE);
|
||||||
|
LexerPathSegment plusminus = new LexerPathSegment(CharGroup.plusminus);
|
||||||
|
|
||||||
|
head.AddFollower(minus);
|
||||||
|
head.AddFollower(zero);
|
||||||
|
head.AddFollower(d19);
|
||||||
|
|
||||||
|
minus.AddFollower(zero);
|
||||||
|
minus.AddFollower(d19);
|
||||||
|
|
||||||
|
zero.AddFollower(dot);
|
||||||
|
zero.AddFollower(ee);
|
||||||
|
|
||||||
|
d19.AddFollower(digit_a);
|
||||||
|
d19.AddFollower(dot);
|
||||||
|
d19.AddFollower(ee);
|
||||||
|
|
||||||
|
digit_a.AddFollower(digit_a);
|
||||||
|
digit_a.AddFollower(dot);
|
||||||
|
digit_a.AddFollower(ee);
|
||||||
|
|
||||||
|
dot.AddFollower(digit_b);
|
||||||
|
|
||||||
|
digit_b.AddFollower(digit_b);
|
||||||
|
digit_b.AddFollower(ee);
|
||||||
|
|
||||||
|
ee.AddFollower(digit_c);
|
||||||
|
ee.AddFollower(plusminus);
|
||||||
|
|
||||||
|
digit_c.AddFollower(digit_c);
|
||||||
|
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
using System;
|
||||||
|
namespace sharp.json
|
||||||
|
{
|
||||||
|
public static class JSONSerializer
|
||||||
|
{
|
||||||
|
|
||||||
|
public static void Apply(JSON json,Object o){
|
||||||
|
Type t = o.GetType();
|
||||||
|
|
||||||
|
if (t.IsPrimitive){
|
||||||
|
ApplyPrimitive(json,o);
|
||||||
|
} else {
|
||||||
|
ApplyClass(json, o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ApplyPrimitive(JSON json,Object o){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ApplyClass(JSON json,Object o){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
using System;
|
using System;
|
||||||
namespace sharp.json
|
namespace sharp.json
|
||||||
{
|
{
|
||||||
public class JSONSpecial: JSON
|
public class JSONSpecial: JSON
|
||||||
|
@ -12,12 +12,12 @@ namespace sharp.json
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool isTrue()
|
public override string[] prettyPrint()
|
||||||
{
|
{
|
||||||
return (JSONType == JSONTypes.True);
|
return new string[] { ToString() };
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string prettyPrint(int d = 0)
|
public override string ToString()
|
||||||
{
|
{
|
||||||
switch (JSONType){
|
switch (JSONType){
|
||||||
case JSONTypes.Null:
|
case JSONTypes.Null:
|
||||||
|
@ -30,9 +30,24 @@ namespace sharp.json
|
||||||
throw new NotImplementedException("JSON Special Type badly wrong....");
|
throw new NotImplementedException("JSON Special Type badly wrong....");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override bool Boolean
|
||||||
{
|
{
|
||||||
return prettyPrint();
|
get
|
||||||
|
{
|
||||||
|
return this == True;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override string String
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (this == Null){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return base.String;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using sharp.extensions;
|
||||||
|
|
||||||
namespace sharp.json
|
namespace sharp.json
|
||||||
{
|
{
|
||||||
|
@ -30,14 +31,30 @@ namespace sharp.json
|
||||||
this.value = value;
|
this.value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string prettyPrint(int d = 0)
|
public override string String
|
||||||
{
|
{
|
||||||
return string.Format("\"{0}\"",escape(value));
|
get { return this.value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override double Double
|
||||||
|
{
|
||||||
|
get { return Double.Parse(this.value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override long Integer
|
||||||
|
{
|
||||||
|
get { return long.Parse(this.value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override string[] prettyPrint()
|
||||||
|
{
|
||||||
|
return new string[] { ToString() };
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return prettyPrint();
|
return String.Format("\"{0}\"",escape(this.value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string escape(string source){
|
public static string escape(string source){
|
||||||
|
@ -46,7 +63,7 @@ namespace sharp.json
|
||||||
if ((ch >= 0x20) && (ch < 128)){
|
if ((ch >= 0x20) && (ch < 128)){
|
||||||
sb.Append(ch);
|
sb.Append(ch);
|
||||||
} else if (ch < 0x20){
|
} else if (ch < 0x20){
|
||||||
foreach (Tuple<char,char> repl in escapeCharacters){
|
foreach (System.Tuple<char,char> repl in escapeCharacters){
|
||||||
if (repl.Item2 == ch){
|
if (repl.Item2 == ch){
|
||||||
sb.Append("\\");
|
sb.Append("\\");
|
||||||
sb.Append(repl.Item1);
|
sb.Append(repl.Item1);
|
||||||
|
@ -62,5 +79,40 @@ namespace sharp.json
|
||||||
}
|
}
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string unescape(string source)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
CharEnumerator ce = source.GetEnumerator();
|
||||||
|
char[] hex = new char[4];
|
||||||
|
|
||||||
|
while (ce.MoveNext()){
|
||||||
|
|
||||||
|
if (ce.Current == '\\'){
|
||||||
|
ce.MoveNext();
|
||||||
|
|
||||||
|
foreach (System.Tuple<char, char> repl in escapeCharacters)
|
||||||
|
{
|
||||||
|
if (repl.Item1 == ce.Current)
|
||||||
|
{
|
||||||
|
sb.Append(repl.Item2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ce.Current == 'u'){
|
||||||
|
for (int n = 0; n < 4;n++){
|
||||||
|
ce.MoveNext();
|
||||||
|
hex[3 - n] = ce.Current;
|
||||||
|
}
|
||||||
|
sb.Append((char)( HexString.toBytes(hex).toUInt32()[0] ));
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
sb.Append(ce.Current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
using System;
|
||||||
|
using sharp.extensions;
|
||||||
|
using System.Net;
|
||||||
|
using sharp.webclient;
|
||||||
|
using System.IO;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace sharp.json
|
||||||
|
{
|
||||||
|
public class JSONWebRequest
|
||||||
|
{
|
||||||
|
private static JSONParser jsonParser = new JSONParser();
|
||||||
|
|
||||||
|
public static JSON Call(string url){
|
||||||
|
return Call(url, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JSON Call(string url, JSON request)
|
||||||
|
{
|
||||||
|
return Call(url, request, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static JSON Call(string url, JSON request, IDictionary<string,string> headers)
|
||||||
|
{
|
||||||
|
HttpRequest req = new HttpRequest(url);
|
||||||
|
if (request != null){
|
||||||
|
byte[] rbody = request.ToString().toBytes();
|
||||||
|
req.RequestStream.Write(rbody,0,rbody.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headers != null)
|
||||||
|
{
|
||||||
|
foreach (string hname in headers.Keys)
|
||||||
|
{
|
||||||
|
req.setHeader(hname, headers[hname]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpResponse response = req.Send();
|
||||||
|
return jsonParser.Parse(response.ContentText);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
using sharp.json;
|
using sharp.json;
|
||||||
|
using sharp.parser;
|
||||||
|
|
||||||
namespace json.test
|
namespace json.test
|
||||||
{
|
{
|
||||||
|
@ -17,19 +18,17 @@ namespace json.test
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
JSON json;
|
JSON json;
|
||||||
|
JSONParser jsonparser = new JSONParser();
|
||||||
|
|
||||||
Console.WriteLine("JSON test Patterns:");
|
Console.WriteLine("JSON test Patterns:");
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
|
|
||||||
foreach (string src in sources){
|
foreach (string src in sources){
|
||||||
json = JSON.parse(src);
|
json = jsonparser.Parse(src);
|
||||||
|
Console.WriteLine("NEW PARSER: {0}",json.ToString());
|
||||||
Console.WriteLine("SOURCE: {0}",src);
|
|
||||||
Console.WriteLine("PARSED: {0}",json.ToString());
|
|
||||||
Console.WriteLine("REPARSED: {0}",JSON.parse(json.ToString()).ToString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
json = JSON.parse(File.ReadAllText("test.json"));
|
json = jsonparser.Parse(File.ReadAllText("test.json"));
|
||||||
Console.WriteLine("");
|
Console.WriteLine("");
|
||||||
Console.WriteLine("test.json file:");
|
Console.WriteLine("test.json file:");
|
||||||
Console.WriteLine("PARSED: {0}",json.ToString());
|
Console.WriteLine("PARSED: {0}",json.ToString());
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<RootNamespace>json.test</RootNamespace>
|
<RootNamespace>json.test</RootNamespace>
|
||||||
<AssemblyName>json.test</AssemblyName>
|
<AssemblyName>json.test</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
@ -38,6 +38,10 @@
|
||||||
<Project>{D9342117-3249-4D8B-87C9-51A50676B158}</Project>
|
<Project>{D9342117-3249-4D8B-87C9-51A50676B158}</Project>
|
||||||
<Name>sharp.json</Name>
|
<Name>sharp.json</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\..\sharp-parser\sharp.parser.csproj">
|
||||||
|
<Project>{32267133-ADB7-4A85-8CF1-03CBDF53715C}</Project>
|
||||||
|
<Name>sharp.parser</Name>
|
||||||
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="test.json">
|
<None Include="test.json">
|
||||||
|
|
|
@ -39,12 +39,28 @@
|
||||||
<Compile Include="JSONString.cs" />
|
<Compile Include="JSONString.cs" />
|
||||||
<Compile Include="JSONTypes.cs" />
|
<Compile Include="JSONTypes.cs" />
|
||||||
<Compile Include="JSONNumber.cs" />
|
<Compile Include="JSONNumber.cs" />
|
||||||
|
<Compile Include="JSONWebRequest.cs" />
|
||||||
|
<Compile Include="JSONSerializer.cs" />
|
||||||
|
<Compile Include="JSONParser.cs" />
|
||||||
|
<Compile Include="JSONField.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\sharp-extensions\sharp.extensions.csproj">
|
<ProjectReference Include="..\sharp-extensions\sharp.extensions.csproj">
|
||||||
<Project>{97CA3CA9-98B3-4492-B072-D7A5995B68E9}</Project>
|
<Project>{97CA3CA9-98B3-4492-B072-D7A5995B68E9}</Project>
|
||||||
<Name>sharp.extensions</Name>
|
<Name>sharp.extensions</Name>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\sharp-webclient\sharp.webclient.csproj">
|
||||||
|
<Project>{01E98E3B-9462-4CF1-8421-4789763FBAA1}</Project>
|
||||||
|
<Name>sharp.webclient</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\sharp-parser\sharp.parser.csproj">
|
||||||
|
<Project>{32267133-ADB7-4A85-8CF1-03CBDF53715C}</Project>
|
||||||
|
<Name>sharp.parser</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
<ProjectReference Include="..\sharp-contracts\sharp.contracts.csproj">
|
||||||
|
<Project>{56733EC1-7D97-48D0-AA4C-98EA624A5A21}</Project>
|
||||||
|
<Name>sharp.contracts</Name>
|
||||||
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
<ProjectExtensions>
|
<ProjectExtensions>
|
||||||
|
|
Loading…
Reference in New Issue