V2 Implementation

master
Harald Wolff 2019-08-07 23:02:00 +02:00
parent 2431f10a8b
commit 8ded5ec2af
27 changed files with 528 additions and 1890 deletions

2
.gitignore vendored
View File

@ -1,2 +1,4 @@
obj
bin
ln.types
ln.logging

View File

@ -0,0 +1,26 @@
<Properties StartupConfiguration="{49FFBD9F-655E-4C74-A078-99B5E09059C6}|Default">
<MonoDevelop.Ide.Workbench>
<Pads>
<Pad Id="ProjectPad">
<State name="__root__">
<Node name="sharp.json" expanded="True">
<Node name="json.test" expanded="True" />
<Node name="ln.json" expanded="True">
<Node name="JSONParser.cs" selected="True" />
</Node>
<Node name="ln.types" expanded="True">
<Node name="stream" expanded="True" />
</Node>
</Node>
</State>
</Pad>
</Pads>
</MonoDevelop.Ide.Workbench>
<MonoDevelop.Ide.ItemProperties.json.test PreferredExecutionTarget="MonoDevelop.Default" />
<MonoDevelop.Ide.DebuggingService.PinnedWatches />
<MonoDevelop.Ide.Workspace ActiveConfiguration="Debug" />
<MonoDevelop.Ide.DebuggingService.Breakpoints>
<BreakpointStore />
</MonoDevelop.Ide.DebuggingService.Breakpoints>
<MultiItemStartupConfigurations />
</Properties>

View File

