diff --git a/Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs b/Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs index 73aa7d34..636ad239 100644 --- a/Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs +++ b/Src/Newtonsoft.Json.Tests/Bson/BsonReaderTests.cs @@ -55,6 +55,19 @@ namespace Newtonsoft.Json.Tests.Bson { private const char Euro = '\u20ac'; + [Test] + public void DeserializeLargeBsonObject() + { + byte[] data = System.IO.File.ReadAllBytes(@"SpaceShipV2.baemf"); + + MemoryStream ms = new MemoryStream(data); + BsonReader reader = new BsonReader(ms); + + JObject o = (JObject)JToken.ReadFrom(reader); + + Assert.AreEqual("1", (string)o["$id"]); + } + [Test] public void CloseInput() { diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Json/CustomJsonReader.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Json/CustomJsonReader.cs new file mode 100644 index 00000000..3257ea26 --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Json/CustomJsonReader.cs @@ -0,0 +1,133 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Xml; + +namespace Newtonsoft.Json.Tests.Documentation.Samples.Json +{ + public class XmlJsonReader : JsonReader + { + private readonly XmlReader _reader; + + public XmlJsonReader(XmlReader reader) + { + _reader = reader; + } + + public override bool Read() + { + if (!_reader.Read()) + return false; + + switch (_reader.NodeType) + { + case XmlNodeType.Element: + if (CurrentState == State.ObjectStart || CurrentState == State.Object) + { + SetToken(JsonToken.PropertyName, _reader.LocalName); + } + else + { + SetToken(JsonToken.StartObject); + } + break; + case XmlNodeType.Text: + case XmlNodeType.CDATA: + SetToken(JsonToken.String, _reader.Value); + break; + case XmlNodeType.Comment: + SetToken(JsonToken.Comment, _reader.Value); + break; + case XmlNodeType.Document: + break; + case XmlNodeType.Whitespace: + case XmlNodeType.SignificantWhitespace: + break; + case XmlNodeType.EndElement: + break; + case XmlNodeType.EndEntity: + break; + case XmlNodeType.XmlDeclaration: + break; + default: + throw new ArgumentOutOfRangeException(); + } + + return true; + } + + public override int? ReadAsInt32() + { + throw new NotImplementedException(); + } + + public override string ReadAsString() + { + throw new NotImplementedException(); + } + + public override byte[] ReadAsBytes() + { + throw new NotImplementedException(); + } + + public override decimal? ReadAsDecimal() + { + throw new NotImplementedException(); + } + + public override DateTime? ReadAsDateTime() + { + throw new NotImplementedException(); + } + + public override DateTimeOffset? ReadAsDateTimeOffset() + { + throw new NotImplementedException(); + } + } + + public class CustomJsonReader + { + public void Example() + { + #region Usage + StringBuilder sb = new StringBuilder(); + StringWriter sw = new StringWriter(sb); + + using (JsonWriter writer = new JsonTextWriter(sw)) + { + writer.Formatting = Formatting.Indented; + + writer.WriteStartObject(); + writer.WritePropertyName("CPU"); + writer.WriteValue("Intel"); + writer.WritePropertyName("PSU"); + writer.WriteValue("500W"); + writer.WritePropertyName("Drives"); + writer.WriteStartArray(); + writer.WriteValue("DVD read/writer"); + writer.WriteComment("(broken)"); + writer.WriteValue("500 gigabyte hard drive"); + writer.WriteValue("200 gigabype hard drive"); + writer.WriteEnd(); + writer.WriteEndObject(); + } + + Console.WriteLine(sb.ToString()); + // { + // "CPU": "Intel", + // "PSU": "500W", + // "Drives": [ + // "DVD read/writer" + // /*(broken)*/, + // "500 gigabyte hard drive", + // "200 gigabype hard drive" + // ] + // } + #endregion + } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Documentation/Samples/Json/CustomJsonWriter.cs b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Json/CustomJsonWriter.cs new file mode 100644 index 00000000..b36cb37b --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/Documentation/Samples/Json/CustomJsonWriter.cs @@ -0,0 +1,380 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; +using System.Xml; +using Newtonsoft.Json.Linq; + +namespace Newtonsoft.Json.Tests.Documentation.Samples.Json +{ + public class XmlJsonWriter : JsonWriter + { + private readonly XmlWriter _writer; + private string _propertyName; + + public XmlJsonWriter(XmlWriter writer) + { + _writer = writer; + } + + public override void WriteComment(string text) + { + base.WriteComment(text); + _writer.WriteComment(text); + } + + public override void WritePropertyName(string name) + { + base.WritePropertyName(name); + _propertyName = name; + } + + public override void WriteNull() + { + base.WriteNull(); + + WriteValueElement(JTokenType.Null); + _writer.WriteEndElement(); + } + + public override void WriteValue(DateTime value) + { + base.WriteValue(value); + + WriteValueElement(JTokenType.Date); + _writer.WriteValue(value); + _writer.WriteEndElement(); + } + + public override void WriteValue(DateTimeOffset value) + { + base.WriteValue(value); + + WriteValueElement(JTokenType.Date); + _writer.WriteValue(value); + _writer.WriteEndElement(); + } + + public override void WriteValue(Guid value) + { + base.WriteValue(value); + + WriteValueElement(JTokenType.Guid); + _writer.WriteValue(value.ToString()); + _writer.WriteEndElement(); + } + + public override void WriteValue(TimeSpan value) + { + base.WriteValue(value); + + WriteValueElement(JTokenType.TimeSpan); + _writer.WriteValue(value); + _writer.WriteEndElement(); + } + + public override void WriteValue(Uri value) + { + base.WriteValue(value); + + WriteValueElement(JTokenType.Uri); + _writer.WriteValue(value); + _writer.WriteEndElement(); + } + + public override void WriteValue(string value) + { + base.WriteValue(value); + + WriteValueElement(JTokenType.String); + _writer.WriteValue(value); + _writer.WriteEndElement(); + } + + public override void WriteValue(int value) + { + base.WriteValue(value); + + WriteValueElement(JTokenType.Integer); + _writer.WriteValue(value); + _writer.WriteEndElement(); + } + + public override void WriteValue(long value) + { + base.WriteValue(value); + + WriteValueElement(JTokenType.Integer); + _writer.WriteValue(value); + _writer.WriteEndElement(); + } + + public override void WriteValue(short value) + { + base.WriteValue(value); + + WriteValueElement(JTokenType.Integer); + _writer.WriteValue(value); + _writer.WriteEndElement(); + } + + public override void WriteValue(byte value) + { + base.WriteValue(value); + + WriteValueElement(JTokenType.Integer); + _writer.WriteValue(value); + _writer.WriteEndElement(); + } + + public override void WriteValue(bool value) + { + base.WriteValue(value); + + WriteValueElement(JTokenType.Boolean); + _writer.WriteValue(value); + _writer.WriteEndElement(); + } + + public override void WriteValue(char value) + { + base.WriteValue(value); + + WriteValueElement(JTokenType.String); + _writer.WriteValue(value.ToString(CultureInfo.InvariantCulture)); + _writer.WriteEndElement(); + } + + public override void WriteValue(decimal value) + { + base.WriteValue(value); + + WriteValueElement(JTokenType.Float); + _writer.WriteValue(value); + _writer.WriteEndElement(); + } + + public override void WriteValue(double value) + { + base.WriteValue(value); + + WriteValueElement(JTokenType.Float); + _writer.WriteValue(value); + _writer.WriteEndElement(); + } + + public override void WriteValue(float value) + { + base.WriteValue(value); + + WriteValueElement(JTokenType.Float); + _writer.WriteValue(value); + _writer.WriteEndElement(); + } + + private void WriteValueElement(JTokenType type) + { + if (_propertyName != null) + { + WriteValueElement(_propertyName, type); + _propertyName = null; + } + else + { + WriteValueElement("Item", type); + } + } + + private void WriteValueElement(string elementName, JTokenType type) + { + _writer.WriteStartElement(elementName); + _writer.WriteAttributeString("type", type.ToString()); + } + + public override void WriteStartArray() + { + bool isStart = (WriteState == WriteState.Start); + + base.WriteStartArray(); + + if (isStart) + WriteValueElement("Root", JTokenType.Array); + else + WriteValueElement(JTokenType.Array); + } + + public override void WriteStartObject() + { + bool isStart = (WriteState == WriteState.Start); + + base.WriteStartObject(); + + if (isStart) + WriteValueElement("Root", JTokenType.Object); + else + WriteValueElement(JTokenType.Object); + } + + public override void WriteStartConstructor(string name) + { + bool isStart = (WriteState == WriteState.Start); + + base.WriteStartConstructor(name); + + if (isStart) + WriteValueElement("Root", JTokenType.Constructor); + else + WriteValueElement(JTokenType.Constructor); + + _writer.WriteAttributeString("name", name); + } + + public override void WriteEndArray() + { + base.WriteEndArray(); + _writer.WriteEndElement(); + } + + public override void WriteEndObject() + { + base.WriteEndObject(); + _writer.WriteEndElement(); + } + + public override void WriteEndConstructor() + { + base.WriteEndConstructor(); + _writer.WriteEndElement(); + } + + public override void Flush() + { + _writer.Flush(); + } + + protected override void WriteIndent() + { + _writer.WriteWhitespace(Environment.NewLine); + + // levels of indentation multiplied by the indent count + int currentIndentCount = Top * 2; + + while (currentIndentCount > 0) + { + // write up to a max of 10 characters at once to avoid creating too many new strings + int writeCount = Math.Min(currentIndentCount, 10); + + _writer.WriteWhitespace(new string(' ', writeCount)); + + currentIndentCount -= writeCount; + } + } + } + + public class CustomJsonWriter + { + public void Example() + { + StringWriter sw = new StringWriter(); + + using (XmlWriter xmlWriter = XmlWriter.Create(sw, new XmlWriterSettings { OmitXmlDeclaration = true })) + using (XmlJsonWriter writer = new XmlJsonWriter(xmlWriter)) + { + writer.Formatting = Formatting.Indented; + + writer.WriteStartObject(); + + writer.WritePropertyName("Null"); + writer.WriteNull(); + + writer.WritePropertyName("String"); + writer.WriteValue("This is a string!"); + + writer.WritePropertyName("Char"); + writer.WriteValue('!'); + + writer.WritePropertyName("Integer"); + writer.WriteValue(123); + + writer.WritePropertyName("DateTime"); + writer.WriteValue(new DateTime(2001, 2, 22, 20, 59, 59, DateTimeKind.Utc)); + + writer.WritePropertyName("DateTimeOffset"); + writer.WriteValue(new DateTimeOffset(2001, 2, 22, 20, 59, 59, TimeSpan.FromHours(12))); + + writer.WritePropertyName("Float"); + writer.WriteValue(1.1f); + + writer.WritePropertyName("Double"); + writer.WriteValue(3.14d); + + writer.WritePropertyName("Decimal"); + writer.WriteValue(19.95m); + + writer.WritePropertyName("Guid"); + writer.WriteValue(Guid.NewGuid()); + + writer.WritePropertyName("Uri"); + writer.WriteValue(new Uri("http://james.newtonking.com")); + + writer.WritePropertyName("Array"); + writer.WriteStartArray(); + writer.WriteValue(1); + writer.WriteValue(2); + writer.WriteValue(3); + writer.WriteEndArray(); + + writer.WritePropertyName("Object"); + writer.WriteStartObject(); + writer.WritePropertyName("String"); + writer.WriteValue("This is a string!"); + writer.WritePropertyName("Null"); + writer.WriteNull(); + writer.WriteEndObject(); + + writer.WritePropertyName("Constructor"); + writer.WriteStartConstructor("Date"); + writer.WriteValue(2000); + writer.WriteValue(12); + writer.WriteValue(30); + writer.WriteEndConstructor(); + + writer.WriteEndObject(); + + writer.Flush(); + } + + Console.WriteLine(sw.ToString()); + + // + // + // This is a string! + // ! + // 123 + // 2001-02-22T20:59:59Z + // 2001-02-22T20:59:59+12:00 + // 1.1 + // 3.14 + // 19.95 + // d66eab59-3715-4b35-9e06-fa61c1216eaa + // http://james.newtonking.com + // + // 1 + // 2 + // 3 + // + // + // This is a string! + // + // + // + // 2000 + // 12 + // 30 + // + // + } + } +} \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs b/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs index afa3071f..580a7a9f 100644 --- a/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs +++ b/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs @@ -48,6 +48,19 @@ namespace Newtonsoft.Json.Tests [TestFixture] public class JsonTextReaderTest : TestFixtureBase { + [Test] + public void ReadSingleQuoteInsideDoubleQuoteString() + { + string json = @"{""NameOfStore"":""Forest's Bakery And Cafe""}"; + + JsonTextReader jsonTextReader = new JsonTextReader(new StringReader(json)); + jsonTextReader.Read(); + jsonTextReader.Read(); + jsonTextReader.Read(); + + Assert.AreEqual(@"Forest's Bakery And Cafe", jsonTextReader.Value); + } + [Test] public void ReadMultilineString() { diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj index e22624f8..f6263a68 100644 --- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj +++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj @@ -90,7 +90,9 @@ + + @@ -484,6 +486,9 @@ Always + + PreserveNewest + diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs index 68c52478..8911670b 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs @@ -7466,6 +7466,44 @@ Parameter name: value", } #endif + [Serializable] + [DataContract] + public struct Pair + { + public Pair(TFirst first, TSecond second) + : this() + { + this.First = first; + this.Second = second; + } + + [DataMember] + public TFirst First { get; set; } + + [DataMember] + public TSecond Second { get; set; } + } + + [Test] + public void SerializeStructWithSerializableAndDataContract() + { + Pair p = new Pair("One", 2); + + DefaultContractResolver r = new DefaultContractResolver(); + r.IgnoreSerializableAttribute = false; + + string json = JsonConvert.SerializeObject(p, new JsonSerializerSettings + { + ContractResolver = r + }); + + Assert.AreEqual(@"{""First"":""One"",""Second"":2}", json); + + json = JsonConvert.SerializeObject(p); + + Assert.AreEqual(@"{""First"":""One"",""Second"":2}", json); + } + [Test] public void ReadStringFloatingPointSymbols() { diff --git a/Src/Newtonsoft.Json.Tests/SpaceShipV2.baemf b/Src/Newtonsoft.Json.Tests/SpaceShipV2.baemf new file mode 100644 index 00000000..6c3e64e8 Binary files /dev/null and b/Src/Newtonsoft.Json.Tests/SpaceShipV2.baemf differ