forked from ln-dotnet/ln.json
V2 Implementation
parent
2431f10a8b
commit
8ded5ec2af
|
@ -1,2 +1,4 @@
|
||||||
obj
|
obj
|
||||||
bin
|
bin
|
||||||
|
ln.types
|
||||||
|
ln.logging
|
|
@ -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>
|
288
ByteParser.cs
288
ByteParser.cs
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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
202
JSON.cs
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
134
JSONArray.cs
134
JSONArray.cs
|
@ -2,110 +2,56 @@ using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace sharp.json
|
namespace ln.json
|
||||||
{
|
{
|
||||||
public class JSONArray : JSON
|
public class JSONArray : JSONValue
|
||||||
{
|
{
|
||||||
public JSONArray()
|
public override IEnumerable<JSONValue> Children => Values;
|
||||||
: base(JSONTypes.Array) { }
|
public override bool HasChildren => true;
|
||||||
|
|
||||||
public JSONArray(object[] init)
|
JSONValue[] Values
|
||||||
: base(JSONTypes.Array)
|
{
|
||||||
{
|
get => values.ToArray();
|
||||||
foreach (object o in init)
|
set
|
||||||
{
|
{
|
||||||
this.values.Add(JSONConverter.From(o));
|
values.Clear();
|
||||||
}
|
values.AddRange(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
List<JSONValue> values = new List<JSONValue>();
|
||||||
|
|
||||||
List<JSON> values = new List<JSON>();
|
public JSONArray()
|
||||||
|
: base(JSONValueType.ARRAY) { }
|
||||||
|
|
||||||
public override bool Boolean
|
public override JSONValue this[int index] {
|
||||||
{
|
get => values[index];
|
||||||
get { return values.Count > 0; }
|
set => values[index] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override JSON this[int n]
|
public JSONArray Add(JSONValue value){ values.Add(value); return this; }
|
||||||
{
|
public JSONArray Remove(int index) { values.RemoveAt(index); return this; }
|
||||||
get
|
|
||||||
{
|
|
||||||
return values[n];
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
values[n] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override int Count
|
public override string ToString()
|
||||||
{
|
{
|
||||||
get
|
|
||||||
{
|
|
||||||
return this.values.Count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Contains(object o)
|
StringBuilder sb = new StringBuilder();
|
||||||
{
|
sb.Append('[');
|
||||||
return this.values.Contains((JSON)o);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Add(JSON child)
|
IEnumerator<JSONValue> kenum = values.GetEnumerator();
|
||||||
{
|
if (kenum.MoveNext())
|
||||||
this.values.Add(child);
|
do
|
||||||
}
|
{
|
||||||
|
sb.Append(kenum.Current.ToString());
|
||||||
|
|
||||||
public override void Remove(JSON child)
|
if (!kenum.MoveNext())
|
||||||
{
|
break;
|
||||||
this.values.Remove(child);
|
sb.Append(',');
|
||||||
}
|
} while (true);
|
||||||
|
|
||||||
public override string[] prettyPrint()
|
sb.Append(']');
|
||||||
{
|
return sb.ToString();
|
||||||
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()
|
|
||||||
{
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
366
JSONConverter.cs
366
JSONConverter.cs
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
111
JSONNumber.cs
111
JSONNumber.cs
|
@ -1,94 +1,35 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
namespace sharp.json
|
namespace ln.json
|
||||||
{
|
{
|
||||||
public class JSONNumber: JSON
|
public class JSONNumber : JSONValue
|
||||||
{
|
{
|
||||||
Int64 intValue;
|
readonly decimal decValue;
|
||||||
Double doubleValue;
|
|
||||||
|
|
||||||
public JSONNumber()
|
public JSONNumber(int i)
|
||||||
:base(JSONTypes.Number)
|
: this((long)i) { }
|
||||||
{
|
|
||||||
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 override double Double
|
public JSONNumber(long integer)
|
||||||
{
|
: base(JSONValueType.NUMBER)
|
||||||
get
|
{
|
||||||
{
|
decValue = new decimal(integer);
|
||||||
if (!Double.IsNaN(doubleValue)){
|
}
|
||||||
return doubleValue;
|
|
||||||
} else {
|
|
||||||
return (double)intValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override long Integer
|
public JSONNumber(double doubleValue)
|
||||||
{
|
: base(JSONValueType.NUMBER)
|
||||||
get
|
{
|
||||||
{
|
decValue = new Decimal(doubleValue);
|
||||||
if (!Double.IsNaN(doubleValue)){
|
}
|
||||||
return (int)doubleValue;
|
public JSONNumber(decimal decValue)
|
||||||
} else {
|
: base(JSONValueType.NUMBER)
|
||||||
return intValue;
|
{
|
||||||
}
|
this.decValue = decValue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public override string String
|
public override string ToString()
|
||||||
{
|
{
|
||||||
get
|
return decValue.ToString(CultureInfo.InvariantCulture);
|
||||||
{
|
}
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
112
JSONObject.cs
112
JSONObject.cs
|
@ -1,86 +1,60 @@
|
||||||
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.Reflection;
|
||||||
using System.Linq;
|
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()
|
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]
|
public JSONObject Add(string propertyName,JSONValue value)
|
||||||
{
|
{
|
||||||
get { return this.values[name]; }
|
values[propertyName] = value;
|
||||||
set { this.values[name] = value; }
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Count
|
public override string ToString()
|
||||||
{
|
{
|
||||||
get { return this.values.Count; }
|
StringBuilder sb = new StringBuilder();
|
||||||
}
|
sb.Append('{');
|
||||||
|
|
||||||
public override bool Boolean
|
IEnumerator<string> kenum = values.Keys.GetEnumerator();
|
||||||
{
|
if (kenum.MoveNext())
|
||||||
get { return this.values.Count > 0; }
|
do
|
||||||
}
|
{
|
||||||
|
sb.Append('"');
|
||||||
|
sb.Append(kenum.Current);
|
||||||
|
sb.Append('"');
|
||||||
|
sb.Append(':');
|
||||||
|
sb.Append(values[kenum.Current].ToString());
|
||||||
|
|
||||||
public override bool Contains(object o)
|
if (!kenum.MoveNext())
|
||||||
{
|
break;
|
||||||
return this.values.ContainsKey((string)o);
|
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
503
JSONParser.cs
503
JSONParser.cs
|
@ -1,321 +1,236 @@
|
||||||
using System;
|
// /**
|
||||||
using sharp.parser;
|
// * File: JSONParser.cs
|
||||||
using Microsoft.Win32.SafeHandles;
|
// * Author: haraldwolff
|
||||||
using System.Globalization;
|
// *
|
||||||
using System.Net.Mime;
|
// * 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;
|
using System.Collections.Generic;
|
||||||
|
using ln.types;
|
||||||
namespace sharp.json
|
using ln.types.stream;
|
||||||
|
using System.Text;
|
||||||
|
using System.Globalization;
|
||||||
|
namespace ln.json
|
||||||
{
|
{
|
||||||
public class JSONParser : Parser<JSON>
|
public class JSONParser
|
||||||
{
|
{
|
||||||
delegate JSON ParseObjectDelegate(TokenQueue tokens);
|
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()
|
public static JSONValue Parse(String jsonSource)
|
||||||
:base(tokenDefinitions)
|
{
|
||||||
{
|
CharStream chars = new CharStream(jsonSource);
|
||||||
parserDelegates.Add(tString,parseString);
|
return ParseValue(chars);
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
chars.MoveNext();
|
||||||
static LexerPathSegment null_l;
|
while (chars.Current != '"')
|
||||||
static LexerPathSegment null_u;
|
{
|
||||||
static LexerPathSegment null_n;
|
stringBuilder.Append(chars.Current);
|
||||||
|
if (chars.Current == '\\')
|
||||||
|
{
|
||||||
|
chars.MoveNext();
|
||||||
|
stringBuilder.Append(chars.Current);
|
||||||
|
}
|
||||||
|
chars.MoveNext();
|
||||||
|
}
|
||||||
|
|
||||||
static LexerPathSegment true_e;
|
chars.TryNext();
|
||||||
static LexerPathSegment true_u;
|
chars.Skip(char.IsWhiteSpace);
|
||||||
static LexerPathSegment true_r;
|
|
||||||
static LexerPathSegment true_t;
|
|
||||||
|
|
||||||
static LexerPathSegment false_e;
|
return new JSONString(JSONString.Unescape(stringBuilder.ToString()));
|
||||||
static LexerPathSegment false_s;
|
}
|
||||||
static LexerPathSegment false_l;
|
static JSONNumber parseNumber(CharStream chars)
|
||||||
static LexerPathSegment false_a;
|
{
|
||||||
static LexerPathSegment false_f;
|
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;
|
chars.Skip(char.IsWhiteSpace);
|
||||||
static TokenDefinition tString;
|
return new JSONNumber(decimal.Parse(sb.ToString(),CultureInfo.InvariantCulture));
|
||||||
static TokenDefinition tColon;
|
}
|
||||||
static TokenDefinition tComma;
|
static JSONArray parseArray(CharStream chars)
|
||||||
static TokenDefinition tObjectOpen;
|
{
|
||||||
static TokenDefinition tObjectClose;
|
if (chars.Current != '[')
|
||||||
static TokenDefinition tArrayOpen;
|
throw new FormatException("Unexpected character");
|
||||||
static TokenDefinition tArrayClose;
|
|
||||||
static TokenDefinition tTrue;
|
|
||||||
static TokenDefinition tFalse;
|
|
||||||
static TokenDefinition tNull;
|
|
||||||
static TokenDefinition tWhiteSpace;
|
|
||||||
|
|
||||||
static private bool initialize(){
|
JSONArray array = new JSONArray();
|
||||||
eE = new CharGroup(new char[] { 'e', 'E' });
|
|
||||||
|
|
||||||
null_ll = new LexerPathSegment('l', true);
|
chars.MoveNext();
|
||||||
null_l = new LexerPathSegment('l', null_ll);
|
while (chars.Current != ']')
|
||||||
null_u = new LexerPathSegment('u', null_l);
|
{
|
||||||
null_n = new LexerPathSegment('n', null_u);
|
array.Add(ParseValue(chars));
|
||||||
|
if (chars.Current == ',')
|
||||||
|
{
|
||||||
|
chars.MoveNext();
|
||||||
|
chars.Skip(char.IsWhiteSpace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
true_e = new LexerPathSegment('e', true);
|
chars.TryNext();
|
||||||
true_u = new LexerPathSegment('u', true_e);
|
chars.Skip(char.IsWhiteSpace);
|
||||||
true_r = new LexerPathSegment('r', true_u);
|
|
||||||
true_t = new LexerPathSegment('t', true_r);
|
|
||||||
|
|
||||||
false_e = new LexerPathSegment('e', true);
|
return array;
|
||||||
false_s = new LexerPathSegment('s', false_e);
|
}
|
||||||
false_l = new LexerPathSegment('l', false_s);
|
static JSONObject parseObject(CharStream chars)
|
||||||
false_a = new LexerPathSegment('a', false_l);
|
{
|
||||||
false_f = new LexerPathSegment('f', false_a);
|
if (chars.Current != '{')
|
||||||
|
throw new FormatException("Unexpected character");
|
||||||
|
|
||||||
ws = new LexerPathSegment(CharGroup.WS, true);
|
JSONObject o = new JSONObject();
|
||||||
ws.AddFollower(ws);
|
|
||||||
|
|
||||||
tNumber = new TokenDefinition("JSON.number", initializeNumberHead());
|
chars.MoveNext();
|
||||||
tString = new TokenDefinition("JSON.string", initializeStringHead());
|
chars.Skip(char.IsWhiteSpace);
|
||||||
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[]{
|
while (chars.Current != '}')
|
||||||
tWhiteSpace,
|
{
|
||||||
tNumber,
|
JSONString s = parseString(chars);
|
||||||
tString,
|
if (chars.Current != ':')
|
||||||
tColon,
|
throw new FormatException("expected :");
|
||||||
tComma,
|
chars.MoveNext();
|
||||||
tObjectOpen,
|
o.Add(s.Value, ParseValue(chars));
|
||||||
tObjectClose,
|
|
||||||
tArrayOpen,
|
if (chars.Current == ',')
|
||||||
tArrayClose,
|
{
|
||||||
tTrue,
|
chars.MoveNext();
|
||||||
tFalse,
|
chars.Skip(char.IsWhiteSpace);
|
||||||
tNull
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new FormatException();
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,53 +1,23 @@
|
||||||
using System;
|
using System;
|
||||||
namespace sharp.json
|
namespace ln.json
|
||||||
{
|
{
|
||||||
public class JSONSpecial: JSON
|
public class JSONTrue : JSONValue
|
||||||
{
|
{
|
||||||
public static readonly JSON True = new JSONSpecial(JSONTypes.True);
|
public static JSONTrue Instance { get; } = new JSONTrue();
|
||||||
public static readonly JSON False = new JSONSpecial(JSONTypes.False);
|
private JSONTrue() : base(JSONValueType.TRUE) { }
|
||||||
public static readonly JSON Null = new JSONSpecial(JSONTypes.Null);
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
122
JSONString.cs
122
JSONString.cs
|
@ -1,10 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Text;
|
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 = {
|
static System.Tuple<char,char>[] escapeCharacters = {
|
||||||
System.Tuple.Create('\\','\\'),
|
System.Tuple.Create('\\','\\'),
|
||||||
|
@ -17,73 +16,45 @@ namespace sharp.json
|
||||||
System.Tuple.Create('t','\t'),
|
System.Tuple.Create('t','\t'),
|
||||||
};
|
};
|
||||||
|
|
||||||
string value;
|
public string Value { get; private set; }
|
||||||
|
|
||||||
public JSONString()
|
public JSONString(String value)
|
||||||
:base(JSONTypes.String)
|
:base(JSONValueType.STRING)
|
||||||
{
|
{
|
||||||
this.value = "";
|
Value = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JSONString(String value)
|
public override string ToString()
|
||||||
:base(JSONTypes.String)
|
{
|
||||||
{
|
return String.Format("\"{0}\"", Escape(Value));
|
||||||
this.value = value;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public override string String
|
public static string Escape(string source){
|
||||||
{
|
|
||||||
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){
|
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
foreach (char ch in source){
|
foreach (char ch in source){
|
||||||
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 (System.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);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int iv = (int)ch;
|
byte[] bytes = BitConverter.GetBytes((int)ch);
|
||||||
sb.Append("\\u");
|
sb.Append("\\u");
|
||||||
sb.Append("____");
|
sb.AppendFormat("{0:x2}{1:x2}", bytes[1], bytes[0]);
|
||||||
Console.WriteLine("JSON WARNING: UNICODE ESCAPE SEQUENCES ARE NOT IMPLEMENTED YET");
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string unescape(string source)
|
public static string Unescape(string jsonString)
|
||||||
{
|
{
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
CharEnumerator ce = source.GetEnumerator();
|
CharEnumerator ce = jsonString.GetEnumerator();
|
||||||
char[] hex = new char[4];
|
char[] hex = new char[4];
|
||||||
|
|
||||||
while (ce.MoveNext()){
|
while (ce.MoveNext()){
|
||||||
|
@ -91,23 +62,26 @@ namespace sharp.json
|
||||||
if (ce.Current == '\\'){
|
if (ce.Current == '\\'){
|
||||||
ce.MoveNext();
|
ce.MoveNext();
|
||||||
|
|
||||||
foreach (System.Tuple<char, char> repl in escapeCharacters)
|
if (ce.Current == 'u')
|
||||||
{
|
{
|
||||||
if (repl.Item1 == ce.Current)
|
for (int n = 0; n < 4; n++)
|
||||||
{
|
{
|
||||||
sb.Append(repl.Item2);
|
ce.MoveNext();
|
||||||
break;
|
hex[3 - n] = ce.Current;
|
||||||
}
|
}
|
||||||
}
|
sb.Append((char)Convert.ToInt16(new String(hex),16));
|
||||||
|
}
|
||||||
if (ce.Current == 'u'){
|
else
|
||||||
for (int n = 0; n < 4;n++){
|
{
|
||||||
ce.MoveNext();
|
foreach (System.Tuple<char, char> repl in escapeCharacters)
|
||||||
hex[3 - n] = ce.Current;
|
{
|
||||||
}
|
if (repl.Item1 == ce.Current)
|
||||||
sb.Append((char)( HexString.toBytes(hex).toUInt32()[0] ));
|
{
|
||||||
}
|
sb.Append(repl.Item2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
sb.Append(ce.Current);
|
sb.Append(ce.Current);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
namespace sharp.json
|
namespace ln.json
|
||||||
{
|
{
|
||||||
public enum JSONTypes
|
public enum JSONTypes
|
||||||
{
|
{
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,7 +4,7 @@ using System.Runtime.CompilerServices;
|
||||||
// Information about this assembly is defined by the following attributes.
|
// Information about this assembly is defined by the following attributes.
|
||||||
// Change them to the values specific to your project.
|
// Change them to the values specific to your project.
|
||||||
|
|
||||||
[assembly: AssemblyTitle("sharp.json")]
|
[assembly: AssemblyTitle("ln.json")]
|
||||||
[assembly: AssemblyDescription("JSON Implementation")]
|
[assembly: AssemblyDescription("JSON Implementation")]
|
||||||
[assembly: AssemblyConfiguration("")]
|
[assembly: AssemblyConfiguration("")]
|
||||||
[assembly: AssemblyCompany("")]
|
[assembly: AssemblyCompany("")]
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
# sharp-json
|
# sharp-json
|
||||||
A lightweight JSON implementation for Mono/.NET
|
A lightweight JSON implementation for Mono/.NET
|
||||||
|
|
||||||
## Usage
|
## 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 n = 123.45;
|
||||||
JSON s = "Hello World!"
|
JSON s = "Hello World!"
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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; }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,8 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
||||||
using sharp.json;
|
using ln.json;
|
||||||
using sharp.parser;
|
|
||||||
|
|
||||||
namespace json.test
|
namespace json.test
|
||||||
{
|
{
|
||||||
|
@ -12,32 +11,32 @@ namespace json.test
|
||||||
"\"I am a string\"",
|
"\"I am a string\"",
|
||||||
"{ \"me\" : \"is a string too\"}",
|
"{ \"me\" : \"is a string too\"}",
|
||||||
"[ \"this\", \"is\", \"an\", \"array\" ]"
|
"[ \"this\", \"is\", \"an\", \"array\" ]"
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public static void Main(string[] args)
|
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;
|
Console.WriteLine(json.ToString());
|
||||||
JSONParser jsonparser = new JSONParser();
|
|
||||||
|
|
||||||
json = jsonparser.Parse("4.9125E-05");
|
JSONValue json2 = JSONParser.Parse(json.ToString());
|
||||||
Console.WriteLine(json.ToString());
|
Console.WriteLine(json2.ToString());
|
||||||
|
|
||||||
//Console.WriteLine("JSON test Patterns:");
|
JSONValue value = JSONParser.Parse(File.ReadAllText("test.json"));
|
||||||
//Console.WriteLine();
|
Console.WriteLine("");
|
||||||
|
Console.WriteLine("test.json file:");
|
||||||
//foreach (string src in sources){
|
Console.WriteLine("PARSED: {0}",value.ToString());
|
||||||
// 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());
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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">
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
@ -34,13 +34,9 @@
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\sharp.json.csproj">
|
<ProjectReference Include="..\ln.json.csproj">
|
||||||
<Project>{D9342117-3249-4D8B-87C9-51A50676B158}</Project>
|
<Project>{D9342117-3249-4D8B-87C9-51A50676B158}</Project>
|
||||||
<Name>sharp.json</Name>
|
<Name>ln.json</Name>
|
||||||
</ProjectReference>
|
|
||||||
<ProjectReference Include="..\..\sharp-parser\sharp.parser.csproj">
|
|
||||||
<Project>{32267133-ADB7-4A85-8CF1-03CBDF53715C}</Project>
|
|
||||||
<Name>sharp.parser</Name>
|
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -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">
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
<ProjectGuid>{D9342117-3249-4D8B-87C9-51A50676B158}</ProjectGuid>
|
<ProjectGuid>{D9342117-3249-4D8B-87C9-51A50676B158}</ProjectGuid>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<RootNamespace>sharp.json</RootNamespace>
|
<RootNamespace>ln.json</RootNamespace>
|
||||||
<AssemblyName>sharp.json</AssemblyName>
|
<AssemblyName>ln.json</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
@ -31,54 +31,26 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="JSON.cs" />
|
|
||||||
<Compile Include="ByteParser.cs" />
|
|
||||||
<Compile Include="JSONSpecial.cs" />
|
<Compile Include="JSONSpecial.cs" />
|
||||||
<Compile Include="JSONObject.cs" />
|
<Compile Include="JSONObject.cs" />
|
||||||
<Compile Include="JSONArray.cs" />
|
<Compile Include="JSONArray.cs" />
|
||||||
<Compile Include="JSONString.cs" />
|
<Compile Include="JSONString.cs" />
|
||||||
<Compile Include="JSONTypes.cs" />
|
|
||||||
<Compile Include="JSONNumber.cs" />
|
<Compile Include="JSONNumber.cs" />
|
||||||
<Compile Include="JSONWebRequest.cs" />
|
<Compile Include="JSONValue.cs" />
|
||||||
<Compile Include="JSONSerializer.cs" />
|
|
||||||
<Compile Include="JSONParser.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>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\sharp-extensions\sharp.extensions.csproj">
|
<ProjectReference Include="ln.types\ln.types.csproj">
|
||||||
<Project>{97CA3CA9-98B3-4492-B072-D7A5995B68E9}</Project>
|
<Project>{8D9AB9A5-E513-4BA7-A450-534F6456BF28}</Project>
|
||||||
<Name>sharp.extensions</Name>
|
<Name>ln.types</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>
|
|
||||||
<Folder Include="network\" />
|
|
||||||
<Folder Include="attributes\" />
|
|
||||||
<Folder Include="simple\" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
<ProjectExtensions>
|
<ProjectExtensions>
|
||||||
<MonoDevelop>
|
<MonoDevelop>
|
||||||
<Properties>
|
<Properties>
|
||||||
<Policies>
|
<Policies>
|
||||||
<DotNetNamingPolicy DirectoryNamespaceAssociation="PrefixedHierarchical" ResourceNamePolicy="FileFormatDefault" />
|
<DotNetNamingPolicy ResourceNamePolicy="FileFormatDefault" DirectoryNamespaceAssociation="PrefixedHierarchical" />
|
||||||
</Policies>
|
</Policies>
|
||||||
</Properties>
|
</Properties>
|
||||||
</MonoDevelop>
|
</MonoDevelop>
|
|
@ -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; }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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
|
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue