Change to .NET 3.5

This commit is contained in:
2015-05-29 23:26:32 +02:00
parent 453e637504
commit eef5e3dbbf
28 changed files with 2270 additions and 2217 deletions

View File

@@ -1,411 +1,411 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Scrummer.Code.JSON
{
public class JSONParser
{
#region Declarations
private ParserContext ctx;
private bool tainted = false;
#endregion
#region Private methods
private int ParseHexShort()
{
int value = 0;
for (int i = 0; i < 4; i++)
{
char c = ctx.Next();
if (Char.IsDigit(c))
{
value = (value << 4) | (c - '0');
}
else
{
c = Char.ToLower(c);
if (c >= 'a' && c <= 'f')
{
value = (value << 4) | ((c - 'a') + 10);
}
}
}
return value;
}
private String ParseQuotedString()
{
StringBuilder scratch = new StringBuilder();
char c = ctx.SkipWhite();
if (c == '"')
{
c = ctx.Next();
}
do
{
if (c == '\\')
{
c = ctx.Next();
if (c == '"')
{
scratch.Append('"');
}
else if (c == '\\')
{
scratch.Append('\\');
}
else if (c == '/')
{
scratch.Append('/');
}
else if (c == 'b')
{
scratch.Append('\b');
}
else if (c == 'f')
{
scratch.Append('\f');
}
else if (c == 'n')
{
scratch.Append('\n');
}
else if (c == 'r')
{
scratch.Append('\r');
}
else if (c == 't')
{
scratch.Append('\t');
}
else if (c == 'u')
{
scratch.Append((char)ParseHexShort());
}
c = ctx.Next();
}
else if (c == '"')
{
break;
}
else
{
scratch.Append(c);
c = ctx.Next();
}
} while (!ctx.AtEnd());
if (c == '"')
{
ctx.Next();
}
return scratch.ToString();
}
private String ParseString()
{
char c = ctx.SkipWhite();
if (c == '"')
{
return ParseQuotedString();
}
StringBuilder scratch = new StringBuilder();
while (!ctx.AtEnd()
&& (Char.IsLetter(c) || Char.IsDigit(c) || c == '_'))
{
scratch.Append(c);
c = ctx.Next();
}
return scratch.ToString();
}
private Object ParseNumber()
{
StringBuilder scratch = new StringBuilder();
bool isFloat = false;
int numberLenght = 0;
char c;
c = ctx.SkipWhite();
// Sign
if (c == '-')
{
scratch.Append('-');
c = ctx.Next();
}
// Integer part
while (Char.IsDigit(c))
{
scratch.Append(c);
c = ctx.Next();
numberLenght++;
}
// Decimal part
if (c == '.')
{
isFloat = true;
scratch.Append('.');
c = ctx.Next();
while (Char.IsDigit(c))
{
scratch.Append(c);
c = ctx.Next();
numberLenght++;
}
}
if (numberLenght == 0)
{
tainted = true;
return null;
}
// Exponential part
if (c == 'e' || c == 'E')
{
isFloat = true;
scratch.Append('E');
c = ctx.Next();
if (c == '+' || c == '-')
{
scratch.Append(c);
}
while (Char.IsDigit(c))
{
scratch.Append(c);
c = ctx.Next();
numberLenght++;
}
}
// Build number object from the parsed string
String s = scratch.ToString();
return isFloat ? (numberLenght < 17) ? (Object)Double.Parse(s)
: Decimal.Parse(s) : (numberLenght < 19) ? (Object)System.Int32.Parse(s)
: (Object)System.Int32.Parse(s);
}
private List<object> ParseArray()
{
char c = ctx.SkipWhite();
List<object> array = new List<object>();
if (c == '[')
{
ctx.Next();
}
do
{
c = ctx.SkipWhite();
if (c == ']')
{
ctx.Next();
break;
}
else if (c == ',')
{
ctx.Next();
}
else
{
array.Add(ParseValue());
}
} while (!ctx.AtEnd());
return array;
}
private Dictionary<string, object> ParseObject()
{
char c = ctx.SkipWhite();
Dictionary<string, object> obj = new Dictionary<string, object>();
if (c == '{')
{
ctx.Next();
c = ctx.SkipWhite();
}
String attributeName;
Object attributeValue;
do
{
attributeName = ParseString();
c = ctx.SkipWhite();
if (c == ':')
{
ctx.Next();
attributeValue = ParseValue();
if (attributeName.Length > 0)
{
obj.Add(attributeName, attributeValue);
}
}
else if (c == ',')
{
ctx.Next();
c = ctx.SkipWhite();
}
else if (c == '}')
{
ctx.Next();
break;
}
else
{
// Unexpected character
tainted = true;
break;
}
} while (!ctx.AtEnd());
if (obj.Count == 0)
{
return null;
}
return obj;
}
private Object ParseValue()
{
Object token = null;
char c = ctx.SkipWhite();
switch (c)
{
case '"':
token = ParseQuotedString();
break;
case '{':
token = ParseObject();
break;
case '[':
token = ParseArray();
break;
default:
if (Char.IsDigit(c) || c == '-')
{
token = ParseNumber();
}
else
{
String aux = ParseString();
if (aux.CompareTo("true") == 0)
{
token = true;
}
else if (aux.CompareTo("false") == 0)
{
token = false;
}
else if (aux.CompareTo("null") == 0)
{
token = null;
}
else
{
// Unexpected string
if (aux.Length == 0)
{
ctx.Next();
}
tainted = true;
token = null;
}
}
break;
}
return token;
}
private String CleanIdentifier(String input)
{
int i;
char c;
i = input.Length - 1;
if (i < 0)
{
return input;
}
c = input[i];
while (Char.IsLetter(c) || Char.IsDigit(c) || c == '_')
{
i--;
if (i < 0)
{
break;
}
c = input[i];
}
return input.Substring(i + 1);
}
#endregion
#region Public methods
public Object Parse(String text)
{
// Get the first object
ctx = new ParserContext(text);
tainted = false;
ctx.Mark();
Object obj = ParseValue();
if (ctx.AtEnd())
{
return obj;
}
// "But wait, there is more!"
int idx = 0;
String name = "";
String strInvalidPrev = "";
Dictionary<string, object> superObject = new Dictionary<string, object>();
do
{
// Add the object to the superObject
if (!tainted && name.Length > 0 && obj != null)
{
if (name.Length == 0)
{
name = String.Format("{0:D2}", idx);
}
superObject.Add(name, obj);
idx++;
name = "";
}
else
{
String strInvalid = ctx.GetMarked();
strInvalid = strInvalid.Trim();
if (strInvalidPrev.Length > 0
&& "=".CompareTo(strInvalid) == 0)
{
name = CleanIdentifier(strInvalidPrev);
}
else
{
name = "";
}
strInvalidPrev = strInvalid;
}
// Check end
if (ctx.AtEnd())
{
break;
}
// Get next object
tainted = false;
ctx.Mark();
obj = ParseValue();
} while (true);
return superObject;
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace Scrummer.Code.JSON
{
public class JSONParser
{
#region Declarations
private ParserContext ctx;
private bool tainted = false;
#endregion
#region Private methods
private int ParseHexShort()
{
int value = 0;
for (int i = 0; i < 4; i++)
{
char c = ctx.Next();
if (Char.IsDigit(c))
{
value = (value << 4) | (c - '0');
}
else
{
c = Char.ToLower(c);
if (c >= 'a' && c <= 'f')
{
value = (value << 4) | ((c - 'a') + 10);
}
}
}
return value;
}
private String ParseQuotedString()
{
StringBuilder scratch = new StringBuilder();
char c = ctx.SkipWhite();
if (c == '"')
{
c = ctx.Next();
}
do
{
if (c == '\\')
{
c = ctx.Next();
if (c == '"')
{
scratch.Append('"');
}
else if (c == '\\')
{
scratch.Append('\\');
}
else if (c == '/')
{
scratch.Append('/');
}
else if (c == 'b')
{
scratch.Append('\b');
}
else if (c == 'f')
{
scratch.Append('\f');
}
else if (c == 'n')
{
scratch.Append('\n');
}
else if (c == 'r')
{
scratch.Append('\r');
}
else if (c == 't')
{
scratch.Append('\t');
}
else if (c == 'u')
{
scratch.Append((char)ParseHexShort());
}
c = ctx.Next();
}
else if (c == '"')
{
break;
}
else
{
scratch.Append(c);
c = ctx.Next();
}
} while (!ctx.AtEnd());
if (c == '"')
{
ctx.Next();
}
return scratch.ToString();
}
private String ParseString()
{
char c = ctx.SkipWhite();
if (c == '"')
{
return ParseQuotedString();
}
StringBuilder scratch = new StringBuilder();
while (!ctx.AtEnd()
&& (Char.IsLetter(c) || Char.IsDigit(c) || c == '_'))
{
scratch.Append(c);
c = ctx.Next();
}
return scratch.ToString();
}
private Object ParseNumber()
{
StringBuilder scratch = new StringBuilder();
bool isFloat = false;
int numberLenght = 0;
char c;
c = ctx.SkipWhite();
// Sign
if (c == '-')
{
scratch.Append('-');
c = ctx.Next();
}
// Integer part
while (Char.IsDigit(c))
{
scratch.Append(c);
c = ctx.Next();
numberLenght++;
}
// Decimal part
if (c == '.')
{
isFloat = true;
scratch.Append('.');
c = ctx.Next();
while (Char.IsDigit(c))
{
scratch.Append(c);
c = ctx.Next();
numberLenght++;
}
}
if (numberLenght == 0)
{
tainted = true;
return null;
}
// Exponential part
if (c == 'e' || c == 'E')
{
isFloat = true;
scratch.Append('E');
c = ctx.Next();
if (c == '+' || c == '-')
{
scratch.Append(c);
}
while (Char.IsDigit(c))
{
scratch.Append(c);
c = ctx.Next();
numberLenght++;
}
}
// Build number object from the parsed string
String s = scratch.ToString();
return isFloat ? (numberLenght < 17) ? (Object)Double.Parse(s)
: Decimal.Parse(s) : (numberLenght < 19) ? (Object)System.Int32.Parse(s)
: (Object)System.Int32.Parse(s);
}
private List<object> ParseArray()
{
char c = ctx.SkipWhite();
List<object> array = new List<object>();
if (c == '[')
{
ctx.Next();
}
do
{
c = ctx.SkipWhite();
if (c == ']')
{
ctx.Next();
break;
}
else if (c == ',')
{
ctx.Next();
}
else
{
array.Add(ParseValue());
}
} while (!ctx.AtEnd());
return array;
}
private Dictionary<string, object> ParseObject()
{
char c = ctx.SkipWhite();
Dictionary<string, object> obj = new Dictionary<string, object>();
if (c == '{')
{
ctx.Next();
c = ctx.SkipWhite();
}
String attributeName;
Object attributeValue;
do
{
attributeName = ParseString();
c = ctx.SkipWhite();
if (c == ':')
{
ctx.Next();
attributeValue = ParseValue();
if (attributeName.Length > 0)
{
obj.Add(attributeName, attributeValue);
}
}
else if (c == ',')
{
ctx.Next();
c = ctx.SkipWhite();
}
else if (c == '}')
{
ctx.Next();
break;
}
else
{
// Unexpected character
tainted = true;
break;
}
} while (!ctx.AtEnd());
if (obj.Count == 0)
{
return null;
}
return obj;
}
private Object ParseValue()
{
Object token = null;
char c = ctx.SkipWhite();
switch (c)
{
case '"':
token = ParseQuotedString();
break;
case '{':
token = ParseObject();
break;
case '[':
token = ParseArray();
break;
default:
if (Char.IsDigit(c) || c == '-')
{
token = ParseNumber();
}
else
{
String aux = ParseString();
if (aux.CompareTo("true") == 0)
{
token = true;
}
else if (aux.CompareTo("false") == 0)
{
token = false;
}
else if (aux.CompareTo("null") == 0)
{
token = null;
}
else
{
// Unexpected string
if (aux.Length == 0)
{
ctx.Next();
}
tainted = true;
token = null;
}
}
break;
}
return token;
}
private String CleanIdentifier(String input)
{
int i;
char c;
i = input.Length - 1;
if (i < 0)
{
return input;
}
c = input[i];
while (Char.IsLetter(c) || Char.IsDigit(c) || c == '_')
{
i--;
if (i < 0)
{
break;
}
c = input[i];
}
return input.Substring(i + 1);
}
#endregion
#region Public methods
public Object Parse(String text)
{
// Get the first object
ctx = new ParserContext(text);
tainted = false;
ctx.Mark();
Object obj = ParseValue();
if (ctx.AtEnd())
{
return obj;
}
// "But wait, there is more!"
int idx = 0;
String name = "";
String strInvalidPrev = "";
Dictionary<string, object> superObject = new Dictionary<string, object>();
do
{
// Add the object to the superObject
if (!tainted && name.Length > 0 && obj != null)
{
if (name.Length == 0)
{
name = String.Format("{0:D2}", idx);
}
superObject.Add(name, obj);
idx++;
name = "";
}
else
{
String strInvalid = ctx.GetMarked();
strInvalid = strInvalid.Trim();
if (strInvalidPrev.Length > 0
&& "=".CompareTo(strInvalid) == 0)
{
name = CleanIdentifier(strInvalidPrev);
}
else
{
name = "";
}
strInvalidPrev = strInvalid;
}
// Check end
if (ctx.AtEnd())
{
break;
}
// Get next object
tainted = false;
ctx.Mark();
obj = ParseValue();
} while (true);
return superObject;
}
#endregion
}
}

View File

@@ -1,328 +1,328 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace Scrummer.Code.JSON
{
public class JSONWriter
{
#region Declarations
private bool indent = false;
private bool useTabForIndent = false;
private int indentChars = 4;
private int indentThresold = 3;
#endregion
#region Creator
public JSONWriter() { }
public JSONWriter(int indentChars)
{
this.indent = true;
this.indentChars = indentChars;
this.useTabForIndent = false;
}
public JSONWriter(bool useTabForIndent)
{
this.indent = true;
this.useTabForIndent = useTabForIndent;
}
#endregion
#region Private methods
private bool IsValue(Object obj)
{
if (obj == null)
{
return true;
}
if ((obj is float) || (obj is double) ||
(obj is System.Int16) || (obj is System.Int32) || (obj is System.Int64)
|| (obj is String) || (obj is Boolean))
{
return true;
}
return false;
}
private void WriteIndent(StringBuilder sbOutput, int level)
{
if (!indent)
{
return;
}
sbOutput.Append('\n');
if (useTabForIndent)
{
for (int i = 0; i < level; i++) { sbOutput.Append('\t'); }
}
else
{
int n = level * indentChars;
for (int i = 0; i < n; i++) { sbOutput.Append(' '); }
}
}
private void WriteString(StringBuilder sbOutput, String str)
{
sbOutput.Append('"');
char c;
int n = str.Length;
for (int i = 0; i < n; i++)
{
c = str[i];
if (c == '"') { sbOutput.Append("\\\""); }
else if (c == '\\') { sbOutput.Append("\\\\"); }
else if (c == '/') { sbOutput.Append("\\/"); }
else if (c == '\b') { sbOutput.Append("\\b"); }
else if (c == '\f') { sbOutput.Append("\\f"); }
else if (c == '\n') { sbOutput.Append("\\n"); }
else if (c == '\r') { sbOutput.Append("\\r"); }
else if (c == '\t') { sbOutput.Append("\\t"); }
else { sbOutput.Append(c); }
// FIXME: Unicode characters
}
sbOutput.Append('"');
}
private void WriteValue(StringBuilder sbOutput, Object obj, int level, bool useReflection)
{
if (obj == null)
{
// NULL
sbOutput.Append("null");
}
else if ((obj is float) || (obj is double) ||
(obj is System.Int16) || (obj is System.Int32) || (obj is System.Int64))
{
// Numbers
sbOutput.Append(obj.ToString());
}
else if (obj is String)
{
// Strings
WriteString(sbOutput, (String)obj);
}
else if (obj is Boolean)
{
// Booleans
sbOutput.Append(((Boolean)obj) ? "true" : "false");
}
else if (obj is IDictionary)
{
// Objects
WriteObject(sbOutput, obj, level);
}
else if (obj is IEnumerable)
{
// Array/List
WriteList(sbOutput, obj, level);
}
else
{
if (useReflection)
{
// Reflected object
WriteReflectedObject(sbOutput, obj, level);
}
else
{
WriteString(sbOutput, Convert.ToString(obj));
}
}
}
private void WriteList(StringBuilder sbOutput, Object obj, int level)
{
IEnumerable list = (IEnumerable)obj;
int n = 0;
// Check if it is a leaf object
bool isLeaf = true;
foreach (object childObj in list)
{
if (!IsValue(childObj))
{
isLeaf = false;
}
n++;
}
// Empty
if (n == 0)
{
sbOutput.Append("[ ]");
return;
}
// Write array
bool first = true;
sbOutput.Append("[ ");
if (!isLeaf || n > indentThresold)
{
WriteIndent(sbOutput, level + 1);
}
foreach (object childObj in list)
{
if (!first)
{
sbOutput.Append(", ");
if (!isLeaf || n > indentThresold)
{
WriteIndent(sbOutput, level + 1);
}
}
first = false;
WriteValue(sbOutput, childObj, level + 1, true);
}
if (!isLeaf || n > indentThresold)
{
WriteIndent(sbOutput, level);
}
sbOutput.Append(" ]");
}
private void WriteObject(StringBuilder sbOutput, Object obj, int level)
{
IDictionary map = (IDictionary)obj;
int n = map.Count;
// Empty
if (map.Count == 0)
{
sbOutput.Append("{ }");
return;
}
// Check if it is a leaf object
bool isLeaf = true;
foreach (object value in map.Values)
{
if (!IsValue(value))
{
isLeaf = false;
break;
}
}
// Write object
bool first = true;
sbOutput.Append("{ ");
if (!isLeaf || n > indentThresold)
{
WriteIndent(sbOutput, level + 1);
}
foreach (object key in map.Keys)
{
object value = map[key];
if (!first)
{
sbOutput.Append(", ");
if (!isLeaf || n > indentThresold)
{
WriteIndent(sbOutput, level + 1);
}
}
first = false;
WriteString(sbOutput, Convert.ToString(key));
sbOutput.Append(": ");
WriteValue(sbOutput, value, level + 1, true);
}
if (!isLeaf || n > indentThresold)
{
WriteIndent(sbOutput, level);
}
sbOutput.Append(" }");
}
private void WriteReflectedObject(StringBuilder sbOutput, Object obj, int level)
{
Type type = obj.GetType();
PropertyInfo[] rawProperties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
List<PropertyInfo> properties = new List<PropertyInfo>();
foreach (PropertyInfo property in rawProperties)
{
if (property.CanRead)
{
properties.Add(property);
}
}
int n = properties.Count;
// Empty
if (n == 0)
{
sbOutput.Append("{ }");
return;
}
// Check if it is a leaf object
bool isLeaf = true;
foreach (PropertyInfo property in properties)
{
object value = property.GetValue(obj, null);
if (!IsValue(value))
{
isLeaf = false;
break;
}
}
// Write object
bool first = true;
sbOutput.Append("{ ");
if (!isLeaf || n > indentThresold)
{
WriteIndent(sbOutput, level + 1);
}
foreach (PropertyInfo property in properties)
{
object value=null;
MethodInfo getMethod = property.GetMethod;
ParameterInfo[] parameters =getMethod.GetParameters();
if (parameters.Length == 0)
{
value = property.GetValue(obj, null);
}
if (!first)
{
sbOutput.Append(", ");
if (!isLeaf || n > indentThresold)
{
WriteIndent(sbOutput, level + 1);
}
}
first = false;
WriteString(sbOutput, property.Name);
sbOutput.Append(": ");
WriteValue(sbOutput, value, level + 1, false);
}
if (!isLeaf || n > indentThresold)
{
WriteIndent(sbOutput, level);
}
sbOutput.Append(" }");
}
#endregion
#region Public methods
public String Write(Object obj)
{
StringBuilder sbOutput = new StringBuilder();
WriteValue(sbOutput, obj, 0, true);
return sbOutput.ToString();
}
#endregion
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace Scrummer.Code.JSON
{
public class JSONWriter
{
#region Declarations
private bool indent = false;
private bool useTabForIndent = false;
private int indentChars = 4;
private int indentThresold = 3;
#endregion
#region Creator
public JSONWriter() { }
public JSONWriter(int indentChars)
{
this.indent = true;
this.indentChars = indentChars;
this.useTabForIndent = false;
}
public JSONWriter(bool useTabForIndent)
{
this.indent = true;
this.useTabForIndent = useTabForIndent;
}
#endregion
#region Private methods
private bool IsValue(Object obj)
{
if (obj == null)
{
return true;
}
if ((obj is float) || (obj is double) ||
(obj is System.Int16) || (obj is System.Int32) || (obj is System.Int64)
|| (obj is String) || (obj is Boolean))
{
return true;
}
return false;
}
private void WriteIndent(StringBuilder sbOutput, int level)
{
if (!indent)
{
return;
}
sbOutput.Append('\n');
if (useTabForIndent)
{
for (int i = 0; i < level; i++) { sbOutput.Append('\t'); }
}
else
{
int n = level * indentChars;
for (int i = 0; i < n; i++) { sbOutput.Append(' '); }
}
}
private void WriteString(StringBuilder sbOutput, String str)
{
sbOutput.Append('"');
char c;
int n = str.Length;
for (int i = 0; i < n; i++)
{
c = str[i];
if (c == '"') { sbOutput.Append("\\\""); }
else if (c == '\\') { sbOutput.Append("\\\\"); }
else if (c == '/') { sbOutput.Append("\\/"); }
else if (c == '\b') { sbOutput.Append("\\b"); }
else if (c == '\f') { sbOutput.Append("\\f"); }
else if (c == '\n') { sbOutput.Append("\\n"); }
else if (c == '\r') { sbOutput.Append("\\r"); }
else if (c == '\t') { sbOutput.Append("\\t"); }
else { sbOutput.Append(c); }
// FIXME: Unicode characters
}
sbOutput.Append('"');
}
private void WriteValue(StringBuilder sbOutput, Object obj, int level, bool useReflection)
{
if (obj == null)
{
// NULL
sbOutput.Append("null");
}
else if ((obj is float) || (obj is double) ||
(obj is System.Int16) || (obj is System.Int32) || (obj is System.Int64))
{
// Numbers
sbOutput.Append(obj.ToString());
}
else if (obj is String)
{
// Strings
WriteString(sbOutput, (String)obj);
}
else if (obj is Boolean)
{
// Booleans
sbOutput.Append(((Boolean)obj) ? "true" : "false");
}
else if (obj is IDictionary)
{
// Objects
WriteObject(sbOutput, obj, level);
}
else if (obj is IEnumerable)
{
// Array/List
WriteList(sbOutput, obj, level);
}
else
{
if (useReflection)
{
// Reflected object
WriteReflectedObject(sbOutput, obj, level);
}
else
{
WriteString(sbOutput, Convert.ToString(obj));
}
}
}
private void WriteList(StringBuilder sbOutput, Object obj, int level)
{
IEnumerable list = (IEnumerable)obj;
int n = 0;
// Check if it is a leaf object
bool isLeaf = true;
foreach (object childObj in list)
{
if (!IsValue(childObj))
{
isLeaf = false;
}
n++;
}
// Empty
if (n == 0)
{
sbOutput.Append("[ ]");
return;
}
// Write array
bool first = true;
sbOutput.Append("[ ");
if (!isLeaf || n > indentThresold)
{
WriteIndent(sbOutput, level + 1);
}
foreach (object childObj in list)
{
if (!first)
{
sbOutput.Append(", ");
if (!isLeaf || n > indentThresold)
{
WriteIndent(sbOutput, level + 1);
}
}
first = false;
WriteValue(sbOutput, childObj, level + 1, true);
}
if (!isLeaf || n > indentThresold)
{
WriteIndent(sbOutput, level);
}
sbOutput.Append(" ]");
}
private void WriteObject(StringBuilder sbOutput, Object obj, int level)
{
IDictionary map = (IDictionary)obj;
int n = map.Count;
// Empty
if (map.Count == 0)
{
sbOutput.Append("{ }");
return;
}
// Check if it is a leaf object
bool isLeaf = true;
foreach (object value in map.Values)
{
if (!IsValue(value))
{
isLeaf = false;
break;
}
}
// Write object
bool first = true;
sbOutput.Append("{ ");
if (!isLeaf || n > indentThresold)
{
WriteIndent(sbOutput, level + 1);
}
foreach (object key in map.Keys)
{
object value = map[key];
if (!first)
{
sbOutput.Append(", ");
if (!isLeaf || n > indentThresold)
{
WriteIndent(sbOutput, level + 1);
}
}
first = false;
WriteString(sbOutput, Convert.ToString(key));
sbOutput.Append(": ");
WriteValue(sbOutput, value, level + 1, true);
}
if (!isLeaf || n > indentThresold)
{
WriteIndent(sbOutput, level);
}
sbOutput.Append(" }");
}
private void WriteReflectedObject(StringBuilder sbOutput, Object obj, int level)
{
Type type = obj.GetType();
PropertyInfo[] rawProperties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
List<PropertyInfo> properties = new List<PropertyInfo>();
foreach (PropertyInfo property in rawProperties)
{
if (property.CanRead)
{
properties.Add(property);
}
}
int n = properties.Count;
// Empty
if (n == 0)
{
sbOutput.Append("{ }");
return;
}
// Check if it is a leaf object
bool isLeaf = true;
foreach (PropertyInfo property in properties)
{
object value = property.GetValue(obj, null);
if (!IsValue(value))
{
isLeaf = false;
break;
}
}
// Write object
bool first = true;
sbOutput.Append("{ ");
if (!isLeaf || n > indentThresold)
{
WriteIndent(sbOutput, level + 1);
}
foreach (PropertyInfo property in properties)
{
object value = null;
MethodInfo getMethod = property.GetGetMethod();
ParameterInfo[] parameters = getMethod.GetParameters();
if (parameters.Length == 0)
{
value = property.GetValue(obj, null);
}
if (!first)
{
sbOutput.Append(", ");
if (!isLeaf || n > indentThresold)
{
WriteIndent(sbOutput, level + 1);
}
}
first = false;
WriteString(sbOutput, property.Name);
sbOutput.Append(": ");
WriteValue(sbOutput, value, level + 1, false);
}
if (!isLeaf || n > indentThresold)
{
WriteIndent(sbOutput, level);
}
sbOutput.Append(" }");
}
#endregion
#region Public methods
public String Write(Object obj)
{
StringBuilder sbOutput = new StringBuilder();
WriteValue(sbOutput, obj, 0, true);
return sbOutput.ToString();
}
#endregion
}
}

View File

@@ -1,84 +1,84 @@
using System;
namespace Scrummer.Code.JSON
{
public class ParserContext
{
#region Declarations
private String text;
private int length;
private int i;
private int markStart;
#endregion
#region Creator
public ParserContext(String text)
{
this.text = text;
this.length = text.Length;
this.i = 0;
this.markStart = 0;
}
#endregion
#region Public methods
public char SkipWhite()
{
while (i < length && Char.IsWhiteSpace(text[i]))
{
i++;
}
if (AtEnd())
{
return (char)0;
}
return text[i];
}
public char Next()
{
i++;
if (AtEnd())
{
return (char)0;
}
return text[i];
}
public bool AtEnd()
{
return i >= length;
}
public void Mark()
{
markStart = this.i;
}
public String GetMarked()
{
if (i < length && markStart < length)
{
return text.Substring(markStart, i);
}
else
{
if (markStart < length)
{
return text.Substring(markStart, length);
}
else
{
return string.Empty;
}
}
}
#endregion
}
}
using System;
namespace Scrummer.Code.JSON
{
public class ParserContext
{
#region Declarations
private String text;
private int length;
private int i;
private int markStart;
#endregion
#region Creator
public ParserContext(String text)
{
this.text = text;
this.length = text.Length;
this.i = 0;
this.markStart = 0;
}
#endregion
#region Public methods
public char SkipWhite()
{
while (i < length && Char.IsWhiteSpace(text[i]))
{
i++;
}
if (AtEnd())
{
return (char)0;
}
return text[i];
}
public char Next()
{
i++;
if (AtEnd())
{
return (char)0;
}
return text[i];
}
public bool AtEnd()
{
return i >= length;
}
public void Mark()
{
markStart = this.i;
}
public String GetMarked()
{
if (i < length && markStart < length)
{
return text.Substring(markStart, i);
}
else
{
if (markStart < length)
{
return text.Substring(markStart, length);
}
else
{
return string.Empty;
}
}
}
#endregion
}
}