@ -1,288 +0,0 @@
using System;
using System.Text;
using System.Collections.Generic;
using sharp.extensions;
using System.Globalization;
namespace sharp.json
{
public class ByteParser
{
private static ASCIIEncoding encoding = new ASCIIEncoding();
static System.Tuple<char,char>[] escapeCharacters = {
System.Tuple.Create('\\','\\'),
System.Tuple.Create('/','/'),
System.Tuple.Create('"','"'),
System.Tuple.Create('b','\b'),
System.Tuple.Create('f','\f'),
System.Tuple.Create('n','\n'),
System.Tuple.Create('r','\r'),
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;
int position;
public ByteParser(string source)
{
this.buffer = source.ToCharArray();
this.position = 0;
}
public char Peek(){
//if (position >= buffer.Length){
// return 0;
//}
return buffer[position];
}
public string Peek(int len){
return new String(buffer.Segment(position,len).Extend(len));
}
public char Read(){
if (position < buffer.Length){
return buffer[position++];
}
throw new Exception("End of buffer reached. No more characters available!");
}
public char[] Read(int len){
if ((position) < buffer.Length){
char[] r = buffer.Segment(position, len).Extend(len);
position += r.Length;
return r;
}
throw new Exception("End of buffer reached. No more characters available!");
}
private Int64 parseInt64(){
Int64 t = 0;
char ch = Read();
bool neg = false;
if (ch == '-'){
neg = true;
ch = Read();
}
if (!ch.isDigit()){
throw new FormatException("JSON: Number format error");
}
while (true){
t *= 10;
t += (int)(ch - '0');
if (!Peek().isDigit()){
break;
}
ch = Read();
}
if (neg){
t *= -1;
}
return t;
}
public JSON parseNumber(){
List<char> digits = new List<char>();
do
{
char n = (char)Peek();
if (!numberScan.Contains(n)){
break;
}
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 {
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(){
if (Read() != '{'){
throw new FormatException("parser error: JSON Object should begin with '{'");
}
JSONObject o = new JSONObject();
scanWhitespace();
if (Peek() == '}'){
return o;
} else {
while (true){
string name = parseStringInternal();
scanWhitespace();
if (Read() != ':'){
throw new FormatException(String.Format("parser error: expected ':' but got '{0}'",buffer[position-1]));
}
scanWhitespace();
o[name] = parseValue();
scanWhitespace();
char n = Read();
if (n == '}'){
break;
}
if (n == ','){
scanWhitespace();
continue;
}
throw new FormatException("parser error: expected ',' or '}' but got '"+n+"'");
}
}
return o;
}
public JSON parseArray(){
if (Read() != '['){
throw new FormatException("parser error: JSON array should begin with '['");
}
JSONArray o = new JSONArray();
scanWhitespace();
if (Peek() == ']'){
return o;
} else {
while (true){
o.Add(parseValue());
scanWhitespace();
char n = Read();
if (n == ']'){
break;
}
if (n == ','){
scanWhitespace();
continue;
}
throw new FormatException(String.Format("parser error: expected ',' or ']' but got '{0}'",n));
}
}
return o;
}
private string parseStringInternal(){
StringBuilder sb = new StringBuilder();
if (Read() != '"'){
throw new FormatException(String.Format("JSON string must start with '\"' but got '{0}'",buffer[position-1]));
}
while (Peek() != '"'){
char ch = Read();
sb.Append(ch);
if (ch == '\\')
{
ch = Read();
sb.Append(ch);
}
}
Read();
return sb.ToString();
}
public JSON parseString(){
return new JSONString(parseStringInternal());
}
public JSON parseValue(){
scanWhitespace();
char peek = Peek();
switch (peek){
case '{':
return parseObject();
case '[':
return parseArray();
case '"':
return parseString();
}
if ((peek >= '0' && peek <= '9') || (peek == '-')){
return parseNumber();
}
String p = Peek(4).ToLower();
if (p.Equals("true")){
position+=4;
return JSONSpecial.True;
}
if (p.Equals("null")){
position+=4;
return JSONSpecial.Null;
}
p = Peek(5).ToLower();
if (p.Equals("false")){
position+=5;
return JSONSpecial.False;
}
throw new FormatException(String.Format("Could not parse source at character '{0}' at position {1}",Peek(),position));
}
public JSON parse(){
return parseValue();
}
private int findNext(char c){
int p = position;
while (p < buffer.Length){
if (buffer[p] == c){
return p - position;
}
}
return -1;
}
private int scanWhitespace(){
while (position < buffer.Length){
if (buffer[position] > 0x20){
return position;
}
position++;
}
return position;
}
}
}

View File

@ -1,45 +0,0 @@
using System;
using System.IO;
namespace sharp.json
{
public class FileBackedJSONValue<T>
{
public string FileName { get; set; }
public DateTime LoadedWriteTime { get; set; }
T current;
JSON jsource;
public FileBackedJSONValue(string filename)
{
FileName = filename;
}
public T CurrentValue {
get
{
if (!File.Exists(FileName)){
current = default(T);
} else if ((current == null) || (File.GetLastWriteTime(FileName) != LoadedWriteTime))
{
jsource = JSON.ReadFrom(FileName);
LoadedWriteTime = File.GetLastWriteTime(FileName);
current = jsource.To<T>();
}
return current;
}
set
{
current = value;
Save();
}
}
public void Save(){
JSONConverter.From(current).WriteTo(FileName,true);
LoadedWriteTime = File.GetLastWriteTime(FileName);
}
}
}

202
JSON.cs
View File

@ -1,202 +0,0 @@
using System;
using System.IO;
using System.Text;
using System.Collections.Generic;
using System.Net;
using System.Reflection;
using System.Collections;
using System.Security.Cryptography;
using System.CodeDom;
using System.Globalization;
namespace sharp.json
{
public delegate object JSONActivationDelegate(Type t);
public abstract class JSON : IEnumerable<JSON>
{
public virtual double Double { get { throw new NotImplementedException(); } }
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 virtual object Object { get { throw new NotImplementedException(); } }
public virtual JSON this[int 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)); }
}
public virtual JSON this[string name] {
get { throw new NotImplementedException(String.Format("{0} has no named elements", GetType().Name)); }
set { throw new NotImplementedException(String.Format("{0} has no named elements", GetType().Name)); }
}
public virtual int Count { get { return 0; } }
public virtual bool Contains(object o){
return false;
}
public virtual void Add(JSON child)
{
throw new NotImplementedException(String.Format("{0} has no numbered elements", GetType().Name));
}
public virtual void Remove(JSON child)
{
throw new NotImplementedException(String.Format("{0} has no numbered elements", GetType().Name));
}
public JSONTypes JSONType { get; private set; }
protected JSON(JSONTypes type){
JSONType = type;
}
public abstract string[] prettyPrint();
public override abstract string ToString();
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 static implicit operator string(JSON json)
{
return json.String;
}
public static implicit operator bool(JSON json)
{
return json.Boolean;
}
public static implicit operator int(JSON json)
{
return (int)json.Integer;
}
public static implicit operator long(JSON json)
{
return json.Integer;
}
public static implicit operator double(JSON json)
{
return json.Double;
}
public T To<T>()
{
return JSONConverter.To<T>(this);
}
public static JSON From(object o){
return JSONConverter.From(o);
}
public void WriteTo(Stream stream)
{
WriteTo(stream);
}
public void WriteTo(Stream stream,bool pretty){
byte[] data = Encoding.ASCII.GetBytes(pretty ? prettyFormat() : ToString() );
stream.Write(data,0,data.Length);
}
public void WriteTo(String filename)
{
WriteTo(filename, false);
}
public void WriteTo(String filename,bool pretty)
{
using (FileStream fs = new FileStream(filename, FileMode.Create))
{
WriteTo(fs, pretty);
fs.Close();
}
}
public static JSON ReadFrom(string filename)
{
return ReadFrom(filename, null);
}
public static JSON ReadFrom(string filename, object defaultValue)
{
JSONParser parser = new JSONParser();
string source = "";
try
{
source = File.ReadAllText(filename);
}
catch (FileNotFoundException e)
{
return JSON.From(defaultValue);
}
return parser.Parse(source);
}
public static JSON ReadFrom(string filename,JSON defaultValue){
JSONParser parser = new JSONParser();
string source = "";
try
{
source = File.ReadAllText(filename);
} catch (FileNotFoundException e){
return defaultValue;
}
if (source.Equals(""))
{
return defaultValue;
}
return parser.Parse(source);
}
public object Native(){
switch (JSONType)
{
case JSONTypes.Null:
return null;
case JSONTypes.True:
return true;
case JSONTypes.False:
return false;
case JSONTypes.Number:
return Double;
case JSONTypes.String:
return String;
}
throw new InvalidCastException(String.Format("Can't create native type of {0}",this.JSONType));
}
public virtual IEnumerator<JSON> GetEnumerator()
{
throw new NotImplementedException();
}
IEnumerator IEnumerable.GetEnumerator()
{
return (IEnumerator)GetEnumerator();
}
}
}

View File

@ -2,110 +2,56 @@ using System;
using System.Text;
using System.Collections.Generic;
namespace sharp.json
namespace ln.json
{
public class JSONArray : JSON
{
public JSONArray()
: base(JSONTypes.Array) { }
public class JSONArray : JSONValue
{
public override IEnumerable<JSONValue> Children => Values;
public override bool HasChildren => true;
public JSONArray(object[] init)
: base(JSONTypes.Array)
{
foreach (object o in init)
{
this.values.Add(JSONConverter.From(o));
}
}
JSONValue[] Values
{
get => values.ToArray();
set
{
values.Clear();
values.AddRange(value);
}
}
List<JSON> values = new List<JSON>();
List<JSONValue> values = new List<JSONValue>();
public override bool Boolean
{
get { return values.Count > 0; }
}
public JSONArray()
: base(JSONValueType.ARRAY) { }
public override JSON this[int n]
{
get
{
return values[n];
}
set
{
values[n] = value;
}
}
public override JSONValue this[int index] {
get => values[index];
set => values[index] = value;
}
public override int Count
{
get
{
return this.values.Count;
}
}
public JSONArray Add(JSONValue value){ values.Add(value); return this; }
public JSONArray Remove(int index) { values.RemoveAt(index); return this; }
public override bool Contains(object o)
{
return this.values.Contains((JSON)o);
}
public override string ToString()
{
public override void Add(JSON child)
{
this.values.Add(child);
}
StringBuilder sb = new StringBuilder();
sb.Append('[');
public override void Remove(JSON child)
{
this.values.Remove(child);
}
IEnumerator<JSONValue> kenum = values.GetEnumerator();
if (kenum.MoveNext())
do
{
sb.Append(kenum.Current.ToString());
public override string[] prettyPrint()
{
List<string> lines = new List<string>();
if (!kenum.MoveNext())
break;
sb.Append(',');
} while (true);
lines.Add("[");
sb.Append(']');
return sb.ToString();
}
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()
{
StringBuilder sb = new StringBuilder();
sb.Append("[");
for (int n = 0; n < this.Count; n++)
{
sb.Append(this[n].ToString());
if (n + 1 < this.Count)
{
sb.Append(",");
}
}
sb.Append("]");
return sb.ToString();
}
public override IEnumerator<JSON> GetEnumerator()
{
return this.values.GetEnumerator();
}
}
}
}

View File

@ -1,366 +0,0 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using sharp.json.attributes;
using System.Reflection;
using sharp.extensions;
namespace sharp.json
{
public static class JSONConverter
{
delegate object ConvertToDelegate(Type t,JSON json);
static Dictionary<Type, ConvertToDelegate> toDelegates = new Dictionary<Type, ConvertToDelegate>{
{ typeof(string), (t, json) => json.String },
{ typeof(int), (t, json) => (int)json.Integer },
{ typeof(short), (t, json) => (short)json.Integer },
{ typeof(long), (t, json) => json.Integer },
{ typeof(uint), (t, json) => (uint)json.Integer },
{ typeof(ushort), (t, json) => (ushort)json.Integer },
{ typeof(ulong), (t, json) => (ulong)json.Integer },
{ typeof(double), (t, json) => json.Double },
{ typeof(float), (t, json) => json.Double },
{ typeof(bool), (t, json) => json.Boolean },
{ typeof(DateTime), (t, json) => DateTime.Parse(json.String, CultureInfo.InvariantCulture) },
{ typeof(Guid), (t, json) => Guid.Parse(json.String)},
{ typeof(object), ToObject }
};
public static T To<T>(JSON json)
{
Type t = typeof(T);
return (T)(object)To(t, json);
}
public static JSON From(object value)
{
if (value == null)
{
return JSONSpecial.Null;
}
return From(value.GetType(), value);
}
public static object To(Type t,JSON json){
if (json.JSONType == JSONTypes.Null){
return null;
}
if (t.IsEnum){
return Enum.Parse(t, json.String);
}
if (toDelegates.ContainsKey(t))
{
return toDelegates[t](t, json);
}
if (t.IsArray){
return ToArray(t, json);
}
if (!t.IsPrimitive){
return ToObject(t, json);
}
throw new InvalidCastException(String.Format("JSON {0} can't be casted to {1}", json.JSONType.ToString(), t.Name));
}
public static void ApplyObject(JSON json, object o)
{
FieldPropertyInfo[] fpilist = fpi(o.GetType());
foreach (FieldPropertyInfo fpi in fpilist)
{
if (json.Contains(fpi.Key))
{
fpi.setValue(o, To(fpi.ValueType, json[fpi.Key]));
}
}
}
public static object ToObject(Type t,JSON json){
ConstructorInfo ci = t.GetConstructor(new Type[] { typeof(JSON) });
if (ci != null)
{
if (ci.GetParameters()[0].ParameterType.Equals(typeof(JSON)))
{
return Activator.CreateInstance(t, (object)json);
}
}
JSONClassPolicy cp = t.GetCustomAttribute<JSONClassPolicy>();
if (cp == null)
{
cp = new JSONClassPolicy();
}
return ToObject(t, json, cp.Policy);
}
private static object ToObject(Type t, JSON json,JSONPolicy policy)
{
object oi = Activator.CreateInstance(t);
ApplyObject(json,oi);
return oi;
}
private static object ToArray(Type t,JSON json)
{
Array a = Array.CreateInstance(t.GetElementType(), json.Count);
Type et = t.GetElementType();
JSONField jfield = t.GetCustomAttribute<JSONField>();
if (!jfield.IsNull())
{
et = jfield.ConstructWithType;
}
for (int n = 0; n < json.Count; n++)
{
a.SetValue(To(et ,json[n]), n);
}
return a;
}
public static JSON From(Type t, object value)
{
if (value == null)
{
return JSONSpecial.Null;
}
if (t == null)
{
t = value.GetType();
}
if ((t.IsPrimitive) || (t == typeof(string)))
{
return FromPrimitive(value);
}
if (t == typeof(DateTime))
{
return new JSONString(((DateTime)value).ToString(CultureInfo.InvariantCulture));
}
if (t == typeof(Guid))
{
return ((Guid)value).ToString();
}
if (t.IsEnum)
{
return new JSONString(value.ToString());
}
if (t.IsArray)
{
JSONArray ja = new JSONArray();
Array a = (Array)value;
Type et = t.GetElementType();
if (et == typeof(object))
{
et = null;
}
foreach (object e in a)
{
ja.Add(From(et, e));
}
return ja;
}
return FromObject(value);
}
public static JSON FromPrimitive(object value)
{
Type t = value.GetType();
if (typeof(int).Equals(t))
{
return new JSONNumber((int)value);
}
if (typeof(long).Equals(t))
{
return new JSONNumber((long)value);
}
if (typeof(double).Equals(t))
{
return new JSONNumber((double)value);
}
if (typeof(float).Equals(t))
{
return new JSONNumber((float)value);
}
if (typeof(string).Equals(t))
{
return new JSONString(value.ToString());
}
if (typeof(bool).Equals(t))
{
return ((bool)value) ? JSONSpecial.True : JSONSpecial.False;
}
throw new NotImplementedException(String.Format("Cast of {0} to JSON is not (yet) supported", t.Name));
}
public static JSON FromObject(object value)
{
return FromObject(value.GetType(), value);
}
public static JSON FromObject(Type type, object value)
{
Type t = value.GetType();
JSONObject jo = new JSONObject();
foreach (FieldPropertyInfo fpi in fpi(t)){
jo[fpi.Key] = JSON.From(fpi.getValue(value));
}
return jo;
}
private static FieldPropertyInfo[] fpi(Type t)
{
JSONClassPolicy cp = t.GetCustomAttribute<JSONClassPolicy>();
if (cp == null)
{
cp = new JSONClassPolicy();
}
return fpi(t, cp);
}
private static FieldPropertyInfo[] fpi(Type t,JSONClassPolicy cp)
{
BindingFlags bf;
switch (cp.Policy){
case JSONPolicy.ALL:
bf = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly;
break;
case JSONPolicy.ATTRIBUTED:
bf = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly;
break;
case JSONPolicy.NONPUBLIC:
bf = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly;
break;
default:
bf = BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly;
break;
}
List<FieldPropertyInfo> fpilist = new List<FieldPropertyInfo>();
foreach (FieldInfo fi in t.GetFields(bf))
{
fpilist.Add(new FieldPropertyInfo(fi));
}
foreach (PropertyInfo pi in t.GetProperties(bf))
{
if (pi.GetIndexParameters().Length == 0){
fpilist.Add(new FieldPropertyInfo(pi));
}
}
FieldPropertyInfo[] temp = fpilist.ToArray();
fpilist.Clear();
foreach (FieldPropertyInfo fpi in temp){
if ((cp.Policy != JSONPolicy.ATTRIBUTED) || (fpi.JSONField != null))
{
fpilist.Add(fpi);
}
}
if (!t.BaseType.IsNull()){
fpilist.AddRange(fpi(t.BaseType,cp));
}
return fpilist.ToArray();
}
struct FieldPropertyInfo
{
public String Key { get; set; }
FieldInfo FieldInfo { get; set; }
PropertyInfo PropertyInfo { get; set; }
public JSONField JSONField { get; set; }
public FieldPropertyInfo(PropertyInfo propertyInfo)
{
this.PropertyInfo = propertyInfo;
this.FieldInfo = null;
this.JSONField = propertyInfo.GetCustomAttribute<JSONField>();
this.Key = (this.JSONField == null) ? propertyInfo.Name : ((this.JSONField.Alias == null) ? propertyInfo.Name : this.JSONField.Alias);
}
public FieldPropertyInfo(FieldInfo fieldInfo)
{
this.PropertyInfo = null;
this.FieldInfo = fieldInfo;
this.JSONField = fieldInfo.GetCustomAttribute<JSONField>();
this.Key = (this.JSONField == null) ? fieldInfo.Name : ((this.JSONField.Alias == null) ? fieldInfo.Name : this.JSONField.Alias);
}
public void setValue(object inst, object value)
{
if (PropertyInfo != null)
{
if (PropertyInfo.SetMethod != null)
{
PropertyInfo.SetValue(inst, value);
}
}
else if (FieldInfo != null)
{
FieldInfo.SetValue(inst, value);
}
}
public object getValue(object inst)
{
if ((PropertyInfo != null)&&(!PropertyInfo.GetMethod.IsNull()))
{
return PropertyInfo.GetValue(inst);
}
else if (FieldInfo != null)
{
return FieldInfo.GetValue(inst);
}
return null;
}
public Type ValueType
{
get
{
if ((JSONField != null)&&(JSONField.ConstructWithType != null))
{
return JSONField.ConstructWithType;
}
if (PropertyInfo != null)
{
return PropertyInfo.PropertyType;
}
else if (FieldInfo != null)
{
return FieldInfo.FieldType;
}
return null;
}
}
}
}
}

View File

@ -1,94 +1,35 @@
using System;
using System.Globalization;
using System.Reflection;
namespace sharp.json
namespace ln.json
{
public class JSONNumber: JSON
{
Int64 intValue;
Double doubleValue;
public class JSONNumber : JSONValue
{
readonly decimal decValue;
public JSONNumber()
:base(JSONTypes.Number)
{
intValue = 0;
doubleValue = Double.NaN;
}
public JSONNumber(Int64 i)
:base(JSONTypes.Number)
{
intValue = i;
doubleValue = Double.NaN;
}
public JSONNumber(Double d)
:base(JSONTypes.Number)
{
intValue = (Int64)d;
doubleValue = d;
}
public JSONNumber(int i)
: this((long)i) { }
public override double Double
{
get
{
if (!Double.IsNaN(doubleValue)){
return doubleValue;
} else {
return (double)intValue;
}
}
}
public JSONNumber(long integer)
: base(JSONValueType.NUMBER)
{
decValue = new decimal(integer);
}
public override long Integer
{
get
{
if (!Double.IsNaN(doubleValue)){
return (int)doubleValue;
} else {
return intValue;
}
}
}
public JSONNumber(double doubleValue)
: base(JSONValueType.NUMBER)
{
decValue = new Decimal(doubleValue);
}
public JSONNumber(decimal decValue)
: base(JSONValueType.NUMBER)
{
this.decValue = decValue;
}
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()
{
if (Double.IsNaN(doubleValue))
{
return this.intValue.ToString();
}
else
{
return this.doubleValue.ToString(CultureInfo.InvariantCulture);
}
}
public bool IsInteger(){
return Double.IsNaN(doubleValue);
}
}
public override string ToString()
{
return decValue.ToString(CultureInfo.InvariantCulture);
}
}
}

View File

@ -1,86 +1,60 @@
using System;
using System.Text;
using System.Collections.Generic;
using sharp.extensions;
using System.Reflection;
using System.Linq;
using ln.types.btree;
using System.Security.Cryptography;
namespace sharp.json
namespace ln.json
{
public class JSONObject : JSON
public class JSONObject : JSONValue
{
public IEnumerable<string> Keys => values.Keys;
public override IEnumerable<JSONValue> Children => values.Values;
public override bool HasChildren => true;
BTree<string, JSONValue> values = new BTree<string, JSONValue>();
public JSONObject()
:base(JSONTypes.Object){}
:base(JSONValueType.OBJECT){}
private Dictionary<string, JSON> values = new Dictionary<string, JSON>();
public override JSONValue this[string property]
{
get => values[property];
set => values[property] = value;
}
public override JSON this[string name]
{
get { return this.values[name]; }
set { this.values[name] = value; }
}
public JSONObject Add(string propertyName,JSONValue value)
{
values[propertyName] = value;
return this;
}
public override int Count
{
get { return this.values.Count; }
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append('{');
public override bool Boolean
{
get { return this.values.Count > 0; }
}
IEnumerator<string> kenum = values.Keys.GetEnumerator();
if (kenum.MoveNext())
do
{
sb.Append('"');
sb.Append(kenum.Current);
sb.Append('"');
sb.Append(':');
sb.Append(values[kenum.Current].ToString());
public override bool Contains(object o)
{
return this.values.ContainsKey((string)o);
}
if (!kenum.MoveNext())
break;
sb.Append(',');
} while (true);
sb.Append('}');
return sb.ToString();
}
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++)
{
string[] clines = this[keys[n]].prettyPrint();
lines.Add(String.Format(" {0} : {1}",new JSONString(keys[n]),clines[0]));
foreach (string cline in clines.Segment(1)){
lines.Add(String.Format(" {0}",cline));
}
if (n < keys.Length-1){
lines[lines.Count - 1] += ",";
}
}
lines.Add("}");
return lines.ToArray();
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append("{");
string[] keys = this.values.Keys.ToArray();
for (int n=0;n<keys.Length;n++)
{
sb.Append(new JSONString(keys[n]).ToString());
sb.Append(":");
sb.Append(this[keys[n]].ToString());
if (n+1 < keys.Length){
sb.Append(",");
}
}
sb.Append("}");
return sb.ToString();
}
}
}
}

