-Added support for converting byte array JValues to Guid
-Added support for deserializing byte arrays to Guid -Changed Guids to be serialized as binary UUID in BSON -Changed JsonNet35BinaryCompatibility on BsonReader to be obsolete
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE)
|
||||
using System.Numerics;
|
||||
@@ -94,6 +95,76 @@ namespace Newtonsoft.Json.Tests.Bson
|
||||
Assert.AreEqual(JsonToken.None, reader.TokenType);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ReadGuid_Text()
|
||||
{
|
||||
byte[] data = HexToBytes("31-00-00-00-02-30-00-25-00-00-00-64-38-32-31-65-65-64-37-2D-34-62-35-63-2D-34-33-63-39-2D-38-61-63-32-2D-36-39-32-38-65-35-37-39-62-37-30-35-00-00");
|
||||
|
||||
MemoryStream ms = new MemoryStream(data);
|
||||
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("d821eed7-4b5c-43c9-8ac2-6928e579b705", reader.Value);
|
||||
Assert.AreEqual(typeof(string), reader.ValueType);
|
||||
|
||||
Assert.IsTrue(reader.Read());
|
||||
Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
|
||||
|
||||
Assert.IsFalse(reader.Read());
|
||||
Assert.AreEqual(JsonToken.None, reader.TokenType);
|
||||
|
||||
ms = new MemoryStream(data);
|
||||
reader = new BsonReader(ms);
|
||||
reader.ReadRootValueAsArray = true;
|
||||
|
||||
JsonSerializer serializer = new JsonSerializer();
|
||||
IList<Guid> l = serializer.Deserialize<IList<Guid>>(reader);
|
||||
|
||||
Assert.AreEqual(1, l.Count);
|
||||
Assert.AreEqual(new Guid("D821EED7-4B5C-43C9-8AC2-6928E579B705"), l[0]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ReadGuid_Bytes()
|
||||
{
|
||||
byte[] data = HexToBytes("1D-00-00-00-05-30-00-10-00-00-00-04-D7-EE-21-D8-5C-4B-C9-43-8A-C2-69-28-E5-79-B7-05-00");
|
||||
|
||||
MemoryStream ms = new MemoryStream(data);
|
||||
BsonReader reader = new BsonReader(ms);
|
||||
reader.ReadRootValueAsArray = true;
|
||||
|
||||
Assert.IsTrue(reader.Read());
|
||||
Assert.AreEqual(JsonToken.StartArray, reader.TokenType);
|
||||
|
||||
Guid g = new Guid("D821EED7-4B5C-43C9-8AC2-6928E579B705");
|
||||
|
||||
Assert.IsTrue(reader.Read());
|
||||
Assert.AreEqual(JsonToken.Bytes, reader.TokenType);
|
||||
CollectionAssert.AreEqual(g.ToByteArray(), (byte[])reader.Value);
|
||||
Assert.AreEqual(typeof(byte[]), reader.ValueType);
|
||||
|
||||
Assert.IsTrue(reader.Read());
|
||||
Assert.AreEqual(JsonToken.EndArray, reader.TokenType);
|
||||
|
||||
Assert.IsFalse(reader.Read());
|
||||
Assert.AreEqual(JsonToken.None, reader.TokenType);
|
||||
|
||||
ms = new MemoryStream(data);
|
||||
reader = new BsonReader(ms);
|
||||
reader.ReadRootValueAsArray = true;
|
||||
|
||||
JsonSerializer serializer = new JsonSerializer();
|
||||
IList<Guid> l = serializer.Deserialize<IList<Guid>>(reader);
|
||||
|
||||
Assert.AreEqual(1, l.Count);
|
||||
Assert.AreEqual(g, l[0]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ReadDouble()
|
||||
{
|
||||
|
||||
@@ -128,6 +128,23 @@ namespace Newtonsoft.Json.Tests.Bson
|
||||
Assert.AreEqual("10-00-00-00-01-30-00-8F-C2-F5-28-5C-FF-58-40-00", bson);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WriteGuid()
|
||||
{
|
||||
Guid g = new Guid("D821EED7-4B5C-43C9-8AC2-6928E579B705");
|
||||
|
||||
MemoryStream ms = new MemoryStream();
|
||||
BsonWriter writer = new BsonWriter(ms);
|
||||
|
||||
writer.WriteStartArray();
|
||||
writer.WriteValue(g);
|
||||
writer.WriteEnd();
|
||||
|
||||
string bson = BytesToHex(ms.ToArray());
|
||||
Console.WriteLine(bson);
|
||||
Assert.AreEqual("1D-00-00-00-05-30-00-10-00-00-00-04-D7-EE-21-D8-5C-4B-C9-43-8A-C2-69-28-E5-79-B7-05-00", bson);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WriteArrayBsonFromSite()
|
||||
{
|
||||
|
||||
@@ -319,6 +319,8 @@ namespace Newtonsoft.Json.Tests.Linq
|
||||
Assert.AreEqual(null, (Uri)(new JValue((object)null)));
|
||||
Assert.AreEqual(Convert.ToBase64String(Encoding.UTF8.GetBytes("hi")), (string)(new JValue(Encoding.UTF8.GetBytes("hi"))));
|
||||
CollectionAssert.AreEquivalent((byte[])Encoding.UTF8.GetBytes("hi"), (byte[])(new JValue(Convert.ToBase64String(Encoding.UTF8.GetBytes("hi")))));
|
||||
Assert.AreEqual(new Guid("46EFE013-B56A-4E83-99E4-4DCE7678A5BC"), (Guid)(new JValue(new Guid("46EFE013-B56A-4E83-99E4-4DCE7678A5BC").ToByteArray())));
|
||||
Assert.AreEqual(new Guid("46EFE013-B56A-4E83-99E4-4DCE7678A5BC"), (Guid?)(new JValue(new Guid("46EFE013-B56A-4E83-99E4-4DCE7678A5BC").ToByteArray())));
|
||||
|
||||
Assert.AreEqual(null, (Uri)(JValue)null);
|
||||
Assert.AreEqual(null, (int?)(JValue)null);
|
||||
|
||||
@@ -32,8 +32,10 @@ namespace Newtonsoft.Json.Bson
|
||||
Binary = 0x00,
|
||||
Function = 0x01,
|
||||
[Obsolete("This type has been deprecated in the BSON specification. Use Binary instead.")]
|
||||
Data = 0x02,
|
||||
Uuid = 0x03,
|
||||
BinaryOld = 0x02,
|
||||
[Obsolete("This type has been deprecated in the BSON specification. Use Uuid instead.")]
|
||||
UuidOld = 0x03,
|
||||
Uuid = 0x04,
|
||||
Md5 = 0x05,
|
||||
UserDefined = 0x80
|
||||
}
|
||||
|
||||
@@ -161,11 +161,11 @@ namespace Newtonsoft.Json.Bson
|
||||
break;
|
||||
case BsonType.Binary:
|
||||
{
|
||||
BsonValue value = (BsonValue)t;
|
||||
BsonBinary value = (BsonBinary)t;
|
||||
|
||||
byte[] data = (byte[])value.Value;
|
||||
_writer.Write(data.Length);
|
||||
_writer.Write((byte)BsonBinaryType.Binary);
|
||||
_writer.Write((byte)value.BinaryType);
|
||||
_writer.Write(data);
|
||||
}
|
||||
break;
|
||||
@@ -298,7 +298,7 @@ namespace Newtonsoft.Json.Bson
|
||||
return 8;
|
||||
case BsonType.Binary:
|
||||
{
|
||||
BsonValue value = (BsonValue)t;
|
||||
BsonBinary value = (BsonBinary)t;
|
||||
|
||||
byte[] data = (byte[])value.Value;
|
||||
value.CalculatedSize = 4 + 1 + data.Length;
|
||||
|
||||
@@ -89,6 +89,7 @@ namespace Newtonsoft.Json.Bson
|
||||
/// <value>
|
||||
/// <c>true</c> if binary data reading will be compatible with incorrect Json.NET 3.5 written binary; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
[Obsolete("JsonNet35BinaryCompatibility will be removed in a future version of Json.NET.")]
|
||||
public bool JsonNet35BinaryCompatibility
|
||||
{
|
||||
get { return _jsonNet35BinaryCompatibility; }
|
||||
@@ -608,7 +609,7 @@ namespace Newtonsoft.Json.Bson
|
||||
|
||||
#pragma warning disable 612,618
|
||||
// the old binary type has the data length repeated in the data for some reason
|
||||
if (binaryType == BsonBinaryType.Data && !_jsonNet35BinaryCompatibility)
|
||||
if (binaryType == BsonBinaryType.BinaryOld && !_jsonNet35BinaryCompatibility)
|
||||
{
|
||||
dataLength = ReadInt32();
|
||||
}
|
||||
|
||||
@@ -121,6 +121,17 @@ namespace Newtonsoft.Json.Bson
|
||||
}
|
||||
}
|
||||
|
||||
internal class BsonBinary : BsonValue
|
||||
{
|
||||
public BsonBinaryType BinaryType { get; set; }
|
||||
|
||||
public BsonBinary(byte[] value, BsonBinaryType binaryType)
|
||||
: base(value, BsonType.Binary)
|
||||
{
|
||||
BinaryType = binaryType;
|
||||
}
|
||||
}
|
||||
|
||||
internal class BsonRegex : BsonToken
|
||||
{
|
||||
public BsonString Pattern { get; set; }
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
namespace Newtonsoft.Json.Bson
|
||||
{
|
||||
internal enum BsonType : sbyte
|
||||
internal enum BsonType : sbyte
|
||||
{
|
||||
Number = 1,
|
||||
String = 2,
|
||||
|
||||
@@ -429,7 +429,7 @@ namespace Newtonsoft.Json.Bson
|
||||
public override void WriteValue(byte[] value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
AddValue(value, BsonType.Binary);
|
||||
AddToken(new BsonBinary(value, BsonBinaryType.Binary));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -439,7 +439,7 @@ namespace Newtonsoft.Json.Bson
|
||||
public override void WriteValue(Guid value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
AddToken(new BsonString(value.ToString(), true));
|
||||
AddToken(new BsonBinary(value.ToByteArray(), BsonBinaryType.Uuid));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -470,7 +470,7 @@ namespace Newtonsoft.Json.Bson
|
||||
public override void WriteValue(BigInteger value)
|
||||
{
|
||||
base.WriteValue(value);
|
||||
AddToken(new BsonValue(value.ToByteArray(), BsonType.Binary));
|
||||
AddToken(new BsonBinary(value.ToByteArray(), BsonBinaryType.Binary));
|
||||
}
|
||||
#endif
|
||||
#endregion
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace Newtonsoft.Json.Linq
|
||||
private static readonly JTokenType[] NumberTypes = new[] { JTokenType.Integer, JTokenType.Float, JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Boolean };
|
||||
private static readonly JTokenType[] BigIntegerTypes = new[] { JTokenType.Integer, JTokenType.Float, JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Boolean, JTokenType.Bytes };
|
||||
private static readonly JTokenType[] StringTypes = new[] { JTokenType.Date, JTokenType.Integer, JTokenType.Float, JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Boolean, JTokenType.Bytes, JTokenType.Guid, JTokenType.TimeSpan, JTokenType.Uri };
|
||||
private static readonly JTokenType[] GuidTypes = new[] { JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Guid };
|
||||
private static readonly JTokenType[] GuidTypes = new[] { JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Guid, JTokenType.Bytes };
|
||||
private static readonly JTokenType[] TimeSpanTypes = new[] { JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.TimeSpan };
|
||||
private static readonly JTokenType[] UriTypes = new[] { JTokenType.String, JTokenType.Comment, JTokenType.Raw, JTokenType.Uri };
|
||||
private static readonly JTokenType[] CharTypes = new[] { JTokenType.Integer, JTokenType.Float, JTokenType.String, JTokenType.Comment, JTokenType.Raw };
|
||||
@@ -1093,7 +1093,10 @@ namespace Newtonsoft.Json.Linq
|
||||
if (v == null || !ValidateToken(v, GuidTypes, false))
|
||||
throw new ArgumentException("Can not convert {0} to Guid.".FormatWith(CultureInfo.InvariantCulture, GetType(value)));
|
||||
|
||||
return (v.Value is Guid) ? (Guid)v.Value : new Guid(Convert.ToString(v.Value, CultureInfo.InvariantCulture));
|
||||
if (v.Value is byte[])
|
||||
return new Guid((byte[]) v.Value);
|
||||
|
||||
return (v.Value is Guid) ? (Guid) v.Value : new Guid(Convert.ToString(v.Value, CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1113,6 +1116,9 @@ namespace Newtonsoft.Json.Linq
|
||||
if (v.Value == null)
|
||||
return null;
|
||||
|
||||
if (v.Value is byte[])
|
||||
return new Guid((byte[])v.Value);
|
||||
|
||||
return (v.Value is Guid) ? (Guid)v.Value : new Guid(Convert.ToString(v.Value, CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
|
||||
@@ -371,17 +371,14 @@ namespace Newtonsoft.Json.Utilities
|
||||
return System.Convert.ChangeType(initialValue, targetType, culture);
|
||||
}
|
||||
|
||||
if (initialValue is string && typeof(Type).IsAssignableFrom(targetType))
|
||||
return Type.GetType((string) initialValue, true);
|
||||
|
||||
if (targetType.IsInterface() || targetType.IsGenericTypeDefinition() || targetType.IsAbstract())
|
||||
throw new ArgumentException("Target type {0} is not a value type or a non-abstract class.".FormatWith(CultureInfo.InvariantCulture, targetType), "targetType");
|
||||
|
||||
#if !NET20
|
||||
if (initialValue is DateTime && targetType == typeof(DateTimeOffset))
|
||||
return new DateTimeOffset((DateTime)initialValue);
|
||||
#endif
|
||||
|
||||
if (initialValue is byte[] && targetType == typeof(Guid))
|
||||
return new Guid((byte[]) initialValue);
|
||||
|
||||
if (initialValue is string)
|
||||
{
|
||||
if (targetType == typeof (Guid))
|
||||
@@ -390,6 +387,8 @@ namespace Newtonsoft.Json.Utilities
|
||||
return new Uri((string) initialValue, UriKind.RelativeOrAbsolute);
|
||||
if (targetType == typeof(TimeSpan))
|
||||
return ParseTimeSpan((string) initialValue);
|
||||
if (typeof(Type).IsAssignableFrom(targetType))
|
||||
return Type.GetType((string) initialValue, true);
|
||||
}
|
||||
|
||||
#if !(NET20 || NET35 || SILVERLIGHT || PORTABLE40 || PORTABLE)
|
||||
@@ -399,6 +398,9 @@ namespace Newtonsoft.Json.Utilities
|
||||
return FromBigInteger((BigInteger)initialValue, targetType);
|
||||
#endif
|
||||
|
||||
if (targetType.IsInterface() || targetType.IsGenericTypeDefinition() || targetType.IsAbstract())
|
||||
throw new ArgumentException("Target type {0} is not a value type or a non-abstract class.".FormatWith(CultureInfo.InvariantCulture, targetType), "targetType");
|
||||
|
||||
#if !(NETFX_CORE || PORTABLE40 || PORTABLE)
|
||||
// see if source or target types have a TypeConverter that converts between the two
|
||||
TypeConverter toConverter = GetConverter(initialType);
|
||||
|
||||
Reference in New Issue
Block a user