-Added support for reading byte arrays from JSON integer arrays

This commit is contained in:
JamesNK
2011-08-02 23:53:15 +00:00
parent 76fc1b3081
commit 18c9400054
3 changed files with 100 additions and 11 deletions
@@ -39,6 +39,20 @@ namespace Newtonsoft.Json.Tests.Converters
Assert.AreEqual(null, binaryClass.NullBinary);
}
[Test]
public void DeserializeBinaryClassFromJsonArray()
{
string json = @"{
""Binary"": [0, 1, 2, 3],
""NullBinary"": null
}";
BinaryClass binaryClass = JsonConvert.DeserializeObject<BinaryClass>(json, new BinaryConverter());
Assert.AreEqual(new byte[] { 0, 1, 2, 3 }, binaryClass.Binary.ToArray());
Assert.AreEqual(null, binaryClass.NullBinary);
}
public class BinaryClass
{
public Binary Binary { get; set; }
@@ -132,5 +146,18 @@ namespace Newtonsoft.Json.Tests.Converters
Assert.AreEqual(null, byteArrayClass.NullByteArray);
}
[Test]
public void DeserializeByteArrayFromJsonArray()
{
string json = @"{
""ByteArray"": [0, 1, 2, 3],
""NullByteArray"": null
}";
ByteArrayClass c = JsonConvert.DeserializeObject<ByteArrayClass>(json);
Assert.IsNotNull(c.ByteArray);
Assert.AreEqual(4, c.ByteArray.Length);
Assert.AreEqual(new byte[] { 0, 1, 2, 3 }, c.ByteArray);
}
}
}
@@ -29,6 +29,7 @@ using System.Data.SqlTypes;
#endif
using System.Globalization;
using Newtonsoft.Json.Utilities;
using System.Collections.Generic;
namespace Newtonsoft.Json.Converters
{
@@ -105,14 +106,25 @@ namespace Newtonsoft.Json.Converters
return null;
}
if (reader.TokenType != JsonToken.String)
throw new Exception("Unexpected token parsing binary. Expected String, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
byte[] data;
// 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 (reader.TokenType == JsonToken.StartArray)
{
data = ReadByteArray(reader);
}
else if (reader.TokenType == JsonToken.String)
{
// current token is already at base64 string
// unable to call ReadAsBytes so do it the old fashion way
string encodedData = reader.Value.ToString();
data = Convert.FromBase64String(encodedData);
}
else
{
throw new Exception("Unexpected token parsing binary. Expected String or StartArray, got {0}.".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
}
#if !SILVERLIGHT && !PocketPC && !NET20
if (t.AssignableToTypeName(BinaryTypeName))
return Activator.CreateInstance(t, data);
@@ -124,6 +136,30 @@ namespace Newtonsoft.Json.Converters
throw new Exception("Unexpected object type when writing binary: {0}".FormatWith(CultureInfo.InvariantCulture, objectType));
}
private byte[] ReadByteArray(JsonReader reader)
{
List<byte> byteList = new List<byte>();
while (reader.Read())
{
switch (reader.TokenType)
{
case JsonToken.Integer:
byteList.Add(Convert.ToByte(reader.Value, CultureInfo.InvariantCulture));
break;
case JsonToken.EndArray:
return byteList.ToArray();
case JsonToken.Comment:
// skip
break;
default:
throw new Exception("Unexpected token when reading bytes: {0}".FormatWith(CultureInfo.InvariantCulture, reader.TokenType));
}
}
throw new Exception("Unexpected end when reading bytes.");
}
/// <summary>
/// Determines whether this instance can convert the specified object type.
/// </summary>
+31 -5
View File
@@ -333,16 +333,42 @@ namespace Newtonsoft.Json
{
_readType = ReadType.ReadAsBytes;
do
{
if (!ReadInternal())
throw CreateJsonReaderException("Unexpected end when reading bytes: Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
} while (TokenType == JsonToken.Comment);
do
{
if (!ReadInternal())
throw CreateJsonReaderException("Unexpected end when reading bytes: Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
} while (TokenType == JsonToken.Comment);
if (TokenType == JsonToken.Null)
return null;
if (TokenType == JsonToken.Bytes)
return (byte[]) Value;
if (TokenType == JsonToken.StartArray)
{
List<byte> data = new List<byte>();
while (ReadInternal())
{
switch (TokenType)
{
case JsonToken.Integer:
data.Add(Convert.ToByte(Value, CultureInfo.InvariantCulture));
break;
case JsonToken.EndArray:
byte[] d = data.ToArray();
SetToken(JsonToken.Bytes, d);
return d;
case JsonToken.Comment:
// skip
break;
default:
throw CreateJsonReaderException("Unexpected token when reading bytes: {0}. Line {1}, position {2}.", TokenType, _currentLineNumber, _currentLinePosition);
}
}
throw CreateJsonReaderException("Unexpected end when reading bytes: Line {0}, position {1}.", _currentLineNumber, _currentLinePosition);
}
throw CreateJsonReaderException("Unexpected token when reading bytes: {0}. Line {1}, position {2}.", TokenType, _currentLineNumber, _currentLinePosition);
}