From be6ed7daaae9804a50914b5702adc9301361f28a Mon Sep 17 00:00:00 2001 From: JamesNK Date: Fri, 22 Jan 2010 22:17:56 +0000 Subject: [PATCH] -Added ReadRootValueAsArray, DateTimeKindHandling properties to BsonReader -Included BSON is .NET 2.0, Silverlight and Compact Framework builds --- .../Bson/BsonReaderTests.cs | 49 ++++++++++++++- .../Bson/BsonWriterTests.cs | 3 +- .../Newtonsoft.Json.Tests.Compact.csproj | 2 + .../Newtonsoft.Json.Tests.Net20.csproj | 2 + .../Newtonsoft.Json.Tests.Silverlight.csproj | 2 + Src/Newtonsoft.Json/Bson/BsonReader.cs | 60 ++++++++++++++++--- .../Newtonsoft.Json.Compact.csproj | 4 ++ .../Newtonsoft.Json.Net20.csproj | 4 ++ .../Newtonsoft.Json.Silverlight.csproj | 4 ++ 9 files changed, 117 insertions(+), 13 deletions(-) diff --git a/Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs b/Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs index e23c8a3e..f8262781 100644 --- a/Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs +++ b/Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs @@ -117,7 +117,16 @@ namespace Newtonsoft.Json.Tests.Bson 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); + BsonReader reader = new BsonReader(ms); + + Assert.AreEqual(false, reader.ReadRootValueAsArray); + Assert.AreEqual(DateTimeKind.Local, reader.DateTimeKindHandling); + + reader.ReadRootValueAsArray = true; + reader.DateTimeKindHandling = DateTimeKind.Utc; + + Assert.AreEqual(true, reader.ReadRootValueAsArray); + Assert.AreEqual(DateTimeKind.Utc, reader.DateTimeKindHandling); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.StartArray, reader.TokenType); @@ -149,7 +158,10 @@ namespace Newtonsoft.Json.Tests.Bson 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); + BsonReader reader = new BsonReader(ms, true, DateTimeKind.Utc); + + Assert.AreEqual(true, reader.ReadRootValueAsArray); + Assert.AreEqual(DateTimeKind.Utc, reader.DateTimeKindHandling); Assert.IsTrue(reader.Read()); Assert.AreEqual(JsonToken.StartArray, reader.TokenType); @@ -175,7 +187,7 @@ namespace Newtonsoft.Json.Tests.Bson Assert.IsFalse(reader.Read()); - string decodedString = Encoding.UTF8.GetString(encodedStringData); + string decodedString = Encoding.UTF8.GetString(encodedStringData, 0, encodedStringData.Length); Assert.AreEqual("Hello world!", decodedString); } @@ -646,5 +658,36 @@ namespace Newtonsoft.Json.Tests.Bson Assert.IsFalse(reader.Read()); } + + [Test] + public void DateTimeKindHandling() + { + DateTime value = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc); + + MemoryStream ms = new MemoryStream(); + BsonWriter writer = new BsonWriter(ms); + + writer.WriteStartObject(); + writer.WritePropertyName("DateTime"); + writer.WriteValue(value); + writer.WriteEndObject(); + + byte[] bson = ms.ToArray(); + + JObject o; + BsonReader reader; + + reader = new BsonReader(new MemoryStream(bson), false, DateTimeKind.Utc); + o = (JObject)JToken.ReadFrom(reader); + Assert.AreEqual(value, (DateTime)o["DateTime"]); + + reader = new BsonReader(new MemoryStream(bson), false, DateTimeKind.Local); + o = (JObject)JToken.ReadFrom(reader); + Assert.AreEqual(value.ToLocalTime(), (DateTime)o["DateTime"]); + + reader = new BsonReader(new MemoryStream(bson), false, DateTimeKind.Unspecified); + o = (JObject)JToken.ReadFrom(reader); + Assert.AreEqual(DateTime.SpecifyKind(value.ToLocalTime(), DateTimeKind.Unspecified), (DateTime)o["DateTime"]); + } } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Bson/BsonWriterTests.cs b/Src/Newtonsoft.Json.Tests/Bson/BsonWriterTests.cs index bc3d323a..e97f5b0a 100644 --- a/Src/Newtonsoft.Json.Tests/Bson/BsonWriterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Bson/BsonWriterTests.cs @@ -147,11 +147,12 @@ namespace Newtonsoft.Json.Tests.Bson s1.Open = true; s1.product.Add(new Product { - ExpiryDate = new DateTime(2000, 9, 28, 3, 59, 58, DateTimeKind.Utc), + ExpiryDate = new DateTime(2000, 9, 28, 3, 59, 58, DateTimeKind.Local), Name = "BSON!", Price = -0.1m, Sizes = new [] { "First", "Second" } }); + s1.Establised = new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Local); JsonSerializer serializer = new JsonSerializer(); serializer.Serialize(writer, s1); diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj index 06566591..2bede4ed 100644 --- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj +++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj @@ -59,6 +59,8 @@ + + diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj index 84ac9c5f..c21295fd 100644 --- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj +++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj @@ -62,6 +62,8 @@ + + diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj index 86cd963c..6720b6d9 100644 --- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj +++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj @@ -68,6 +68,8 @@ + + diff --git a/Src/Newtonsoft.Json/Bson/BsonReader.cs b/Src/Newtonsoft.Json/Bson/BsonReader.cs index 60b0b5ea..a88deda9 100644 --- a/Src/Newtonsoft.Json/Bson/BsonReader.cs +++ b/Src/Newtonsoft.Json/Bson/BsonReader.cs @@ -38,8 +38,9 @@ namespace Newtonsoft.Json.Bson /// public class BsonReader : JsonReader { + private const int MaxCharBytesSize = 128; + private readonly BinaryReader _reader; - private readonly bool _rootTypeIsArray; private readonly List _stack; private byte[] _byteBuffer; @@ -48,7 +49,8 @@ namespace Newtonsoft.Json.Bson private BsonReaderState _bsonReaderState; private ContainerContext _currentContext; - private const int MaxCharBytesSize = 128; + private bool _readRootValueAsArray; + private DateTimeKind _dateTimeKindHandling; private enum BsonReaderState { @@ -75,11 +77,34 @@ namespace Newtonsoft.Json.Bson } } + /// + /// Gets or sets a value indicating whether the root object will be read as a JSON array. + /// + /// + /// true if the root object will be read as a JSON array; otherwise, false. + /// + public bool ReadRootValueAsArray + { + get { return _readRootValueAsArray; } + set { _readRootValueAsArray = value; } + } + + /// + /// Gets or sets the used when reading values from BSON. + /// + /// The used when reading values from BSON. + public DateTimeKind DateTimeKindHandling + { + get { return _dateTimeKindHandling; } + set { _dateTimeKindHandling = value; } + } + /// /// Initializes a new instance of the class. /// /// The stream. - public BsonReader(Stream stream) : this(stream, false) + public BsonReader(Stream stream) + : this(stream, false, DateTimeKind.Local) { } @@ -87,13 +112,15 @@ namespace Newtonsoft.Json.Bson /// Initializes a new instance of the class. /// /// The stream. - /// if set to true the root object will be read as a JSON array. - public BsonReader(Stream stream, bool rootTypeIsArray) + /// if set to true the root object will be read as a JSON array. + /// The used when reading values from BSON. + public BsonReader(Stream stream, bool readRootValueAsArray, DateTimeKind dateTimeKindHandling) { ValidationUtils.ArgumentNotNull(stream, "stream"); _reader = new BinaryReader(stream); _stack = new List(); - _rootTypeIsArray = rootTypeIsArray; + _readRootValueAsArray = readRootValueAsArray; + _dateTimeKindHandling = dateTimeKindHandling; } private string ReadElement() @@ -256,8 +283,8 @@ namespace Newtonsoft.Json.Bson { case State.Start: { - JsonToken token = (!_rootTypeIsArray) ? JsonToken.StartObject : JsonToken.StartArray; - JTokenType type = (!_rootTypeIsArray) ? JTokenType.Object : JTokenType.Array; + JsonToken token = (!_readRootValueAsArray) ? JsonToken.StartObject : JsonToken.StartArray; + JTokenType type = (!_readRootValueAsArray) ? JTokenType.Object : JTokenType.Array; SetToken(token); ContainerContext newContext = new ContainerContext(type); @@ -394,7 +421,22 @@ namespace Newtonsoft.Json.Bson break; case BsonType.Date: long ticks = ReadInt64(); - DateTime dateTime = JsonConvert.ConvertJavaScriptTicksToDateTime(ticks); + DateTime utcDateTime = JsonConvert.ConvertJavaScriptTicksToDateTime(ticks); + + DateTime dateTime; + switch (DateTimeKindHandling) + { + case DateTimeKind.Unspecified: + dateTime = DateTime.SpecifyKind(utcDateTime.ToLocalTime(), DateTimeKind.Unspecified); + break; + case DateTimeKind.Local: + dateTime = utcDateTime.ToLocalTime(); + break; + default: + dateTime = utcDateTime; + break; + } + SetToken(JsonToken.Date, dateTime); break; case BsonType.Null: diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj index 48f03403..d974e421 100644 --- a/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj +++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj @@ -57,6 +57,10 @@ + + + + diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj index 18c6920b..60a0dac3 100644 --- a/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj +++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj @@ -77,6 +77,10 @@ + + + + diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj index 274c90fb..b6868ddf 100644 --- a/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj +++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj @@ -54,6 +54,10 @@ + + + +