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
path: root/Src
diff options
context:
space:
mode:
authorJamesNK <james@newtonking.com>2010-03-27 09:18:40 +0300
committerJamesNK <james@newtonking.com>2010-03-27 09:18:40 +0300
commitb0c6db675ef57848c9aa7bdb5614193fc241fecf (patch)
tree148e7ee3d1ed4bb49c3cfe6c175eb8d55a2c7845 /Src
parent6ce972156dd187cb428593ec7a51574169b58ff6 (diff)
-Added WriteRegex to BsonWriter
-Added RegexConverter -Fixed BsonWriter writing empty string instead of null
Diffstat (limited to 'Src')
-rw-r--r--Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs35
-rw-r--r--Src/Newtonsoft.Json.Tests/Bson/BsonWriterTests.cs86
-rw-r--r--Src/Newtonsoft.Json.Tests/Converters/RegexConverterTests.cs156
-rw-r--r--Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj2
-rw-r--r--Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj2
-rw-r--r--Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj2
-rw-r--r--Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj1
-rw-r--r--Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs1
-rw-r--r--Src/Newtonsoft.Json/Bson/BsonBinaryWriter.cs59
-rw-r--r--Src/Newtonsoft.Json/Bson/BsonToken.cs121
-rw-r--r--Src/Newtonsoft.Json/Bson/BsonWriter.cs150
-rw-r--r--Src/Newtonsoft.Json/Converters/RegexConverter.cs127
-rw-r--r--Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj2
-rw-r--r--Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj2
-rw-r--r--Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj2
-rw-r--r--Src/Newtonsoft.Json/Newtonsoft.Json.csproj2
16 files changed, 615 insertions, 135 deletions
diff --git a/Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs b/Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs
index a648982..939e347 100644
--- a/Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs
@@ -979,5 +979,40 @@ namespace Newtonsoft.Json.Tests.Bson
string expected = sb.ToString();
Assert.AreEqual(expected, WriteAndReadStringPropertyName(expected));
}
+
+ [Test]
+ public void ReadRegexWithOptions()
+ {
+ string hexdoc = "1A-00-00-00-0B-72-65-67-65-78-00-61-62-63-00-69-00-0B-74-65-73-74-00-00-00-00";
+
+ byte[] data = MiscellaneousUtils.HexToBytes(hexdoc);
+
+ 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.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.String, reader.TokenType);
+ Assert.AreEqual("/abc/i", reader.Value);
+ Assert.AreEqual(typeof(string), reader.ValueType);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.PropertyName, reader.TokenType);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.String, reader.TokenType);
+ Assert.AreEqual("//", reader.Value);
+ Assert.AreEqual(typeof(string), reader.ValueType);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.EndObject, reader.TokenType);
+
+ Assert.IsFalse(reader.Read());
+ }
}
} \ 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 e99595e..ca64132 100644
--- a/Src/Newtonsoft.Json.Tests/Bson/BsonWriterTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Bson/BsonWriterTests.cs
@@ -472,5 +472,91 @@ namespace Newtonsoft.Json.Tests.Bson
Assert.AreEqual(expected, ms.ToArray());
}
+
+ [Test]
+ public void WriteRegexPlusContent()
+ {
+ MemoryStream ms = new MemoryStream();
+ BsonWriter writer = new BsonWriter(ms);
+
+ writer.WriteStartObject();
+ writer.WritePropertyName("regex");
+ writer.WriteRegex("abc", "i");
+ writer.WritePropertyName("test");
+ writer.WriteRegex(string.Empty, null);
+ writer.WriteEndObject();
+
+ byte[] expected = MiscellaneousUtils.HexToBytes("1A-00-00-00-0B-72-65-67-65-78-00-61-62-63-00-69-00-0B-74-65-73-74-00-00-00-00");
+
+ Assert.AreEqual(expected, ms.ToArray());
+ }
+
+ [Test]
+ public void SerializeEmptyAndNullStrings()
+ {
+ Product p = new Product();
+ p.ExpiryDate = DateTime.Parse("2009-04-05T14:45:00Z");
+ p.Name = null;
+ p.Price = 9.95m;
+ p.Sizes = new[] { "Small", "", null };
+
+ MemoryStream ms = new MemoryStream();
+ JsonSerializer serializer = new JsonSerializer();
+
+ BsonWriter writer = new BsonWriter(ms);
+ serializer.Serialize(writer, p);
+
+ ms.Seek(0, SeekOrigin.Begin);
+
+ BsonReader reader = new BsonReader(ms);
+ Product deserializedProduct = serializer.Deserialize<Product>(reader);
+
+ Console.WriteLine(deserializedProduct.Name);
+
+ Assert.AreEqual(null, deserializedProduct.Name);
+ Assert.AreEqual(9.95m, deserializedProduct.Price);
+ Assert.AreEqual(3, deserializedProduct.Sizes.Length);
+ Assert.AreEqual("Small", deserializedProduct.Sizes[0]);
+ Assert.AreEqual("", deserializedProduct.Sizes[1]);
+ Assert.AreEqual(null, deserializedProduct.Sizes[2]);
+ }
+
+ [Test]
+ public void WriteReadEmptyAndNullStrings()
+ {
+ MemoryStream ms = new MemoryStream();
+ BsonWriter writer = new BsonWriter(ms);
+
+ writer.WriteStartArray();
+ writer.WriteValue("Content!");
+ writer.WriteValue("");
+ writer.WriteValue((string)null);
+ writer.WriteEndArray();
+
+ ms.Seek(0, SeekOrigin.Begin);
+
+ BsonReader reader = new BsonReader(ms);
+ reader.ReadRootValueAsArray = true;
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.String, reader.TokenType);
+ Assert.AreEqual("Content!", reader.Value);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.String, reader.TokenType);
+ Assert.AreEqual("", reader.Value);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.Null, reader.TokenType);
+ Assert.AreEqual(null, reader.Value);
+
+ Assert.IsTrue(reader.Read());
+ Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
+
+ Assert.IsFalse(reader.Read());
+ }
}
} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/Converters/RegexConverterTests.cs b/Src/Newtonsoft.Json.Tests/Converters/RegexConverterTests.cs
new file mode 100644
index 0000000..7f0b4d8
--- /dev/null
+++ b/Src/Newtonsoft.Json.Tests/Converters/RegexConverterTests.cs
@@ -0,0 +1,156 @@
+using System;
+using System.Collections.Generic;
+#if !SILVERLIGHT && !PocketPC && !NET20
+using System.Data.Linq;
+#endif
+#if !SILVERLIGHT
+using System.Data.SqlTypes;
+#endif
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using Newtonsoft.Json.Bson;
+using Newtonsoft.Json.Converters;
+using Newtonsoft.Json.Utilities;
+using NUnit.Framework;
+using Newtonsoft.Json.Tests.TestObjects;
+
+namespace Newtonsoft.Json.Tests.Converters
+{
+ public class RegexConverterTests : TestFixtureBase
+ {
+ public class RegexTestClass
+ {
+ public Regex Regex { get; set; }
+ }
+
+ [Test]
+ public void SerializeToText()
+ {
+ Regex regex = new Regex("abc", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
+
+ string json = JsonConvert.SerializeObject(regex, Formatting.Indented, new RegexConverter());
+
+ Assert.AreEqual(@"{
+ ""Pattern"": ""abc"",
+ ""Options"": 513
+}", json);
+ }
+
+ [Test]
+ public void SerializeToBson()
+ {
+ Regex regex = new Regex("abc", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
+
+ MemoryStream ms = new MemoryStream();
+ BsonWriter writer = new BsonWriter(ms);
+ JsonSerializer serializer = new JsonSerializer();
+ serializer.Converters.Add(new RegexConverter());
+
+ serializer.Serialize(writer, new RegexTestClass { Regex = regex });
+
+ string expected = "13-00-00-00-0B-52-65-67-65-78-00-61-62-63-00-69-75-00-00";
+ string bson = MiscellaneousUtils.BytesToHex(ms.ToArray());
+
+ Assert.AreEqual(expected, bson);
+ }
+
+ [Test]
+ public void DeserializeFromText()
+ {
+ string json = @"{
+ ""Pattern"": ""abc"",
+ ""Options"": 513
+}";
+
+ Regex newRegex = JsonConvert.DeserializeObject<Regex>(json, new RegexConverter());
+ Assert.AreEqual("abc", newRegex.ToString());
+ Assert.AreEqual(RegexOptions.IgnoreCase | RegexOptions.CultureInvariant, newRegex.Options);
+ }
+
+ [Test]
+ public void DeserializeFromBson()
+ {
+ MemoryStream ms = new MemoryStream(MiscellaneousUtils.HexToBytes("13-00-00-00-0B-52-65-67-65-78-00-61-62-63-00-69-75-00-00"));
+ BsonReader reader = new BsonReader(ms);
+ JsonSerializer serializer = new JsonSerializer();
+ serializer.Converters.Add(new RegexConverter());
+
+ RegexTestClass c = serializer.Deserialize<RegexTestClass>(reader);
+
+ Assert.AreEqual("abc", c.Regex.ToString());
+ Assert.AreEqual(RegexOptions.IgnoreCase, c.Regex.Options);
+ }
+
+ [Test]
+ public void ConvertEmptyRegexBson()
+ {
+ Regex regex = new Regex(string.Empty);
+
+ MemoryStream ms = new MemoryStream();
+ BsonWriter writer = new BsonWriter(ms);
+ JsonSerializer serializer = new JsonSerializer();
+ serializer.Converters.Add(new RegexConverter());
+
+ serializer.Serialize(writer, new RegexTestClass { Regex = regex });
+
+ ms.Seek(0, SeekOrigin.Begin);
+ BsonReader reader = new BsonReader(ms);
+ serializer.Converters.Add(new RegexConverter());
+
+ RegexTestClass c = serializer.Deserialize<RegexTestClass>(reader);
+
+ Assert.AreEqual("", c.Regex.ToString());
+ Assert.AreEqual(RegexOptions.None, c.Regex.Options);
+ }
+
+ [Test]
+ public void ConvertRegexWithAllOptionsBson()
+ {
+ Regex regex = new Regex(
+ "/",
+ RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Multiline | RegexOptions.ExplicitCapture);
+
+ MemoryStream ms = new MemoryStream();
+ BsonWriter writer = new BsonWriter(ms);
+ JsonSerializer serializer = new JsonSerializer();
+ serializer.Converters.Add(new RegexConverter());
+
+ serializer.Serialize(writer, new RegexTestClass { Regex = regex });
+
+ string expected = "14-00-00-00-0B-52-65-67-65-78-00-2F-00-69-6D-73-75-78-00-00";
+ string bson = MiscellaneousUtils.BytesToHex(ms.ToArray());
+
+ Assert.AreEqual(expected, bson);
+
+ ms.Seek(0, SeekOrigin.Begin);
+ BsonReader reader = new BsonReader(ms);
+ serializer.Converters.Add(new RegexConverter());
+
+ RegexTestClass c = serializer.Deserialize<RegexTestClass>(reader);
+
+ Assert.AreEqual("/", c.Regex.ToString());
+ Assert.AreEqual(RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Multiline | RegexOptions.ExplicitCapture, c.Regex.Options);
+ }
+
+ [Test]
+ public void ConvertEmptyRegexJson()
+ {
+ Regex regex = new Regex("");
+
+ string json = JsonConvert.SerializeObject(new RegexTestClass { Regex = regex }, Formatting.Indented, new RegexConverter());
+
+ Assert.AreEqual(@"{
+ ""Regex"": {
+ ""Pattern"": """",
+ ""Options"": 0
+ }
+}", json);
+
+ RegexTestClass newRegex = JsonConvert.DeserializeObject<RegexTestClass>(json, new RegexConverter());
+ Assert.AreEqual("", newRegex.Regex.ToString());
+ Assert.AreEqual(RegexOptions.None, newRegex.Regex.Options);
+ }
+ }
+} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj
index 7e2ea82..c8a92c4 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Compact.csproj
@@ -66,6 +66,8 @@
<Compile Include="Converters\DataSetConverterTests.cs" />
<Compile Include="Converters\DataTableConverterTests.cs" />
<Compile Include="Converters\HtmlColorConverterTests.cs" />
+ <Compile Include="Converters\ObjectIdConverterTests.cs" />
+ <Compile Include="Converters\RegexConverterTests.cs" />
<Compile Include="Converters\StringEnumConverterTests.cs" />
<Compile Include="Linq\ComponentModel\BindingTests.cs" />
<Compile Include="Linq\ComponentModel\JPropertyDescriptorTests.cs" />
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj
index 7eb545e..a5382d9 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Net20.csproj
@@ -70,6 +70,8 @@
<Compile Include="Converters\DataSetConverterTests.cs" />
<Compile Include="Converters\DataTableConverterTests.cs" />
<Compile Include="Converters\HtmlColorConverterTests.cs" />
+ <Compile Include="Converters\ObjectIdConverterTests.cs" />
+ <Compile Include="Converters\RegexConverterTests.cs" />
<Compile Include="Converters\StringEnumConverterTests.cs" />
<Compile Include="JsonArrayAttributeTests.cs" />
<Compile Include="ExceptionTests.cs" />
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj
index 638022d..08b88c7 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.Silverlight.csproj
@@ -75,6 +75,8 @@
<Compile Include="Converters\DataSetConverterTests.cs" />
<Compile Include="Converters\DataTableConverterTests.cs" />
<Compile Include="Converters\HtmlColorConverterTests.cs" />
+ <Compile Include="Converters\ObjectIdConverterTests.cs" />
+ <Compile Include="Converters\RegexConverterTests.cs" />
<Compile Include="Converters\StringEnumConverterTests.cs" />
<Compile Include="ExceptionTests.cs" />
<Compile Include="JsonArrayAttributeTests.cs" />
diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
index e2d332d..121ef0f 100644
--- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
+++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj
@@ -87,6 +87,7 @@
<Compile Include="Bson\BsonWriterTests.cs" />
<Compile Include="Bson\BsonReaderTests.cs" />
<Compile Include="Converters\BinaryConverterTests.cs" />
+ <Compile Include="Converters\RegexConverterTests.cs" />
<Compile Include="Converters\DataTableConverterTests.cs" />
<Compile Include="Converters\DataSetConverterTests.cs" />
<Compile Include="Converters\CustomCreationConverterTests.cs" />
diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
index 0ace842..2920a09 100644
--- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
+++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs
@@ -50,6 +50,7 @@ using Newtonsoft.Json.Utilities;
using System.Reflection;
#if !NET20 && !SILVERLIGHT
using System.Xml.Linq;
+using System.Text.RegularExpressions;
#endif
namespace Newtonsoft.Json.Tests.Serialization
diff --git a/Src/Newtonsoft.Json/Bson/BsonBinaryWriter.cs b/Src/Newtonsoft.Json/Bson/BsonBinaryWriter.cs
index 7ff6965..397702c 100644
--- a/Src/Newtonsoft.Json/Bson/BsonBinaryWriter.cs
+++ b/Src/Newtonsoft.Json/Bson/BsonBinaryWriter.cs
@@ -139,6 +139,14 @@ namespace Newtonsoft.Json.Bson
_writer.Write(data);
}
break;
+ case BsonType.Regex:
+ {
+ BsonRegex value = (BsonRegex) t;
+
+ WriteString((string)value.Pattern.Value, value.Pattern.ByteCount, null);
+ WriteString((string)value.Options.Value, value.Options.ByteCount, null);
+ }
+ break;
default:
throw new ArgumentOutOfRangeException("t", "Unexpected token when writing BSON: {0}".FormatWith(CultureInfo.InvariantCulture, t.Type));
}
@@ -149,26 +157,29 @@ namespace Newtonsoft.Json.Bson
if (calculatedlengthPrefix != null)
_writer.Write(calculatedlengthPrefix.Value);
- if (_largeByteBuffer == null)
- {
- _largeByteBuffer = new byte[256];
- _maxChars = 256 / Encoding.GetMaxByteCount(1);
- }
- if (byteCount <= 256)
- {
- Encoding.GetBytes(s, 0, s.Length, _largeByteBuffer, 0);
- _writer.Write(_largeByteBuffer, 0, byteCount);
- }
- else
+ if (s != null)
{
- int charCount;
- int totalCharsWritten = 0;
- for (int i = s.Length; i > 0; i -= charCount)
+ if (_largeByteBuffer == null)
+ {
+ _largeByteBuffer = new byte[256];
+ _maxChars = 256/Encoding.GetMaxByteCount(1);
+ }
+ if (byteCount <= 256)
{
- charCount = (i > _maxChars) ? _maxChars : i;
- int count = Encoding.GetBytes(s, totalCharsWritten, charCount, _largeByteBuffer, 0);
- _writer.Write(_largeByteBuffer, 0, count);
- totalCharsWritten += charCount;
+ Encoding.GetBytes(s, 0, s.Length, _largeByteBuffer, 0);
+ _writer.Write(_largeByteBuffer, 0, byteCount);
+ }
+ else
+ {
+ int charCount;
+ int totalCharsWritten = 0;
+ for (int i = s.Length; i > 0; i -= charCount)
+ {
+ charCount = (i > _maxChars) ? _maxChars : i;
+ int count = Encoding.GetBytes(s, totalCharsWritten, charCount, _largeByteBuffer, 0);
+ _writer.Write(_largeByteBuffer, 0, count);
+ totalCharsWritten += charCount;
+ }
}
}
@@ -238,7 +249,7 @@ namespace Newtonsoft.Json.Bson
{
BsonString value = (BsonString)t;
string s = (string) value.Value;
- value.ByteCount = Encoding.GetByteCount(s);
+ value.ByteCount = (s != null) ? Encoding.GetByteCount(s) : 0;
value.CalculatedSize = CalculateSizeWithLength(value.ByteCount, value.IncludeLength);
return value.CalculatedSize;
@@ -261,6 +272,16 @@ namespace Newtonsoft.Json.Bson
}
case BsonType.Oid:
return 12;
+ case BsonType.Regex:
+ {
+ BsonRegex value = (BsonRegex) t;
+ int size = 0;
+ size += CalculateSize(value.Pattern);
+ size += CalculateSize(value.Options);
+ value.CalculatedSize = size;
+
+ return value.CalculatedSize;
+ }
default:
throw new ArgumentOutOfRangeException("t", "Unexpected token when writing BSON: {0}".FormatWith(CultureInfo.InvariantCulture, t.Type));
}
diff --git a/Src/Newtonsoft.Json/Bson/BsonToken.cs b/Src/Newtonsoft.Json/Bson/BsonToken.cs
new file mode 100644
index 0000000..ff4b21d
--- /dev/null
+++ b/Src/Newtonsoft.Json/Bson/BsonToken.cs
@@ -0,0 +1,121 @@
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Newtonsoft.Json.Bson
+{
+ internal abstract class BsonToken
+ {
+ public abstract BsonType Type { get; }
+ public BsonToken Parent { get; set; }
+ public int CalculatedSize { get; set; }
+ }
+
+ internal class BsonObject : BsonToken, IEnumerable<BsonProperty>
+ {
+ private readonly List<BsonProperty> _children = new List<BsonProperty>();
+
+ public void Add(string name, BsonToken token)
+ {
+ _children.Add(new BsonProperty { Name = new BsonString(name, false), Value = token });
+ token.Parent = this;
+ }
+
+ public override BsonType Type
+ {
+ get { return BsonType.Object; }
+ }
+
+ public IEnumerator<BsonProperty> GetEnumerator()
+ {
+ return _children.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+ }
+
+ internal class BsonArray : BsonToken, IEnumerable<BsonToken>
+ {
+ private readonly List<BsonToken> _children = new List<BsonToken>();
+
+ public void Add(BsonToken token)
+ {
+ _children.Add(token);
+ token.Parent = this;
+ }
+
+ public override BsonType Type
+ {
+ get { return BsonType.Array; }
+ }
+
+ public IEnumerator<BsonToken> GetEnumerator()
+ {
+ return _children.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+ }
+
+ internal class BsonValue : BsonToken
+ {
+ private object _value;
+ private BsonType _type;
+
+ public BsonValue(object value, BsonType type)
+ {
+ _value = value;
+ _type = type;
+ }
+
+ public object Value
+ {
+ get { return _value; }
+ }
+
+ public override BsonType Type
+ {
+ get { return _type; }
+ }
+ }
+
+ internal class BsonString : BsonValue
+ {
+ public int ByteCount { get; set; }
+ public bool IncludeLength { get; set; }
+
+ public BsonString(object value, bool includeLength)
+ : base(value, BsonType.String)
+ {
+ IncludeLength = includeLength;
+ }
+ }
+
+ internal class BsonRegex : BsonToken
+ {
+ public BsonString Pattern { get; set; }
+ public BsonString Options { get; set; }
+
+ public BsonRegex(string pattern, string options)
+ {
+ Pattern = new BsonString(pattern, false);
+ Options = new BsonString(options, false);
+ }
+
+ public override BsonType Type
+ {
+ get { return BsonType.Regex; }
+ }
+ }
+
+ internal class BsonProperty
+ {
+ public BsonString Name { get; set; }
+ public BsonToken Value { get; set; }
+ }
+} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Bson/BsonWriter.cs b/Src/Newtonsoft.Json/Bson/BsonWriter.cs
index 82940a6..076bcbb 100644
--- a/Src/Newtonsoft.Json/Bson/BsonWriter.cs
+++ b/Src/Newtonsoft.Json/Bson/BsonWriter.cs
@@ -34,105 +34,6 @@ using System.Globalization;
namespace Newtonsoft.Json.Bson
{
- internal abstract class BsonToken
- {
- public abstract BsonType Type { get; }
- public BsonToken Parent { get; set; }
- public int CalculatedSize { get; set; }
- }
-
- internal class BsonObject : BsonToken, IEnumerable<BsonProperty>
- {
- private readonly List<BsonProperty> _children = new List<BsonProperty>();
-
- public void Add(string name, BsonToken token)
- {
- _children.Add(new BsonProperty { Name = new BsonString(name, false), Value = token });
- token.Parent = this;
- }
-
- public override BsonType Type
- {
- get { return BsonType.Object; }
- }
-
- public IEnumerator<BsonProperty> GetEnumerator()
- {
- return _children.GetEnumerator();
- }
-
- IEnumerator IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
- }
-
- internal class BsonArray : BsonToken, IEnumerable<BsonToken>
- {
- private readonly List<BsonToken> _children = new List<BsonToken>();
-
- public void Add(BsonToken token)
- {
- _children.Add(token);
- token.Parent = this;
- }
-
- public override BsonType Type
- {
- get { return BsonType.Array; }
- }
-
- public IEnumerator<BsonToken> GetEnumerator()
- {
- return _children.GetEnumerator();
- }
-
- IEnumerator IEnumerable.GetEnumerator()
- {
- return GetEnumerator();
- }
- }
-
- internal class BsonValue : BsonToken
- {
- private object _value;
- private BsonType _type;
-
- public BsonValue(object value, BsonType type)
- {
- _value = value;
- _type = type;
- }
-
- public object Value
- {
- get { return _value; }
- }
-
- public override BsonType Type
- {
- get { return _type; }
- }
- }
-
- internal class BsonString : BsonValue
- {
- public int ByteCount { get; set; }
- public bool IncludeLength { get; set; }
-
- public BsonString(object value, bool includeLength)
- : base(value, BsonType.String)
- {
- IncludeLength = includeLength;
- }
- }
-
- internal class BsonProperty
- {
- public BsonString Name { get; set; }
- public BsonToken Value { get; set; }
- }
-
/// <summary>
/// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data.
/// </summary>
@@ -214,22 +115,6 @@ namespace Newtonsoft.Json.Bson
}
/// <summary>
- /// Writes a <see cref="T:Byte[]"/> value that represents a BSON object id.
- /// </summary>
- /// <param name="value"></param>
- public void WriteObjectId(byte[] value)
- {
- ValidationUtils.ArgumentNotNull(value, "value");
-
- if (value.Length != 12)
- throw new Exception("An object id must be 12 bytes");
-
- // hack to update the writer state
- AutoComplete(JsonToken.Undefined);
- AddValue(value, BsonType.Oid);
- }
-
- /// <summary>
/// Writes the beginning of a Json array.
/// </summary>
public override void WriteStartArray()
@@ -319,7 +204,10 @@ namespace Newtonsoft.Json.Bson
public override void WriteValue(string value)
{
base.WriteValue(value);
- AddToken(new BsonString(value ?? string.Empty, true));
+ if (value == null)
+ AddValue(null, BsonType.Null);
+ else
+ AddToken(new BsonString(value, true));
}
/// <summary>
@@ -490,5 +378,35 @@ namespace Newtonsoft.Json.Bson
AddValue(value, BsonType.Binary);
}
#endregion
+
+ /// <summary>
+ /// Writes a <see cref="T:Byte[]"/> value that represents a BSON object id.
+ /// </summary>
+ /// <param name="value"></param>
+ public void WriteObjectId(byte[] value)
+ {
+ ValidationUtils.ArgumentNotNull(value, "value");
+
+ if (value.Length != 12)
+ throw new Exception("An object id must be 12 bytes");
+
+ // hack to update the writer state
+ AutoComplete(JsonToken.Undefined);
+ AddValue(value, BsonType.Oid);
+ }
+
+ /// <summary>
+ /// Writes a BSON regex.
+ /// </summary>
+ /// <param name="pattern">The regex pattern.</param>
+ /// <param name="options">The regex options.</param>
+ public void WriteRegex(string pattern, string options)
+ {
+ ValidationUtils.ArgumentNotNull(pattern, "pattern");
+
+ // hack to update the writer state
+ AutoComplete(JsonToken.Undefined);
+ AddToken(new BsonRegex(pattern, options));
+ }
}
} \ No newline at end of file
diff --git a/Src/Newtonsoft.Json/Converters/RegexConverter.cs b/Src/Newtonsoft.Json/Converters/RegexConverter.cs
new file mode 100644
index 0000000..21d78d2
--- /dev/null
+++ b/Src/Newtonsoft.Json/Converters/RegexConverter.cs
@@ -0,0 +1,127 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using Newtonsoft.Json.Bson;
+
+namespace Newtonsoft.Json.Converters
+{
+ public class RegexConverter : JsonConverter
+ {
+ public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
+ {
+ Regex regex = (Regex) value;
+
+ BsonWriter bsonWriter = writer as BsonWriter;
+ if (bsonWriter != null)
+ WriteBson(bsonWriter, regex);
+ else
+ WriteJson(writer, regex);
+ }
+
+ private bool HasFlag(RegexOptions options, RegexOptions flag)
+ {
+ return ((options & flag) == flag);
+ }
+
+ private void WriteBson(BsonWriter writer, Regex regex)
+ {
+ // Regular expression - The first cstring is the regex pattern, the second
+ // is the regex options string. Options are identified by characters, which
+ // must be stored in alphabetical order. Valid options are 'i' for case
+ // insensitive matching, 'm' for multiline matching, 'x' for verbose mode,
+ // 'l' to make \w, \W, etc. locale dependent, 's' for dotall mode
+ // ('.' matches everything), and 'u' to make \w, \W, etc. match unicode.
+
+ string options = null;
+
+ if (HasFlag(regex.Options, RegexOptions.IgnoreCase))
+ options += "i";
+
+ if (HasFlag(regex.Options, RegexOptions.Multiline))
+ options += "m";
+
+ if (HasFlag(regex.Options, RegexOptions.Singleline))
+ options += "s";
+
+ options += "u";
+
+ if (HasFlag(regex.Options, RegexOptions.ExplicitCapture))
+ options += "x";
+
+ writer.WriteRegex(regex.ToString(), options);
+ }
+
+ private void WriteJson(JsonWriter writer, Regex regex)
+ {
+ writer.WriteStartObject();
+ writer.WritePropertyName("Pattern");
+ writer.WriteValue(regex.ToString());
+ writer.WritePropertyName("Options");
+ writer.WriteValue(regex.Options);
+ writer.WriteEndObject();
+ }
+
+ public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
+ {
+ BsonReader bsonReader = reader as BsonReader;
+
+ if (bsonReader != null)
+ return ReadBson(bsonReader);
+ else
+ return ReadJson(reader);
+ }
+
+ private object ReadBson(BsonReader reader)
+ {
+ string regexText = (string)reader.Value;
+ int patternOptionDelimiterIndex = regexText.LastIndexOf(@"/");
+
+ string patternText = regexText.Substring(1, patternOptionDelimiterIndex - 1);
+ string optionsText = regexText.Substring(patternOptionDelimiterIndex + 1);
+
+ RegexOptions options = RegexOptions.None;
+ foreach (char c in optionsText)
+ {
+ switch (c)
+ {
+ case 'i':
+ options |= RegexOptions.IgnoreCase;
+ break;
+ case 'm':
+ options |= RegexOptions.Multiline;
+ break;
+ case 's':
+ options |= RegexOptions.Singleline;
+ break;
+ case 'x':
+ options |= RegexOptions.ExplicitCapture;
+ break;
+ }
+ }
+
+ return new Regex(patternText, options);
+ }
+
+ private Regex ReadJson(JsonReader reader)
+ {
+ reader.Read();
+ reader.Read();
+ string pattern = (string) reader.Value;
+
+ reader.Read();
+ reader.Read();
+ int options = Convert.ToInt32(reader.Value);
+
+ reader.Read();
+
+ return new Regex(pattern, (RegexOptions)options);
+ }
+
+ public override bool CanConvert(Type objectType)
+ {
+ return (objectType == typeof (Regex));
+ }
+ }
+}
diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj
index 04581ed..0bd69f5 100644
--- a/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj
+++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Compact.csproj
@@ -61,6 +61,7 @@
<Compile Include="Bson\BsonBinaryWriter.cs" />
<Compile Include="Bson\BsonObjectId.cs" />
<Compile Include="Bson\BsonReader.cs" />
+ <Compile Include="Bson\BsonToken.cs" />
<Compile Include="Bson\BsonType.cs" />
<Compile Include="Bson\BsonWriter.cs" />
<Compile Include="ConstructorHandling.cs" />
@@ -72,6 +73,7 @@
<Compile Include="Converters\DateTimeConverterBase.cs" />
<Compile Include="Converters\EntityKeyMemberConverter.cs" />
<Compile Include="Converters\KeyValuePairConverter.cs" />
+ <Compile Include="Converters\RegexConverter.cs" />
<Compile Include="Converters\StringEnumConverter.cs" />
<Compile Include="IJsonLineInfo.cs" />
<Compile Include="JsonArrayAttribute.cs" />
diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj
index 0021f90..9317497 100644
--- a/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj
+++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Net20.csproj
@@ -81,6 +81,7 @@
<Compile Include="Bson\BsonBinaryWriter.cs" />
<Compile Include="Bson\BsonObjectId.cs" />
<Compile Include="Bson\BsonReader.cs" />
+ <Compile Include="Bson\BsonToken.cs" />
<Compile Include="Bson\BsonType.cs" />
<Compile Include="Bson\BsonWriter.cs" />
<Compile Include="ConstructorHandling.cs" />
@@ -92,6 +93,7 @@
<Compile Include="Converters\DateTimeConverterBase.cs" />
<Compile Include="Converters\EntityKeyMemberConverter.cs" />
<Compile Include="Converters\KeyValuePairConverter.cs" />
+ <Compile Include="Converters\RegexConverter.cs" />
<Compile Include="Converters\StringEnumConverter.cs" />
<Compile Include="Linq\ComponentModel\JPropertyDescriptor.cs" />
<Compile Include="Linq\ComponentModel\JTypeDescriptionProvider.cs" />
diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj
index 4745f60..f11cc1f 100644
--- a/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj
+++ b/Src/Newtonsoft.Json/Newtonsoft.Json.Silverlight.csproj
@@ -58,6 +58,7 @@
<Compile Include="Bson\BsonBinaryWriter.cs" />
<Compile Include="Bson\BsonObjectId.cs" />
<Compile Include="Bson\BsonReader.cs" />
+ <Compile Include="Bson\BsonToken.cs" />
<Compile Include="Bson\BsonType.cs" />
<Compile Include="Bson\BsonWriter.cs" />
<Compile Include="ConstructorHandling.cs" />
@@ -72,6 +73,7 @@
<Compile Include="Converters\JavaScriptDateTimeConverter.cs" />
<Compile Include="Converters\JsonDateTimeSerializationMode.cs" />
<Compile Include="Converters\KeyValuePairConverter.cs" />
+ <Compile Include="Converters\RegexConverter.cs" />
<Compile Include="Converters\StringEnumConverter.cs" />
<Compile Include="Converters\XmlNodeConverter.cs" />
<Compile Include="Converters\HtmlColorConverter.cs" />
diff --git a/Src/Newtonsoft.Json/Newtonsoft.Json.csproj b/Src/Newtonsoft.Json/Newtonsoft.Json.csproj
index 79acf22..313e58b 100644
--- a/Src/Newtonsoft.Json/Newtonsoft.Json.csproj
+++ b/Src/Newtonsoft.Json/Newtonsoft.Json.csproj
@@ -83,6 +83,7 @@
<Compile Include="Bson\BsonBinaryType.cs" />
<Compile Include="Bson\BsonBinaryWriter.cs" />
<Compile Include="Bson\BsonReader.cs" />
+ <Compile Include="Bson\BsonToken.cs" />
<Compile Include="Bson\BsonType.cs" />
<Compile Include="Bson\BsonWriter.cs" />
<Compile Include="Bson\BsonObjectId.cs" />
@@ -94,6 +95,7 @@
<Compile Include="Converters\EntityKeyMemberConverter.cs" />
<Compile Include="Converters\KeyValuePairConverter.cs" />
<Compile Include="Converters\BsonObjectIdConverter.cs" />
+ <Compile Include="Converters\RegexConverter.cs" />
<Compile Include="Converters\StringEnumConverter.cs" />
<Compile Include="ConstructorHandling.cs" />
<Compile Include="Linq\JPath.cs" />