diff --git a/Octokit/SimpleJson.cs b/Octokit/SimpleJson.cs
index b8300f34..9266c3dc 100644
--- a/Octokit/SimpleJson.cs
+++ b/Octokit/SimpleJson.cs
@@ -17,7 +17,7 @@
// https://github.com/facebook-csharp-sdk/simple-json
//-----------------------------------------------------------------------
-// VERSION: 0.30.0
+// VERSION: 0.34.0
// NOTE: uncomment the following line to make SimpleJson class internal.
//#define SIMPLE_JSON_INTERNAL
@@ -31,6 +31,9 @@
// NOTE: uncomment the following line to enable DataContract support.
//#define SIMPLE_JSON_DATACONTRACT
+// NOTE: uncomment the following line to enable IReadOnlyCollection and IReadOnlyList support.
+//#define SIMPLE_JSON_READONLY_COLLECTIONS
+
// NOTE: uncomment the following line to disable linq expressions/compiled lambda (better performance) instead of method.invoke().
// define if you are using .net framework <= 3.0 or < WP7.5
//#define SIMPLE_JSON_NO_LINQ_EXPRESSION
@@ -51,7 +54,6 @@ using System;
using System.CodeDom.Compiler;
using System.Collections;
using System.Collections.Generic;
-using System.Linq;
#if !SIMPLE_JSON_NO_LINQ_EXPRESSION
using System.Linq.Expressions;
#endif
@@ -513,6 +515,22 @@ namespace Octokit
private const int TOKEN_NULL = 11;
private const int BUILDER_CAPACITY = 2000;
+ private static readonly char[] EscapeTable;
+ private static readonly char[] EscapeCharacters = new char[] { '"', '\\', '\b', '\f', '\n', '\r', '\t' };
+ private static readonly string EscapeCharactersString = new string(EscapeCharacters);
+
+ static SimpleJson()
+ {
+ EscapeTable = new char[93];
+ EscapeTable['"'] = '"';
+ EscapeTable['\\'] = '\\';
+ EscapeTable['\b'] = 'b';
+ EscapeTable['\f'] = 'f';
+ EscapeTable['\n'] = 'n';
+ EscapeTable['\r'] = 'r';
+ EscapeTable['\t'] = 't';
+ }
+
///
/// Parses the string json into a value
///
@@ -1074,29 +1092,50 @@ namespace Octokit
static bool SerializeString(string aString, StringBuilder builder)
{
- builder.Append("\"");
+ // Happy path if there's nothing to be escaped. IndexOfAny is highly optimized (and unmanaged)
+ if (aString.IndexOfAny(EscapeCharacters) == -1)
+ {
+ builder.Append('"');
+ builder.Append(aString);
+ builder.Append('"');
+
+ return true;
+ }
+
+ builder.Append('"');
+ int safeCharacterCount = 0;
char[] charArray = aString.ToCharArray();
+
for (int i = 0; i < charArray.Length; i++)
{
char c = charArray[i];
- if (c == '"')
- builder.Append("\\\"");
- else if (c == '\\')
- builder.Append("\\\\");
- else if (c == '\b')
- builder.Append("\\b");
- else if (c == '\f')
- builder.Append("\\f");
- else if (c == '\n')
- builder.Append("\\n");
- else if (c == '\r')
- builder.Append("\\r");
- else if (c == '\t')
- builder.Append("\\t");
+
+ // Non ascii characters are fine, buffer them up and send them to the builder
+ // in larger chunks if possible. The escape table is a 1:1 translation table
+ // with \0 [default(char)] denoting a safe character.
+ if (c >= EscapeTable.Length || EscapeTable[c] == default(char))
+ {
+ safeCharacterCount++;
+ }
else
- builder.Append(c);
+ {
+ if (safeCharacterCount > 0)
+ {
+ builder.Append(charArray, i - safeCharacterCount, safeCharacterCount);
+ safeCharacterCount = 0;
+ }
+
+ builder.Append('\\');
+ builder.Append(EscapeTable[c]);
+ }
}
- builder.Append("\"");
+
+ if (safeCharacterCount > 0)
+ {
+ builder.Append(charArray, charArray.Length - safeCharacterCount, safeCharacterCount);
+ }
+
+ builder.Append('"');
return true;
}
@@ -1647,7 +1686,14 @@ namespace Octokit
Type genericDefinition = type.GetGenericTypeDefinition();
- return (genericDefinition == typeof(IList<>) || genericDefinition == typeof(ICollection<>) || genericDefinition == typeof(IEnumerable<>));
+ return (genericDefinition == typeof(IList<>)
+ || genericDefinition == typeof(ICollection<>)
+ || genericDefinition == typeof(IEnumerable<>)
+#if SIMPLE_JSON_READONLY_COLLECTIONS
+ || genericDefinition == typeof(IReadOnlyCollection<>)
+ || genericDefinition == typeof(IReadOnlyList<>)
+#endif
+ );
}
public static bool IsAssignableFrom(Type type1, Type type2)
@@ -1727,13 +1773,7 @@ namespace Octokit
public static IEnumerable GetProperties(Type type)
{
#if SIMPLE_JSON_TYPEINFO
- var info = type.GetTypeInfo();
-
- var baseProperties = info.BaseType != null && info.BaseType != typeof(Object)
- ? GetProperties(info.BaseType)
- : new PropertyInfo[0];
-
- return info.DeclaredProperties.Concat(baseProperties);
+ return type.GetTypeInfo().DeclaredProperties;
#else
return type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
#endif
diff --git a/Octokit/packages.config b/Octokit/packages.config
index fe57a08e..3771b8bf 100644
--- a/Octokit/packages.config
+++ b/Octokit/packages.config
@@ -6,5 +6,5 @@
-
+
\ No newline at end of file
diff --git a/packages/SimpleJson.0.30.0/SimpleJson.0.30.0.nupkg b/packages/SimpleJson.0.30.0/SimpleJson.0.30.0.nupkg
deleted file mode 100644
index b35a0dda..00000000
Binary files a/packages/SimpleJson.0.30.0/SimpleJson.0.30.0.nupkg and /dev/null differ
diff --git a/packages/SimpleJson.0.30.0/SimpleJson.0.30.0.nuspec b/packages/SimpleJson.0.30.0/SimpleJson.0.30.0.nuspec
deleted file mode 100644
index bfc5f00d..00000000
--- a/packages/SimpleJson.0.30.0/SimpleJson.0.30.0.nuspec
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
-
- SimpleJson
- 0.30.0
- Jim Zimmerman, Nathan Totten, Prabir Shrestha
- Jim Zimmerman, Nathan Totten, Prabir Shrestha
- https://raw.github.com/facebook-csharp-sdk/simple-json/master/LICENSE.txt
- https://raw.github.com/facebook-csharp-sdk/simple-json
- false
- Super lightweight Json library for .NET 2.0+/SL4+/WP7/WindowsStore Apps/Portable Class Libraries along with dynamic and DataContract support
- en-US
- json
-
-
\ No newline at end of file
diff --git a/packages/SimpleJson.0.34.0/SimpleJson.0.34.0.nupkg b/packages/SimpleJson.0.34.0/SimpleJson.0.34.0.nupkg
new file mode 100644
index 00000000..3dbe14c4
Binary files /dev/null and b/packages/SimpleJson.0.34.0/SimpleJson.0.34.0.nupkg differ
diff --git a/packages/SimpleJson.0.30.0/SimpleJson.psm1 b/packages/SimpleJson.0.34.0/SimpleJson.psm1
similarity index 97%
rename from packages/SimpleJson.0.30.0/SimpleJson.psm1
rename to packages/SimpleJson.0.34.0/SimpleJson.psm1
index d34066dd..7cfbf98b 100644
--- a/packages/SimpleJson.0.30.0/SimpleJson.psm1
+++ b/packages/SimpleJson.0.34.0/SimpleJson.psm1
@@ -1,6 +1,6 @@
# SimpleJson https://github.com/facebook-csharp-sdk/simple-json
# License: MIT License
-# Version: 0.30.0
+# Version: 0.34.0
function ConvertFrom-Json
{
@@ -87,7 +87,7 @@ $source = @"
// https://github.com/facebook-csharp-sdk/simple-json
//-----------------------------------------------------------------------
-// VERSION: 0.30.0
+// VERSION: 0.34.0
// NOTE: uncomment the following line to make SimpleJson class internal.
//#define SIMPLE_JSON_INTERNAL
@@ -101,6 +101,9 @@ $source = @"
// NOTE: uncomment the following line to enable DataContract support.
//#define SIMPLE_JSON_DATACONTRACT
+// NOTE: uncomment the following line to enable IReadOnlyCollection and IReadOnlyList support.
+//#define SIMPLE_JSON_READONLY_COLLECTIONS
+
// NOTE: uncomment the following line to disable linq expressions/compiled lambda (better performance) instead of method.invoke().
// define if you are using .net framework <= 3.0 or < WP7.5
//#define SIMPLE_JSON_NO_LINQ_EXPRESSION
@@ -582,6 +585,22 @@ namespace SimpleJson
private const int TOKEN_NULL = 11;
private const int BUILDER_CAPACITY = 2000;
+ private static readonly char[] EscapeTable;
+ private static readonly char[] EscapeCharacters = new char[] { '"', '\\', '\b', '\f', '\n', '\r', '\t' };
+ private static readonly string EscapeCharactersString = new string(EscapeCharacters);
+
+ static SimpleJson()
+ {
+ EscapeTable = new char[93];
+ EscapeTable['"'] = '"';
+ EscapeTable['\\'] = '\\';
+ EscapeTable['\b'] = 'b';
+ EscapeTable['\f'] = 'f';
+ EscapeTable['\n'] = 'n';
+ EscapeTable['\r'] = 'r';
+ EscapeTable['\t'] = 't';
+ }
+
///
/// Parses the string json into a value
///
@@ -1143,29 +1162,50 @@ namespace SimpleJson
static bool SerializeString(string aString, StringBuilder builder)
{
- builder.Append("\"");
+ // Happy path if there's nothing to be escaped. IndexOfAny is highly optimized (and unmanaged)
+ if (aString.IndexOfAny(EscapeCharacters) == -1)
+ {
+ builder.Append('"');
+ builder.Append(aString);
+ builder.Append('"');
+
+ return true;
+ }
+
+ builder.Append('"');
+ int safeCharacterCount = 0;
char[] charArray = aString.ToCharArray();
+
for (int i = 0; i < charArray.Length; i++)
{
char c = charArray[i];
- if (c == '"')
- builder.Append("\\\"");
- else if (c == '\\')
- builder.Append("\\\\");
- else if (c == '\b')
- builder.Append("\\b");
- else if (c == '\f')
- builder.Append("\\f");
- else if (c == '\n')
- builder.Append("\\n");
- else if (c == '\r')
- builder.Append("\\r");
- else if (c == '\t')
- builder.Append("\\t");
+
+ // Non ascii characters are fine, buffer them up and send them to the builder
+ // in larger chunks if possible. The escape table is a 1:1 translation table
+ // with \0 [default(char)] denoting a safe character.
+ if (c >= EscapeTable.Length || EscapeTable[c] == default(char))
+ {
+ safeCharacterCount++;
+ }
else
- builder.Append(c);
+ {
+ if (safeCharacterCount > 0)
+ {
+ builder.Append(charArray, i - safeCharacterCount, safeCharacterCount);
+ safeCharacterCount = 0;
+ }
+
+ builder.Append('\\');
+ builder.Append(EscapeTable[c]);
+ }
}
- builder.Append("\"");
+
+ if (safeCharacterCount > 0)
+ {
+ builder.Append(charArray, charArray.Length - safeCharacterCount, safeCharacterCount);
+ }
+
+ builder.Append('"');
return true;
}
@@ -1716,7 +1756,14 @@ namespace SimpleJson
Type genericDefinition = type.GetGenericTypeDefinition();
- return (genericDefinition == typeof(IList<>) || genericDefinition == typeof(ICollection<>) || genericDefinition == typeof(IEnumerable<>));
+ return (genericDefinition == typeof(IList<>)
+ || genericDefinition == typeof(ICollection<>)
+ || genericDefinition == typeof(IEnumerable<>)
+#if SIMPLE_JSON_READONLY_COLLECTIONS
+ || genericDefinition == typeof(IReadOnlyCollection<>)
+ || genericDefinition == typeof(IReadOnlyList<>)
+#endif
+ );
}
public static bool IsAssignableFrom(Type type1, Type type2)
diff --git a/packages/SimpleJson.0.30.0/content/SimpleJson.cs.pp b/packages/SimpleJson.0.34.0/content/SimpleJson.cs.pp
similarity index 97%
rename from packages/SimpleJson.0.30.0/content/SimpleJson.cs.pp
rename to packages/SimpleJson.0.34.0/content/SimpleJson.cs.pp
index 47dbe189..b7c86642 100644
--- a/packages/SimpleJson.0.30.0/content/SimpleJson.cs.pp
+++ b/packages/SimpleJson.0.34.0/content/SimpleJson.cs.pp
@@ -17,7 +17,7 @@
// https://github.com/facebook-csharp-sdk/simple-json
//-----------------------------------------------------------------------
-// VERSION: 0.30.0
+// VERSION: 0.34.0
// NOTE: uncomment the following line to make SimpleJson class internal.
//#define SIMPLE_JSON_INTERNAL
@@ -31,6 +31,9 @@
// NOTE: uncomment the following line to enable DataContract support.
//#define SIMPLE_JSON_DATACONTRACT
+// NOTE: uncomment the following line to enable IReadOnlyCollection and IReadOnlyList support.
+//#define SIMPLE_JSON_READONLY_COLLECTIONS
+
// NOTE: uncomment the following line to disable linq expressions/compiled lambda (better performance) instead of method.invoke().
// define if you are using .net framework <= 3.0 or < WP7.5
//#define SIMPLE_JSON_NO_LINQ_EXPRESSION
@@ -512,6 +515,22 @@ namespace $rootnamespace$
private const int TOKEN_NULL = 11;
private const int BUILDER_CAPACITY = 2000;
+ private static readonly char[] EscapeTable;
+ private static readonly char[] EscapeCharacters = new char[] { '"', '\\', '\b', '\f', '\n', '\r', '\t' };
+ private static readonly string EscapeCharactersString = new string(EscapeCharacters);
+
+ static SimpleJson()
+ {
+ EscapeTable = new char[93];
+ EscapeTable['"'] = '"';
+ EscapeTable['\\'] = '\\';
+ EscapeTable['\b'] = 'b';
+ EscapeTable['\f'] = 'f';
+ EscapeTable['\n'] = 'n';
+ EscapeTable['\r'] = 'r';
+ EscapeTable['\t'] = 't';
+ }
+
///
/// Parses the string json into a value
///
@@ -1073,29 +1092,50 @@ namespace $rootnamespace$
static bool SerializeString(string aString, StringBuilder builder)
{
- builder.Append("\"");
+ // Happy path if there's nothing to be escaped. IndexOfAny is highly optimized (and unmanaged)
+ if (aString.IndexOfAny(EscapeCharacters) == -1)
+ {
+ builder.Append('"');
+ builder.Append(aString);
+ builder.Append('"');
+
+ return true;
+ }
+
+ builder.Append('"');
+ int safeCharacterCount = 0;
char[] charArray = aString.ToCharArray();
+
for (int i = 0; i < charArray.Length; i++)
{
char c = charArray[i];
- if (c == '"')
- builder.Append("\\\"");
- else if (c == '\\')
- builder.Append("\\\\");
- else if (c == '\b')
- builder.Append("\\b");
- else if (c == '\f')
- builder.Append("\\f");
- else if (c == '\n')
- builder.Append("\\n");
- else if (c == '\r')
- builder.Append("\\r");
- else if (c == '\t')
- builder.Append("\\t");
+
+ // Non ascii characters are fine, buffer them up and send them to the builder
+ // in larger chunks if possible. The escape table is a 1:1 translation table
+ // with \0 [default(char)] denoting a safe character.
+ if (c >= EscapeTable.Length || EscapeTable[c] == default(char))
+ {
+ safeCharacterCount++;
+ }
else
- builder.Append(c);
+ {
+ if (safeCharacterCount > 0)
+ {
+ builder.Append(charArray, i - safeCharacterCount, safeCharacterCount);
+ safeCharacterCount = 0;
+ }
+
+ builder.Append('\\');
+ builder.Append(EscapeTable[c]);
+ }
}
- builder.Append("\"");
+
+ if (safeCharacterCount > 0)
+ {
+ builder.Append(charArray, charArray.Length - safeCharacterCount, safeCharacterCount);
+ }
+
+ builder.Append('"');
return true;
}
@@ -1646,7 +1686,14 @@ namespace $rootnamespace$
Type genericDefinition = type.GetGenericTypeDefinition();
- return (genericDefinition == typeof(IList<>) || genericDefinition == typeof(ICollection<>) || genericDefinition == typeof(IEnumerable<>));
+ return (genericDefinition == typeof(IList<>)
+ || genericDefinition == typeof(ICollection<>)
+ || genericDefinition == typeof(IEnumerable<>)
+#if SIMPLE_JSON_READONLY_COLLECTIONS
+ || genericDefinition == typeof(IReadOnlyCollection<>)
+ || genericDefinition == typeof(IReadOnlyList<>)
+#endif
+ );
}
public static bool IsAssignableFrom(Type type1, Type type2)