View File

@ -1,321 +1,236 @@
using System;
using sharp.parser;
using Microsoft.Win32.SafeHandles;
using System.Globalization;
using System.Net.Mime;
// /**
// * File: JSONParser.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using System;
using System.Collections.Generic;
namespace sharp.json
using ln.types;
using ln.types.stream;
using System.Text;
using System.Globalization;
namespace ln.json
{
public class JSONParser : Parser<JSON>
{
delegate JSON ParseObjectDelegate(TokenQueue tokens);
public class JSONParser
{
static char[] chNull = new char[] { 'n', 'u', 'l', 'l' };
static char[] chTrue = new char[] { 't', 'r', 'u', 'e' };
static char[] chFalse = new char[] { 'f', 'a', 'l', 's', 'e' };
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());
}
public static JSONValue Parse(String jsonSource)
{
CharStream chars = new CharStream(jsonSource);
return ParseValue(chars);
}
/**
* Für alle Parser Methoden welche als Parameter ein CharStream erhalten
* gilt folgendes:
*
* - CharStream.Current zeitg auf das erste Zeichen,
* welches interpretiert werden soll
* - Bei Rücksprung zeigt CharStream.Current auf das erste zeichen,
* welches nicht mehr zum aktuellen Wert gehört und kein Whitespace
* ist
*
**/
static bool initializer = initialize();
static JSONValue ParseValue(CharStream chars)
{
chars.Skip(char.IsWhiteSpace);
switch (chars.Current)
{
case '"':
return parseString(chars);
case 't':
return parseTrue(chars);
case 'f':
return parseFalse(chars);
case 'n':
return parseNull(chars);
case '[':
return parseArray(chars);
case '{':
return parseObject(chars);
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '-':
return parseNumber(chars);
default:
throw new FormatException(String.Format("Unexpected character: {0} [ 0x{0:x4} ]", chars.Current));
}
}
static TokenDefinition[] tokenDefinitions;
static JSONString parseString(CharStream chars)
{
if (chars.Current != '"')
throw new FormatException("Unexpected character");
static CharGroup eE = new CharGroup(new char[] { 'e', 'E' } );
StringBuilder stringBuilder = new StringBuilder();
static LexerPathSegment null_ll;
static LexerPathSegment null_l;
static LexerPathSegment null_u;
static LexerPathSegment null_n;
chars.MoveNext();
while (chars.Current != '"')
{
stringBuilder.Append(chars.Current);
if (chars.Current == '\\')
{
chars.MoveNext();
stringBuilder.Append(chars.Current);
}
chars.MoveNext();
}
static LexerPathSegment true_e;
static LexerPathSegment true_u;
static LexerPathSegment true_r;
static LexerPathSegment true_t;
chars.TryNext();
chars.Skip(char.IsWhiteSpace);
static LexerPathSegment false_e;
static LexerPathSegment false_s;
static LexerPathSegment false_l;
static LexerPathSegment false_a;
static LexerPathSegment false_f;
return new JSONString(JSONString.Unescape(stringBuilder.ToString()));
}
static JSONNumber parseNumber(CharStream chars)
{
StringBuilder sb = new StringBuilder();
static LexerPathSegment ws;
if (chars.Current == '-')
{
sb.Append(chars.Current);
chars.MoveNext();
}
sb.Append(chars.Read(char.IsDigit));
if (chars.Current == '.')
{
sb.Append('.');
chars.MoveNext();
sb.Append(chars.Read(char.IsDigit));
}
if ((chars.Current == 'e')|| (chars.Current == 'E'))
{
sb.Append('e');
if ((chars.Current == '-')|| (chars.Current == '+'))
{
sb.Append(chars.Current);
chars.MoveNext();
}
sb.Append(chars.Read(char.IsDigit));
}
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;
chars.Skip(char.IsWhiteSpace);
return new JSONNumber(decimal.Parse(sb.ToString(),CultureInfo.InvariantCulture));
}
static JSONArray parseArray(CharStream chars)
{
if (chars.Current != '[')
throw new FormatException("Unexpected character");
static private bool initialize(){
eE = new CharGroup(new char[] { 'e', 'E' });
JSONArray array = new JSONArray();
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);
chars.MoveNext();
while (chars.Current != ']')
{
array.Add(ParseValue(chars));
if (chars.Current == ',')
{
chars.MoveNext();
chars.Skip(char.IsWhiteSpace);
}
}
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);
chars.TryNext();
chars.Skip(char.IsWhiteSpace);
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);
return array;
}
static JSONObject parseObject(CharStream chars)
{
if (chars.Current != '{')
throw new FormatException("Unexpected character");
ws = new LexerPathSegment(CharGroup.WS, true);
ws.AddFollower(ws);
JSONObject o = new JSONObject();
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);
chars.MoveNext();
chars.Skip(char.IsWhiteSpace);
tokenDefinitions = new TokenDefinition[]{
tWhiteSpace,
tNumber,
tString,
tColon,
tComma,
tObjectOpen,
tObjectClose,
tArrayOpen,
tArrayClose,
tTrue,
tFalse,
tNull
};
while (chars.Current != '}')
{
JSONString s = parseString(chars);
if (chars.Current != ':')
throw new FormatException("expected :");
chars.MoveNext();
o.Add(s.Value, ParseValue(chars));
if (chars.Current == ',')
{
chars.MoveNext();
chars.Skip(char.IsWhiteSpace);
}
}
chars.TryNext();
chars.Skip(char.IsWhiteSpace);
return o;
}
static JSONTrue parseTrue(CharStream chars)
{
char[] ch = new char[4];
for (int n = 0; n < ch.Length; n++)
{
ch[n] = chars.Current;
chars.MoveNext();
}
if (ch.AreEqual(chTrue))
{
chars.Skip(char.IsWhiteSpace);
return JSONTrue.Instance;
}
throw new FormatException();
}
static JSONFalse parseFalse(CharStream chars)
{
char[] ch = new char[5];
for (int n = 0; n < ch.Length; n++)
{
ch[n] = chars.Current;
chars.MoveNext();
}
if (ch.AreEqual(chFalse))
{
chars.Skip(char.IsWhiteSpace);
return JSONFalse.Instance;
}
return true;
}
throw new FormatException();
}
static JSONNull parseNull(CharStream chars)
{
char[] ch = new char[4];
for (int n=0;n<ch.Length;n++)
{
ch[n] = chars.Current;
chars.MoveNext();
}
if (ch.AreEqual(chNull))
{
chars.Skip(char.IsWhiteSpace);
return JSONNull.Instance;
}
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 eminus = new LexerPathSegment(CharGroup.minus);
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);
plusminus.AddFollower(digit_c);
digit_c.AddFollower(digit_c);
return head;
}
}
throw new FormatException();
}
}
}

View File

@ -1,28 +0,0 @@
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){
}
}
}

View File

@ -1,53 +1,23 @@
using System;
namespace sharp.json
namespace ln.json
{
public class JSONSpecial: JSON
{
public static readonly JSON True = new JSONSpecial(JSONTypes.True);
public static readonly JSON False = new JSONSpecial(JSONTypes.False);
public static readonly JSON Null = new JSONSpecial(JSONTypes.Null);
public class JSONTrue : JSONValue
{
public static JSONTrue Instance { get; } = new JSONTrue();
private JSONTrue() : base(JSONValueType.TRUE) { }
public override string ToString() => "true";
}
public class JSONFalse : JSONValue
{
public static JSONFalse Instance { get; } = new JSONFalse();
private JSONFalse() : base(JSONValueType.FALSE) { }
public override string ToString() => "false";
}
public class JSONNull : JSONValue
{
public static JSONNull Instance { get; } = new JSONNull();
private JSONNull() : base(JSONValueType.NULL) { }
public override string ToString() => "null";
}
private JSONSpecial(JSONTypes type)
:base(type)
{
}
public override string[] prettyPrint()
{
return new string[] { ToString() };
}
public override string ToString()
{
switch (JSONType){
case JSONTypes.Null:
return "null";
case JSONTypes.True:
return "true";
case JSONTypes.False:
return "false";
}
throw new NotImplementedException("JSON Special Type badly wrong....");
}
public override bool Boolean
{
get
{
return this == True;
}
}
public override string String
{
get
{
if (this == Null){
return null;
}
return base.String;
}
}
}
}

View File

@ -1,10 +1,9 @@
using System;
using System.Text;
using sharp.extensions;
namespace sharp.json
namespace ln.json
{
public class JSONString : JSON
public class JSONString : JSONValue
{
static System.Tuple<char,char>[] escapeCharacters = {
System.Tuple.Create('\\','\\'),
@ -17,73 +16,45 @@ namespace sharp.json
System.Tuple.Create('t','\t'),
};
string value;
public string Value { get; private set; }
public JSONString()
:base(JSONTypes.String)
public JSONString(String value)
:base(JSONValueType.STRING)
{
this.value = "";
Value = value;
}
public JSONString(String value)
:base(JSONTypes.String)
{
this.value = value;
}
public override string ToString()
{
return String.Format("\"{0}\"", Escape(Value));
}
public override string String
{
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()
{
return String.Format("\"{0}\"",escape(this.value));
}
public static string escape(string source){
public static string Escape(string source){
StringBuilder sb = new StringBuilder();
foreach (char ch in source){
if ((ch >= 0x20) && (ch < 128)){
sb.Append(ch);
} else if (ch < 0x20){
foreach (System.Tuple<char,char> repl in escapeCharacters){
if (repl.Item2 == ch){
sb.Append("\\");
sb.Append(repl.Item1);
break;
}
}
} else {
int iv = (int)ch;
sb.Append("\\u");
sb.Append("____");
Console.WriteLine("JSON WARNING: UNICODE ESCAPE SEQUENCES ARE NOT IMPLEMENTED YET");
}
if ((ch >= 0x20) && (ch < 128)) {
sb.Append(ch);
} else if (ch < 0x20) {
foreach (System.Tuple<char, char> repl in escapeCharacters) {
if (repl.Item2 == ch) {
sb.Append("\\");
sb.Append(repl.Item1);
break;
}
}
} else {
byte[] bytes = BitConverter.GetBytes((int)ch);
sb.Append("\\u");
sb.AppendFormat("{0:x2}{1:x2}", bytes[1], bytes[0]);
}
}
return sb.ToString();
}
public static string unescape(string source)
public static string Unescape(string jsonString)
{
StringBuilder sb = new StringBuilder();
CharEnumerator ce = source.GetEnumerator();
CharEnumerator ce = jsonString.GetEnumerator();
char[] hex = new char[4];
while (ce.MoveNext()){
@ -91,23 +62,26 @@ namespace sharp.json
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] ));
}
if (ce.Current == 'u')
{
for (int n = 0; n < 4; n++)
{
ce.MoveNext();
hex[3 - n] = ce.Current;
}
sb.Append((char)Convert.ToInt16(new String(hex),16));
}
else
{
foreach (System.Tuple<char, char> repl in escapeCharacters)
{
if (repl.Item1 == ce.Current)
{
sb.Append(repl.Item2);
break;
}
}
}
} else {
sb.Append(ce.Current);
}

View File

@ -1,5 +1,5 @@
using System;
namespace sharp.json
namespace ln.json
{
public enum JSONTypes
{

43
JSONValue.cs 100644
View File

@ -0,0 +1,43 @@
// /**
// * File: JSONValue.cs
// * Author: haraldwolff
// *
// * This file and it's content is copyrighted by the Author and / or copyright holder.
// * Any use wihtout proper permission is illegal and may lead to legal actions.
// *
// *
// **/
using System;
using System.Collections.Generic;
namespace ln.json
{
public enum JSONValueType
{
NULL, OBJECT, ARRAY, STRING, NUMBER, TRUE, FALSE
}
public abstract class JSONValue
{
public JSONValueType ValueType { get; private set; }
public virtual bool HasChildren => false;
public virtual IEnumerable<JSONValue> Children => throw new NotSupportedException();
public JSONValue(JSONValueType valueType)
{
ValueType = valueType;
}
public virtual JSONValue this[string property]
{
get => throw new NotSupportedException();
set => throw new NotSupportedException();
}
public virtual JSONValue this[int index]
{
get => throw new NotSupportedException();
set => throw new NotSupportedException();
}
public override string ToString() => throw new NotImplementedException();
}
}

View File

@ -1,54 +0,0 @@
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();
try {
return jsonParser.Parse(response.ContentText);
} catch (Exception e){
Console.WriteLine("JSONWebRequest could not parse response.");
Console.WriteLine("Response was:");
Console.WriteLine(">-------------------------------------------");
Console.WriteLine(response.ContentText);
Console.WriteLine("<-------------------------------------------");
throw e;
}
}
}
}

