-Performance
This commit is contained in:
@@ -77,22 +77,30 @@
|
||||
<Compile Include="Linq\JPathTests.cs" />
|
||||
<Compile Include="Linq\JRawTests.cs" />
|
||||
<Compile Include="Serialization\ConstructorHandlingTests.cs" />
|
||||
<Compile Include="TestObjects\Bar.cs" />
|
||||
<Compile Include="TestObjects\Car.cs" />
|
||||
<Compile Include="TestObjects\Computer.cs" />
|
||||
<Compile Include="TestObjects\ConstructorReadonlyFields.cs" />
|
||||
<Compile Include="TestObjects\Container.cs" />
|
||||
<Compile Include="TestObjects\Content.cs" />
|
||||
<Compile Include="TestObjects\DictionaryInterfaceClass.cs" />
|
||||
<Compile Include="Serialization\EntitiesSerializationTests.cs" />
|
||||
<Compile Include="TestObjects\Event.cs" />
|
||||
<Compile Include="TestObjects\Foo.cs" />
|
||||
<Compile Include="TestObjects\GoogleMapGeocoderStructure.cs" />
|
||||
<Compile Include="TestObjects\InterfacePropertyTestClass.cs" />
|
||||
<Compile Include="TestObjects\JsonPropertyClass.cs" />
|
||||
<Compile Include="Serialization\JsonSerializerTest.cs" />
|
||||
<Compile Include="TestObjects\ListOfIds.cs" />
|
||||
<Compile Include="TestObjects\ListTestClass.cs" />
|
||||
<Compile Include="TestObjects\LogEntry.cs" />
|
||||
<Compile Include="Serialization\MissingMemberHandlingTests.cs" />
|
||||
<Compile Include="TestObjects\Movie.cs" />
|
||||
<Compile Include="TestObjects\NonRequest.cs" />
|
||||
<Compile Include="TestObjects\ObjectArrayPropertyTest.cs" />
|
||||
<Compile Include="Serialization\PopulateTests.cs" />
|
||||
<Compile Include="TestObjects\PersonError.cs" />
|
||||
<Compile Include="TestObjects\PersonPropertyClass.cs" />
|
||||
<Compile Include="TestObjects\PrivateConstructorTestClass.cs" />
|
||||
<Compile Include="TestObjects\PrivateConstructorWithPublicParametizedConstructorTestClass.cs" />
|
||||
<Compile Include="TestObjects\PropertyCase.cs" />
|
||||
@@ -105,7 +113,9 @@
|
||||
<Compile Include="Schema\JsonSchemaNodeTests.cs" />
|
||||
<Compile Include="Serialization\CamelCasePropertyNamesContractResolverTests.cs" />
|
||||
<Compile Include="Serialization\PreserveReferencesHandlingTests.cs" />
|
||||
<Compile Include="TestObjects\SearchResult.cs" />
|
||||
<Compile Include="TestObjects\SetOnlyPropertyClass2.cs" />
|
||||
<Compile Include="TestObjects\StructTest.cs" />
|
||||
<Compile Include="TestObjects\SubKlass.cs" />
|
||||
<Compile Include="TestObjects\SuperKlass.cs" />
|
||||
<Compile Include="Serialization\TypeNameHandlingTests.cs" />
|
||||
@@ -189,6 +199,7 @@
|
||||
<Compile Include="TestObjects\TypedSubHashtable.cs" />
|
||||
<Compile Include="TestObjects\UserNullable.cs" />
|
||||
<Compile Include="TestObjects\VersionKeyedCollection.cs" />
|
||||
<Compile Include="TestObjects\WagePerson.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Service Include="{3259AA49-8AA1-44D3-9025-A0B520596A8C}" />
|
||||
|
||||
@@ -3,8 +3,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Diagnostics;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using System.IO;
|
||||
|
||||
using System.Web.Script.Serialization;
|
||||
@@ -16,6 +14,13 @@ using Newtonsoft.Json.Bson;
|
||||
|
||||
namespace Newtonsoft.Json.Tests
|
||||
{
|
||||
public class Image
|
||||
{
|
||||
public string FileName { get; set; }
|
||||
public string Title { get; set; }
|
||||
public byte[] Data { get; set; }
|
||||
}
|
||||
|
||||
public class PerformanceTests : TestFixtureBase
|
||||
{
|
||||
private const int Iterations = 100;
|
||||
@@ -70,6 +75,50 @@ namespace Newtonsoft.Json.Tests
|
||||
|
||||
[Test]
|
||||
public void Serialize()
|
||||
{
|
||||
TestClass test = CreateSerializationObject();
|
||||
|
||||
BenchmarkSerializeMethod(SerializeMethod.JsonNet, test);
|
||||
BenchmarkSerializeMethod(SerializeMethod.JsonNetBinary, test);
|
||||
BenchmarkSerializeMethod(SerializeMethod.JavaScriptSerializer, test);
|
||||
BenchmarkSerializeMethod(SerializeMethod.DataContractJsonSerializer, test);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Deserialize()
|
||||
{
|
||||
BenchmarkDeserializeMethod<TestClass>(SerializeMethod.JsonNet, JsonText);
|
||||
BenchmarkDeserializeMethod<TestClass>(SerializeMethod.JsonNetBinary, MiscellaneousUtils.HexToBytes(BsonHex));
|
||||
BenchmarkDeserializeMethod<TestClass>(SerializeMethod.JavaScriptSerializer, JsonText);
|
||||
BenchmarkDeserializeMethod<TestClass>(SerializeMethod.DataContractJsonSerializer, JsonText);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SerializeDataSize()
|
||||
{
|
||||
Image image = new Image();
|
||||
image.Data = System.IO.File.ReadAllBytes(@"..\..\bunny_pancake.jpg");
|
||||
image.FileName = "bunny_pancake.jpg";
|
||||
image.Title = "I have no idea what you are talking about so here's a bunny with a pancake on its head";
|
||||
|
||||
string json = JsonConvert.SerializeObject(image, Formatting.None);
|
||||
byte[] jsonBytes = Encoding.UTF8.GetBytes(json);
|
||||
|
||||
MemoryStream ms = new MemoryStream();
|
||||
JsonSerializer serializer = new JsonSerializer();
|
||||
BsonWriter writer = new BsonWriter(ms);
|
||||
|
||||
serializer.Serialize(writer, image);
|
||||
writer.Flush();
|
||||
|
||||
byte[] bsonBytes = ms.ToArray();
|
||||
|
||||
Console.WriteLine("Image size: {0} bytes", image.Data.Length);
|
||||
Console.WriteLine("JSON size: {0} bytes", jsonBytes.Length);
|
||||
Console.WriteLine("BSON size: {0} bytes", bsonBytes.Length);
|
||||
}
|
||||
|
||||
private TestClass CreateSerializationObject()
|
||||
{
|
||||
TestClass test = new TestClass();
|
||||
|
||||
@@ -90,20 +139,7 @@ namespace Newtonsoft.Json.Tests
|
||||
address.Entered = DateTime.Now.AddDays(-2);
|
||||
address.Address = "array 2 address";
|
||||
test.Addresses.Add(address);
|
||||
|
||||
BenchmarkSerializeMethod(SerializeMethod.JsonNet, test);
|
||||
BenchmarkSerializeMethod(SerializeMethod.JsonNetBinary, test);
|
||||
BenchmarkSerializeMethod(SerializeMethod.JavaScriptSerializer, test);
|
||||
BenchmarkSerializeMethod(SerializeMethod.DataContractJsonSerializer, test);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Deserialize()
|
||||
{
|
||||
BenchmarkDeserializeMethod<TestClass>(SerializeMethod.JsonNet, JsonText);
|
||||
BenchmarkDeserializeMethod<TestClass>(SerializeMethod.JsonNetBinary, MiscellaneousUtils.HexToBytes(BsonHex));
|
||||
BenchmarkDeserializeMethod<TestClass>(SerializeMethod.JavaScriptSerializer, JsonText);
|
||||
BenchmarkDeserializeMethod<TestClass>(SerializeMethod.DataContractJsonSerializer, JsonText);
|
||||
return test;
|
||||
}
|
||||
|
||||
public string SerializeJsonNet(object value)
|
||||
@@ -203,33 +239,49 @@ namespace Newtonsoft.Json.Tests
|
||||
return dataContractSerializer.ReadObject(ms);
|
||||
}
|
||||
|
||||
private static readonly byte[] Buffer = new byte[4096];
|
||||
|
||||
private string Serialize(SerializeMethod method, object value)
|
||||
{
|
||||
string json;
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case SerializeMethod.JsonNet:
|
||||
json = JsonConvert.SerializeObject(value);
|
||||
break;
|
||||
case SerializeMethod.JsonNetBinary:
|
||||
MemoryStream ms = new MemoryStream(Buffer);
|
||||
JsonSerializer serializer = new JsonSerializer();
|
||||
BsonWriter writer = new BsonWriter(ms);
|
||||
serializer.Serialize(writer, value);
|
||||
|
||||
json = "Bytes = " + ms.Length;
|
||||
break;
|
||||
case SerializeMethod.JavaScriptSerializer:
|
||||
json = SerializeWebExtensions(value);
|
||||
break;
|
||||
case SerializeMethod.DataContractJsonSerializer:
|
||||
json = SerializeDataContract(value);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("method");
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
public void BenchmarkSerializeMethod(SerializeMethod method, object value)
|
||||
{
|
||||
Serialize(method, value);
|
||||
|
||||
Stopwatch timed = new Stopwatch();
|
||||
timed.Start();
|
||||
|
||||
string json = null;
|
||||
for (int x = 0; x < Iterations; x++)
|
||||
{
|
||||
switch (method)
|
||||
{
|
||||
case SerializeMethod.JsonNet:
|
||||
json = JsonConvert.SerializeObject(value);
|
||||
break;
|
||||
case SerializeMethod.JsonNetBinary:
|
||||
JsonSerializer serializer = new JsonSerializer();
|
||||
MemoryStream ms = new MemoryStream();
|
||||
BsonWriter writer = new BsonWriter(ms);
|
||||
serializer.Serialize(writer, value);
|
||||
json = "{Bytes " + ms.Length + "}";
|
||||
break;
|
||||
case SerializeMethod.JavaScriptSerializer:
|
||||
json = SerializeWebExtensions(value);
|
||||
break;
|
||||
case SerializeMethod.DataContractJsonSerializer:
|
||||
json = SerializeDataContract(value);
|
||||
break;
|
||||
}
|
||||
json = Serialize(method, value);
|
||||
}
|
||||
|
||||
timed.Stop();
|
||||
@@ -248,21 +300,7 @@ namespace Newtonsoft.Json.Tests
|
||||
object value = null;
|
||||
for (int x = 0; x < Iterations; x++)
|
||||
{
|
||||
switch (method)
|
||||
{
|
||||
case SerializeMethod.JsonNet:
|
||||
value = DeserializeJsonNet<T>((string)json);
|
||||
break;
|
||||
case SerializeMethod.JsonNetBinary:
|
||||
value = DeserializeJsonNetBinary<T>((byte[])json);
|
||||
break;
|
||||
case SerializeMethod.JavaScriptSerializer:
|
||||
value = DeserializeWebExtensions<T>((string)json);
|
||||
break;
|
||||
case SerializeMethod.DataContractJsonSerializer:
|
||||
value = DeserializeDataContract<T>((string)json);
|
||||
break;
|
||||
}
|
||||
value = Deserialize<T>(method, json);
|
||||
}
|
||||
|
||||
timed.Stop();
|
||||
@@ -272,6 +310,30 @@ namespace Newtonsoft.Json.Tests
|
||||
Console.WriteLine(value);
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
private object Deserialize<T>(SerializeMethod method, object json)
|
||||
{
|
||||
object value;
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case SerializeMethod.JsonNet:
|
||||
value = DeserializeJsonNet<T>((string) json);
|
||||
break;
|
||||
case SerializeMethod.JsonNetBinary:
|
||||
value = DeserializeJsonNetBinary<T>((byte[]) json);
|
||||
break;
|
||||
case SerializeMethod.JavaScriptSerializer:
|
||||
value = DeserializeWebExtensions<T>((string) json);
|
||||
break;
|
||||
case SerializeMethod.DataContractJsonSerializer:
|
||||
value = DeserializeDataContract<T>((string) json);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("method");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 18 KiB |
@@ -37,8 +37,13 @@ namespace Newtonsoft.Json.Bson
|
||||
/// </summary>
|
||||
public class BsonWriter : JTokenWriter
|
||||
{
|
||||
private static readonly Encoding Encoding = Encoding.UTF8;
|
||||
|
||||
private readonly BinaryWriter _writer;
|
||||
|
||||
private byte[] _largeByteBuffer;
|
||||
private int _maxChars;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BsonWriter"/> class.
|
||||
/// </summary>
|
||||
@@ -68,7 +73,7 @@ namespace Newtonsoft.Json.Bson
|
||||
foreach (JProperty property in t)
|
||||
{
|
||||
_writer.Write((sbyte)GetTypeNumber(property.Value));
|
||||
WriteString(property.Name);
|
||||
WriteString(property.Name, false);
|
||||
WriteToken(property.Value);
|
||||
}
|
||||
_writer.Write((byte)0);
|
||||
@@ -82,7 +87,7 @@ namespace Newtonsoft.Json.Bson
|
||||
foreach (JToken c in t)
|
||||
{
|
||||
_writer.Write((sbyte)GetTypeNumber(c));
|
||||
WriteString(index.ToString(CultureInfo.InvariantCulture));
|
||||
WriteString(index.ToString(CultureInfo.InvariantCulture), false);
|
||||
WriteToken(c);
|
||||
index++;
|
||||
}
|
||||
@@ -96,7 +101,7 @@ namespace Newtonsoft.Json.Bson
|
||||
_writer.Write(Convert.ToDouble(((JValue)t).Value, CultureInfo.InvariantCulture));
|
||||
break;
|
||||
case JTokenType.String:
|
||||
WriteStringWithLength((string)t);
|
||||
WriteString((string)t, true);
|
||||
break;
|
||||
case JTokenType.Boolean:
|
||||
_writer.Write((bool)t);
|
||||
@@ -121,17 +126,37 @@ namespace Newtonsoft.Json.Bson
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteString(string s)
|
||||
private void WriteString(string s, bool includeLength)
|
||||
{
|
||||
byte[] bytes = Encoding.UTF8.GetBytes(s);
|
||||
_writer.Write(bytes);
|
||||
_writer.Write((byte)0);
|
||||
}
|
||||
int byteCount = Encoding.GetByteCount(s);
|
||||
|
||||
private void WriteStringWithLength(string s)
|
||||
{
|
||||
_writer.Write(CalculateSizeWithLength(s, false));
|
||||
WriteString(s);
|
||||
if (includeLength)
|
||||
_writer.Write(CalculateSizeWithLength(byteCount, false));
|
||||
|
||||
if (_largeByteBuffer == null)
|
||||
{
|
||||
_largeByteBuffer = new byte[256];
|
||||
_maxChars = 256 / Encoding.GetMaxByteCount(1);
|
||||
}
|
||||
if (byteCount <= 256)
|
||||
{
|
||||
Encoding.GetBytes(s, 0, s.Length, _largeByteBuffer, 0);
|
||||
_writer.Write(_largeByteBuffer, 0, byteCount);
|
||||
}
|
||||
else
|
||||
{
|
||||
int charCount;
|
||||
int totalCharsWritten = 0;
|
||||
for (int i = s.Length; i > 0; i -= charCount)
|
||||
{
|
||||
charCount = (i > _maxChars) ? _maxChars : i;
|
||||
int count = Encoding.GetBytes(s, totalCharsWritten, charCount, _largeByteBuffer, 0);
|
||||
_writer.Write(_largeByteBuffer, 0, count);
|
||||
totalCharsWritten += charCount;
|
||||
}
|
||||
}
|
||||
|
||||
_writer.Write((byte)0);
|
||||
}
|
||||
|
||||
private BsonType GetTypeNumber(JToken t)
|
||||
@@ -164,18 +189,21 @@ namespace Newtonsoft.Json.Bson
|
||||
|
||||
private int CalculateSize(string s)
|
||||
{
|
||||
return Encoding.UTF8.GetByteCount(s) + 1;
|
||||
return Encoding.GetByteCount(s) + 1;
|
||||
}
|
||||
|
||||
private int CalculateSizeWithLength(string s, bool includeSize)
|
||||
{
|
||||
return CalculateSizeWithLength(Encoding.GetByteCount(s), includeSize);
|
||||
}
|
||||
|
||||
private int CalculateSizeWithLength(int stringByteCount, bool includeSize)
|
||||
{
|
||||
int baseSize = (includeSize)
|
||||
? 5 // size bytes + terminator
|
||||
: 1; // terminator
|
||||
|
||||
int byteCount = Encoding.UTF8.GetByteCount(s);
|
||||
|
||||
return baseSize + byteCount;
|
||||
return baseSize + stringByteCount;
|
||||
}
|
||||
|
||||
private int CalculateSize(JToken t)
|
||||
|
||||
@@ -601,9 +601,11 @@ namespace Newtonsoft.Json
|
||||
WriteIndentSpace();
|
||||
}
|
||||
|
||||
WriteState writeState = WriteState;
|
||||
|
||||
// don't indent a property when it is the first token to be written (i.e. at the start)
|
||||
if ((tokenBeingWritten == JsonToken.PropertyName && WriteState != WriteState.Start) ||
|
||||
WriteState == WriteState.Array || WriteState == WriteState.Constructor)
|
||||
if ((tokenBeingWritten == JsonToken.PropertyName && writeState != WriteState.Start) ||
|
||||
writeState == WriteState.Array || writeState == WriteState.Constructor)
|
||||
{
|
||||
WriteIndent();
|
||||
}
|
||||
|
||||
@@ -219,8 +219,7 @@ namespace Newtonsoft.Json.Linq
|
||||
{
|
||||
yield return current;
|
||||
}
|
||||
while (current != null
|
||||
&& ((current = current.Next) != null));
|
||||
while ((current = current.Next) != null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -105,10 +105,14 @@ namespace Newtonsoft.Json.Linq
|
||||
if (o.Type != JTokenType.Property)
|
||||
throw new ArgumentException("Can not add {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, o.GetType(), GetType()));
|
||||
|
||||
// looping over all properties every time isn't good
|
||||
// need to think about performance here
|
||||
JProperty property = (JProperty)o;
|
||||
bool matchingProperty = Properties().Any(p => string.Equals(p.Name, property.Name, StringComparison.Ordinal) && p != existing);
|
||||
if (matchingProperty)
|
||||
throw new ArgumentException("Can not add property {0} to {1}. Property with the same name already exists on object.".FormatWith(CultureInfo.InvariantCulture, property.Name, GetType()));
|
||||
foreach (JProperty childProperty in Children())
|
||||
{
|
||||
if (childProperty != existing && string.Equals(childProperty.Name, property.Name, StringComparison.Ordinal))
|
||||
throw new ArgumentException("Can not add property {0} to {1}. Property with the same name already exists on object.".FormatWith(CultureInfo.InvariantCulture, property.Name, GetType()));
|
||||
}
|
||||
}
|
||||
|
||||
internal void InternalPropertyChanged(JProperty childProperty)
|
||||
|
||||
@@ -35,71 +35,68 @@ namespace Newtonsoft.Json.Utilities
|
||||
{
|
||||
internal static class JavaScriptUtils
|
||||
{
|
||||
public static void WriteEscapedJavaScriptChar(TextWriter writer, char c, char delimiter)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case '\t':
|
||||
writer.Write(@"\t");
|
||||
break;
|
||||
case '\n':
|
||||
writer.Write(@"\n");
|
||||
break;
|
||||
case '\r':
|
||||
writer.Write(@"\r");
|
||||
break;
|
||||
case '\f':
|
||||
writer.Write(@"\f");
|
||||
break;
|
||||
case '\b':
|
||||
writer.Write(@"\b");
|
||||
break;
|
||||
case '\\':
|
||||
writer.Write(@"\\");
|
||||
break;
|
||||
case '\u0085': // Next Line
|
||||
writer.Write(@"\u0085");
|
||||
break;
|
||||
case '\u2028': // Line Separator
|
||||
writer.Write(@"\u2028");
|
||||
break;
|
||||
case '\u2029': // Paragraph Separator
|
||||
writer.Write(@"\u2029");
|
||||
break;
|
||||
case '\'':
|
||||
// only escape if this charater is being used as the delimiter
|
||||
writer.Write((delimiter == '\'') ? @"\'" : @"'");
|
||||
break;
|
||||
case '"':
|
||||
// only escape if this charater is being used as the delimiter
|
||||
writer.Write((delimiter == '"') ? "\\\"" : @"""");
|
||||
break;
|
||||
default:
|
||||
if (c > '\u001f')
|
||||
writer.Write(c);
|
||||
else
|
||||
StringUtils.WriteCharAsUnicode(writer, c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static void WriteEscapedJavaScriptString(TextWriter writer, string value, char delimiter, bool appendDelimiters)
|
||||
public static void WriteEscapedJavaScriptString(StringBuilder writer, string value, char delimiter, bool appendDelimiters)
|
||||
{
|
||||
// leading delimiter
|
||||
if (appendDelimiters)
|
||||
writer.Write(delimiter);
|
||||
writer.Append(delimiter);
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
{
|
||||
WriteEscapedJavaScriptChar(writer, value[i], delimiter);
|
||||
char c = value[i];
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '\t':
|
||||
writer.Append(@"\t");
|
||||
break;
|
||||
case '\n':
|
||||
writer.Append(@"\n");
|
||||
break;
|
||||
case '\r':
|
||||
writer.Append(@"\r");
|
||||
break;
|
||||
case '\f':
|
||||
writer.Append(@"\f");
|
||||
break;
|
||||
case '\b':
|
||||
writer.Append(@"\b");
|
||||
break;
|
||||
case '\\':
|
||||
writer.Append(@"\\");
|
||||
break;
|
||||
case '\u0085': // Next Line
|
||||
writer.Append(@"\u0085");
|
||||
break;
|
||||
case '\u2028': // Line Separator
|
||||
writer.Append(@"\u2028");
|
||||
break;
|
||||
case '\u2029': // Paragraph Separator
|
||||
writer.Append(@"\u2029");
|
||||
break;
|
||||
case '\'':
|
||||
// only escape if this charater is being used as the delimiter
|
||||
writer.Append((delimiter == '\'') ? @"\'" : @"'");
|
||||
break;
|
||||
case '"':
|
||||
// only escape if this charater is being used as the delimiter
|
||||
writer.Append((delimiter == '"') ? "\\\"" : @"""");
|
||||
break;
|
||||
default:
|
||||
if (c > '\u001f')
|
||||
writer.Append(c);
|
||||
else
|
||||
StringUtils.WriteCharAsUnicode(writer, c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// trailing delimiter
|
||||
if (appendDelimiters)
|
||||
writer.Write(delimiter);
|
||||
writer.Append(delimiter);
|
||||
}
|
||||
|
||||
public static string ToEscapedJavaScriptString(string value)
|
||||
@@ -109,11 +106,14 @@ namespace Newtonsoft.Json.Utilities
|
||||
|
||||
public static string ToEscapedJavaScriptString(string value, char delimiter, bool appendDelimiters)
|
||||
{
|
||||
using (StringWriter w = StringUtils.CreateStringWriter(StringUtils.GetLength(value) ?? 16))
|
||||
{
|
||||
WriteEscapedJavaScriptString(w, value, delimiter, appendDelimiters);
|
||||
return w.ToString();
|
||||
}
|
||||
int length = value.Length;
|
||||
if (appendDelimiters)
|
||||
length += 2;
|
||||
|
||||
StringBuilder builder = new StringBuilder(length);
|
||||
|
||||
WriteEscapedJavaScriptString(builder, value, delimiter, appendDelimiters);
|
||||
return builder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -325,14 +325,13 @@ namespace Newtonsoft.Json.Utilities
|
||||
|
||||
public static string ToCharAsUnicode(char c)
|
||||
{
|
||||
using (StringWriter w = new StringWriter(CultureInfo.InvariantCulture))
|
||||
{
|
||||
WriteCharAsUnicode(w, c);
|
||||
return w.ToString();
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
WriteCharAsUnicode(builder, c);
|
||||
|
||||
return builder.ToString();
|
||||
}
|
||||
|
||||
public static void WriteCharAsUnicode(TextWriter writer, char c)
|
||||
public static void WriteCharAsUnicode(StringBuilder writer, char c)
|
||||
{
|
||||
ValidationUtils.ArgumentNotNull(writer, "writer");
|
||||
|
||||
@@ -341,12 +340,12 @@ namespace Newtonsoft.Json.Utilities
|
||||
char h3 = MathUtils.IntToHex((c >> 4) & '\x000f');
|
||||
char h4 = MathUtils.IntToHex(c & '\x000f');
|
||||
|
||||
writer.Write('\\');
|
||||
writer.Write('u');
|
||||
writer.Write(h1);
|
||||
writer.Write(h2);
|
||||
writer.Write(h3);
|
||||
writer.Write(h4);
|
||||
writer.Append('\\');
|
||||
writer.Append('u');
|
||||
writer.Append(h1);
|
||||
writer.Append(h2);
|
||||
writer.Append(h3);
|
||||
writer.Append(h4);
|
||||
}
|
||||
|
||||
public static TSource ForgivingCaseSensitiveFind<TSource>(this IEnumerable<TSource> source, Func<TSource, string> valueSelector, string testValue)
|
||||
|
||||
Reference in New Issue
Block a user