Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/Newtonsoft.Json.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJamesNK <james@newtonking.com>2009-12-07 02:10:14 +0300
committerJamesNK <james@newtonking.com>2009-12-07 02:10:14 +0300
commitf1a9993723e8bcb3ec61456a17ff4c47ed2326b2 (patch)
tree122dc00f49d2f59b0f908c35b01790a772a6b479
parent7d845d1f135dfe27aa35950e344171e06d0543fd (diff)
-Added reading and writing binary JSON (BSON) support - work in progress
-Added BsonReader, BsonWriter -Added support for reading and writing byte arrays to JsonReader, JsonWriter and LINQ to JSON classes -Added ReadAsBytes to JsonReader -Changed Silverlight build serializer to look for a TypeConverter -Changed .NET build to not rely on System.ComponentModel.DataAnnotations assembly to support .NET 4.0 client profile -Remove DateTimeOffset stand-in from Compact Framework build -Fixed .NET 2.0 build to run on environments without .NET 2.0 SP1 -Fixed deserialization to always use a new value created from a JsonConverter -Fixed XmlNodeConverter to support converting comments in JSON
-rw-r--r--Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs180
-rw-r--r--Src/Newtonsoft.Json.Tests/Bson/BsonWriterTests.cs112
-rw-r--r--Src/Newtonsoft.Json.Tests/Converters/IsoDateTimeConverterTests.cs2
-rw-r--r--Src/Newtonsoft.Json.Tests/Converters/JavaScriptDateTimeConverterTests.cs20
-rw-r--r--Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs29
-rw-r--r--Src/Newtonsoft.Json.Tests/JsonConvertTest.cs4
-rw-r--r--Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs13
-rw-r--r--Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs70
-rw-r--r--Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs4
-rw-r--r--Src/Newtonsoft.Json.Tests/Linq/JTokenReaderTest.cs53
-rw-r--r--Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs14
-rw-r--r--Src/Newtonsoft.Json.Tests/Linq/JTokenWriterTest.cs10
-rw-r--r--Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs6
-rw-r--r--Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs7
-rw-r--r--Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj2
-rw-r--r--Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs84
-rw-r--r--Src/Newtonsoft.Json.Tests/Serialization/NullValueHandlingTests.cs29
-rw-r--r--Src/Newtonsoft.Json.Tests/TestObjects/DateTimeTestClass.cs4
-rw-r--r--Src/Newtonsoft.Json.Tests/TestObjects/NullableDateTimeTestClass.cs4
-rw-r--r--Src/Newtonsoft.Json.Tests/TestObjects/Store.cs4
-rw-r--r--Src/Newtonsoft.Json/Bson/BsonBinaryType.cs41
-rw-r--r--Src/Newtonsoft.Json/Bson/BsonReader.cs312
-rw-r--r--Src/Newtonsoft.Json/Bson/BsonType.cs55
-rw-r--r--Src/Newtonsoft.Json/Bson/BsonWriter.cs291
-rw-r--r--Src/Newtonsoft.Json/Converters/BinaryConverter.cs20
-rw-r--r--Src/Newtonsoft.Json/Converters/DataSetConverter.cs29
-rw-r--r--Src/Newtonsoft.Json/Converters/DataTableConverter.cs29
-rw-r--r--Src/Newtonsoft.Json/Converters/HtmlColorConverter.cs2
-rw-r--r--Src/Newtonsoft.Json/Converters/IsoDateTimeConverter.cs10
-rw-r--r--Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs16
-rw-r--r--Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs3
-rw-r--r--Src/Newtonsoft.Json/DateTimeOffset.cs544
-rw-r--r--Src/Newtonsoft.Json/JsonConvert.cs11
-rw-r--r--Src/Newtonsoft.Json/JsonReader.cs6
-rw-r--r--Src/Newtonsoft.Json/JsonSerializer.cs2
-rw-r--r--Src/Newtonsoft.Json/JsonTextReader.cs87
-rw-r--r--Src/Newtonsoft.Json/JsonTextWriter.cs29
-rw-r--r--Src/Newtonsoft.Json/JsonToken.cs14
-rw-r--r--Src/Newtonsoft.Json/JsonValidatingReader.cs26
-rw-r--r--Src/Newtonsoft.Json/JsonWriter.cs21
-rw-r--r--Src/Newtonsoft.Json/Linq/JContainer.cs2
-rw-r--r--Src/Newtonsoft.Json/Linq/JObject.cs10
-rw-r--r--Src/Newtonsoft.Json/Linq/JToken.cs27
-rw-r--r--Src/Newtonsoft.Json/Linq/JTokenReader.cs15
-rw-r--r--Src/Newtonsoft.Json/Linq/JTokenType.cs3
-rw-r--r--Src/Newtonsoft.Json/Linq/JTokenWriter.cs8
-rw-r--r--Src/Newtonsoft.Json/Linq/JValue.cs20
-rw-r--r--Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj2
-rw-r--r--Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj3
-rw-r--r--Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj2
-rw-r--r--Src/Newtonsoft.Json/Newtonsoft.Json.csproj8
-rw-r--r--Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs6
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs56
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs18
-rw-r--r--Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs91
-rw-r--r--Src/Newtonsoft.Json/Utilities/Base64Encoder.cs95
-rw-r--r--Src/Newtonsoft.Json/Utilities/ConvertUtils.cs21
-rw-r--r--Src/Newtonsoft.Json/Utilities/MiscellaneousUtils.cs58
-rw-r--r--Src/Newtonsoft.Json/Utilities/StringBuffer.cs5
59 files changed, 1952 insertions, 697 deletions
diff --git a/Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs b/Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs
new file mode 100644
index 0000000..95880fd
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs
@@ -0,0 +1,180 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using Newtonsoft.Json.Bson;
+using System.IO;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Tests.Bson
+{
+ public class BsonReaderTests : TestFixtureBase
+ {
+ [Test]
+ public void ReadSingleObject()
+ {
+ byte[] data = MiscellaneousUtils.HexToBytes("0F-00-00-00-10-42-6C-61-68-00-01-00-00-00-00");
+ MemoryStream ms = new MemoryStream(data);
+ BsonReader reader = new BsonReader(ms);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+ Assert.AreEqual("Blah", reader.Value);
+ Assert.AreEqual(typeof(string), reader.ValueType);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.Integer, reader.TokenType);
+ Assert.AreEqual(1, reader.Value);
+ Assert.AreEqual(typeof(long), reader.ValueType);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+ Assert.IsFalse(reader.Read());
+ }
+
+ [Test]
+ public void ReadObjectBsonFromSite()
+ {
+ byte[] data = MiscellaneousUtils.HexToBytes("20-00-00-00-02-30-00-02-00-00-00-61-00-02-31-00-02-00-00-00-62-00-02-32-00-02-00-00-00-63-00-00");
+
+ MemoryStream ms = new MemoryStream(data);
+ BsonReader reader = new BsonReader(ms);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.StartObject, reader.TokenType);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+ Assert.AreEqual("0", reader.Value);
+ Assert.AreEqual(typeof(string), reader.ValueType);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.String, reader.TokenType);
+ Assert.AreEqual("a", reader.Value);
+ Assert.AreEqual(typeof(string), reader.ValueType);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+ Assert.AreEqual("1", reader.Value);
+ Assert.AreEqual(typeof(string), reader.ValueType);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.String, reader.TokenType);
+ Assert.AreEqual("b", reader.Value);
+ Assert.AreEqual(typeof(string), reader.ValueType);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+ Assert.AreEqual("2", reader.Value);
+ Assert.AreEqual(typeof(string), reader.ValueType);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.String, reader.TokenType);
+ Assert.AreEqual("c", reader.Value);
+ Assert.AreEqual(typeof(string), reader.ValueType);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+ Assert.IsFalse(reader.Read());
+ }
+
+ [Test]
+ public void ReadArrayBsonFromSite()
+ {
+ byte[] data = MiscellaneousUtils.HexToBytes("20-00-00-00-02-30-00-02-00-00-00-61-00-02-31-00-02-00-00-00-62-00-02-32-00-02-00-00-00-63-00-00");
+
+ MemoryStream ms = new MemoryStream(data);
+ BsonReader reader = new BsonReader(ms, true);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.String, reader.TokenType);
+ Assert.AreEqual("a", reader.Value);
+ Assert.AreEqual(typeof(string), reader.ValueType);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.String, reader.TokenType);
+ Assert.AreEqual("b", reader.Value);
+ Assert.AreEqual(typeof(string), reader.ValueType);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.String, reader.TokenType);
+ Assert.AreEqual("c", reader.Value);
+ Assert.AreEqual(typeof(string), reader.ValueType);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+
+ Assert.IsFalse(reader.Read());
+ }
+
+ [Test]
+ public void ReadBytes()
+ {
+ byte[] data = MiscellaneousUtils.HexToBytes("2B-00-00-00-02-30-00-02-00-00-00-61-00-02-31-00-02-00-00-00-62-00-05-32-00-0C-00-00-00-02-48-65-6C-6C-6F-20-77-6F-72-6C-64-21-00");
+
+ MemoryStream ms = new MemoryStream(data);
+ BsonReader reader = new BsonReader(ms, true);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.String, reader.TokenType);
+ Assert.AreEqual("a", reader.Value);
+ Assert.AreEqual(typeof(string), reader.ValueType);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.String, reader.TokenType);
+ Assert.AreEqual("b", reader.Value);
+ Assert.AreEqual(typeof(string), reader.ValueType);
+
+ byte[] encodedStringData = reader.ReadAsBytes();
+ Assert.IsNotNull(encodedStringData);
+ Assert.AreEqual(JsonToken.Bytes, reader.TokenType);
+ Assert.AreEqual(encodedStringData, reader.Value);
+ Assert.AreEqual(typeof(byte[]), reader.ValueType);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+
+ Assert.IsFalse(reader.Read());
+
+ string decodedString = Encoding.UTF8.GetString(encodedStringData);
+ Assert.AreEqual("Hello world!", decodedString);
+ }
+ }
+} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/Bson/BsonWriterTests.cs b/Src/Newtonsoft.Json.Tests/Bson/BsonWriterTests.cs
new file mode 100644
index 0000000..f3ce880
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/Bson/BsonWriterTests.cs
@@ -0,0 +1,112 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using Newtonsoft.Json.Bson;
+using System.IO;
+using Newtonsoft.Json.Utilities;
+
+namespace Newtonsoft.Json.Tests.Bson
+{
+ public class BsonWriterTests : TestFixtureBase
+ {
+ [Test]
+ public void WriteSingleObject()
+ {
+ MemoryStream ms = new MemoryStream();
+ BsonWriter writer = new BsonWriter(ms);
+
+ writer.WriteStartObject();
+ writer.WritePropertyName("Blah");
+ writer.WriteValue(1);
+ writer.WriteEndObject();
+ writer.Flush();
+
+ string bson = MiscellaneousUtils.BytesToHex(ms.ToArray());
+ Assert.AreEqual("0F-00-00-00-10-42-6C-61-68-00-01-00-00-00-00", bson);
+ }
+
+ [Test]
+ [ExpectedException(typeof(JsonWriterException), ExpectedMessage = "Cannot flush BsonWriter until JSON is complete.")]
+ public void FlushInsideObject()
+ {
+ MemoryStream ms = new MemoryStream();
+ BsonWriter writer = new BsonWriter(ms);
+
+ writer.WriteStartObject();
+ writer.WritePropertyName("Blah");
+ writer.WriteValue(1);
+ writer.Flush();
+ }
+
+ [Test]
+ public void WriteArrayBsonFromSite()
+ {
+ MemoryStream ms = new MemoryStream();
+ BsonWriter writer = new BsonWriter(ms);
+ writer.WriteStartArray();
+ writer.WriteValue("a");
+ writer.WriteValue("b");
+ writer.WriteValue("c");
+ writer.WriteEndArray();
+
+ writer.Flush();
+
+ ms.Seek(0, SeekOrigin.Begin);
+
+ string expected = "20-00-00-00-02-30-00-02-00-00-00-61-00-02-31-00-02-00-00-00-62-00-02-32-00-02-00-00-00-63-00-00";
+ string bson = MiscellaneousUtils.BytesToHex(ms.ToArray());
+
+ Assert.AreEqual(expected, bson);
+ }
+
+ [Test]
+ public void WriteBytes()
+ {
+ byte[] data = Encoding.UTF8.GetBytes("Hello world!");
+
+ MemoryStream ms = new MemoryStream();
+ BsonWriter writer = new BsonWriter(ms);
+ writer.WriteStartArray();
+ writer.WriteValue("a");
+ writer.WriteValue("b");
+ writer.WriteValue(data);
+ writer.WriteEndArray();
+
+ writer.Flush();
+
+ ms.Seek(0, SeekOrigin.Begin);
+
+ string expected = "2B-00-00-00-02-30-00-02-00-00-00-61-00-02-31-00-02-00-00-00-62-00-05-32-00-0C-00-00-00-02-48-65-6C-6C-6F-20-77-6F-72-6C-64-21-00";
+ string bson = MiscellaneousUtils.BytesToHex(ms.ToArray());
+
+ Assert.AreEqual(expected, bson);
+ }
+ }
+} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/Converters/IsoDateTimeConverterTests.cs b/Src/Newtonsoft.Json.Tests/Converters/IsoDateTimeConverterTests.cs
index 351f0ca..3b2558a 100644
--- a/Src/Newtonsoft.Json.Tests/Converters/IsoDateTimeConverterTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Converters/IsoDateTimeConverterTests.cs
@@ -142,6 +142,7 @@ namespace Newtonsoft.Json.Tests.Converters
}
#endif
+#if !PocketPC && !NET20
[Test]
public void SerializeDateTimeOffset()
{
@@ -266,6 +267,7 @@ namespace Newtonsoft.Json.Tests.Converters
string json2 = JsonConvert.SerializeObject(c, new IsoDateTimeConverter() { DateTimeStyles = DateTimeStyles.AssumeUniversal });
Assert.AreNotEqual(json, json2);
}
+#endif
[Test]
public void BlogCodeSample()
diff --git a/Src/Newtonsoft.Json.Tests/Converters/JavaScriptDateTimeConverterTests.cs b/Src/Newtonsoft.Json.Tests/Converters/JavaScriptDateTimeConverterTests.cs
index 31a947e..0111607 100644
--- a/Src/Newtonsoft.Json.Tests/Converters/JavaScriptDateTimeConverterTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Converters/JavaScriptDateTimeConverterTests.cs
@@ -47,6 +47,7 @@ namespace Newtonsoft.Json.Tests.Converters
Assert.AreEqual("new Date(976918263055)", result);
}
+#if !PocketPC && !NET20
[Test]
public void SerializeDateTimeOffset()
{
@@ -86,15 +87,6 @@ namespace Newtonsoft.Json.Tests.Converters
}
[Test]
- public void DeserializeDateTime()
- {
- JavaScriptDateTimeConverter converter = new JavaScriptDateTimeConverter();
-
- DateTime result = JsonConvert.DeserializeObject<DateTime>("new Date(976918263055)", converter);
- Assert.AreEqual(new DateTime(2000, 12, 15, 22, 11, 3, 55, DateTimeKind.Utc), result);
- }
-
- [Test]
[ExpectedException(typeof(Exception), ExpectedMessage = "Cannot convert null value to System.DateTime.")]
public void DeserializeNullToNonNullable()
{
@@ -113,5 +105,15 @@ namespace Newtonsoft.Json.Tests.Converters
DateTimeOffset result = JsonConvert.DeserializeObject<DateTimeOffset>(json, converter);
Assert.AreEqual(new DateTimeOffset(2000, 12, 15, 22, 11, 3, 55, TimeSpan.Zero), result);
}
+#endif
+
+ [Test]
+ public void DeserializeDateTime()
+ {
+ JavaScriptDateTimeConverter converter = new JavaScriptDateTimeConverter();
+
+ DateTime result = JsonConvert.DeserializeObject<DateTime>("new Date(976918263055)", converter);
+ Assert.AreEqual(new DateTime(2000, 12, 15, 22, 11, 3, 55, DateTimeKind.Utc), result);
+ }
}
} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs b/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs
index e6cd961..a3dc965 100644
--- a/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs
+++ b/Src/Newtonsoft.Json.Tests/Converters/XmlNodeConverterTest.cs
@@ -523,6 +523,35 @@ namespace Newtonsoft.Json.Tests.Converters
string json = JsonConvert.SerializeXmlNode(doc);
Assert.AreEqual(@"{""name"":""O\""Connor""}", json);
}
+
+ [Test]
+ public void SerializeComment()
+ {
+ string xml = @"<span class=""vevent"">
+ <a class=""url"" href=""http://www.web2con.com/"">Text</a><!-- Hi! -->
+</span>";
+ XmlDocument doc = new XmlDocument();
+ doc.LoadXml(xml);
+
+ string jsonText = JsonConvert.SerializeObject(doc, Formatting.Indented, new XmlNodeConverter());
+
+ string expected = @"{
+ ""span"": {
+ ""@class"": ""vevent"",
+ ""a"": {
+ ""@class"": ""url"",
+ ""@href"": ""http://www.web2con.com/"",
+ ""#text"": ""Text""
+ }/* Hi! */
+ }
+}";
+
+ Assert.AreEqual(expected, jsonText);
+
+ XmlDocument newDoc = JsonConvert.DeserializeObject<XmlDocument>(jsonText, new XmlNodeConverter());
+ Assert.AreEqual(@"<span class=""vevent""><a class=""url"" href=""http://www.web2con.com/"">Text</a><!-- Hi! --></span>", newDoc.InnerXml);
+ }
+
}
}
#endif \ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/JsonConvertTest.cs b/Src/Newtonsoft.Json.Tests/JsonConvertTest.cs
index a9e49cb..3e0982f 100644
--- a/Src/Newtonsoft.Json.Tests/JsonConvertTest.cs
+++ b/Src/Newtonsoft.Json.Tests/JsonConvertTest.cs
@@ -232,8 +232,10 @@ now brown cow?", '"', true);
value = new DateTime(JsonConvert.InitialJavaScriptDateTicks, DateTimeKind.Utc);
Assert.AreEqual(@"""\/Date(0)\/""", JsonConvert.ToString(value));
+#if !PocketPC && !NET20
value = new DateTimeOffset(JsonConvert.InitialJavaScriptDateTicks, TimeSpan.Zero);
Assert.AreEqual(@"""\/Date(0+0000)\/""", JsonConvert.ToString(value));
+#endif
value = null;
Assert.AreEqual("null", JsonConvert.ToString(value));
@@ -271,7 +273,7 @@ now brown cow?", '"', true);
int i = JsonConvert.DeserializeObject<int>("1");
Assert.AreEqual(1, i);
-#if !PocketPC
+#if !PocketPC && !NET20
DateTimeOffset d = JsonConvert.DeserializeObject<DateTimeOffset>(@"""\/Date(-59011455539000+0000)\/""");
Assert.AreEqual(new DateTimeOffset(new DateTime(100, 1, 1, 1, 1, 1, DateTimeKind.Utc)), d);
#endif
diff --git a/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs b/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs
index 6735c6f..62cf12a 100644
--- a/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs
+++ b/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs
@@ -469,5 +469,18 @@ namespace Newtonsoft.Json.Tests
reader.Read();
}
+
+ [Test]
+ public void ReadSingleBytes()
+ {
+ StringReader s = new StringReader(@"""SGVsbG8gd29ybGQu""");
+ JsonTextReader reader = new JsonTextReader(s);
+
+ byte[] data = reader.ReadAsBytes();
+ Assert.IsNotNull(data);
+
+ string text = Encoding.UTF8.GetString(data, 0, data.Length);
+ Assert.AreEqual("Hello world.", text);
+ }
}
} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs b/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs
index 66c1c9e..e94ef7a 100644
--- a/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs
+++ b/Src/Newtonsoft.Json.Tests/JsonTextWriterTest.cs
@@ -103,13 +103,21 @@ namespace Newtonsoft.Json.Tests
jsonWriter.WriteValue((decimal?)1.1m);
jsonWriter.WriteValue((DateTime?)null);
jsonWriter.WriteValue((DateTime?)new DateTime(JsonConvert.InitialJavaScriptDateTicks, DateTimeKind.Utc));
+#if !PocketPC && !NET20
jsonWriter.WriteValue((DateTimeOffset?)null);
jsonWriter.WriteValue((DateTimeOffset?)new DateTimeOffset(JsonConvert.InitialJavaScriptDateTicks, TimeSpan.Zero));
+#endif
jsonWriter.WriteEndArray();
}
string json = sw.ToString();
- string expected = @"[null,""c"",null,true,null,1,null,1,null,1,null,1,null,1,null,1,null,1,null,1,null,1.1,null,1.1,null,1.1,null,""\/Date(0)\/"",null,""\/Date(0+0000)\/""]";
+ string expected;
+
+#if !PocketPC && !NET20
+ expected = @"[null,""c"",null,true,null,1,null,1,null,1,null,1,null,1,null,1,null,1,null,1,null,1.1,null,1.1,null,1.1,null,""\/Date(0)\/"",null,""\/Date(0+0000)\/""]";
+#else
+ expected = @"[null,""c"",null,true,null,1,null,1,null,1,null,1,null,1,null,1,null,1,null,1,null,1.1,null,1.1,null,1.1,null,""\/Date(0)\/""]";
+#endif
Assert.AreEqual(expected, json);
}
@@ -532,5 +540,65 @@ _____'propertyName': NaN
Assert.AreEqual(expected, result);
}
+
+ [Test]
+ public void WriteSingleBytes()
+ {
+ StringBuilder sb = new StringBuilder();
+ StringWriter sw = new StringWriter(sb);
+
+ string text = "Hello world.";
+ byte[] data = Encoding.UTF8.GetBytes(text);
+
+ using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
+ {
+ jsonWriter.Formatting = Formatting.Indented;
+ Assert.AreEqual(Formatting.Indented, jsonWriter.Formatting);
+
+ jsonWriter.WriteValue(data);
+ }
+
+ string expected = @"""SGVsbG8gd29ybGQu""";
+ string result = sb.ToString();
+
+ Assert.AreEqual(expected, result);
+
+ byte[] d2 = Convert.FromBase64String(result.Trim('"'));
+
+ Assert.AreEqual(text, Encoding.UTF8.GetString(d2, 0, d2.Length));
+ }
+
+ [Test]
+ public void WriteBytesInArray()
+ {
+ StringBuilder sb = new StringBuilder();
+ StringWriter sw = new StringWriter(sb);
+
+ string text = "Hello world.";
+ byte[] data = Encoding.UTF8.GetBytes(text);
+
+ using (JsonTextWriter jsonWriter = new JsonTextWriter(sw))
+ {
+ jsonWriter.Formatting = Formatting.Indented;
+ Assert.AreEqual(Formatting.Indented, jsonWriter.Formatting);
+
+ jsonWriter.WriteStartArray();
+ jsonWriter.WriteValue(data);
+ jsonWriter.WriteValue(data);
+ jsonWriter.WriteValue((object)data);
+ jsonWriter.WriteValue((byte[])null);
+ jsonWriter.WriteEndArray();
+ }
+
+ string expected = @"[
+ ""SGVsbG8gd29ybGQu"",
+ ""SGVsbG8gd29ybGQu"",
+ ""SGVsbG8gd29ybGQu"",
+ null
+]";
+ string result = sb.ToString();
+
+ Assert.AreEqual(expected, result);
+ }
}
} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs
index 4a541d4..df01bbd 100644
--- a/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Linq/JObjectTests.cs
@@ -11,8 +11,6 @@ using System.IO;
using System.Collections;
#if !PocketPC && !SILVERLIGHT
using System.Web.UI;
-using System.Collections;
-using System.ComponentModel;
#endif
namespace Newtonsoft.Json.Tests.Linq
@@ -596,7 +594,7 @@ Parameter name: arrayIndex")]
Assert.AreEqual(p4, l[1]);
}
-#if !PocketPC && !SILVERLIGHT
+#if !PocketPC && !SILVERLIGHT && !NET20
[Test]
public void PropertyChanging()
{
diff --git a/Src/Newtonsoft.Json.Tests/Linq/JTokenReaderTest.cs b/Src/Newtonsoft.Json.Tests/Linq/JTokenReaderTest.cs
index d988bab..51e4459 100644
--- a/Src/Newtonsoft.Json.Tests/Linq/JTokenReaderTest.cs
+++ b/Src/Newtonsoft.Json.Tests/Linq/JTokenReaderTest.cs
@@ -35,6 +35,7 @@ namespace Newtonsoft.Json.Tests.Linq
{
public class JTokenReaderTest : TestFixtureBase
{
+#if !PocketPC && !NET20
[Test]
public void YahooFinance()
{
@@ -109,6 +110,7 @@ namespace Newtonsoft.Json.Tests.Linq
Assert.IsFalse(jsonReader.Read());
}
}
+#endif
[Test]
public void ReadLineInfo()
@@ -194,5 +196,56 @@ namespace Newtonsoft.Json.Tests.Linq
Assert.AreEqual(false, lineInfo.HasLineInfo());
}
}
+
+ [Test]
+ public void ReadBytes()
+ {
+ byte[] data = Encoding.UTF8.GetBytes("Hello world!");
+
+ JObject o =
+ new JObject(
+ new JProperty("Test1", data)
+ );
+
+ using (JTokenReader jsonReader = new JTokenReader(o))
+ {
+ jsonReader.Read();
+ Assert.AreEqual(JsonToken.StartObject, jsonReader.TokenType);
+
+ jsonReader.Read();
+ Assert.AreEqual(JsonToken.PropertyName, jsonReader.TokenType);
+ Assert.AreEqual("Test1", jsonReader.Value);
+
+ byte[] readBytes = jsonReader.ReadAsBytes();
+ Assert.AreEqual(data, readBytes);
+
+ Assert.IsTrue(jsonReader.Read());
+ Assert.AreEqual(JsonToken.EndObject, jsonReader.TokenType);
+
+ Assert.IsFalse(jsonReader.Read());
+ }
+ }
+
+ [Test]
+ [ExpectedException(typeof(JsonReaderException), ExpectedMessage = "Error reading bytes. Expected bytes but got Integer.")]
+ public void ReadBytesFailure()
+ {
+ JObject o =
+ new JObject(
+ new JProperty("Test1", 1)
+ );
+
+ using (JTokenReader jsonReader = new JTokenReader(o))
+ {
+ jsonReader.Read();
+ Assert.AreEqual(JsonToken.StartObject, jsonReader.TokenType);
+
+ jsonReader.Read();
+ Assert.AreEqual(JsonToken.PropertyName, jsonReader.TokenType);
+ Assert.AreEqual("Test1", jsonReader.Value);
+
+ jsonReader.ReadAsBytes();
+ }
+ }
}
} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs
index 973053e..f98ad14 100644
--- a/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Linq/JTokenTests.cs
@@ -196,7 +196,7 @@ namespace Newtonsoft.Json.Tests.Linq
public void Casting()
{
Assert.AreEqual(new DateTime(2000, 12, 20), (DateTime)new JValue(new DateTime(2000, 12, 20)));
-#if !PocketPC
+#if !PocketPC && !NET20
Assert.AreEqual(new DateTimeOffset(2000, 12, 20, 23, 50, 10, TimeSpan.Zero), (DateTimeOffset)new JValue(new DateTimeOffset(2000, 12, 20, 23, 50, 10, TimeSpan.Zero)));
Assert.AreEqual(null, (DateTimeOffset?)new JValue((DateTimeOffset?)null));
Assert.AreEqual(null, (DateTimeOffset?)(JValue)null);
@@ -240,13 +240,16 @@ namespace Newtonsoft.Json.Tests.Linq
Assert.AreEqual(5f, (float)(new JValue(5L)));
Assert.AreEqual(5f, (float)(new JValue(5m)));
Assert.AreEqual(5f, (float?)(new JValue(5m)));
+
+ byte[] data = new byte[0];
+ Assert.AreEqual(data, (byte[])(new JValue(data)));
}
[Test]
public void ImplicitCastingTo()
{
Assert.IsTrue(JToken.DeepEquals(new JValue(new DateTime(2000, 12, 20)), (JValue)new DateTime(2000, 12, 20)));
-#if !PocketPC
+#if !PocketPC && !NET20
Assert.IsTrue(JToken.DeepEquals(new JValue(new DateTimeOffset(2000, 12, 20, 23, 50, 10, TimeSpan.Zero)), (JValue)new DateTimeOffset(2000, 12, 20, 23, 50, 10, TimeSpan.Zero)));
Assert.IsTrue(JToken.DeepEquals(new JValue((DateTimeOffset?)null), (JValue)(DateTimeOffset?)null));
#endif
@@ -269,6 +272,7 @@ namespace Newtonsoft.Json.Tests.Linq
Assert.IsTrue(JToken.DeepEquals(new JValue(ushort.MaxValue), (JValue)ushort.MaxValue));
Assert.IsTrue(JToken.DeepEquals(new JValue(11.1f), (JValue)11.1f));
Assert.IsTrue(JToken.DeepEquals(new JValue(float.MinValue), (JValue)float.MinValue));
+ Assert.IsTrue(JToken.DeepEquals(new JValue(double.MinValue), (JValue)double.MinValue));
Assert.IsTrue(JToken.DeepEquals(new JValue(uint.MaxValue), (JValue)uint.MaxValue));
Assert.IsTrue(JToken.DeepEquals(new JValue(ulong.MaxValue), (JValue)ulong.MaxValue));
Assert.IsTrue(JToken.DeepEquals(new JValue(ulong.MinValue), (JValue)ulong.MinValue));
@@ -281,7 +285,13 @@ namespace Newtonsoft.Json.Tests.Linq
Assert.IsTrue(JToken.DeepEquals(new JValue(double.MaxValue), (JValue)(double?)double.MaxValue));
Assert.IsTrue(JToken.DeepEquals(new JValue((object)null), (JValue)(double?)null));
+ Assert.IsFalse(JToken.DeepEquals(new JValue(true), (JValue)(bool?)null));
Assert.IsFalse(JToken.DeepEquals(new JValue((object)null), (JValue)(object)null));
+
+ byte[] emptyData = new byte[0];
+ Assert.IsTrue(JToken.DeepEquals(new JValue(emptyData), (JValue)emptyData));
+ Assert.IsFalse(JToken.DeepEquals(new JValue(emptyData), (JValue)new byte[1]));
+ Assert.IsTrue(JToken.DeepEquals(new JValue(Encoding.UTF8.GetBytes("Hi")), (JValue)Encoding.UTF8.GetBytes("Hi")));
}
[Test]
diff --git a/Src/Newtonsoft.Json.Tests/Linq/JTokenWriterTest.cs b/Src/Newtonsoft.Json.Tests/Linq/JTokenWriterTest.cs
index 94bb8d9..e8d55ff 100644
--- a/Src/Newtonsoft.Json.Tests/Linq/JTokenWriterTest.cs
+++ b/Src/Newtonsoft.Json.Tests/Linq/JTokenWriterTest.cs
@@ -39,6 +39,8 @@ namespace Newtonsoft.Json.Tests.Linq
[Test]
public void ValueFormatting()
{
+ byte[] data = Encoding.UTF8.GetBytes("Hello world.");
+
JToken root;
using (JTokenWriter jsonWriter = new JTokenWriter())
{
@@ -55,13 +57,14 @@ namespace Newtonsoft.Json.Tests.Linq
jsonWriter.WriteValue("This is a string.");
jsonWriter.WriteNull();
jsonWriter.WriteUndefined();
+ jsonWriter.WriteValue(data);
jsonWriter.WriteEndArray();
root = jsonWriter.Token;
}
Assert.IsInstanceOfType(typeof(JArray), root);
- Assert.AreEqual(12, root.Children().Count());
+ Assert.AreEqual(13, root.Children().Count());
Assert.AreEqual("@", (string)root[0]);
Assert.AreEqual("\r\n\t\f\b?{\\r\\n\"\'", (string)root[1]);
Assert.AreEqual(true, (bool)root[2]);
@@ -73,6 +76,8 @@ namespace Newtonsoft.Json.Tests.Linq
Assert.AreEqual(string.Empty, (string)root[8]);
Assert.AreEqual("This is a string.", (string)root[9]);
Assert.AreEqual(null, ((JValue)root[10]).Value);
+ Assert.AreEqual(null, ((JValue)root[11]).Value);
+ Assert.AreEqual(data, (byte[])root[12]);
}
[Test]
@@ -100,6 +105,9 @@ namespace Newtonsoft.Json.Tests.Linq
jsonWriter.WriteValue("DVD read/writer");
Assert.AreEqual(WriteState.Array, jsonWriter.WriteState);
+ jsonWriter.WriteValue(new byte[0]);
+ Assert.AreEqual(WriteState.Array, jsonWriter.WriteState);
+
jsonWriter.WriteEnd();
Assert.AreEqual(WriteState.Object, jsonWriter.WriteState);
diff --git a/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs
index 8cacf95..a7c5f58 100644
--- a/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Linq/JValueTests.cs
@@ -60,6 +60,12 @@ namespace Newtonsoft.Json.Tests.Linq
v.Value = DBNull.Value;
Assert.AreEqual(DBNull.Value, v.Value);
Assert.AreEqual(JTokenType.Null, v.Type);
+
+ byte[] data = new byte[0];
+ v.Value = data;
+
+ Assert.AreEqual(data, v.Value);
+ Assert.AreEqual(JTokenType.Bytes, v.Type);
}
[Test]
diff --git a/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs b/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs
index ac9d479..749d8b3 100644
--- a/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs
+++ b/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs
@@ -545,6 +545,7 @@ keyword such as type of business.""
Assert.AreEqual(null, c["purple"]);
}
+#if !PocketPC && !NET20
[Test]
public void ToStringJsonConverter()
{
@@ -597,6 +598,7 @@ keyword such as type of business.""
Assert.AreEqual(4, jsonWriter.Token.Children().Count());
}
+#endif
[Test]
public void FromObject()
@@ -683,9 +685,8 @@ keyword such as type of business.""
o =
new JObject(
new JProperty("Test1", new DateTime(2000, 10, 15, 5, 5, 5, DateTimeKind.Utc)),
- new JProperty("Test2", new DateTimeOffset(2000, 10, 15, 5, 5, 5, new TimeSpan(11, 11, 0))),
- new JProperty("Test3", "Test3Value"),
- new JProperty("Test4", null)
+ new JProperty("Test2", "Test2Value"),
+ new JProperty("Test3", null)
);
enumerable = o.AsJEnumerable();
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
index 9208f68..89fe846 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
@@ -83,6 +83,8 @@
</Reference>
</ItemGroup>
<ItemGroup>
+ <Compile Include="Bson\BsonWriterTests.cs" />
+ <Compile Include="Bson\BsonReaderTests.cs" />
<Compile Include="Converters\BinaryConverterTests.cs" />
<Compile Include="Converters\DataTableConverterTests.cs" />
<Compile Include="Converters\DataSetConverterTests.cs" />
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
index bfba81c..fdd81b1 100644
--- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
+++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
@@ -428,7 +428,6 @@ keyword such as type of business.""
result = JsonConvert.SerializeObject(testDates);
Assert.AreEqual(expected, result);
}
-#endif
[Test]
public void DateTimeOffset()
@@ -443,6 +442,7 @@ keyword such as type of business.""
string result = JsonConvert.SerializeObject(testDates);
Assert.AreEqual(@"[""\/Date(-59011455539000+0000)\/"",""\/Date(946688461000+0000)\/"",""\/Date(946641661000+1300)\/"",""\/Date(946701061000-0330)\/""]", result);
}
+#endif
[Test]
public void NonStringKeyDictionary()
@@ -1715,6 +1715,7 @@ keyword such as type of business.""
Assert.AreEqual("Product 1", products[0].Name);
}
+#if !PocketPC && !NET20
[Test]
public void DeserializeEmptyStringToNullableDateTime()
{
@@ -1723,6 +1724,7 @@ keyword such as type of business.""
NullableDateTimeTestClass c = JsonConvert.DeserializeObject<NullableDateTimeTestClass>(json);
Assert.AreEqual(null, c.DateTimeField);
}
+#endif
[Test]
[ExpectedException(typeof(JsonSerializationException), ExpectedMessage = @"Unable to find a constructor to use for type Newtonsoft.Json.Tests.TestObjects.Event. A class should either have a default constructor or only one constructor with arguments.")]
@@ -1911,5 +1913,85 @@ keyword such as type of business.""
Assert.AreEqual(structTest.IntProperty, deserialized.IntProperty);
Assert.AreEqual(structTest.IntField, deserialized.IntField);
}
+
+ public class ListOfIds<T> : JsonConverter where T : Bar, new()
+ {
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ {
+ IList<T> list = (IList<T>) value;
+
+ writer.WriteStartArray();
+ foreach (T item in list)
+ {
+ writer.WriteValue(item.Id);
+ }
+ writer.WriteEndArray();
+ }
+
+ public override object ReadJson(JsonReader reader, Type objectType, JsonSerializer serializer)
+ {
+ IList<T> list = new List<T>();
+
+ reader.Read();
+ while (reader.TokenType != JsonToken.EndArray)
+ {
+ long id = (long)reader.Value;
+
+ list.Add(new T
+ {
+ Id = Convert.ToInt32(id)
+ });
+
+ reader.Read();
+ }
+
+ return list;
+ }
+
+ public override bool CanConvert(Type objectType)
+ {
+ return typeof (IList<T>).IsAssignableFrom(objectType);
+ }
+ }
+
+ public class Foo
+ {
+ public Foo()
+ {
+ Bars = new List<Bar>();
+ }
+
+ [JsonConverter(typeof(ListOfIds<Bar>))]
+ public List<Bar> Bars { get; set; }
+ }
+
+ public class Bar
+ {
+ public int Id { get; set; }
+ }
+
+ [Test]
+ public void SerializeListWithJsonConverter()
+ {
+ Foo f = new Foo();
+ f.Bars.Add(new Bar { Id = 0 });
+ f.Bars.Add(new Bar { Id = 1 });
+ f.Bars.Add(new Bar { Id = 2 });
+
+ string json = JsonConvert.SerializeObject(f, Formatting.Indented);
+ Assert.AreEqual(@"{
+ ""Bars"": [
+ 0,
+ 1,
+ 2
+ ]
+}", json);
+
+ Foo newFoo = JsonConvert.DeserializeObject<Foo>(json);
+ Assert.AreEqual(3, newFoo.Bars.Count);
+ Assert.AreEqual(0, newFoo.Bars[0].Id);
+ Assert.AreEqual(1, newFoo.Bars[1].Id);
+ Assert.AreEqual(2, newFoo.Bars[2].Id);
+ }
}
} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/NullValueHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/NullValueHandlingTests.cs
index f7abe80..cf55e79 100644
--- a/Src/Newtonsoft.Json.Tests/Serialization/NullValueHandlingTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Serialization/NullValueHandlingTests.cs
@@ -1,4 +1,29 @@
-using System;
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -23,7 +48,7 @@ namespace Newtonsoft.Json.Tests.Serialization
//JsonConvert.ConvertDateTimeToJavaScriptTicks(s1.Establised.DateTime)
- Assert.AreEqual(@"{""Color"":4,""Establised"":""\/Date(1264122061000+0000)\/"",""Width"":1.1,""Employees"":999,""RoomsPerFloor"":[1,2,3,4,5,6,7,8,9],""Open"":false,""Symbol"":""@"",""Mottos"":[""Hello World"",""öäüÖÄÜ\\'{new Date(12345);}[222]_µ@²³~"",null,"" ""],""Cost"":100980.1,""Escape"":""\r\n\t\f\b?{\\r\\n\""'"",""product"":[{""Name"":""Rocket"",""ExpiryDate"":""\/Date(949532490000)\/"",""Price"":0.0},{""Name"":""Alien"",""ExpiryDate"":""\/Date(946684800000)\/"",""Price"":0.0}]}", sw.GetStringBuilder().ToString());
+ Assert.AreEqual(@"{""Color"":4,""Establised"":""\/Date(1264122061000)\/"",""Width"":1.1,""Employees"":999,""RoomsPerFloor"":[1,2,3,4,5,6,7,8,9],""Open"":false,""Symbol"":""@"",""Mottos"":[""Hello World"",""öäüÖÄÜ\\'{new Date(12345);}[222]_µ@²³~"",null,"" ""],""Cost"":100980.1,""Escape"":""\r\n\t\f\b?{\\r\\n\""'"",""product"":[{""Name"":""Rocket"",""ExpiryDate"":""\/Date(949532490000)\/"",""Price"":0.0},{""Name"":""Alien"",""ExpiryDate"":""\/Date(946684800000)\/"",""Price"":0.0}]}", sw.GetStringBuilder().ToString());
Store s2 = (Store)jsonSerializer.Deserialize(new JsonTextReader(new StringReader("{}")), typeof(Store));
Assert.AreEqual("\r\n\t\f\b?{\\r\\n\"\'", s2.Escape);
diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/DateTimeTestClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/DateTimeTestClass.cs
index fe49cd3..c51d55a 100644
--- a/Src/Newtonsoft.Json.Tests/TestObjects/DateTimeTestClass.cs
+++ b/Src/Newtonsoft.Json.Tests/TestObjects/DateTimeTestClass.cs
@@ -23,6 +23,7 @@
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
+#if !PocketPC && !NET20
using System;
using System.Collections.Generic;
using System.Linq;
@@ -37,4 +38,5 @@ namespace Newtonsoft.Json.Tests.TestObjects
public DateTimeOffset DateTimeOffsetField { get; set; }
public string PostField { get; set; }
}
-} \ No newline at end of file
+}
+#endif \ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/NullableDateTimeTestClass.cs b/Src/Newtonsoft.Json.Tests/TestObjects/NullableDateTimeTestClass.cs
index 118b4f5..71af0af 100644
--- a/Src/Newtonsoft.Json.Tests/TestObjects/NullableDateTimeTestClass.cs
+++ b/Src/Newtonsoft.Json.Tests/TestObjects/NullableDateTimeTestClass.cs
@@ -23,6 +23,7 @@
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
+#if !PocketPC && !NET20
using System;
using System.Collections.Generic;
using System.Linq;
@@ -37,4 +38,5 @@ namespace Newtonsoft.Json.Tests.TestObjects
public DateTimeOffset? DateTimeOffsetField { get; set; }
public string PostField { get; set; }
}
-} \ No newline at end of file
+}
+#endif \ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/TestObjects/Store.cs b/Src/Newtonsoft.Json.Tests/TestObjects/Store.cs
index a64aa2e..1c0df19 100644
--- a/Src/Newtonsoft.Json.Tests/TestObjects/Store.cs
+++ b/Src/Newtonsoft.Json.Tests/TestObjects/Store.cs
@@ -31,7 +31,7 @@ namespace Newtonsoft.Json.Tests.TestObjects
public class Store
{
public StoreColor Color = StoreColor.Yellow;
- public DateTimeOffset Establised = new DateTimeOffset(2010, 1, 22, 1, 1, 1, TimeSpan.Zero);
+ public DateTime Establised = new DateTime(2010, 1, 22, 1, 1, 1, DateTimeKind.Utc);
public double Width = 1.1;
public int Employees = 999;
public int[] RoomsPerFloor = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
@@ -61,4 +61,4 @@ namespace Newtonsoft.Json.Tests.TestObjects
product.Add(alien);
}
}
-} \ No newline at end of file
+}
diff --git a/Src/Newtonsoft.Json/Bson/BsonBinaryType.cs b/Src/Newtonsoft.Json/Bson/BsonBinaryType.cs
new file mode 100644
index 0000000..5a967db
--- /dev/null
+++ b/Src/Newtonsoft.Json/Bson/BsonBinaryType.cs
@@ -0,0 +1,41 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Bson
+{
+ internal enum BsonBinaryType : byte
+ {
+ Function = 0x01,
+ Data = 0x02,
+ Uuid = 0x03,
+ Md5 = 0x05,
+ UserDefined = 0x80
+ }
+} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Bson/BsonReader.cs b/Src/Newtonsoft.Json/Bson/BsonReader.cs
new file mode 100644
index 0000000..f0e421d
--- /dev/null
+++ b/Src/Newtonsoft.Json/Bson/BsonReader.cs
@@ -0,0 +1,312 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.IO;
+using Newtonsoft.Json.Utilities;
+using Newtonsoft.Json.Linq;
+
+namespace Newtonsoft.Json.Bson
+{
+ public class BsonReader : JsonReader
+ {
+ private readonly BinaryReader _reader;
+ private readonly bool _rootTypeIsArray;
+ private readonly List<ContainerContext> _stack;
+
+ private BsonType _currentElementType;
+
+
+ private class ContainerContext
+ {
+ public JTokenType Type { get; private set; }
+ public int Length { get; set; }
+ public int Position { get; set; }
+
+ public ContainerContext(JTokenType type)
+ {
+ Type = type;
+ }
+ }
+
+ public BsonReader(Stream stream) : this(stream, false)
+ {
+ }
+
+ public BsonReader(Stream stream, bool rootTypeIsArray)
+ {
+ ValidationUtils.ArgumentNotNull(stream, "stream");
+ _reader = new BinaryReader(stream);
+ _stack = new List<ContainerContext>();
+ _rootTypeIsArray = rootTypeIsArray;
+ }
+
+ private string ReadElement()
+ {
+ _currentElementType = ReadType();
+ string elementName = ReadString();
+ return elementName;
+ }
+
+ public override byte[] ReadAsBytes()
+ {
+ Read();
+ if (TokenType != JsonToken.Bytes)
+ throw new JsonReaderException("Error reading bytes. Expected bytes but got {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
+
+ return (byte[])Value;
+ }
+
+ public override bool Read()
+ {
+ try
+ {
+ switch (CurrentState)
+ {
+ case State.Start:
+ {
+ JsonToken token = (!_rootTypeIsArray) ? JsonToken.StartObject : JsonToken.StartArray;
+ JTokenType type = (!_rootTypeIsArray) ? JTokenType.Object : JTokenType.Array;
+
+ SetToken(token);
+ ContainerContext newContext = new ContainerContext(type);
+ _stack.Add(newContext);
+ newContext.Length = ReadInt32();
+ return true;
+ }
+ case State.ObjectStart:
+ {
+ SetToken(JsonToken.PropertyName, ReadElement());
+ return true;
+ }
+ case State.Complete:
+ break;
+ case State.Property:
+ {
+ ReadType(_currentElementType);
+ return true;
+ }
+ case State.Object:
+ break;
+ case State.ArrayStart:
+ ReadElement();
+ ReadType(_currentElementType);
+ return true;
+ case State.Array:
+ break;
+ case State.Closed:
+ break;
+ case State.PostValue:
+ ContainerContext context = GetCurrentContext();
+ if (context == null)
+ return false;
+
+ int lengthMinusEnd = context.Length - 1;
+
+ if (context.Position < lengthMinusEnd)
+ {
+ if (context.Type == JTokenType.Array)
+ {
+ ReadElement();
+ ReadType(_currentElementType);
+ return true;
+ }
+ else
+ {
+ SetToken(JsonToken.PropertyName, ReadElement());
+ return true;
+ }
+ }
+ else if (context.Position == lengthMinusEnd)
+ {
+ if (ReadByte() != 0)
+ throw new JsonReaderException("Unexpected end of object byte value.");
+
+ _stack.RemoveAt(_stack.Count - 1);
+ if (_stack.Count != 0)
+ MovePosition(context.Length);
+
+ JsonToken endToken = (context.Type == JTokenType.Object) ? JsonToken.EndObject : JsonToken.EndArray;
+ SetToken(endToken);
+ return true;
+ }
+ break;
+ case State.ConstructorStart:
+ break;
+ case State.Constructor:
+ break;
+ case State.Error:
+ break;
+ case State.Finished:
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+
+ return false;
+ }
+ catch (EndOfStreamException)
+ {
+ return false;
+ }
+ }
+
+ private byte ReadByte()
+ {
+ MovePosition(1);
+ return _reader.ReadByte();
+ }
+
+ private void ReadType(BsonType type)
+ {
+ switch (type)
+ {
+ case BsonType.Number:
+ SetToken(JsonToken.Float, ReadDouble());
+ break;
+ case BsonType.String:
+ SetToken(JsonToken.String, ReadLengthString());
+ break;
+ case BsonType.Object:
+ break;
+ case BsonType.Array:
+ break;
+ case BsonType.Binary:
+ SetToken(JsonToken.Bytes, ReadBinary());
+ break;
+ case BsonType.Undefined:
+ break;
+ case BsonType.Oid:
+ break;
+ case BsonType.Boolean:
+ break;
+ case BsonType.Date:
+ break;
+ case BsonType.Null:
+ break;
+ case BsonType.Regex:
+ break;
+ case BsonType.Reference:
+ break;
+ case BsonType.Code:
+ break;
+ case BsonType.Symbol:
+ break;
+ case BsonType.CodeWScope:
+ break;
+ case BsonType.Integer:
+ SetToken(JsonToken.Integer, (long)ReadInt32());
+ break;
+ case BsonType.TimeStamp:
+ break;
+ case BsonType.MinKey:
+ break;
+ case BsonType.MaxKey:
+ break;
+ default:
+ throw new ArgumentOutOfRangeException("type");
+ }
+ }
+
+ private byte[] ReadBinary()
+ {
+ int dataLength = ReadInt32();
+
+ // BsonBinaryType not used
+ ReadByte();
+
+ return ReadBytes(dataLength);
+ }
+
+ private string ReadString()
+ {
+ List<byte> buff = new List<byte>();
+ byte b = _reader.ReadByte();
+ while (b != 0)
+ {
+ buff.Add(b);
+ b = _reader.ReadByte();
+ }
+
+ MovePosition(buff.Count + 1);
+ string ret = Encoding.UTF8.GetString(buff.ToArray());
+ return ret;
+ }
+
+ private string ReadLengthString()
+ {
+ int length = ReadInt32();
+
+ MovePosition(length);
+ byte[] buffer = _reader.ReadBytes(length - 1);
+ _reader.ReadByte();
+
+ return Encoding.UTF8.GetString(buffer);
+ }
+
+ private double ReadDouble()
+ {
+ MovePosition(8);
+ return _reader.ReadDouble();
+ }
+
+ private int ReadInt32()
+ {
+ MovePosition(4);
+ return _reader.ReadInt32();
+ }
+
+ private BsonType ReadType()
+ {
+ MovePosition(1);
+ return (BsonType)_reader.ReadSByte();
+ }
+
+ private ContainerContext GetCurrentContext()
+ {
+ int count = _stack.Count;
+ if (count == 0)
+ return null;
+
+ return _stack[count - 1];
+ }
+
+ private void MovePosition(int count)
+ {
+ ContainerContext context = GetCurrentContext();
+ context.Position += count;
+ }
+
+ private byte[] ReadBytes(int count)
+ {
+ MovePosition(count);
+ return _reader.ReadBytes(count);
+ }
+ }
+}
diff --git a/Src/Newtonsoft.Json/Bson/BsonType.cs b/Src/Newtonsoft.Json/Bson/BsonType.cs
new file mode 100644
index 0000000..5a65c5f
--- /dev/null
+++ b/Src/Newtonsoft.Json/Bson/BsonType.cs
@@ -0,0 +1,55 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Newtonsoft.Json.Bson
+{
+ internal enum BsonType : sbyte
+ {
+ Number = 1,
+ String = 2,
+ Object = 3,
+ Array = 4,
+ Binary = 5,
+ Undefined = 6,
+ Oid = 7,
+ Boolean = 8,
+ Date = 9,
+ Null = 10,
+ Regex = 11,
+ Reference = 12,
+ Code = 13,
+ Symbol = 14,
+ CodeWScope = 15,
+ Integer = 16,
+ TimeStamp = 17,
+ MinKey = -1,
+ MaxKey = 127
+ }
+} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Bson/BsonWriter.cs b/Src/Newtonsoft.Json/Bson/BsonWriter.cs
new file mode 100644
index 0000000..2b007fb
--- /dev/null
+++ b/Src/Newtonsoft.Json/Bson/BsonWriter.cs
@@ -0,0 +1,291 @@
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json.Utilities;
+using Newtonsoft.Json.Linq;
+
+namespace Newtonsoft.Json.Bson
+{
+ public class BsonWriter : JTokenWriter
+ {
+ private readonly Stream _stream;
+ private readonly BinaryWriter _writer;
+
+
+ public BsonWriter(Stream stream)
+ {
+ ValidationUtils.ArgumentNotNull(stream, "stream");
+ _stream = stream;
+ _writer = new BinaryWriter(stream);
+ }
+
+ public override void Flush()
+ {
+ if (Top != 0)
+ throw new JsonWriterException("Cannot flush BsonWriter until JSON is complete.");
+
+ WriteToken(Token);
+ _writer.Flush();
+ }
+
+ private void WriteToken(JToken t)
+ {
+ switch (t.Type)
+ {
+ case JTokenType.Object:
+ {
+ int size = CalculateSize(t);
+ _writer.Write(size);
+ foreach (JProperty property in t)
+ {
+ _writer.Write((sbyte)GetTypeNumber(property.Value));
+ WriteString(property.Name);
+ WriteToken(property.Value);
+ }
+ _writer.Write((byte)0);
+ }
+ break;
+ case JTokenType.Array:
+ {
+ int size = CalculateSize(t);
+ _writer.Write(size);
+ int index = 0;
+ foreach (JToken c in t)
+ {
+ _writer.Write((sbyte)GetTypeNumber(c));
+ WriteString(index.ToString());
+ WriteToken(c);
+ index++;
+ }
+ _writer.Write((byte)0);
+ }
+ break;
+ case JTokenType.Integer:
+ _writer.Write((int)t);
+ break;
+ case JTokenType.Float:
+ _writer.Write((double)t);
+ break;
+ case JTokenType.String:
+ WriteStringWithLength((string)t);
+ break;
+ case JTokenType.Boolean:
+ _writer.Write((bool)t);
+ break;
+ case JTokenType.Null:
+ case JTokenType.Undefined:
+ break;
+ case JTokenType.Date:
+ DateTime dateTime = (DateTime) t;
+ dateTime = dateTime.ToUniversalTime();
+ long ticks = JsonConvert.ConvertDateTimeToJavaScriptTicks(dateTime);
+ _writer.Write(ticks);
+ break;
+ case JTokenType.Bytes:
+ byte[] data = (byte[])t;
+ _writer.Write(data.Length);
+ _writer.Write((byte)BsonBinaryType.Data);
+ _writer.Write(data);
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+
+ private void WriteString(string s)
+ {
+ byte[] bytes = Encoding.UTF8.GetBytes(s);
+ _writer.Write(bytes);
+ _writer.Write((byte)0);
+ }
+
+ private void WriteStringWithLength(string s)
+ {
+ _writer.Write(CalculateSizeWithLength(s, false));
+ WriteString(s);
+ }
+
+ private BsonType GetTypeNumber(JToken t)
+ {
+ switch (t.Type)
+ {
+ case JTokenType.Object:
+ return BsonType.Object;
+ case JTokenType.Array:
+ return BsonType.Array;
+ case JTokenType.Integer:
+ return BsonType.Integer;
+ case JTokenType.Float:
+ return BsonType.Number;
+ case JTokenType.String:
+ return BsonType.String;
+ case JTokenType.Boolean:
+ return BsonType.Boolean;
+ case JTokenType.Null:
+ case JTokenType.Undefined:
+ return BsonType.Null;
+ case JTokenType.Date:
+ return BsonType.Date;
+ case JTokenType.Bytes:
+ return BsonType.Binary;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+
+ private int CalculateSize(string s)
+ {
+ int ret;
+ if (s != null)
+ ret = Encoding.UTF8.GetByteCount(s);
+ else
+ ret = 0;
+ return ret + 1;
+ }
+
+ private int CalculateSizeWithLength(string s, bool includeSize)
+ {
+ int baseSize = (includeSize)
+ ? 5 // size bytes + terminator
+ : 1; // terminator
+
+ int ret;
+ if (s != null)
+ ret = Encoding.UTF8.GetByteCount(s);
+ else
+ ret = 0;
+ return baseSize + ret;
+ }
+
+ private int CalculateSize(JToken t)
+ {
+ switch (t.Type)
+ {
+ case JTokenType.Object:
+ {
+ int bases = 4;
+ foreach (JProperty p in t)
+ {
+ bases += CalculateSize(p);
+ }
+ bases += 1;
+ return bases;
+ }
+ case JTokenType.Array:
+ {
+ int bases = 4;
+ int index = 0;
+ foreach (JToken c in t)
+ {
+ bases += 1;
+ bases += CalculateSize(index.ToString());
+ bases += CalculateSize(c);
+ index++;
+ }
+ bases += 1;
+ return bases;
+ }
+ case JTokenType.Constructor:
+ throw new JsonWriterException("Cannot write JSON constructor as BSON.");
+ case JTokenType.Property:
+ JProperty property = (JProperty) t;
+ int ss = 1;
+ ss += CalculateSize(property.Name);
+ ss += CalculateSize(property.Value);
+ return ss;
+ case JTokenType.Comment:
+ throw new JsonWriterException("Cannot write JSON comment as BSON.");
+ case JTokenType.Integer:
+ return 4;
+ case JTokenType.Float:
+ return 8;
+ case JTokenType.String:
+ string s = (string)t;
+
+ return CalculateSizeWithLength(s, true);
+ case JTokenType.Boolean:
+ return 1;
+ case JTokenType.Null:
+ case JTokenType.Undefined:
+ return 0;
+ case JTokenType.Date:
+ return 8;
+ case JTokenType.Raw:
+ throw new JsonWriterException("Cannot write raw JSON as BSON.");
+ case JTokenType.Bytes:
+ byte[] data = (byte[]) t;
+ return 4 + 1 + data.Length;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+ }
+
+ public void Write(string str)
+ {
+ Byte[] buf = new byte[Encoding.UTF8.GetByteCount(str) + 1];
+ buf[buf.Length - 1] = 0;
+ Encoding.UTF8.GetBytes(str, 0, str.Length, buf, 0);
+ _writer.Write(buf);
+ }
+
+ public void Write(bool val)
+ {
+ if (val)
+ _writer.Write((byte)1);
+ else
+ _writer.Write((byte)0);
+ }
+
+ public void Write(byte val)
+ {
+ _writer.Write(val);
+ }
+
+ public void Write(byte[] val)
+ {
+ _writer.Write(val);
+ }
+
+ public void Write(int val)
+ {
+ _writer.Write(val);
+ }
+
+ public void Write(long val)
+ {
+ _writer.Write(val);
+ }
+
+ public void Write(double val)
+ {
+ _writer.Write(val);
+ }
+ }
+} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Converters/BinaryConverter.cs b/Src/Newtonsoft.Json/Converters/BinaryConverter.cs
index 01ac5af..2a34423 100644
--- a/Src/Newtonsoft.Json/Converters/BinaryConverter.cs
+++ b/Src/Newtonsoft.Json/Converters/BinaryConverter.cs
@@ -65,12 +65,9 @@ namespace Newtonsoft.Json.Converters
return;
}
- byte[] data = value as byte[];
+ byte[] data = GetByteArray(value);
- if (data == null)
- data = GetByteArray(value);
-
- writer.WriteValue(Convert.ToBase64String(data));
+ writer.WriteValue(data);
}
private byte[] GetByteArray(object value)
@@ -113,19 +110,17 @@ namespace Newtonsoft.Json.Converters
if (reader.TokenType != JsonToken.String)
throw new Exception("Unexpected token parsing binary. Expected String, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+ // current token is already at base64 string
+ // unable to call ReadAsBytes so do it the old fashion way
string encodedData = reader.Value.ToString();
-
byte[] data = Convert.FromBase64String(encodedData);
- if (t == typeof(byte[]))
- return data;
-
#if !SILVERLIGHT && !PocketPC && !NET20
if (t.AssignableToTypeName(BinaryTypeName))
return Activator.CreateInstance(t, data);
#endif
#if !SILVERLIGHT
- if (typeof(SqlBinary).IsAssignableFrom(t))
+ if (t == typeof(SqlBinary))
return new SqlBinary(data);
#endif
throw new Exception("Unexpected object type when writing binary: {0}".FormatWith(CultureInfo.InvariantCulture, objectType));
@@ -144,15 +139,12 @@ namespace Newtonsoft.Json.Converters
? Nullable.GetUnderlyingType(objectType)
: objectType;
- if (t == typeof(byte[]))
- return true;
-
#if !SILVERLIGHT && !PocketPC && !NET20
if (t.AssignableToTypeName(BinaryTypeName))
return true;
#endif
#if !SILVERLIGHT
- if (typeof(SqlBinary).IsAssignableFrom(t))
+ if (t == typeof(SqlBinary))
return true;
#endif
return false;
diff --git a/Src/Newtonsoft.Json/Converters/DataSetConverter.cs b/Src/Newtonsoft.Json/Converters/DataSetConverter.cs
index 692de6b..6fe951a 100644
--- a/Src/Newtonsoft.Json/Converters/DataSetConverter.cs
+++ b/Src/Newtonsoft.Json/Converters/DataSetConverter.cs
@@ -1,4 +1,29 @@
-#if !SILVERLIGHT
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !SILVERLIGHT
using System;
using System.Collections.Generic;
using System.Data;
@@ -48,7 +73,7 @@ namespace Newtonsoft.Json.Converters
public override bool CanConvert(Type valueType)
{
- return typeof(DataSet).IsAssignableFrom(valueType);
+ return (valueType == typeof(DataSet));
}
}
}
diff --git a/Src/Newtonsoft.Json/Converters/DataTableConverter.cs b/Src/Newtonsoft.Json/Converters/DataTableConverter.cs
index 675d733..e207f8a 100644
--- a/Src/Newtonsoft.Json/Converters/DataTableConverter.cs
+++ b/Src/Newtonsoft.Json/Converters/DataTableConverter.cs
@@ -1,4 +1,29 @@
-#if !SILVERLIGHT
+#region License
+// Copyright (c) 2007 James Newton-King
+//
+// Permission is hereby granted, free of charge, to any person
+// obtaining a copy of this software and associated documentation
+// files (the "Software"), to deal in the Software without
+// restriction, including without limitation the rights to use,
+// copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following
+// conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+// OTHER DEALINGS IN THE SOFTWARE.
+#endregion
+
+#if !SILVERLIGHT
using System;
using System.Collections.Generic;
using System.Linq;
@@ -100,7 +125,7 @@ namespace Newtonsoft.Json.Converters
public override bool CanConvert(Type valueType)
{
- return typeof(DataTable).IsAssignableFrom(valueType);
+ return (valueType == typeof(DataTable));
}
}
}
diff --git a/Src/Newtonsoft.Json/Converters/HtmlColorConverter.cs b/Src/Newtonsoft.Json/Converters/HtmlColorConverter.cs
index b4a29b7..c82875e 100644
--- a/Src/Newtonsoft.Json/Converters/HtmlColorConverter.cs
+++ b/Src/Newtonsoft.Json/Converters/HtmlColorConverter.cs
@@ -56,7 +56,7 @@ namespace Newtonsoft.Json.Converters
/// </returns>
public override bool CanConvert(Type valueType)
{
- return typeof(Color).IsAssignableFrom(valueType);
+ return (valueType == typeof(Color));
}
/// <summary>
diff --git a/Src/Newtonsoft.Json/Converters/IsoDateTimeConverter.cs b/Src/Newtonsoft.Json/Converters/IsoDateTimeConverter.cs
index b03e7d8..0e37a87 100644
--- a/Src/Newtonsoft.Json/Converters/IsoDateTimeConverter.cs
+++ b/Src/Newtonsoft.Json/Converters/IsoDateTimeConverter.cs
@@ -68,6 +68,7 @@ namespace Newtonsoft.Json.Converters
text = dateTime.ToString(_dateTimeFormat ?? DefaultDateTimeFormat, Culture);
}
+#if !PocketPC && !NET20
else if (value is DateTimeOffset)
{
DateTimeOffset dateTimeOffset = (DateTimeOffset)value;
@@ -77,6 +78,7 @@ namespace Newtonsoft.Json.Converters
text = dateTimeOffset.ToString(_dateTimeFormat ?? DefaultDateTimeFormat, Culture);
}
+#endif
else
{
throw new Exception("Unexpected value when converting date. Expected DateTime or DateTimeOffset, got {0}.".FormatWith(CultureInfo.InvariantCulture, ReflectionUtils.GetObjectType(value)));
@@ -115,6 +117,7 @@ namespace Newtonsoft.Json.Converters
if (string.IsNullOrEmpty(dateText) && nullable)
return null;
+#if !PocketPC && !NET20
if (t == typeof(DateTimeOffset))
{
if (!string.IsNullOrEmpty(_dateTimeFormat))
@@ -122,6 +125,7 @@ namespace Newtonsoft.Json.Converters
else
return DateTimeOffset.Parse(dateText, Culture, _dateTimeStyles);
}
+#endif
if (!string.IsNullOrEmpty(_dateTimeFormat))
return DateTime.ParseExact(dateText, _dateTimeFormat, Culture, _dateTimeStyles);
@@ -142,10 +146,12 @@ namespace Newtonsoft.Json.Converters
? Nullable.GetUnderlyingType(objectType)
: objectType;
- if (typeof(DateTime).IsAssignableFrom(t))
+ if (t == typeof(DateTime))
return true;
- if (typeof(DateTimeOffset).IsAssignableFrom(t))
+#if !PocketPC && !NET20
+ if (t == typeof(DateTimeOffset))
return true;
+#endif
return false;
}
diff --git a/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs b/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs
index 74b4028..be043dd 100644
--- a/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs
+++ b/Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs
@@ -25,12 +25,18 @@ namespace Newtonsoft.Json.Converters
DateTime utcDateTime = dateTime.ToUniversalTime();
ticks = JsonConvert.ConvertDateTimeToJavaScriptTicks(utcDateTime);
}
- else
+#if !PocketPC && !NET20
+ else if (value is DateTimeOffset)
{
DateTimeOffset dateTimeOffset = (DateTimeOffset)value;
DateTimeOffset utcDateTimeOffset = dateTimeOffset.ToUniversalTime();
ticks = JsonConvert.ConvertDateTimeToJavaScriptTicks(utcDateTimeOffset.UtcDateTime);
}
+#endif
+ else
+ {
+ throw new Exception("Expected date object value.");
+ }
writer.WriteStartConstructor("Date");
writer.WriteValue(ticks);
@@ -75,8 +81,10 @@ namespace Newtonsoft.Json.Converters
if (reader.TokenType != JsonToken.EndConstructor)
throw new Exception("Unexpected token parsing date. Expected EndConstructor, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
+#if !PocketPC && !NET20
if (t == typeof(DateTimeOffset))
return new DateTimeOffset(d);
+#endif
return d;
}
@@ -94,10 +102,12 @@ namespace Newtonsoft.Json.Converters
? Nullable.GetUnderlyingType(objectType)
: objectType;
- if (typeof(DateTime).IsAssignableFrom(t))
+ if (t == typeof(DateTime))
return true;
- if (typeof(DateTimeOffset).IsAssignableFrom(t))
+#if !PocketPC && !NET20
+ if (t == typeof(DateTimeOffset))
return true;
+#endif
return false;
}
diff --git a/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs b/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs
index ed2e06b..1336165 100644
--- a/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs
+++ b/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs
@@ -522,6 +522,9 @@ namespace Newtonsoft.Json.Converters
DeserializeValue(reader, document, manager, "-" + constructorName, currentNode);
}
break;
+ case JsonToken.Comment:
+ currentNode.AppendChild(document.CreateComment((string)reader.Value));
+ break;
case JsonToken.EndObject:
case JsonToken.EndArray:
return;
diff --git a/Src/Newtonsoft.Json/DateTimeOffset.cs b/Src/Newtonsoft.Json/DateTimeOffset.cs
deleted file mode 100644
index 601ea53..0000000
--- a/Src/Newtonsoft.Json/DateTimeOffset.cs
+++ /dev/null
@@ -1,544 +0,0 @@
-#if PocketPC
-#pragma warning disable 1591
-
-// This class is... borrowed from .NET and Microsoft for a short time.
-// Hopefully Microsoft will add DateTimeOffset to the compact framework
-// or I will rewrite a striped down version of this file myself
-
-using System.Globalization;
-using System.Runtime.InteropServices;
-using System.Runtime.Serialization;
-using System.Security.Permissions;
-using System;
-
-namespace System
-{
- public struct DateTimeOffset : IComparable, IFormattable, IComparable<DateTimeOffset>, IEquatable<DateTimeOffset>
- {
- private DateTime _dateTime;
- private short _offsetMinutes;
- internal const long MaxOffset = 0x7558bdb000L;
- public static readonly DateTimeOffset MaxValue;
- internal const long MinOffset = -504000000000L;
- public static readonly DateTimeOffset MinValue;
-
- static DateTimeOffset()
- {
- MinValue = new DateTimeOffset(0L, TimeSpan.Zero);
- MaxValue = new DateTimeOffset(0x2bca2875f4373fffL, TimeSpan.Zero);
- }
-
- public DateTimeOffset(System.DateTime dateTime)
- {
- TimeSpan utcOffset;
- if (dateTime.Kind != DateTimeKind.Utc)
- {
- utcOffset = TimeZone.CurrentTimeZone.GetUtcOffset(dateTime);
- }
- else
- {
- utcOffset = new TimeSpan(0L);
- }
- this._offsetMinutes = ValidateOffset(utcOffset);
- this._dateTime = ValidateDate(dateTime, utcOffset);
- }
-
- public DateTimeOffset(System.DateTime dateTime, TimeSpan offset)
- {
- if (dateTime.Kind == DateTimeKind.Local)
- {
- if (offset != TimeZone.CurrentTimeZone.GetUtcOffset(dateTime))
- {
- throw new ArgumentException("The UTC Offset of the local dateTime parameter does not match the offset argument.", "offset");
- }
- }
- else if ((dateTime.Kind == DateTimeKind.Utc) && (offset != TimeSpan.Zero))
- {
- throw new ArgumentException("The UTC Offset for Utc DateTime instances must be 0.", "offset");
- }
- this._offsetMinutes = ValidateOffset(offset);
- this._dateTime = ValidateDate(dateTime, offset);
- }
-
- public DateTimeOffset(long ticks, TimeSpan offset)
- {
- this._offsetMinutes = ValidateOffset(offset);
- System.DateTime dateTime = new System.DateTime(ticks);
- this._dateTime = ValidateDate(dateTime, offset);
- }
-
- public DateTimeOffset(int year, int month, int day, int hour, int minute, int second, TimeSpan offset)
- {
- this._offsetMinutes = ValidateOffset(offset);
- this._dateTime = ValidateDate(new System.DateTime(year, month, day, hour, minute, second), offset);
- }
-
- public DateTimeOffset(int year, int month, int day, int hour, int minute, int second, int millisecond, TimeSpan offset)
- {
- this._offsetMinutes = ValidateOffset(offset);
- this._dateTime = ValidateDate(new System.DateTime(year, month, day, hour, minute, second, millisecond), offset);
- }
-
- public DateTimeOffset(int year, int month, int day, int hour, int minute, int second, int millisecond, Calendar calendar, TimeSpan offset)
- {
- this._offsetMinutes = ValidateOffset(offset);
- this._dateTime = ValidateDate(new System.DateTime(year, month, day, hour, minute, second, millisecond, calendar), offset);
- }
-
- public DateTimeOffset Add(TimeSpan timeSpan)
- {
- return new DateTimeOffset(this.ClockDateTime.Add(timeSpan), this.Offset);
- }
-
- public DateTimeOffset AddDays(double days)
- {
- return new DateTimeOffset(this.ClockDateTime.AddDays(days), this.Offset);
- }
-
- public DateTimeOffset AddHours(double hours)
- {
- return new DateTimeOffset(this.ClockDateTime.AddHours(hours), this.Offset);
- }
-
- public DateTimeOffset AddMilliseconds(double milliseconds)
- {
- return new DateTimeOffset(this.ClockDateTime.AddMilliseconds(milliseconds), this.Offset);
- }
-
- public DateTimeOffset AddMinutes(double minutes)
- {
- return new DateTimeOffset(this.ClockDateTime.AddMinutes(minutes), this.Offset);
- }
-
- public DateTimeOffset AddMonths(int months)
- {
- return new DateTimeOffset(this.ClockDateTime.AddMonths(months), this.Offset);
- }
-
- public DateTimeOffset AddSeconds(double seconds)
- {
- return new DateTimeOffset(this.ClockDateTime.AddSeconds(seconds), this.Offset);
- }
-
- public DateTimeOffset AddTicks(long ticks)
- {
- return new DateTimeOffset(this.ClockDateTime.AddTicks(ticks), this.Offset);
- }
-
- public DateTimeOffset AddYears(int years)
- {
- return new DateTimeOffset(this.ClockDateTime.AddYears(years), this.Offset);
- }
-
- public static int Compare(DateTimeOffset first, DateTimeOffset second)
- {
- return System.DateTime.Compare(first.UtcDateTime, second.UtcDateTime);
- }
-
- public int CompareTo(DateTimeOffset other)
- {
- System.DateTime utcDateTime = other.UtcDateTime;
- System.DateTime time2 = this.UtcDateTime;
- if (time2 > utcDateTime)
- {
- return 1;
- }
- if (time2 < utcDateTime)
- {
- return -1;
- }
- return 0;
- }
-
- public bool Equals(DateTimeOffset other)
- {
- return this.UtcDateTime.Equals(other.UtcDateTime);
- }
-
- public override bool Equals(object obj)
- {
- if (obj is DateTimeOffset)
- {
- DateTimeOffset offset = (DateTimeOffset)obj;
- return this.UtcDateTime.Equals(offset.UtcDateTime);
- }
- return false;
- }
-
- public static bool Equals(DateTimeOffset first, DateTimeOffset second)
- {
- return System.DateTime.Equals(first.UtcDateTime, second.UtcDateTime);
- }
-
- public bool EqualsExact(DateTimeOffset other)
- {
- return (((this.ClockDateTime == other.ClockDateTime) && (this.Offset == other.Offset)) && (this.ClockDateTime.Kind == other.ClockDateTime.Kind));
- }
-
- public static DateTimeOffset FromFileTime(long fileTime)
- {
- return new DateTimeOffset(System.DateTime.FromFileTime(fileTime));
- }
-
- public override int GetHashCode()
- {
- return this.UtcDateTime.GetHashCode();
- }
-
- public static DateTimeOffset operator +(DateTimeOffset dateTimeTz, TimeSpan timeSpan)
- {
- return new DateTimeOffset(dateTimeTz.ClockDateTime + timeSpan, dateTimeTz.Offset);
- }
-
- public static bool operator ==(DateTimeOffset left, DateTimeOffset right)
- {
- return (left.UtcDateTime == right.UtcDateTime);
- }
-
- public static bool operator >(DateTimeOffset left, DateTimeOffset right)
- {
- return (left.UtcDateTime > right.UtcDateTime);
- }
-
- public static bool operator >=(DateTimeOffset left, DateTimeOffset right)
- {
- return (left.UtcDateTime >= right.UtcDateTime);
- }
-
- public static implicit operator DateTimeOffset(System.DateTime dateTime)
- {
- return new DateTimeOffset(dateTime);
- }
-
- public static bool operator !=(DateTimeOffset left, DateTimeOffset right)
- {
- return (left.UtcDateTime != right.UtcDateTime);
- }
-
- public static bool operator <(DateTimeOffset left, DateTimeOffset right)
- {
- return (left.UtcDateTime < right.UtcDateTime);
- }
-
- public static bool operator <=(DateTimeOffset left, DateTimeOffset right)
- {
- return (left.UtcDateTime <= right.UtcDateTime);
- }
-
- public static TimeSpan operator -(DateTimeOffset left, DateTimeOffset right)
- {
- return (TimeSpan)(left.UtcDateTime - right.UtcDateTime);
- }
-
- public static DateTimeOffset operator -(DateTimeOffset dateTimeTz, TimeSpan timeSpan)
- {
- return new DateTimeOffset(dateTimeTz.ClockDateTime - timeSpan, dateTimeTz.Offset);
- }
-
- public static DateTimeOffset Parse(string input)
- {
- return new DateTimeOffset(DateTime.Parse(input, DateTimeFormatInfo.CurrentInfo, DateTimeStyles.None));
- }
-
- public static DateTimeOffset Parse(string input, IFormatProvider formatProvider)
- {
- return Parse(input, formatProvider, DateTimeStyles.None);
- }
-
- public static DateTimeOffset Parse(string input, IFormatProvider formatProvider, DateTimeStyles styles)
- {
- styles = ValidateStyles(styles, "styles");
- return new DateTimeOffset(DateTime.Parse(input, DateTimeFormatInfo.GetInstance(formatProvider), styles));
- }
-
- public static DateTimeOffset ParseExact(string input, string format, IFormatProvider formatProvider)
- {
- return ParseExact(input, format, formatProvider, DateTimeStyles.None);
- }
-
- public static DateTimeOffset ParseExact(string input, string format, IFormatProvider formatProvider, DateTimeStyles styles)
- {
- styles = ValidateStyles(styles, "styles");
- return new DateTimeOffset(DateTime.ParseExact(input, format, DateTimeFormatInfo.GetInstance(formatProvider), styles));
- }
-
- public static DateTimeOffset ParseExact(string input, string[] formats, IFormatProvider formatProvider, DateTimeStyles styles)
- {
- styles = ValidateStyles(styles, "styles");
- return new DateTimeOffset(DateTime.ParseExact(input, formats, DateTimeFormatInfo.GetInstance(formatProvider), styles));
- }
-
- public TimeSpan Subtract(DateTimeOffset value)
- {
- return this.UtcDateTime.Subtract(value.UtcDateTime);
- }
-
- public DateTimeOffset Subtract(TimeSpan value)
- {
- return new DateTimeOffset(this.ClockDateTime.Subtract(value), this.Offset);
- }
-
- int IComparable.CompareTo(object obj)
- {
- if (obj == null)
- {
- return 1;
- }
- if (!(obj is DateTimeOffset))
- {
- throw new ArgumentException("Object must be of type DateTimeOffset.");
- }
- DateTimeOffset offset = (DateTimeOffset)obj;
- System.DateTime utcDateTime = offset.UtcDateTime;
- System.DateTime time2 = this.UtcDateTime;
- if (time2 > utcDateTime)
- {
- return 1;
- }
- if (time2 < utcDateTime)
- {
- return -1;
- }
- return 0;
- }
-
- public long ToFileTime()
- {
- return this.UtcDateTime.ToFileTime();
- }
-
- public DateTimeOffset ToLocalTime()
- {
- return new DateTimeOffset(this.UtcDateTime.ToLocalTime());
- }
-
- public DateTimeOffset ToOffset(TimeSpan offset)
- {
- System.DateTime time = this._dateTime + offset;
- return new DateTimeOffset(time.Ticks, offset);
- }
-
- public string ToString(string format, IFormatProvider formatProvider)
- {
- if (!string.IsNullOrEmpty(format))
- {
- format = format.Replace("K", "zzz");
- format = format.Replace("zzz", Offset.Hours.ToString("+00;-00", CultureInfo.InvariantCulture) + ":" + Offset.Minutes.ToString("00;00", CultureInfo.InvariantCulture));
- format = format.Replace("zz", Offset.Hours.ToString("+00;-00", CultureInfo.InvariantCulture));
- format = format.Replace("z", Offset.Hours.ToString("+0;-0", CultureInfo.InvariantCulture));
- }
-
- return ClockDateTime.ToString(format, formatProvider);
- }
-
- public DateTimeOffset ToUniversalTime()
- {
- return new DateTimeOffset(this.UtcDateTime);
- }
-
- private static System.DateTime ValidateDate(System.DateTime dateTime, TimeSpan offset)
- {
- long ticks = dateTime.Ticks - offset.Ticks;
- if ((ticks < 0L) || (ticks > 0x2bca2875f4373fffL))
- {
- throw new ArgumentOutOfRangeException("offset", "The UTC time represented when the offset is applied must be between year 0 and 10,000.");
- }
- return new System.DateTime(ticks, DateTimeKind.Unspecified);
- }
-
- private static short ValidateOffset(TimeSpan offset)
- {
- long ticks = offset.Ticks;
- if ((ticks % 0x23c34600L) != 0L)
- {
- throw new ArgumentException("Offset must be specified in whole minutes.", "offset");
- }
- if ((ticks < -504000000000L) || (ticks > 0x7558bdb000L))
- {
- throw new ArgumentOutOfRangeException("offset", "Offset must be within plus or minus 14 hours.");
- }
- return (short)(offset.Ticks / 0x23c34600L);
- }
-
- private static DateTimeStyles ValidateStyles(DateTimeStyles style, string parameterName)
- {
- if ((style & ~(DateTimeStyles.RoundtripKind | DateTimeStyles.AssumeUniversal | DateTimeStyles.AssumeLocal | DateTimeStyles.AdjustToUniversal | DateTimeStyles.NoCurrentDateDefault | DateTimeStyles.AllowWhiteSpaces)) != DateTimeStyles.None)
- {
- throw new ArgumentException("An undefined DateTimeStyles value is being used.", parameterName);
- }
- if (((style & DateTimeStyles.AssumeLocal) != DateTimeStyles.None) && ((style & DateTimeStyles.AssumeUniversal) != DateTimeStyles.None))
- {
- throw new ArgumentException("The DateTimeStyles values AssumeLocal and AssumeUniversal cannot be used together.", parameterName);
- }
- if ((style & DateTimeStyles.NoCurrentDateDefault) != DateTimeStyles.None)
- {
- throw new ArgumentException("The DateTimeStyles value 'NoCurrentDateDefault' is not allowed when parsing DateTimeOffset.", parameterName);
- }
- style &= ~DateTimeStyles.RoundtripKind;
- style &= ~DateTimeStyles.AssumeLocal;
- return style;
- }
-
- private System.DateTime ClockDateTime
- {
- get
- {
- System.DateTime time = this._dateTime + this.Offset;
- return new System.DateTime(time.Ticks, DateTimeKind.Unspecified);
- }
- }
-
- public System.DateTime Date
- {
- get
- {
- return this.ClockDateTime.Date;
- }
- }
-
- public System.DateTime DateTime
- {
- get
- {
- return this.ClockDateTime;
- }
- }
-
- public int Day
- {
- get
- {
- return this.ClockDateTime.Day;
- }
- }
-
- public System.DayOfWeek DayOfWeek
- {
- get
- {
- return this.ClockDateTime.DayOfWeek;
- }
- }
-
- public int DayOfYear
- {
- get
- {
- return this.ClockDateTime.DayOfYear;
- }
- }
-
- public int Hour
- {
- get
- {
- return this.ClockDateTime.Hour;
- }
- }
-
- public System.DateTime LocalDateTime
- {
- get
- {
- return this.UtcDateTime.ToLocalTime();
- }
- }
-
- public int Millisecond
- {
- get
- {
- return this.ClockDateTime.Millisecond;
- }
- }
-
- public int Minute
- {
- get
- {
- return this.ClockDateTime.Minute;
- }
- }
-
- public int Month
- {
- get
- {
- return this.ClockDateTime.Month;
- }
- }
-
- public static DateTimeOffset Now
- {
- get
- {
- return new DateTimeOffset(System.DateTime.Now);
- }
- }
-
- public TimeSpan Offset
- {
- get
- {
- return new TimeSpan(0, this._offsetMinutes, 0);
- }
- }
-
- public int Second
- {
- get
- {
- return this.ClockDateTime.Second;
- }
- }
-
- public long Ticks
- {
- get
- {
- return this.ClockDateTime.Ticks;
- }
- }
-
- public TimeSpan TimeOfDay
- {
- get
- {
- return this.ClockDateTime.TimeOfDay;
- }
- }
-
- public System.DateTime UtcDateTime
- {
- get
- {
- return System.DateTime.SpecifyKind(this._dateTime, DateTimeKind.Utc);
- }
- }
-
- public static DateTimeOffset UtcNow
- {
- get
- {
- return new DateTimeOffset(System.DateTime.UtcNow);
- }
- }
-
- public long UtcTicks
- {
- get
- {
- return this.UtcDateTime.Ticks;
- }
- }
-
- public int Year
- {
- get
- {
- return this.ClockDateTime.Year;
- }
- }
- }
-}
-#endif \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/JsonConvert.cs b/Src/Newtonsoft.Json/JsonConvert.cs
index 9c6d443..db5d1c7 100644
--- a/Src/Newtonsoft.Json/JsonConvert.cs
+++ b/Src/Newtonsoft.Json/JsonConvert.cs
@@ -106,6 +106,7 @@ namespace Newtonsoft.Json
return ToStringInternal(value, utcOffset, value.Kind);
}
+#if !PocketPC && !NET20
/// <summary>
/// Converts the <see cref="DateTimeOffset"/> to its JSON string representation.
/// </summary>
@@ -115,6 +116,7 @@ namespace Newtonsoft.Json
{
return ToStringInternal(value.UtcDateTime, value.Offset, DateTimeKind.Local);
}
+#endif
internal static string ToStringInternal(DateTime value, TimeSpan offset, DateTimeKind kind)
{
@@ -387,10 +389,12 @@ namespace Newtonsoft.Json
return Null;
}
}
+#if !PocketPC && !NET20
else if (value is DateTimeOffset)
{
return ToString((DateTimeOffset)value);
}
+#endif
throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType()));
}
@@ -427,9 +431,14 @@ namespace Newtonsoft.Json
return false;
}
}
-
+
+#if !PocketPC && !NET20
if (value is DateTimeOffset)
return true;
+#endif
+
+ if (value is byte[])
+ return true;
return false;
}
diff --git a/Src/Newtonsoft.Json/JsonReader.cs b/Src/Newtonsoft.Json/JsonReader.cs
index 86a38e2..875a5ac 100644
--- a/Src/Newtonsoft.Json/JsonReader.cs
+++ b/Src/Newtonsoft.Json/JsonReader.cs
@@ -169,7 +169,7 @@ namespace Newtonsoft.Json
/// <summary>
/// Initializes a new instance of the <see cref="JsonReader"/> class with the specified <see cref="TextReader"/>.
/// </summary>
- public JsonReader()
+ protected JsonReader()
{
//_testBuffer = new StringBuilder();
_currentState = State.Start;
@@ -204,6 +204,8 @@ namespace Newtonsoft.Json
/// <returns>true if the next token was read successfully; false if there are no more tokens to read.</returns>
public abstract bool Read();
+ public abstract byte[] ReadAsBytes();
+
/// <summary>
/// Skips the children of the current token.
/// </summary>
@@ -275,6 +277,7 @@ namespace Newtonsoft.Json
case JsonToken.Date:
case JsonToken.String:
case JsonToken.Raw:
+ case JsonToken.Bytes:
_currentState = State.PostValue;
break;
}
@@ -351,6 +354,7 @@ namespace Newtonsoft.Json
case JsonToken.EndConstructor:
case JsonToken.Date:
case JsonToken.Raw:
+ case JsonToken.Bytes:
return false;
default:
throw MiscellaneousUtils.CreateArgumentOutOfRangeException("token", token, "Unexpected JsonToken value.");
diff --git a/Src/Newtonsoft.Json/JsonSerializer.cs b/Src/Newtonsoft.Json/JsonSerializer.cs
index 2d65567..e8cc599 100644
--- a/Src/Newtonsoft.Json/JsonSerializer.cs
+++ b/Src/Newtonsoft.Json/JsonSerializer.cs
@@ -423,7 +423,7 @@ namespace Newtonsoft.Json
if (objectType == null)
throw new ArgumentNullException("objectType");
- converter = JsonTypeReflector.GetConverter(objectType, objectType);
+ converter = JsonTypeReflector.GetJsonConverter(objectType, objectType);
return (converter != null);
}
diff --git a/Src/Newtonsoft.Json/JsonTextReader.cs b/Src/Newtonsoft.Json/JsonTextReader.cs
index 83d4e98..00ce3f6 100644
--- a/Src/Newtonsoft.Json/JsonTextReader.cs
+++ b/Src/Newtonsoft.Json/JsonTextReader.cs
@@ -61,11 +61,29 @@ namespace Newtonsoft.Json
private void ParseString(char quote)
{
+ ReadStringIntoBuffer(quote, null);
+
+ string text = _buffer.ToString();
+ _buffer.Position = 0;
+
+ if (text.StartsWith("/Date(", StringComparison.Ordinal) && text.EndsWith(")/", StringComparison.Ordinal))
+ {
+ ParseDate(text);
+ }
+ else
+ {
+ SetToken(JsonToken.String, text);
+ QuoteChar = quote;
+ }
+ }
+
+ private void ReadStringIntoBuffer(char quote, int? untilPosition)
+ {
bool stringTerminated = false;
bool hexNumber = false;
int hexCount = 0;
- while (!stringTerminated && MoveNext())
+ while (!stringTerminated && (untilPosition == null || _buffer.Position < untilPosition) && MoveNext())
{
if (hexNumber)
hexCount++;
@@ -136,18 +154,6 @@ namespace Newtonsoft.Json
throw CreateJsonReaderException("Unterminated string. Expected delimiter: {0}. Line {1}, position {2}.", quote, _currentLineNumber, _currentLinePosition);
ClearCurrentChar();
- string text = _buffer.ToString();
- _buffer.Position = 0;
-
- if (text.StartsWith("/Date(", StringComparison.Ordinal) && text.EndsWith(")/", StringComparison.Ordinal))
- {
- ParseDate(text);
- }
- else
- {
- SetToken(JsonToken.String, text);
- QuoteChar = quote;
- }
}
private JsonReaderException CreateJsonReaderException(string format, params object[] args)
@@ -321,6 +327,61 @@ namespace Newtonsoft.Json
}
}
+ public override byte[] ReadAsBytes()
+ {
+ while (true)
+ {
+ if (_currentChar == '\0')
+ {
+ if (!MoveNext())
+ throw CreateJsonReaderException("Unexpected end: Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
+ }
+
+ switch (CurrentState)
+ {
+ case State.Start:
+ case State.Property:
+ case State.Array:
+ case State.ArrayStart:
+ case State.Constructor:
+ case State.ConstructorStart:
+ do
+ {
+ switch (_currentChar)
+ {
+ case '"':
+ case '\'':
+ ReadStringIntoBuffer(_currentChar, null);
+
+ byte[] data = Convert.FromBase64CharArray(_buffer.GetInternalBuffer(), 0, _buffer.Position);
+ _buffer.Position = 0;
+
+ SetToken(JsonToken.Bytes, data);
+
+ return data;
+ case 'n':
+ ParseNull();
+ return null;
+ default:
+ if (char.IsWhiteSpace(_currentChar))
+ {
+ // eat
+ }
+ else
+ {
+ throw CreateJsonReaderException("Unexpected character encountered while parsing value: {0}. Line {1}, position {2}.", _currentChar, _currentLineNumber, _currentLinePosition);
+ }
+ break;
+ }
+ } while (MoveNext());
+ ParseValue();
+ break;
+ default:
+ throw CreateJsonReaderException("Unexpected state: {0}. Line {1}, position {2}.", CurrentState, _currentLineNumber, _currentLinePosition);
+ }
+ }
+ }
+
private bool ParsePostValue()
{
do
diff --git a/Src/Newtonsoft.Json/JsonTextWriter.cs b/Src/Newtonsoft.Json/JsonTextWriter.cs
index 0746b1e..ce2ee00 100644
--- a/Src/Newtonsoft.Json/JsonTextWriter.cs
+++ b/Src/Newtonsoft.Json/JsonTextWriter.cs
@@ -37,12 +37,24 @@ namespace Newtonsoft.Json
/// </summary>
public class JsonTextWriter : JsonWriter
{
- private TextWriter _writer;
+ private readonly TextWriter _writer;
+ private Base64Encoder _base64Encoder;
private char _indentChar;
private int _indentation;
private char _quoteChar;
private bool _quoteName;
+ private Base64Encoder Base64Encoder
+ {
+ get
+ {
+ if (_base64Encoder == null)
+ _base64Encoder = new Base64Encoder(_writer);
+
+ return _base64Encoder;
+ }
+ }
+
/// <summary>
/// Gets or sets how many IndentChars to write for each level in the hierarchy when <paramref name="Formatting"/> is set to <c>Formatting.Indented</c>.
/// </summary>
@@ -419,6 +431,20 @@ namespace Newtonsoft.Json
WriteValueInternal(JsonConvert.ToString(value), JsonToken.Date);
}
+ public override void WriteValue(byte[] value)
+ {
+ base.WriteValue(value);
+
+ if (value != null)
+ {
+ _writer.Write(_quoteChar);
+ Base64Encoder.Encode(value, 0, value.Length);
+ Base64Encoder.Flush();
+ _writer.Write(_quoteChar);
+ }
+ }
+
+#if !PocketPC && !NET20
/// <summary>
/// Writes a <see cref="DateTimeOffset"/> value.
/// </summary>
@@ -428,6 +454,7 @@ namespace Newtonsoft.Json
base.WriteValue(value);
WriteValueInternal(JsonConvert.ToString(value), JsonToken.Date);
}
+#endif
#endregion
/// <summary>
diff --git a/Src/Newtonsoft.Json/JsonToken.cs b/Src/Newtonsoft.Json/JsonToken.cs
index 1e5fae1..5870c42 100644
--- a/Src/Newtonsoft.Json/JsonToken.cs
+++ b/Src/Newtonsoft.Json/JsonToken.cs
@@ -47,11 +47,11 @@ namespace Newtonsoft.Json
/// </summary>
StartArray,
/// <summary>
- /// An object property name.
+ /// A constructor start token.
/// </summary>
StartConstructor,
/// <summary>
- /// A constructor end token.
+ /// An object property name.
/// </summary>
PropertyName,
/// <summary>
@@ -95,12 +95,16 @@ namespace Newtonsoft.Json
/// </summary>
EndArray,
/// <summary>
- /// A constructor start token.
+ /// A constructor end token.
/// </summary>
EndConstructor,
/// <summary>
/// A Date.
/// </summary>
- Date
+ Date,
+ /// <summary>
+ /// Byte data.
+ /// </summary>
+ Bytes
}
-}
+} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/JsonValidatingReader.cs b/Src/Newtonsoft.Json/JsonValidatingReader.cs
index 0899c2d..2b958aa 100644
--- a/Src/Newtonsoft.Json/JsonValidatingReader.cs
+++ b/Src/Newtonsoft.Json/JsonValidatingReader.cs
@@ -304,6 +304,14 @@ namespace Newtonsoft.Json
}
}
+ public override byte[] ReadAsBytes()
+ {
+ byte[] data = _reader.ReadAsBytes();
+
+ ValidateCurrentToken();
+ return data;
+ }
+
/// <summary>
/// Reads the next JSON token from the stream.
/// </summary>
@@ -318,7 +326,13 @@ namespace Newtonsoft.Json
if (_reader.TokenType == JsonToken.Comment)
return true;
- // first time Read has been called. build model
+ ValidateCurrentToken();
+ return true;
+ }
+
+ private void ValidateCurrentToken()
+ {
+ // first time validate has been called. build model
if (_model == null)
{
JsonSchemaModelBuilder builder = new JsonSchemaModelBuilder();
@@ -330,15 +344,15 @@ namespace Newtonsoft.Json
case JsonToken.StartObject:
ProcessValue();
JsonSchemaModel objectSchema = (ValidateObject(CurrentMemberSchema))
- ? CurrentMemberSchema
- : null;
+ ? CurrentMemberSchema
+ : null;
Push(new SchemaScope(JTokenType.Object, objectSchema));
break;
case JsonToken.StartArray:
ProcessValue();
JsonSchemaModel arraySchema = (ValidateArray(CurrentMemberSchema))
- ? CurrentMemberSchema
- : null;
+ ? CurrentMemberSchema
+ : null;
Push(new SchemaScope(JTokenType.Array, arraySchema));
break;
case JsonToken.StartConstructor:
@@ -387,8 +401,6 @@ namespace Newtonsoft.Json
default:
throw new ArgumentOutOfRangeException();
}
-
- return true;
}
private void ValidateEndObject(JsonSchemaModel schema)
diff --git a/Src/Newtonsoft.Json/JsonWriter.cs b/Src/Newtonsoft.Json/JsonWriter.cs
index e7738d7..eeabf6f 100644
--- a/Src/Newtonsoft.Json/JsonWriter.cs
+++ b/Src/Newtonsoft.Json/JsonWriter.cs
@@ -101,6 +101,7 @@ namespace Newtonsoft.Json
Array,
ConstructorStart,
Constructor,
+ Bytes,
Closed,
Error
}
@@ -578,6 +579,7 @@ namespace Newtonsoft.Json
case JsonToken.Null:
case JsonToken.Undefined:
case JsonToken.Date:
+ case JsonToken.Bytes:
// a value is being written
token = 7;
break;
@@ -780,6 +782,7 @@ namespace Newtonsoft.Json
AutoComplete(JsonToken.Date);
}
+#if !PocketPC && !NET20
/// <summary>
/// Writes a <see cref="DateTimeOffset"/> value.
/// </summary>
@@ -788,6 +791,7 @@ namespace Newtonsoft.Json
{
AutoComplete(JsonToken.Date);
}
+#endif
/// <summary>
/// Writes a <see cref="Nullable{Int32}"/> value.
@@ -957,6 +961,7 @@ namespace Newtonsoft.Json
WriteValue(value.Value);
}
+#if !PocketPC && !NET20
/// <summary>
/// Writes a <see cref="Nullable{DateTimeOffset}"/> value.
/// </summary>
@@ -968,6 +973,15 @@ namespace Newtonsoft.Json
else
WriteValue(value.Value);
}
+#endif
+
+ public virtual void WriteValue(byte[] value)
+ {
+ if (value == null)
+ WriteNull();
+ else
+ AutoComplete(JsonToken.Bytes);
+ }
/// <summary>
/// Writes a <see cref="Object"/> value.
@@ -1037,11 +1051,18 @@ namespace Newtonsoft.Json
return;
}
}
+#if !PocketPC && !NET20
else if (value is DateTimeOffset)
{
WriteValue((DateTimeOffset)value);
return;
}
+#endif
+ else if (value is byte[])
+ {
+ WriteValue((byte[])value);
+ return;
+ }
throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType()));
}
diff --git a/Src/Newtonsoft.Json/Linq/JContainer.cs b/Src/Newtonsoft.Json/Linq/JContainer.cs
index fc81366..2336577 100644
--- a/Src/Newtonsoft.Json/Linq/JContainer.cs
+++ b/Src/Newtonsoft.Json/Linq/JContainer.cs
@@ -257,7 +257,7 @@ namespace Newtonsoft.Json.Linq
internal bool IsMultiContent(object content)
{
- return (content is IEnumerable && !(content is string) && !(content is JToken));
+ return (content is IEnumerable && !(content is string) && !(content is JToken) && !(content is byte[]));
}
internal virtual void AddItem(bool isLast, JToken previous, JToken item)
diff --git a/Src/Newtonsoft.Json/Linq/JObject.cs b/Src/Newtonsoft.Json/Linq/JObject.cs
index f6a01d1..5fb4260 100644
--- a/Src/Newtonsoft.Json/Linq/JObject.cs
+++ b/Src/Newtonsoft.Json/Linq/JObject.cs
@@ -43,7 +43,7 @@ namespace Newtonsoft.Json.Linq
[TypeDescriptionProvider(typeof(JTypeDescriptionProvider))]
#endif
public class JObject : JContainer, IDictionary<string, JToken>, INotifyPropertyChanged
-#if !PocketPC && !SILVERLIGHT
+#if !PocketPC && !SILVERLIGHT && !NET20
, INotifyPropertyChanging
#endif
{
@@ -51,7 +51,7 @@ namespace Newtonsoft.Json.Linq
/// Occurs when a property value changes.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
-#if !PocketPC && !SILVERLIGHT
+#if !PocketPC && !SILVERLIGHT && !NET20
/// <summary>
/// Occurs when a property value is changing.
/// </summary>
@@ -121,7 +121,7 @@ namespace Newtonsoft.Json.Linq
internal void InternalPropertyChanging(JProperty childProperty)
{
-#if !PocketPC && !SILVERLIGHT
+#if !PocketPC && !SILVERLIGHT && !NET20
OnPropertyChanging(childProperty.Name);
#endif
}
@@ -221,7 +221,7 @@ namespace Newtonsoft.Json.Linq
}
else
{
-#if !PocketPC && !SILVERLIGHT
+#if !PocketPC && !SILVERLIGHT && !NET20
OnPropertyChanging(propertyName);
#endif
Add(new JProperty(propertyName, value));
@@ -472,7 +472,7 @@ namespace Newtonsoft.Json.Linq
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
-#if !PocketPC && !SILVERLIGHT
+#if !PocketPC && !SILVERLIGHT && !NET20
/// <summary>
/// Raises the <see cref="PropertyChanging"/> event with the provided arguments.
/// </summary>
diff --git a/Src/Newtonsoft.Json/Linq/JToken.cs b/Src/Newtonsoft.Json/Linq/JToken.cs
index 3cde628..8587e5e 100644
--- a/Src/Newtonsoft.Json/Linq/JToken.cs
+++ b/Src/Newtonsoft.Json/Linq/JToken.cs
@@ -400,6 +400,11 @@ namespace Newtonsoft.Json.Linq
return (o.Type == JTokenType.String || o.Type == JTokenType.Comment || o.Type == JTokenType.Raw || IsNullable(o));
}
+ private static bool ValidateBytes(JToken o)
+ {
+ return (o.Type == JTokenType.Bytes || IsNullable(o));
+ }
+
private static string GetType(JToken t)
{
return (t != null) ? t.Type.ToString() : "{null}";
@@ -420,6 +425,7 @@ namespace Newtonsoft.Json.Linq
return (bool)v.Value;
}
+#if !PocketPC && !NET20
/// <summary>
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="System.DateTimeOffset"/>.
/// </summary>
@@ -433,6 +439,7 @@ namespace Newtonsoft.Json.Linq
return (DateTimeOffset)v.Value;
}
+#endif
/// <summary>
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Boolean}"/>.
@@ -482,6 +489,7 @@ namespace Newtonsoft.Json.Linq
return (DateTime?)v.Value;
}
+#if !PocketPC && !NET20
/// <summary>
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{DateTimeOffset}"/>.
/// </summary>
@@ -498,6 +506,7 @@ namespace Newtonsoft.Json.Linq
return (DateTimeOffset?)v.Value;
}
+#endif
/// <summary>
/// Performs an explicit conversion from <see cref="Newtonsoft.Json.Linq.JToken"/> to <see cref="Nullable{Decimal}"/>.
@@ -732,6 +741,15 @@ namespace Newtonsoft.Json.Linq
return Convert.ToUInt64(v.Value, CultureInfo.InvariantCulture);
}
+
+ public static explicit operator byte[](JToken value)
+ {
+ JValue v = EnsureValue(value);
+ if (v == null || !ValidateBytes(v))
+ throw new ArgumentException("Can not convert {0} to byte array.".FormatWith(CultureInfo.InvariantCulture, GetType(v)));
+
+ return (byte[])v.Value;
+ }
#endregion
#region Cast to operators
@@ -745,6 +763,7 @@ namespace Newtonsoft.Json.Linq
return new JValue(value);
}
+#if !PocketPC && !NET20
/// <summary>
/// Performs an implicit conversion from <see cref="DateTimeOffset"/> to <see cref="JToken"/>.
/// </summary>
@@ -754,6 +773,7 @@ namespace Newtonsoft.Json.Linq
{
return new JValue(value);
}
+#endif
/// <summary>
/// Performs an implicit conversion from <see cref="Nullable{Boolean}"/> to <see cref="JToken"/>.
@@ -785,6 +805,7 @@ namespace Newtonsoft.Json.Linq
return new JValue(value);
}
+#if !PocketPC && !NET20
/// <summary>
/// Performs an implicit conversion from <see cref="Nullable{DateTimeOffset}"/> to <see cref="JToken"/>.
/// </summary>
@@ -794,6 +815,7 @@ namespace Newtonsoft.Json.Linq
{
return new JValue(value);
}
+#endif
/// <summary>
/// Performs an implicit conversion from <see cref="Nullable{Decimal}"/> to <see cref="JToken"/>.
@@ -964,6 +986,11 @@ namespace Newtonsoft.Json.Linq
{
return new JValue(value);
}
+
+ public static implicit operator JToken(byte[] value)
+ {
+ return new JValue(value);
+ }
#endregion
IEnumerator IEnumerable.GetEnumerator()
diff --git a/Src/Newtonsoft.Json/Linq/JTokenReader.cs b/Src/Newtonsoft.Json/Linq/JTokenReader.cs
index 28d9982..dc22042 100644
--- a/Src/Newtonsoft.Json/Linq/JTokenReader.cs
+++ b/Src/Newtonsoft.Json/Linq/JTokenReader.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json.Utilities;
+using System.Globalization;
namespace Newtonsoft.Json.Linq
{
@@ -27,6 +28,15 @@ namespace Newtonsoft.Json.Linq
_current = token;
}
+ public override byte[] ReadAsBytes()
+ {
+ Read();
+ if (TokenType != JsonToken.Bytes)
+ throw new JsonReaderException("Error reading bytes. Expected bytes but got {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
+
+ return (byte[])Value;
+ }
+
/// <summary>
/// Reads the next JSON token from the stream.
/// </summary>
@@ -172,6 +182,9 @@ namespace Newtonsoft.Json.Linq
case JTokenType.Raw:
SetToken(JsonToken.Raw, ((JValue)token).Value);
break;
+ case JTokenType.Bytes:
+ SetToken(JsonToken.Bytes, ((JValue)token).Value);
+ break;
default:
throw MiscellaneousUtils.CreateArgumentOutOfRangeException("Type", token.Type, "Unexpected JTokenType.");
}
@@ -216,4 +229,4 @@ namespace Newtonsoft.Json.Linq
}
}
}
-}
+} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Linq/JTokenType.cs b/Src/Newtonsoft.Json/Linq/JTokenType.cs
index d0106da..e20ce27 100644
--- a/Src/Newtonsoft.Json/Linq/JTokenType.cs
+++ b/Src/Newtonsoft.Json/Linq/JTokenType.cs
@@ -90,6 +90,7 @@ namespace Newtonsoft.Json.Linq
/// <summary>
/// A raw JSON value.
/// </summary>
- Raw
+ Raw,
+ Bytes
}
} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Linq/JTokenWriter.cs b/Src/Newtonsoft.Json/Linq/JTokenWriter.cs
index 273dea3..baae1ed 100644
--- a/Src/Newtonsoft.Json/Linq/JTokenWriter.cs
+++ b/Src/Newtonsoft.Json/Linq/JTokenWriter.cs
@@ -334,6 +334,7 @@ namespace Newtonsoft.Json.Linq
AddValue(value, JsonToken.Date);
}
+#if !PocketPC && !NET20
/// <summary>
/// Writes a <see cref="DateTimeOffset"/> value.
/// </summary>
@@ -343,6 +344,13 @@ namespace Newtonsoft.Json.Linq
base.WriteValue(value);
AddValue(value, JsonToken.Date);
}
+#endif
+
+ public override void WriteValue(byte[] value)
+ {
+ base.WriteValue(value);
+ AddValue(value, JsonToken.Bytes);
+ }
#endregion
}
}
diff --git a/Src/Newtonsoft.Json/Linq/JValue.cs b/Src/Newtonsoft.Json/Linq/JValue.cs
index e731207..5725511 100644
--- a/Src/Newtonsoft.Json/Linq/JValue.cs
+++ b/Src/Newtonsoft.Json/Linq/JValue.cs
@@ -142,6 +142,8 @@ namespace Newtonsoft.Json.Linq
{
if (objA == null && objB == null)
return true;
+ if (objA == null || objB == null)
+ return false;
switch (_valueType)
{
@@ -158,6 +160,13 @@ namespace Newtonsoft.Json.Linq
return objA.Equals(objB);
case JTokenType.Date:
return objA.Equals(objB);
+ case JTokenType.Bytes:
+ byte[] b1 = objA as byte[];
+ byte[] b2 = objB as byte[];
+ if (b1 == null || b2 == null)
+ return false;
+
+ return MiscellaneousUtils.ByteArrayCompare(b1, b2);
default:
throw MiscellaneousUtils.CreateArgumentOutOfRangeException("valueType", _valueType, "Unexpected value type: {0}".FormatWith(CultureInfo.InvariantCulture, _valueType));
}
@@ -214,8 +223,12 @@ namespace Newtonsoft.Json.Linq
return JTokenType.Float;
else if (value is DateTime)
return JTokenType.Date;
+#if !PocketPC && !NET20
else if (value is DateTimeOffset)
return JTokenType.Date;
+#endif
+ else if (value is byte[])
+ return JTokenType.Bytes;
else if (value is bool)
return JTokenType.Boolean;
@@ -303,12 +316,17 @@ namespace Newtonsoft.Json.Linq
case JTokenType.Date:
WriteConvertableValue(writer, converters, v =>
{
+#if !PocketPC && !NET20
if (v is DateTimeOffset)
writer.WriteValue((DateTimeOffset)v);
else
- writer.WriteValue(Convert.ToDateTime(v, CultureInfo.InvariantCulture));
+#endif
+ writer.WriteValue(Convert.ToDateTime(v, CultureInfo.InvariantCulture));
}, _value);
break;
+ case JTokenType.Bytes:
+ WriteConvertableValue(writer, converters, v => writer.WriteValue((byte[])v), _value);
+ break;
case JTokenType.Raw:
writer.WriteRawValue(_value.ToString());
break;
diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj
index 4e07914..3fedf28 100644
--- a/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj
+++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj
@@ -64,7 +64,6 @@
<Compile Include="Converters\DataTableConverter.cs" />
<Compile Include="Converters\EntityKeyMemberConverter.cs" />
<Compile Include="Converters\StringEnumConverter.cs" />
- <Compile Include="DateTimeOffset.cs" />
<Compile Include="IJsonLineInfo.cs" />
<Compile Include="JsonArrayAttribute.cs" />
<Compile Include="JsonContainerAttribute.cs" />
@@ -159,6 +158,7 @@
<Compile Include="Serialization\ReflectionValueProvider.cs" />
<Compile Include="StreamingContext.cs" />
<Compile Include="TypeNameHandling.cs" />
+ <Compile Include="Utilities\Base64Encoder.cs" />
<Compile Include="Utilities\BidirectionalDictionary.cs" />
<Compile Include="Utilities\ConvertUtils.cs" />
<Compile Include="Utilities\CollectionWrapper.cs" />
diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj
index b8f3ec9..325ddac 100644
--- a/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj
+++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj
@@ -54,7 +54,7 @@
<WarningLevel>4</WarningLevel>
<DocumentationFile>bin\Debug\Newtonsoft.Json.Net20.xml</DocumentationFile>
<RunCodeAnalysis>true</RunCodeAnalysis>
- <CodeAnalysisRules>-Microsoft.Design#CA1012;-Microsoft.Design#CA2210;-Microsoft.Design#CA1040;-Microsoft.Design#CA1005;-Microsoft.Design#CA1020;-Microsoft.Design#CA1021;-Microsoft.Design#CA1010;-Microsoft.Design#CA1011;-Microsoft.Design#CA1009;-Microsoft.Design#CA1050;-Microsoft.Design#CA1026;-Microsoft.Design#CA1019;-Microsoft.Design#CA1031;-Microsoft.Design#CA1047;-Microsoft.Design#CA1000;-Microsoft.Design#CA1048;-Microsoft.Design#CA1051;-Microsoft.Design#CA1002;-Microsoft.Design#CA1061;-Microsoft.Design#CA1006;-Microsoft.Design#CA1046;-Microsoft.Design#CA1045;-Microsoft.Design#CA1065;-Microsoft.Design#CA1038;-Microsoft.Design#CA1008;-Microsoft.Design#CA1028;-Microsoft.Design#CA1064;-Microsoft.Design#CA1004;-Microsoft.Design#CA1035;-Microsoft.Design#CA1063;-Microsoft.Design#CA1032;-Microsoft.Design#CA1023;-Microsoft.Design#CA1033;-Microsoft.Design#CA1039;-Microsoft.Design#CA1016;-Microsoft.Design#CA1014;-Microsoft.Design#CA1017;-Microsoft.Design#CA1018;-Microsoft.Design#CA1027;-Microsoft.Design#CA1059;-Microsoft.Design#CA1060;-Microsoft.Design#CA1034;-Microsoft.Design#CA1013;-Microsoft.Design#CA1036;-Microsoft.Design#CA1044;-Microsoft.Design#CA1041;-Microsoft.Design#CA1025;-Microsoft.Design#CA1052;-Microsoft.Design#CA1053;-Microsoft.Design#CA1057;-Microsoft.Design#CA1058;-Microsoft.Design#CA1001;-Microsoft.Design#CA1049;-Microsoft.Design#CA1054;-Microsoft.Design#CA1056;-Microsoft.Design#CA1055;-Microsoft.Design#CA1030;-Microsoft.Design#CA1003;-Microsoft.Design#CA1007;-Microsoft.Design#CA1043;-Microsoft.Design#CA1024;-Microsoft.Globalization#CA1301;-Microsoft.Globalization#CA1302;-Microsoft.Globalization#CA1308;-Microsoft.Globalization#CA1306;-Microsoft.Globalization#CA2101;-Microsoft.Globalization#CA1300;-Microsoft.Globalization#CA1307;-Microsoft.Globalization#CA1309;-Microsoft.Interoperability#CA1403;-Microsoft.Interoperability#CA1406;-Microsoft.Interoperability#CA1413;-Microsoft.Interoperability#CA1402;-Microsoft.Interoperability#CA1407;-Microsoft.Interoperability#CA1404;-Microsoft.Interoperability#CA1410;-Microsoft.Interoperability#CA1411;-Microsoft.Interoperability#CA1405;-Microsoft.Interoperability#CA1409;-Microsoft.Interoperability#CA1415;-Microsoft.Interoperability#CA1408;-Microsoft.Interoperability#CA1414;-Microsoft.Interoperability#CA1412;-Microsoft.Interoperability#CA1400;-Microsoft.Interoperability#CA1401;-Microsoft.Maintainability#CA1506;-Microsoft.Maintainability#CA1502;-Microsoft.Maintainability#CA1501;-Microsoft.Maintainability#CA1505;-Microsoft.Maintainability#CA1504;-Microsoft.Maintainability#CA1500;-Microsoft.Mobility#CA1600;-Microsoft.Mobility#CA1601;-Microsoft.Naming#CA1702;-Microsoft.Naming#CA1700;-Microsoft.Naming#CA1712;-Microsoft.Naming#CA1713;-Microsoft.Naming#CA1714;-Microsoft.Naming#CA1709;-Microsoft.Naming#CA1704;-Microsoft.Naming#CA1708;-Microsoft.Naming#CA1715;-Microsoft.Naming#CA1710;-Microsoft.Naming#CA1720;-Microsoft.Naming#CA1707;-Microsoft.Naming#CA1722;-Microsoft.Naming#CA1711;-Microsoft.Naming#CA1716;-Microsoft.Naming#CA1717;-Microsoft.Naming#CA1725;-Microsoft.Naming#CA1719;-Microsoft.Naming#CA1721;-Microsoft.Naming#CA1701;-Microsoft.Naming#CA1703;-Microsoft.Naming#CA1724;-Microsoft.Naming#CA1726;-Microsoft.Performance#CA1809;-Microsoft.Performance#CA1811;-Microsoft.Performance#CA1812;-Microsoft.Performance#CA1813;-Microsoft.Performance#CA1823;-Microsoft.Performance#CA1800;-Microsoft.Performance#CA1805;-Microsoft.Performance#CA1810;-Microsoft.Performance#CA1824;-Microsoft.Performance#CA1822;-Microsoft.Performance#CA1815;-Microsoft.Performance#CA1814;-Microsoft.Performance#CA1819;-Microsoft.Performance#CA1821;-Microsoft.Performance#CA1804;-Microsoft.Performance#CA1820;-Microsoft.Performance#CA1802;-Microsoft.Portability#CA1901;-Microsoft.Portability#CA1900;-Microsoft.Reliability#CA2001;-Microsoft.Reliability#CA2002;-Microsoft.Reliability#CA2003;-Microsoft.Reliability#CA2004;-Microsoft.Reliability#CA2006;-Microsoft.Security#CA2116;-Microsoft.Security#CA2117;-Microsoft.Security#CA2105;-Microsoft.Security#CA2115;-Microsoft.Security#CA2102;-Microsoft.Security#CA2104;-Microsoft.Security#CA2122;-Microsoft.Security#CA2114;-Microsoft.Security#CA2123;-Microsoft.Security#CA2111;-Microsoft.Security#CA2108;-Microsoft.Security#CA2107;-Microsoft.Security#CA2103;-Microsoft.Security#CA2118;-Microsoft.Security#CA2109;-Microsoft.Security#CA2119;-Microsoft.Security#CA2106;-Microsoft.Security#CA2112;-Microsoft.Security#CA2120;-Microsoft.Security#CA2121;-Microsoft.Security#CA2126;-Microsoft.Security#CA2124;-Microsoft.Security#CA2127;-Microsoft.Security#CA2128;-Microsoft.Security#CA2129;-Microsoft.Usage#CA2243;-Microsoft.Usage#CA2236;-Microsoft.Usage#CA1816;-Microsoft.Usage#CA2227;-Microsoft.Usage#CA2213;-Microsoft.Usage#CA2216;-Microsoft.Usage#CA2214;-Microsoft.Usage#CA2222;-Microsoft.Usage#CA1806;-Microsoft.Usage#CA2217;-Microsoft.Usage#CA2212;-Microsoft.Usage#CA2219;-Microsoft.Usage#CA2201;-Microsoft.Usage#CA2228;-Microsoft.Usage#CA2221;-Microsoft.Usage#CA2220;-Microsoft.Usage#CA2240;-Microsoft.Usage#CA2229;-Microsoft.Usage#CA2238;-Microsoft.Usage#CA2207;-Microsoft.Usage#CA2208;-Microsoft.Usage#CA2235;-Microsoft.Usage#CA2237;-Microsoft.Usage#CA2232;-Microsoft.Usage#CA2223;-Microsoft.Usage#CA2211;-Microsoft.Usage#CA2233;-Microsoft.Usage#CA2225;-Microsoft.Usage#CA2226;-Microsoft.Usage#CA2231;-Microsoft.Usage#CA2224;-Microsoft.Usage#CA2218;-Microsoft.Usage#CA2234;-Microsoft.Usage#CA2239;-Microsoft.Usage#CA2200;-Microsoft.Usage#CA1801;-Microsoft.Usage#CA2242;-Microsoft.Usage#CA2205;-Microsoft.Usage#CA2230</CodeAnalysisRules>
+ <CodeAnalysisRules>-Microsoft.Design#CA1012;-Microsoft.Design#CA2210;-Microsoft.Design#CA1040;-Microsoft.Design#CA1005;-Microsoft.Design#CA1020;-Microsoft.Design#CA1021;-Microsoft.Design#CA1010;-Microsoft.Design#CA1011;-Microsoft.Design#CA1009;-Microsoft.Design#CA1050;-Microsoft.Design#CA1026;-Microsoft.Design#CA1019;-Microsoft.Design#CA1031;-Microsoft.Design#CA1047;-Microsoft.Design#CA1000;-Microsoft.Design#CA1048;-Microsoft.Design#CA1051;-Microsoft.Design#CA1002;-Microsoft.Design#CA1061;-Microsoft.Design#CA1006;-Microsoft.Design#CA1046;-Microsoft.Design#CA1045;-Microsoft.Design#CA1065;-Microsoft.Design#CA1038;-Microsoft.Design#CA1008;-Microsoft.Design#CA1028;-Microsoft.Design#CA1064;-Microsoft.Design#CA1004;-Microsoft.Design#CA1035;-Microsoft.Design#CA1063;-Microsoft.Design#CA1032;-Microsoft.Design#CA1023;-Microsoft.Design#CA1033;-Microsoft.Design#CA1039;-Microsoft.Design#CA1016;-Microsoft.Design#CA1014;-Microsoft.Design#CA1017;-Microsoft.Design#CA1018;-Microsoft.Design#CA1027;-Microsoft.Design#CA1059;-Microsoft.Design#CA1060;-Microsoft.Design#CA1034;-Microsoft.Design#CA1013;-Microsoft.Design#CA1036;-Microsoft.Design#CA1044;-Microsoft.Design#CA1041;-Microsoft.Design#CA1025;-Microsoft.Design#CA1052;-Microsoft.Design#CA1053;-Microsoft.Design#CA1057;-Microsoft.Design#CA1058;-Microsoft.Design#CA1001;-Microsoft.Design#CA1049;-Microsoft.Design#CA1054;-Microsoft.Design#CA1056;-Microsoft.Design#CA1055;-Microsoft.Design#CA1030;-Microsoft.Design#CA1003;-Microsoft.Design#CA1007;-Microsoft.Design#CA1043;-Microsoft.Design#CA1024;-Microsoft.Globalization#CA1301;-Microsoft.Globalization#CA1302;-Microsoft.Globalization#CA1308;-Microsoft.Globalization#CA1306;-Microsoft.Globalization#CA2101;-Microsoft.Globalization#CA1300;-Microsoft.Globalization#CA1307;-Microsoft.Globalization#CA1309;-Microsoft.Interoperability#CA1403;-Microsoft.Interoperability#CA1406;-Microsoft.Interoperability#CA1413;-Microsoft.Interoperability#CA1402;-Microsoft.Interoperability#CA1407;-Microsoft.Interoperability#CA1404;-Microsoft.Interoperability#CA1410;-Microsoft.Interoperability#CA1411;-Microsoft.Interoperability#CA1405;-Microsoft.Interoperability#CA1409;-Microsoft.Interoperability#CA1415;-Microsoft.Interoperability#CA1408;-Microsoft.Interoperability#CA1414;-Microsoft.Interoperability#CA1412;-Microsoft.Interoperability#CA1400;-Microsoft.Interoperability#CA1401;-Microsoft.Maintainability#CA1506;-Microsoft.Maintainability#CA1502;-Microsoft.Maintainability#CA1501;-Microsoft.Maintainability#CA1505;-Microsoft.Maintainability#CA1504;-Microsoft.Maintainability#CA1500;-Microsoft.Mobility#CA1600;-Microsoft.Mobility#CA1601;-Microsoft.Naming#CA1702;-Microsoft.Naming#CA1700;-Microsoft.Naming#CA1712;-Microsoft.Naming#CA1713;-Microsoft.Naming#CA1714;-Microsoft.Naming#CA1709;-Microsoft.Naming#CA1704;-Microsoft.Naming#CA1708;-Microsoft.Naming#CA1715;-Microsoft.Naming#CA1710;-Microsoft.Naming#CA1720;-Microsoft.Naming#CA1707;-Microsoft.Naming#CA1722;-Microsoft.Naming#CA1711;-Microsoft.Naming#CA1716;-Microsoft.Naming#CA1717;-Microsoft.Naming#CA1725;-Microsoft.Naming#CA1719;-Microsoft.Naming#CA1721;-Microsoft.Naming#CA1701;-Microsoft.Naming#CA1703;-Microsoft.Naming#CA1724;-Microsoft.Naming#CA1726;-Microsoft.Performance#CA1809;-Microsoft.Performance#CA1811;-Microsoft.Performance#CA1812;-Microsoft.Performance#CA1813;-Microsoft.Performance#CA1823;-Microsoft.Performance#CA1800;-Microsoft.Performance#CA1805;-Microsoft.Performance#CA1810;-Microsoft.Performance#CA1824;-Microsoft.Performance#CA1822;-Microsoft.Performance#CA1815;-Microsoft.Performance#CA1814;-Microsoft.Performance#CA1819;-Microsoft.Performance#CA1821;-Microsoft.Performance#CA1804;-Microsoft.Performance#CA1820;-Microsoft.Performance#CA1802;+!Microsoft.Portability#CA1903;-Microsoft.Portability#CA1901;-Microsoft.Portability#CA1900;-Microsoft.Reliability#CA2001;-Microsoft.Reliability#CA2002;-Microsoft.Reliability#CA2003;-Microsoft.Reliability#CA2004;-Microsoft.Reliability#CA2006;-Microsoft.Security#CA2116;-Microsoft.Security#CA2117;-Microsoft.Security#CA2105;-Microsoft.Security#CA2115;-Microsoft.Security#CA2102;-Microsoft.Security#CA2104;-Microsoft.Security#CA2122;-Microsoft.Security#CA2114;-Microsoft.Security#CA2123;-Microsoft.Security#CA2111;-Microsoft.Security#CA2108;-Microsoft.Security#CA2107;-Microsoft.Security#CA2103;-Microsoft.Security#CA2118;-Microsoft.Security#CA2109;-Microsoft.Security#CA2119;-Microsoft.Security#CA2106;-Microsoft.Security#CA2112;-Microsoft.Security#CA2120;-Microsoft.Security#CA2121;-Microsoft.Security#CA2126;-Microsoft.Security#CA2124;-Microsoft.Security#CA2127;-Microsoft.Security#CA2128;-Microsoft.Security#CA2129;-Microsoft.Usage#CA2243;-Microsoft.Usage#CA2236;-Microsoft.Usage#CA1816;-Microsoft.Usage#CA2227;-Microsoft.Usage#CA2213;-Microsoft.Usage#CA2216;-Microsoft.Usage#CA2214;-Microsoft.Usage#CA2222;-Microsoft.Usage#CA1806;-Microsoft.Usage#CA2217;-Microsoft.Usage#CA2212;-Microsoft.Usage#CA2219;-Microsoft.Usage#CA2201;-Microsoft.Usage#CA2228;-Microsoft.Usage#CA2221;-Microsoft.Usage#CA2220;-Microsoft.Usage#CA2240;-Microsoft.Usage#CA2229;-Microsoft.Usage#CA2238;-Microsoft.Usage#CA2207;-Microsoft.Usage#CA2208;-Microsoft.Usage#CA2235;-Microsoft.Usage#CA2237;-Microsoft.Usage#CA2232;-Microsoft.Usage#CA2223;-Microsoft.Usage#CA2211;-Microsoft.Usage#CA2233;-Microsoft.Usage#CA2225;-Microsoft.Usage#CA2226;-Microsoft.Usage#CA2231;-Microsoft.Usage#CA2224;-Microsoft.Usage#CA2218;-Microsoft.Usage#CA2234;-Microsoft.Usage#CA2239;-Microsoft.Usage#CA2200;-Microsoft.Usage#CA1801;-Microsoft.Usage#CA2242;-Microsoft.Usage#CA2205;-Microsoft.Usage#CA2230</CodeAnalysisRules>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@@ -175,6 +175,7 @@
<Compile Include="Serialization\CachedAttributeGetter.cs" />
<Compile Include="Serialization\OnErrorAttribute.cs" />
<Compile Include="Serialization\ReflectionValueProvider.cs" />
+ <Compile Include="Utilities\Base64Encoder.cs" />
<Compile Include="Utilities\DynamicWrapper.cs" />
<Compile Include="Utilities\LateBoundDelegateFactory.cs" />
<Compile Include="Utilities\ThreadSafeStore.cs" />
diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj
index f5c4a81..0de29b4 100644
--- a/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj
+++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj
@@ -66,7 +66,6 @@
<Compile Include="Converters\StringEnumConverter.cs" />
<Compile Include="Converters\XmlNodeConverter.cs" />
<Compile Include="Converters\HtmlColorConverter.cs" />
- <Compile Include="DateTimeOffset.cs" />
<Compile Include="DefaultValueHandling.cs" />
<Compile Include="IJsonLineInfo.cs" />
<Compile Include="JsonArrayAttribute.cs" />
@@ -142,6 +141,7 @@
<Compile Include="Serialization\ReflectionValueProvider.cs" />
<Compile Include="StreamingContext.cs" />
<Compile Include="TypeNameHandling.cs" />
+ <Compile Include="Utilities\Base64Encoder.cs" />
<Compile Include="Utilities\BidirectionalDictionary.cs" />
<Compile Include="Utilities\CollectionUtils.cs" />
<Compile Include="Utilities\CollectionWrapper.cs" />
diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.csproj
index 21868f0..f81607f 100644
--- a/Src/Newtonsoft.Json/Newtonsoft.Json.csproj
+++ b/Src/Newtonsoft.Json/Newtonsoft.Json.csproj
@@ -65,9 +65,6 @@
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
- <Reference Include="System.ComponentModel.DataAnnotations">
- <RequiredTargetFramework>3.5</RequiredTargetFramework>
- </Reference>
<Reference Include="System.Core">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
@@ -80,6 +77,10 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
+ <Compile Include="Bson\BsonBinaryType.cs" />
+ <Compile Include="Bson\BsonReader.cs" />
+ <Compile Include="Bson\BsonType.cs" />
+ <Compile Include="Bson\BsonWriter.cs" />
<Compile Include="Converters\BinaryConverter.cs" />
<Compile Include="Converters\DataSetConverter.cs" />
<Compile Include="Converters\DataTableConverter.cs" />
@@ -178,6 +179,7 @@
<Compile Include="Serialization\CachedAttributeGetter.cs" />
<Compile Include="Serialization\ReflectionValueProvider.cs" />
<Compile Include="Serialization\OnErrorAttribute.cs" />
+ <Compile Include="Utilities\Base64Encoder.cs" />
<Compile Include="Utilities\DynamicWrapper.cs" />
<Compile Include="Utilities\LateBoundDelegateFactory.cs" />
<Compile Include="Utilities\ThreadSafeStore.cs" />
diff --git a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
index a1eda08..1847319 100644
--- a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
+++ b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs
@@ -193,6 +193,8 @@ namespace Newtonsoft.Json.Serialization
foreach (MethodInfo method in contract.UnderlyingType.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
{
+ // compact framework errors when getting parameters for a generic method
+ // lame, but generic methods should not be callbacks anyway
if (method.ContainsGenericParameters)
continue;
@@ -348,7 +350,7 @@ namespace Newtonsoft.Json.Serialization
#else
property.ValueProvider = new ReflectionValueProvider(member);
#endif
- property.Converter = JsonTypeReflector.GetConverter(member, property.PropertyType);
+ property.Converter = JsonTypeReflector.GetJsonConverter(member, property.PropertyType);
#if !PocketPC && !NET20
DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(member.DeclaringType);
@@ -395,7 +397,7 @@ namespace Newtonsoft.Json.Serialization
property.Readable = ReflectionUtils.CanReadMemberValue(member);
property.Writable = ReflectionUtils.CanSetMemberValue(member);
- property.MemberConverter = JsonTypeReflector.GetConverter(member, ReflectionUtils.GetMemberUnderlyingType(member));
+ property.MemberConverter = JsonTypeReflector.GetJsonConverter(member, ReflectionUtils.GetMemberUnderlyingType(member));
DefaultValueAttribute defaultValueAttribute = JsonTypeReflector.GetAttribute<DefaultValueAttribute>(member);
property.DefaultValue = (defaultValueAttribute != null) ? defaultValueAttribute.Value : null;
diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
index 5b14a2d..cf7eddc 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs
@@ -168,6 +168,7 @@ namespace Newtonsoft.Json.Serialization
case JsonToken.Float:
case JsonToken.Boolean:
case JsonToken.Date:
+ case JsonToken.Bytes:
return EnsureType(reader.Value, objectType);
case JsonToken.String:
// convert empty string to null automatically for nullable types
@@ -382,24 +383,6 @@ namespace Newtonsoft.Json.Serialization
return value.ToString();
}
- private void SetObjectMember(JsonReader reader, object target, JsonObjectContract contract, string memberName)
- {
- JsonProperty property;
- // attempt exact case match first
- // then try match ignoring case
- if (contract.Properties.TryGetClosestMatchProperty(memberName, out property))
- {
- SetPropertyValue(property, reader, target);
- }
- else
- {
- if (Serializer.MissingMemberHandling == MissingMemberHandling.Error)
- throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, contract.UnderlyingType.Name));
-
- reader.Skip();
- }
- }
-
private void SetPropertyValue(JsonProperty property, JsonReader reader, object target)
{
if (property.Ignored)
@@ -431,7 +414,11 @@ namespace Newtonsoft.Json.Serialization
object value = CreateValue(reader, property.PropertyType, (useExistingValue) ? currentValue : null, property.Converter);
- if (!useExistingValue && ShouldSetPropertyValue(property, value))
+ // always set the value if useExistingValue is false,
+ // otherwise also set it if CreateValue returns a new value compared to the currentValue
+ // this could happen because of a JsonConverter against the type
+ if ((!useExistingValue || value != currentValue)
+ && ShouldSetPropertyValue(property, value))
property.ValueProvider.SetValue(target, value);
}
@@ -679,14 +666,34 @@ namespace Newtonsoft.Json.Serialization
case JsonToken.PropertyName:
string memberName = reader.Value.ToString();
- if (!reader.Read())
- throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
+ JsonProperty property;
+ // attempt exact case match first
+ // then try match ignoring case
+ if (!contract.Properties.TryGetClosestMatchProperty(memberName, out property))
+ {
+ if (Serializer.MissingMemberHandling == MissingMemberHandling.Error)
+ throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, contract.UnderlyingType.Name));
+
+ reader.Skip();
+ continue;
+ }
+
+ if (property.PropertyType == typeof(byte[]))
+ {
+ reader.ReadAsBytes();
+ }
+ else
+ {
+ if (!reader.Read())
+ throw new JsonSerializationException(
+ "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
+ }
- SetRequiredProperty(reader, memberName, contract, requiredProperties);
+ SetRequiredProperty(reader, property, requiredProperties);
try
{
- SetObjectMember(reader, newObject, contract, memberName);
+ SetPropertyValue(property, reader, newObject);
}
catch (Exception ex)
{
@@ -718,9 +725,8 @@ namespace Newtonsoft.Json.Serialization
throw new JsonSerializationException("Unexpected end when deserializing object.");
}
- private void SetRequiredProperty(JsonReader reader, string memberName, JsonObjectContract contract, Dictionary<JsonProperty, RequiredValue> requiredProperties)
+ private void SetRequiredProperty(JsonReader reader, JsonProperty property, Dictionary<JsonProperty, RequiredValue> requiredProperties)
{
- JsonProperty property = requiredProperties.Keys.ForgivingCaseSensitiveFind(p => p.PropertyName, memberName);
if (property != null)
{
requiredProperties[property] = (reader.TokenType == JsonToken.Null || reader.TokenType == JsonToken.Undefined)
diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
index fc07969..e47d651 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs
@@ -226,19 +226,29 @@ namespace Newtonsoft.Json.Serialization
internal static bool TryConvertToString(object value, Type type, out string s)
{
-#if !SILVERLIGHT && !PocketPC
- TypeConverter converter = TypeDescriptor.GetConverter(type);
+#if !PocketPC
+ TypeConverter converter = ConvertUtils.GetConverter(type);
// use the objectType's TypeConverter if it has one and can convert to a string
- if (converter != null && !(converter is ComponentConverter) && (converter.GetType() != typeof(TypeConverter) || value is Type))
+ if (converter != null
+#if !SILVERLIGHT
+ && !(converter is ComponentConverter)
+#endif
+ && (converter.GetType() != typeof(TypeConverter) || value is Type))
{
if (converter.CanConvertTo(typeof(string)))
{
+#if !SILVERLIGHT
s = converter.ConvertToInvariantString(value);
+#else
+ s = converter.ConvertToString(value);
+#endif
return true;
}
}
-#else
+#endif
+
+#if SILVERLIGHT || PocketPC
if (value is Guid || value is Type || value is Uri || value is TimeSpan)
{
s = value.ToString();
diff --git a/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs b/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs
index 6694d52..04882bd 100644
--- a/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs
+++ b/Src/Newtonsoft.Json/Serialization/JsonTypeReflector.cs
@@ -24,9 +24,7 @@
#endregion
using System;
-#if !SILVERLIGHT && !PocketPC && !NET20
-using System.ComponentModel.DataAnnotations;
-#endif
+using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Reflection;
@@ -35,6 +33,13 @@ using Newtonsoft.Json.Utilities;
namespace Newtonsoft.Json.Serialization
{
+#if !SILVERLIGHT && !PocketPC && !NET20
+ internal interface IMetadataTypeAttribute
+ {
+ Type MetadataClassType { get; }
+ }
+#endif
+
internal static class JsonTypeReflector
{
public const string IdPropertyName = "$id";
@@ -42,9 +47,30 @@ namespace Newtonsoft.Json.Serialization
public const string TypePropertyName = "$type";
public const string ArrayValuesPropertyName = "$values";
- private static readonly ThreadSafeStore<ICustomAttributeProvider, Type> ConverterTypeCache = new ThreadSafeStore<ICustomAttributeProvider, Type>(GetConverterTypeFromAttribute);
+ private static readonly ThreadSafeStore<ICustomAttributeProvider, Type> JsonConverterTypeCache = new ThreadSafeStore<ICustomAttributeProvider, Type>(GetJsonConverterTypeFromAttribute);
#if !SILVERLIGHT && !PocketPC && !NET20
private static readonly ThreadSafeStore<Type, Type> AssociatedMetadataTypesCache = new ThreadSafeStore<Type, Type>(GetAssociateMetadataTypeFromAttribute);
+
+ private const string MetadataTypeAttributeTypeName =
+ "System.ComponentModel.DataAnnotations.MetadataTypeAttribute, System.ComponentModel.DataAnnotations, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";
+ private static Type _cachedMetadataTypeAttributeType;
+#endif
+#if SILVERLIGHT
+ private static readonly ThreadSafeStore<ICustomAttributeProvider, Type> TypeConverterTypeCache = new ThreadSafeStore<ICustomAttributeProvider, Type>(GetTypeConverterTypeFromAttribute);
+
+ private static Type GetTypeConverterTypeFromAttribute(ICustomAttributeProvider attributeProvider)
+ {
+ TypeConverterAttribute converterAttribute = GetAttribute<TypeConverterAttribute>(attributeProvider);
+ if (converterAttribute == null)
+ return null;
+
+ return Type.GetType(converterAttribute.ConverterTypeName);
+ }
+
+ private static Type GetTypeConverterType(ICustomAttributeProvider attributeProvider)
+ {
+ return TypeConverterTypeCache.Get(attributeProvider);
+ }
#endif
public static JsonContainerAttribute GetJsonContainerAttribute(Type type)
@@ -83,12 +109,12 @@ namespace Newtonsoft.Json.Serialization
return objectAttribute.MemberSerialization;
}
- private static Type GetConverterType(ICustomAttributeProvider attributeProvider)
+ private static Type GetJsonConverterType(ICustomAttributeProvider attributeProvider)
{
- return ConverterTypeCache.Get(attributeProvider);
+ return JsonConverterTypeCache.Get(attributeProvider);
}
- private static Type GetConverterTypeFromAttribute(ICustomAttributeProvider attributeProvider)
+ private static Type GetJsonConverterTypeFromAttribute(ICustomAttributeProvider attributeProvider)
{
JsonConverterAttribute converterAttribute = GetAttribute<JsonConverterAttribute>(attributeProvider);
return (converterAttribute != null)
@@ -96,9 +122,9 @@ namespace Newtonsoft.Json.Serialization
: null;
}
- public static JsonConverter GetConverter(ICustomAttributeProvider attributeProvider, Type targetConvertedType)
+ public static JsonConverter GetJsonConverter(ICustomAttributeProvider attributeProvider, Type targetConvertedType)
{
- Type converterType = GetConverterType(attributeProvider);
+ Type converterType = GetJsonConverterType(attributeProvider);
if (converterType != null)
{
@@ -113,6 +139,22 @@ namespace Newtonsoft.Json.Serialization
return null;
}
+#if !PocketPC
+ public static TypeConverter GetTypeConverter(Type type)
+ {
+#if !SILVERLIGHT
+ return TypeDescriptor.GetConverter(type);
+#else
+ Type converterType = GetTypeConverterType(type);
+
+ if (converterType != null)
+ return (TypeConverter)ReflectionUtils.CreateInstance(converterType);
+
+ return null;
+#endif
+ }
+#endif
+
#if !SILVERLIGHT && !PocketPC && !NET20
private static Type GetAssociatedMetadataType(Type type)
{
@@ -121,9 +163,34 @@ namespace Newtonsoft.Json.Serialization
private static Type GetAssociateMetadataTypeFromAttribute(Type type)
{
- MetadataTypeAttribute metadataTypeAttribute = ReflectionUtils.GetAttribute<MetadataTypeAttribute>(type, true);
+ Type metadataTypeAttributeType = GetMetadataTypeAttributeType();
+ if (metadataTypeAttributeType == null)
+ return null;
+
+ object attribute = type.GetCustomAttributes(metadataTypeAttributeType, true).SingleOrDefault();
+ if (attribute == null)
+ return null;
+
+ IMetadataTypeAttribute metadataTypeAttribute = DynamicWrapper.CreateWrapper<IMetadataTypeAttribute>(attribute);
+
+ return metadataTypeAttribute.MetadataClassType;
+ }
+
+ private static Type GetMetadataTypeAttributeType()
+ {
+ // always attempt to get the metadata type attribute type
+ // the assembly may have been loaded since last time
+ if (_cachedMetadataTypeAttributeType == null)
+ {
+ Type metadataTypeAttributeType = Type.GetType(MetadataTypeAttributeTypeName);
- return (metadataTypeAttribute != null) ? metadataTypeAttribute.MetadataClassType : null;
+ if (metadataTypeAttributeType != null)
+ _cachedMetadataTypeAttributeType = metadataTypeAttributeType;
+ else
+ return null;
+ }
+
+ return _cachedMetadataTypeAttributeType;
}
private static T GetAttribute<T>(Type type) where T : Attribute
@@ -169,7 +236,5 @@ namespace Newtonsoft.Json.Serialization
return ReflectionUtils.GetAttribute<T>(attributeProvider, true);
}
#endif
-
-
}
} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Utilities/Base64Encoder.cs b/Src/Newtonsoft.Json/Utilities/Base64Encoder.cs
new file mode 100644
index 0000000..2a1d86a
--- /dev/null
+++ b/Src/Newtonsoft.Json/Utilities/Base64Encoder.cs
@@ -0,0 +1,95 @@
+using System;
+using System.IO;
+
+namespace Newtonsoft.Json.Utilities
+{
+ internal class Base64Encoder
+ {
+ private const int Base64LineSize = 76;
+ private const int LineSizeInBytes = 57;
+
+ private readonly char[] _charsLine = new char[Base64LineSize];
+ private readonly TextWriter _writer;
+
+ private byte[] _leftOverBytes;
+ private int _leftOverBytesCount;
+
+ public Base64Encoder(TextWriter writer)
+ {
+ ValidationUtils.ArgumentNotNull(writer, "writer");
+ _writer = writer;
+ }
+
+ public void Encode(byte[] buffer, int index, int count)
+ {
+ if (buffer == null)
+ throw new ArgumentNullException("buffer");
+
+ if (index < 0)
+ throw new ArgumentOutOfRangeException("index");
+
+ if (count < 0)
+ throw new ArgumentOutOfRangeException("count");
+
+ if (count > (buffer.Length - index))
+ throw new ArgumentOutOfRangeException("count");
+
+ if (_leftOverBytesCount > 0)
+ {
+ int leftOverBytesCount = _leftOverBytesCount;
+ while (leftOverBytesCount < 3 && count > 0)
+ {
+ _leftOverBytes[leftOverBytesCount++] = buffer[index++];
+ count--;
+ }
+ if (count == 0 && leftOverBytesCount < 3)
+ {
+ _leftOverBytesCount = leftOverBytesCount;
+ return;
+ }
+ int num2 = Convert.ToBase64CharArray(_leftOverBytes, 0, 3, _charsLine, 0);
+ WriteChars(_charsLine, 0, num2);
+ }
+ _leftOverBytesCount = count % 3;
+ if (_leftOverBytesCount > 0)
+ {
+ count -= _leftOverBytesCount;
+ if (_leftOverBytes == null)
+ {
+ _leftOverBytes = new byte[3];
+ }
+ for (int i = 0; i < _leftOverBytesCount; i++)
+ {
+ _leftOverBytes[i] = buffer[(index + count) + i];
+ }
+ }
+ int num4 = index + count;
+ int length = LineSizeInBytes;
+ while (index < num4)
+ {
+ if ((index + length) > num4)
+ {
+ length = num4 - index;
+ }
+ int num6 = Convert.ToBase64CharArray(buffer, index, length, _charsLine, 0);
+ WriteChars(_charsLine, 0, num6);
+ index += length;
+ }
+ }
+
+ public void Flush()
+ {
+ if (_leftOverBytesCount > 0)
+ {
+ int count = Convert.ToBase64CharArray(_leftOverBytes, 0, _leftOverBytesCount, _charsLine, 0);
+ WriteChars(_charsLine, 0, count);
+ _leftOverBytesCount = 0;
+ }
+ }
+
+ private void WriteChars(char[] chars, int index, int count)
+ {
+ _writer.Write(chars, index, count);
+ }
+ }
+} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs b/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs
index 2486328..9bb213a 100644
--- a/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs
+++ b/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs
@@ -29,6 +29,8 @@ using System.Linq;
using System.Text;
using System.Globalization;
using System.ComponentModel;
+using Newtonsoft.Json.Serialization;
+
#if !SILVERLIGHT
using System.Data.SqlTypes;
#endif
@@ -53,8 +55,10 @@ namespace Newtonsoft.Json.Utilities
return true;
}
+#if !PocketPC && !NET20
if (initialType == typeof(DateTime) && targetType == typeof(DateTimeOffset))
return true;
+#endif
if (initialType == typeof(Guid) && (targetType == typeof(Guid) || targetType == typeof(string)))
return true;
@@ -161,8 +165,10 @@ namespace Newtonsoft.Json.Utilities
return System.Convert.ChangeType(initialValue, targetType, culture);
}
+#if !PocketPC && !NET20
if (initialValue is DateTime && targetType == typeof(DateTimeOffset))
return new DateTimeOffset((DateTime)initialValue);
+#endif
if (initialValue is string)
{
@@ -403,20 +409,9 @@ namespace Newtonsoft.Json.Utilities
#endif
#if !PocketPC
- private static TypeConverter GetConverter(Type t)
+ internal static TypeConverter GetConverter(Type t)
{
- ValidationUtils.ArgumentNotNull(t, "t");
-
-#if !SILVERLIGHT
- return TypeDescriptor.GetConverter(t);
-#else
- object[] customAttributes = t.GetCustomAttributes(typeof(TypeConverterAttribute), true);
- if (customAttributes.Length != 1)
- return null;
-
- TypeConverterAttribute typeConverterAttribute = (TypeConverterAttribute)customAttributes[0];
- return (Activator.CreateInstance(Type.GetType(typeConverterAttribute.ConverterTypeName)) as TypeConverter);
-#endif
+ return JsonTypeReflector.GetTypeConverter(t);
}
#endif
diff --git a/Src/Newtonsoft.Json/Utilities/MiscellaneousUtils.cs b/Src/Newtonsoft.Json/Utilities/MiscellaneousUtils.cs
index 71ae170..108cecd 100644
--- a/Src/Newtonsoft.Json/Utilities/MiscellaneousUtils.cs
+++ b/Src/Newtonsoft.Json/Utilities/MiscellaneousUtils.cs
@@ -42,5 +42,61 @@ namespace Newtonsoft.Json.Utilities
return (value is string) ? @"""" + value.ToString() + @"""" : value.ToString();
}
+
+ public static byte[] HexToBytes(string hex)
+ {
+ // array to put the result in
+ byte[] bytes = new byte[hex.Length / 2];
+ // variable to determine shift of high/low nibble
+ int shift = 4;
+ // offset of the current byte in the array
+ int offset = 0;
+ // loop the characters in the string
+ foreach (char c in hex)
+ {
+ if (c == '-' && shift == 4)
+ continue;
+
+ // get character code in range 0-9, 17-22
+ // the % 32 handles lower case characters
+ int b = (c - '0') % 32;
+ // correction for a-f
+ if (b > 9) b -= 7;
+ // store nibble (4 bits) in byte array
+ bytes[offset] |= (byte)(b << shift);
+ // toggle the shift variable between 0 and 4
+ shift ^= 4;
+ // move to next byte
+ if (shift != 0) offset++;
+ }
+ return bytes;
+ }
+
+ public static string BytesToHex(byte[] bytes)
+ {
+ return BytesToHex(bytes, false);
+ }
+
+ public static string BytesToHex(byte[] bytes, bool removeDashes)
+ {
+ string hex = BitConverter.ToString(bytes);
+ if (removeDashes)
+ hex = hex.Replace("-", "");
+
+ return hex;
+ }
+
+ public static bool ByteArrayCompare(byte[] a1, byte[] a2)
+ {
+ if (a1.Length != a2.Length)
+ return false;
+
+ for (int i = 0; i < a1.Length; i++)
+ if (a1[i] != a2[i])
+ return false;
+
+ return true;
+ }
+
}
-}
+} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Utilities/StringBuffer.cs b/Src/Newtonsoft.Json/Utilities/StringBuffer.cs
index b458f39..22897f4 100644
--- a/Src/Newtonsoft.Json/Utilities/StringBuffer.cs
+++ b/Src/Newtonsoft.Json/Utilities/StringBuffer.cs
@@ -90,5 +90,10 @@ namespace Newtonsoft.Json.Utilities
// TODO: validation
return new string(_buffer, start, length);
}
+
+ public char[] GetInternalBuffer()
+ {
+ return _buffer;
+ }
}
} \ No newline at end of file