View File

@ -4,7 +4,7 @@ using System.Runtime.CompilerServices;
// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.
[assembly: AssemblyTitle("sharp.json")]
[assembly: AssemblyTitle("ln.json")]
[assembly: AssemblyDescription("JSON Implementation")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]

View File

@ -1,11 +1,11 @@
# sharp-json
# sharp-json
A lightweight JSON implementation for Mono/.NET
## Usage
Use the base type *sharp.json.JSON* to represent JSON variables.
Use the base type *ln.json.JSON* to represent JSON variables.
import sharp.json;
import ln.json;
...
JSON n = 123.45;
JSON s = "Hello World!"

View File

@ -1,10 +0,0 @@
using System;
namespace sharp.json.attributes
{
public enum JSONPolicy { ALL, PUBLIC, NONPUBLIC, ATTRIBUTED }
public class JSONClassPolicy : Attribute
{
public JSONPolicy Policy { get; set; } = JSONPolicy.PUBLIC;
}
}

View File

@ -1,11 +0,0 @@
using System;
namespace sharp.json.attributes
{
public class JSONField : Attribute
{
public string Alias { get; set; }
public bool ConstructWithOwner { get; set; }
public Type ConstructWithType { get; set; }
}
}

View File

@ -1,8 +1,7 @@
using System;
using System.IO;
using sharp.json;
using sharp.parser;
using ln.json;
namespace json.test
{
@ -12,32 +11,32 @@ namespace json.test
"\"I am a string\"",
"{ \"me\" : \"is a string too\"}",
"[ \"this\", \"is\", \"an\", \"array\" ]"
};
public static void Main(string[] args)
{
JSONObject json = new JSONObject()
.Add("version", new JSONNumber(123.456))
.Add("text", new JSONString("Ich bin ein Text! Lächerlich, oder?"))
.Add("Obst",new JSONArray()
.Add(new JSONString("Apfel"))
.Add(new JSONString("Birne"))
.Add(new JSONString("Zwetschge"))
.Add(JSONNull.Instance)
.Add(JSONTrue.Instance)
.Add(JSONFalse.Instance)
)
;
JSON json;
JSONParser jsonparser = new JSONParser();
Console.WriteLine(json.ToString());
json = jsonparser.Parse("4.9125E-05");
Console.WriteLine(json.ToString());
JSONValue json2 = JSONParser.Parse(json.ToString());
Console.WriteLine(json2.ToString());
//Console.WriteLine("JSON test Patterns:");
//Console.WriteLine();
//foreach (string src in sources){
// json = jsonparser.Parse(src);
// Console.WriteLine("NEW PARSER: {0}",json.ToString());
//}
//json = jsonparser.Parse(File.ReadAllText("test.json"));
//Console.WriteLine("");
//Console.WriteLine("test.json file:");
//Console.WriteLine("PARSED: {0}",json.ToString());
}
JSONValue value = JSONParser.Parse(File.ReadAllText("test.json"));
Console.WriteLine("");
Console.WriteLine("test.json file:");
Console.WriteLine("PARSED: {0}",value.ToString());
}
}
}

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -34,13 +34,9 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\sharp.json.csproj">
<ProjectReference Include="..\ln.json.csproj">
<Project>{D9342117-3249-4D8B-87C9-51A50676B158}</Project>
<Name>sharp.json</Name>
</ProjectReference>
<ProjectReference Include="..\..\sharp-parser\sharp.parser.csproj">
<Project>{32267133-ADB7-4A85-8CF1-03CBDF53715C}</Project>
<Name>sharp.parser</Name>
<Name>ln.json</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>

