From c545dc3f4320269b192a6be53120170524620ebe Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Sat, 21 Jun 2014 16:38:52 +1200 Subject: [PATCH] -Refactoring --- .../Converters/DataTableConverterTests.cs | 44 ++++++++++++ .../Converters/DataTableConverter.cs | 3 +- .../Schema/JsonSchemaGenerator.cs | 2 +- .../Serialization/DefaultContractResolver.cs | 4 +- .../Serialization/JsonArrayContract.cs | 6 +- .../Serialization/JsonDictionaryContract.cs | 6 +- Src/Newtonsoft.Json/Utilities/EnumUtils.cs | 8 +-- Src/Newtonsoft.Json/Utilities/EnumValues.cs | 70 +++++++++---------- .../Utilities/ILGeneratorExtensions.cs | 1 - 9 files changed, 94 insertions(+), 50 deletions(-) diff --git a/Src/Newtonsoft.Json.Tests/Converters/DataTableConverterTests.cs b/Src/Newtonsoft.Json.Tests/Converters/DataTableConverterTests.cs index 0231c080..3b7cccec 100644 --- a/Src/Newtonsoft.Json.Tests/Converters/DataTableConverterTests.cs +++ b/Src/Newtonsoft.Json.Tests/Converters/DataTableConverterTests.cs @@ -23,7 +23,10 @@ // OTHER DEALINGS IN THE SOFTWARE. #endregion +using System.IO; using System.Text; +using Newtonsoft.Json.Bson; +using Newtonsoft.Json.Linq; #if !(NETFX_CORE || PORTABLE || PORTABLE40) using System; using System.Collections.Generic; @@ -272,6 +275,47 @@ namespace Newtonsoft.Json.Tests.Converters Assert.AreEqual(t1.TableName, t2.TableName); } + [Test] + public void RoundtripBsonBytes() + { + Guid g = new Guid("EDE9A599-A7D9-44A9-9243-7C287049DD20"); + + var table = new DataTable(); + table.Columns.Add("data", typeof(byte[])); + table.Columns.Add("id", typeof(Guid)); + table.Rows.Add(Encoding.UTF8.GetBytes("Hello world!"), g); + + JsonSerializer serializer = new JsonSerializer(); + + MemoryStream ms = new MemoryStream(); + BsonWriter bw = new BsonWriter(ms); + + serializer.Serialize(bw, table); + + JToken o = JToken.ReadFrom(new BsonReader(new MemoryStream(ms.ToArray())) { ReadRootValueAsArray = true }); + Assert.AreEqual(@"[ + { + ""data"": ""SGVsbG8gd29ybGQh"", + ""id"": ""ede9a599-a7d9-44a9-9243-7c287049dd20"" + } +]", o.ToString()); + + DataTable deserializedDataTable = serializer.Deserialize(new BsonReader(new MemoryStream(ms.ToArray())) { ReadRootValueAsArray = true }); + + Assert.AreEqual(string.Empty, deserializedDataTable.TableName); + Assert.AreEqual(2, deserializedDataTable.Columns.Count); + Assert.AreEqual("data", deserializedDataTable.Columns[0].ColumnName); + Assert.AreEqual(typeof(byte[]), deserializedDataTable.Columns[0].DataType); + Assert.AreEqual("id", deserializedDataTable.Columns[1].ColumnName); + Assert.AreEqual(typeof(Guid), deserializedDataTable.Columns[1].DataType); + + Assert.AreEqual(1, deserializedDataTable.Rows.Count); + + DataRow dr1 = deserializedDataTable.Rows[0]; + CollectionAssert.AreEquivalent(Encoding.UTF8.GetBytes("Hello world!"), (byte[])dr1["data"]); + Assert.AreEqual(g, (Guid)dr1["id"]); + } + [Test] public void SerializeDataTableWithNull() { diff --git a/Src/Newtonsoft.Json/Converters/DataTableConverter.cs b/Src/Newtonsoft.Json/Converters/DataTableConverter.cs index 47636e17..774cd894 100644 --- a/Src/Newtonsoft.Json/Converters/DataTableConverter.cs +++ b/Src/Newtonsoft.Json/Converters/DataTableConverter.cs @@ -143,7 +143,7 @@ namespace Newtonsoft.Json.Converters dr[columnName] = nestedDt; } - else if (column.DataType.IsArray) + else if (column.DataType.IsArray && column.DataType != typeof(byte[])) { if (reader.TokenType == JsonToken.StartArray) reader.Read(); @@ -184,6 +184,7 @@ namespace Newtonsoft.Json.Converters case JsonToken.Float: case JsonToken.String: case JsonToken.Date: + case JsonToken.Bytes: return reader.ValueType; case JsonToken.Null: case JsonToken.Undefined: diff --git a/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs b/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs index 2aa2606e..fef3fca2 100644 --- a/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs +++ b/Src/Newtonsoft.Json/Schema/JsonSchemaGenerator.cs @@ -295,7 +295,7 @@ namespace Newtonsoft.Json.Schema { CurrentSchema.Enum = new List(); - EnumValues enumValues = EnumUtils.GetNamesAndValues(type); + IList> enumValues = EnumUtils.GetNamesAndValues(type); foreach (EnumValue enumValue in enumValues) { JToken value = JToken.FromObject(enumValue.Value); diff --git a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs index a383bf26..775d9d67 100644 --- a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs +++ b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs @@ -916,9 +916,9 @@ namespace Newtonsoft.Json.Serialization ConstructorInfo constructorInfo = contract.NonNullableUnderlyingType.GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(SerializationInfo), typeof(StreamingContext) }, null); if (constructorInfo != null) { - MethodCall methodCall = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(constructorInfo); + ObjectConstructor creator = JsonTypeReflector.ReflectionDelegateFactory.CreateParametrizedConstructor(constructorInfo); - contract.ISerializableCreator = (args => methodCall(null, args)); + contract.ISerializableCreator = creator; } return contract; diff --git a/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs b/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs index 325ca4d9..6f6bf84a 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonArrayContract.cs @@ -60,7 +60,7 @@ namespace Newtonsoft.Json.Serialization private readonly Type _genericCollectionDefinitionType; private Type _genericWrapperType; - private MethodCall _genericWrapperCreator; + private ObjectConstructor _genericWrapperCreator; private Func _genericTemporaryCollectionCreator; internal bool IsArray { get; private set; } @@ -222,10 +222,10 @@ namespace Newtonsoft.Json.Serialization constructorArgument = _genericCollectionDefinitionType; ConstructorInfo genericWrapperConstructor = _genericWrapperType.GetConstructor(new[] { constructorArgument }); - _genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(genericWrapperConstructor); + _genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateParametrizedConstructor(genericWrapperConstructor); } - return (IWrappedCollection)_genericWrapperCreator(null, list); + return (IWrappedCollection)_genericWrapperCreator(list); } internal IList CreateTemporaryCollection() diff --git a/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs b/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs index a6b7d539..fe06df80 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonDictionaryContract.cs @@ -64,7 +64,7 @@ namespace Newtonsoft.Json.Serialization private readonly Type _genericCollectionDefinitionType; private Type _genericWrapperType; - private MethodCall _genericWrapperCreator; + private ObjectConstructor _genericWrapperCreator; private Func _genericTemporaryDictionaryCreator; @@ -166,10 +166,10 @@ namespace Newtonsoft.Json.Serialization _genericWrapperType = typeof(DictionaryWrapper<,>).MakeGenericType(DictionaryKeyType, DictionaryValueType); ConstructorInfo genericWrapperConstructor = _genericWrapperType.GetConstructor(new[] { _genericCollectionDefinitionType }); - _genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateMethodCall(genericWrapperConstructor); + _genericWrapperCreator = JsonTypeReflector.ReflectionDelegateFactory.CreateParametrizedConstructor(genericWrapperConstructor); } - return (IWrappedDictionary)_genericWrapperCreator(null, dictionary); + return (IWrappedDictionary)_genericWrapperCreator(dictionary); } internal IDictionary CreateTemporaryDictionary() diff --git a/Src/Newtonsoft.Json/Utilities/EnumUtils.cs b/Src/Newtonsoft.Json/Utilities/EnumUtils.cs index 5a9e8a43..6837e32e 100644 --- a/Src/Newtonsoft.Json/Utilities/EnumUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/EnumUtils.cs @@ -47,7 +47,7 @@ namespace Newtonsoft.Json.Utilities Type underlyingType = Enum.GetUnderlyingType(value.GetType()); ulong num = Convert.ToUInt64(value, CultureInfo.InvariantCulture); - EnumValues enumNameValues = GetNamesAndValues(); + IList> enumNameValues = GetNamesAndValues(); IList selectedFlagsValues = new List(); foreach (EnumValue enumNameValue in enumNameValues) @@ -66,7 +66,7 @@ namespace Newtonsoft.Json.Utilities /// Gets a dictionary of the names and values of an Enum type. /// /// - public static EnumValues GetNamesAndValues() where T : struct + public static IList> GetNamesAndValues() where T : struct { return GetNamesAndValues(typeof(T)); } @@ -76,7 +76,7 @@ namespace Newtonsoft.Json.Utilities /// /// The enum type to get names and values for. /// - public static EnumValues GetNamesAndValues(Type enumType) where TUnderlyingType : struct + public static IList> GetNamesAndValues(Type enumType) where TUnderlyingType : struct { if (enumType == null) throw new ArgumentNullException("enumType"); @@ -86,7 +86,7 @@ namespace Newtonsoft.Json.Utilities IList enumValues = GetValues(enumType); IList enumNames = GetNames(enumType); - EnumValues nameValues = new EnumValues(); + IList> nameValues = new List>(); for (int i = 0; i < enumValues.Count; i++) { diff --git a/Src/Newtonsoft.Json/Utilities/EnumValues.cs b/Src/Newtonsoft.Json/Utilities/EnumValues.cs index 51de5ff9..dee896b3 100644 --- a/Src/Newtonsoft.Json/Utilities/EnumValues.cs +++ b/Src/Newtonsoft.Json/Utilities/EnumValues.cs @@ -1,37 +1,37 @@ -#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 +//#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.Collections.ObjectModel; +//using System.Collections.ObjectModel; -namespace Newtonsoft.Json.Utilities -{ - internal class EnumValues : KeyedCollection> where T : struct - { - protected override string GetKeyForItem(EnumValue item) - { - return item.Name; - } - } -} \ No newline at end of file +//namespace Newtonsoft.Json.Utilities +//{ +// internal class EnumValues : KeyedCollection> where T : struct +// { +// protected override string GetKeyForItem(EnumValue item) +// { +// return item.Name; +// } +// } +//} \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Utilities/ILGeneratorExtensions.cs b/Src/Newtonsoft.Json/Utilities/ILGeneratorExtensions.cs index 40d900e5..cbed7db6 100644 --- a/Src/Newtonsoft.Json/Utilities/ILGeneratorExtensions.cs +++ b/Src/Newtonsoft.Json/Utilities/ILGeneratorExtensions.cs @@ -71,5 +71,4 @@ namespace Newtonsoft.Json.Utilities } } } - #endif \ No newline at end of file