View File

@ -1,12 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{D9342117-3249-4D8B-87C9-51A50676B158}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>sharp.json</RootNamespace>
<AssemblyName>sharp.json</AssemblyName>
<RootNamespace>ln.json</RootNamespace>
<AssemblyName>ln.json</AssemblyName>
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
@ -31,54 +31,26 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="JSON.cs" />
<Compile Include="ByteParser.cs" />
<Compile Include="JSONSpecial.cs" />
<Compile Include="JSONObject.cs" />
<Compile Include="JSONArray.cs" />
<Compile Include="JSONString.cs" />
<Compile Include="JSONTypes.cs" />
<Compile Include="JSONNumber.cs" />
<Compile Include="JSONWebRequest.cs" />
<Compile Include="JSONSerializer.cs" />
<Compile Include="JSONValue.cs" />
<Compile Include="JSONParser.cs" />
<Compile Include="FileBackedJSONValue.cs" />
<Compile Include="network\JSONTcpServer.cs" />
<Compile Include="network\JSONTcpClient.cs" />
<Compile Include="attributes\JSONClassPolicy.cs" />
<Compile Include="attributes\JSONField.cs" />
<Compile Include="JSONConverter.cs" />
<Compile Include="simple\KeyValue.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\sharp-extensions\sharp.extensions.csproj">
<Project>{97CA3CA9-98B3-4492-B072-D7A5995B68E9}</Project>
<Name>sharp.extensions</Name>
<ProjectReference Include="ln.types\ln.types.csproj">
<Project>{8D9AB9A5-E513-4BA7-A450-534F6456BF28}</Project>
<Name>ln.types</Name>
</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>
<Folder Include="network\" />
<Folder Include="attributes\" />
<Folder Include="simple\" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
<MonoDevelop>
<Properties>
<Policies>
<DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="FileFormatDefault" />
<DotNetNamingPolicy ResourceNamePolicy="FileFormatDefault" DirectoryNamespaceAssociation="PrefixedHierarchical" />
</Policies>
</Properties>
</MonoDevelop>

View File

@ -1,57 +0,0 @@
using System;
using System.Net.Sockets;
using System.Net;
using System.IO;
namespace sharp.json.network
{
public class JSONTcpClient
{
TcpClient client;
StreamReader reader;
StreamWriter writer;
JSONParser parser = new JSONParser();
public JSONTcpClient(int port)
{
this.client = new TcpClient();
this.client.Connect("127.0.0.1",port);
this.initialize();
}
public JSONTcpClient(TcpClient client)
{
this.client = client;
initialize();
}
private void initialize(){
this.reader = new StreamReader(client.GetStream());
this.writer = new StreamWriter(client.GetStream());
}
public JSON Receive()
{
string line = reader.ReadLine();
JSON json = parser.Parse(line);
return json;
}
public void Send(JSON json){
writer.WriteLine(json.ToString());
writer.Flush();
}
public void Close(){
this.client.Close();
}
public TcpClient TcpClient
{
get { return this.client; }
}
}
}

View File

@ -1,74 +0,0 @@
using System;
using System.Net.Sockets;
using System.Net;
using System.Threading;
namespace sharp.json.network
{
public delegate void JSONClientConnected(JSONTcpClient jsonClient);
public class JSONTcpServer
{
public JSONClientConnected ClientConnected { get; set; }
TcpListener listener;
Thread serverThread;
bool shouldExit;
public JSONTcpServer(int port)
{
this.listener = new TcpListener(IPAddress.Loopback, port);
}
public void Start()
{
lock (this){
if (serverThread == null){
serverThread = new Thread(Serve);
serverThread.Start();
}
}
}
public void Stop()
{
lock (this){
shouldExit = true;
this.listener.Stop();
Monitor.Wait(this);
this.serverThread = null;
}
}
public void Serve()
{
this.listener.Start();
while (true){
lock (this){
if (shouldExit){
shouldExit = false;
Monitor.Pulse(this);
break;
}
}
try {
TcpClient client = this.listener.AcceptTcpClient();
ThreadPool.QueueUserWorkItem((state) => fireClientConnected(client));
} catch (SocketException se){
}
}
}
private void fireClientConnected(TcpClient client){
if (ClientConnected != null){
JSONTcpClient jsonCLient = new JSONTcpClient(client);
ClientConnected.Invoke(jsonCLient);
}
}
}
}

35
sharp.json.sln 100644
View File

@ -0,0 +1,35 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.json", "ln.json.csproj", "{D9342117-3249-4D8B-87C9-51A50676B158}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "json.test", "json.test\json.test.csproj", "{49FFBD9F-655E-4C74-A078-99B5E09059C6}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.types", "ln.types\ln.types.csproj", "{8D9AB9A5-E513-4BA7-A450-534F6456BF28}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ln.logging", "ln.logging\ln.logging.csproj", "{D471A566-9FB6-41B2-A777-3C32874ECD0E}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D9342117-3249-4D8B-87C9-51A50676B158}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D9342117-3249-4D8B-87C9-51A50676B158}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D9342117-3249-4D8B-87C9-51A50676B158}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D9342117-3249-4D8B-87C9-51A50676B158}.Release|Any CPU.Build.0 = Release|Any CPU
{49FFBD9F-655E-4C74-A078-99B5E09059C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{49FFBD9F-655E-4C74-A078-99B5E09059C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{49FFBD9F-655E-4C74-A078-99B5E09059C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{49FFBD9F-655E-4C74-A078-99B5E09059C6}.Release|Any CPU.Build.0 = Release|Any CPU
{8D9AB9A5-E513-4BA7-A450-534F6456BF28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8D9AB9A5-E513-4BA7-A450-534F6456BF28}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8D9AB9A5-E513-4BA7-A450-534F6456BF28}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8D9AB9A5-E513-4BA7-A450-534F6456BF28}.Release|Any CPU.Build.0 = Release|Any CPU
{D471A566-9FB6-41B2-A777-3C32874ECD0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D471A566-9FB6-41B2-A777-3C32874ECD0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D471A566-9FB6-41B2-A777-3C32874ECD0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D471A566-9FB6-41B2-A777-3C32874ECD0E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal

View File

@ -1,20 +0,0 @@
using System;
namespace sharp.json.simple
{
public class KeyValue
{
public String Key;
public String Value;
private KeyValue()
{
}
public KeyValue(string key,string value = "")
{
Key = key;
Value = value;
}
}
}