From 7fc785c1d463c4424cf3e3c8d7fbe796e0197b70 Mon Sep 17 00:00:00 2001 From: csharptest Date: Fri, 10 Jun 2011 23:54:53 -0500 Subject: Reader/Writer implementations changed to use static factories --- src/ProtoBench/Program.cs | 49 +++-- src/ProtoBench/ProtoBench.csproj | 24 +-- .../CompatTests/CompatibilityTests.cs | 112 ++++++++++++ .../CompatTests/JsonCompatibilityTests.cs | 4 +- .../CompatTests/XmlCompatibilityTests.cs | 4 +- src/ProtocolBuffers.Test/TestWriterFormatJson.cs | 32 ++-- src/ProtocolBuffers.Test/TestWriterFormatXml.cs | 66 ++++--- .../Serialization/DictionaryReader.cs | 15 +- .../Serialization/JsonFormatReader.cs | 48 +++-- .../Serialization/JsonFormatWriter.cs | 202 +++++++++++++++------ .../Serialization/JsonTextCursor.cs | 133 ++++++++++---- .../Serialization/XmlFormatReader.cs | 22 ++- .../Serialization/XmlFormatWriter.cs | 21 ++- 13 files changed, 525 insertions(+), 207 deletions(-) (limited to 'src') diff --git a/src/ProtoBench/Program.cs b/src/ProtoBench/Program.cs index ec051310..23af195c 100644 --- a/src/ProtoBench/Program.cs +++ b/src/ProtoBench/Program.cs @@ -131,30 +131,40 @@ namespace Google.ProtocolBuffers.ProtoBench MemoryStream inputStream = new MemoryStream(inputData); ByteString inputString = ByteString.CopyFrom(inputData); IMessage sampleMessage = defaultMessage.WeakCreateBuilderForType().WeakMergeFrom(inputString, registry).WeakBuild(); - - StringWriter temp = new StringWriter(); - new XmlFormatWriter(temp).WriteMessage(sampleMessage); - string xmlMessageText = temp.ToString(); - temp = new StringWriter(); - new JsonFormatWriter(temp).WriteMessage(sampleMessage); - string jsonMessageText = temp.ToString(); - byte[] jsonBytes /*no pun intended*/ = Encoding.UTF8.GetBytes(jsonMessageText); + byte[] jsonBytes, xmlBytes;/*no pun intended, well... maybe for xml*/ + using (MemoryStream temp = new MemoryStream()) + { + XmlFormatWriter.CreateInstance(temp).WriteMessage(sampleMessage); + xmlBytes = temp.ToArray(); + } + using (MemoryStream temp = new MemoryStream()) + { + JsonFormatWriter.CreateInstance(temp).WriteMessage(sampleMessage); + jsonBytes = temp.ToArray(); + } IDictionary dictionary = new Dictionary(StringComparer.Ordinal); new DictionaryWriter(dictionary).WriteMessage(sampleMessage); - //Serializers if(!FastTest) RunBenchmark("Serialize to byte string", inputData.Length, () => sampleMessage.ToByteString()); RunBenchmark("Serialize to byte array", inputData.Length, () => sampleMessage.ToByteArray()); if (!FastTest) RunBenchmark("Serialize to memory stream", inputData.Length, () => sampleMessage.WriteTo(new MemoryStream())); - RunBenchmark("Serialize to xml", xmlMessageText.Length, () => new XmlFormatWriter(new StringWriter()).WriteMessage(sampleMessage)); - RunBenchmark("Serialize to json", jsonMessageText.Length, () => new JsonFormatWriter(new StringWriter()).WriteMessage(sampleMessage)); - RunBenchmark("Serialize to json via xml", jsonMessageText.Length, - () => new XmlFormatWriter(JsonReaderWriterFactory.CreateJsonWriter(new MemoryStream(), Encoding.UTF8)) - { Options = XmlWriterOptions.OutputJsonTypes }.WriteMessage(sampleMessage) + RunBenchmark("Serialize to xml", xmlBytes.Length, () => + { + XmlFormatWriter.CreateInstance(new MemoryStream(), Encoding.UTF8).WriteMessage(sampleMessage); + } ); + RunBenchmark("Serialize to json", jsonBytes.Length, () => + { + JsonFormatWriter.CreateInstance(new MemoryStream()).WriteMessage(sampleMessage); + }); + RunBenchmark("Serialize to json via xml", jsonBytes.Length, + () => + XmlFormatWriter.CreateInstance(JsonReaderWriterFactory.CreateJsonWriter(new MemoryStream(), Encoding.UTF8)) + .SetOptions(XmlWriterOptions.OutputJsonTypes) + .WriteMessage(sampleMessage) ); RunBenchmark("Serialize to dictionary", sampleMessage.SerializedSize, () => new DictionaryWriter().WriteMessage(sampleMessage)); @@ -179,12 +189,11 @@ namespace Google.ProtocolBuffers.ProtoBench .WeakBuild(); }); - RunBenchmark("Deserialize from xml", xmlMessageText.Length, () => new XmlFormatReader(xmlMessageText).Merge(defaultMessage.WeakCreateBuilderForType()).WeakBuild()); - RunBenchmark("Deserialize from json", jsonMessageText.Length, () => new JsonFormatReader(jsonMessageText).Merge(defaultMessage.WeakCreateBuilderForType()).WeakBuild()); - RunBenchmark("Deserialize from json via xml", jsonMessageText.Length, - () => new XmlFormatReader(JsonReaderWriterFactory.CreateJsonReader(jsonBytes, System.Xml.XmlDictionaryReaderQuotas.Max)) - { Options = XmlReaderOptions.ReadNestedArrays } - .Merge(defaultMessage.WeakCreateBuilderForType()).WeakBuild()); + RunBenchmark("Deserialize from xml", xmlBytes.Length, () => XmlFormatReader.CreateInstance(xmlBytes).Merge(defaultMessage.WeakCreateBuilderForType()).WeakBuild()); + RunBenchmark("Deserialize from json", jsonBytes.Length, () => JsonFormatReader.CreateInstance(jsonBytes).Merge(defaultMessage.WeakCreateBuilderForType()).WeakBuild()); + RunBenchmark("Deserialize from json via xml", jsonBytes.Length, + () => XmlFormatReader.CreateInstance(JsonReaderWriterFactory.CreateJsonReader(jsonBytes, System.Xml.XmlDictionaryReaderQuotas.Max)) + .SetOptions(XmlReaderOptions.ReadNestedArrays).Merge(defaultMessage.WeakCreateBuilderForType()).WeakBuild()); RunBenchmark("Deserialize from dictionary", sampleMessage.SerializedSize, () => new DictionaryReader(dictionary).Merge(defaultMessage.WeakCreateBuilderForType()).WeakBuild()); diff --git a/src/ProtoBench/ProtoBench.csproj b/src/ProtoBench/ProtoBench.csproj index b1d676af..7722f8d2 100644 --- a/src/ProtoBench/ProtoBench.csproj +++ b/src/ProtoBench/ProtoBench.csproj @@ -56,15 +56,9 @@ - - 3.0 - - - 3.0 - - - 3.5 - + + + @@ -105,11 +99,11 @@ - \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/CompatTests/CompatibilityTests.cs b/src/ProtocolBuffers.Test/CompatTests/CompatibilityTests.cs index 0306c41e..b54900bb 100644 --- a/src/ProtocolBuffers.Test/CompatTests/CompatibilityTests.cs +++ b/src/ProtocolBuffers.Test/CompatTests/CompatibilityTests.cs @@ -71,5 +71,117 @@ namespace Google.ProtocolBuffers.CompatTests Assert.AreEqual(TestResources.google_message2, copy.ToByteArray()); } + #region Test message builders + + private static TestAllTypes.Builder AddAllTypes(TestAllTypes.Builder builder) + { + return builder.SetOptionalInt32(1001) + .SetOptionalInt64(1001) + .SetOptionalUint32(1001) + .SetOptionalUint64(1001) + .SetOptionalSint32(-1001) + .SetOptionalSint64(-1001) + .SetOptionalFixed32(1001) + .SetOptionalFixed64(1001) + .SetOptionalSfixed32(-1001) + .SetOptionalSfixed64(-1001) + .SetOptionalFloat(1001.1001f) + .SetOptionalDouble(1001.1001) + .SetOptionalBool(true) + .SetOptionalString("this is a string value") + .SetOptionalBytes(ByteString.CopyFromUtf8("this is an array of bytes")) + .SetOptionalGroup(new TestAllTypes.Types.OptionalGroup.Builder().SetA(1001)) + .SetOptionalNestedMessage(new TestAllTypes.Types.NestedMessage.Builder().SetBb(1001)) + .SetOptionalNestedEnum(TestAllTypes.Types.NestedEnum.FOO) + ; + } + + private static TestAllTypes.Builder AddRepeatedTypes(TestAllTypes.Builder builder, int size) + { + //repeated values + for (int i = 0; i < size; i++) + builder.AddRepeatedInt32(1001 + i) + .AddRepeatedInt64(1001) + .AddRepeatedUint32(1001) + .AddRepeatedUint64(1001) + .AddRepeatedSint32(-1001) + .AddRepeatedSint64(-1001) + .AddRepeatedFixed32(1001) + .AddRepeatedFixed64(1001) + .AddRepeatedSfixed32(-1001) + .AddRepeatedSfixed64(-1001) + .AddRepeatedFloat(1001.1001f) + .AddRepeatedDouble(1001.1001) + .AddRepeatedBool(true) + .AddRepeatedString("this is a string value") + .AddRepeatedBytes(ByteString.CopyFromUtf8("this is an array of bytes")) + .AddRepeatedGroup(new TestAllTypes.Types.RepeatedGroup.Builder().SetA(1001)) + .AddRepeatedNestedMessage(new TestAllTypes.Types.NestedMessage.Builder().SetBb(1001)) + .AddRepeatedNestedEnum(TestAllTypes.Types.NestedEnum.FOO) + ; + return builder; + } + + private static TestPackedTypes.Builder AddPackedTypes(TestPackedTypes.Builder builder, int size) + { + for(int i=0; i < size; i++ ) + builder.AddPackedInt32(1001) + .AddPackedInt64(1001) + .AddPackedUint32(1001) + .AddPackedUint64(1001) + .AddPackedSint32(-1001) + .AddPackedSint64(-1001) + .AddPackedFixed32(1001) + .AddPackedFixed64(1001) + .AddPackedSfixed32(-1001) + .AddPackedSfixed64(-1001) + .AddPackedFloat(1001.1001f) + .AddPackedDouble(1001.1001) + .AddPackedBool(true) + .AddPackedEnum(ForeignEnum.FOREIGN_FOO) + ; + return builder; + } + + #endregion + + [Test] + public void TestRoundTripAllTypes() + { + TestAllTypes msg = AddAllTypes(new TestAllTypes.Builder()).Build(); + object content = SerializeMessage(msg); + + TestAllTypes copy = DeerializeMessage(content, TestAllTypes.CreateBuilder(), ExtensionRegistry.Empty).Build(); + + Assert.AreEqual(msg, copy); + AssertOutputEquals(content, SerializeMessage(copy)); + Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); + } + + [Test] + public void TestRoundTripRepeatedTypes() + { + TestAllTypes msg = AddRepeatedTypes(new TestAllTypes.Builder(), 5).Build(); + object content = SerializeMessage(msg); + + TestAllTypes copy = DeerializeMessage(content, TestAllTypes.CreateBuilder(), ExtensionRegistry.Empty).Build(); + + Assert.AreEqual(msg, copy); + AssertOutputEquals(content, SerializeMessage(copy)); + Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); + } + + [Test] + public void TestRoundTripPackedTypes() + { + TestPackedTypes msg = AddPackedTypes(new TestPackedTypes.Builder(), 5).Build(); + object content = SerializeMessage(msg); + + TestPackedTypes copy = DeerializeMessage(content, TestPackedTypes.CreateBuilder(), ExtensionRegistry.Empty).Build(); + + Assert.AreEqual(msg, copy); + AssertOutputEquals(content, SerializeMessage(copy)); + Assert.AreEqual(msg.ToByteArray(), copy.ToByteArray()); + } } } diff --git a/src/ProtocolBuffers.Test/CompatTests/JsonCompatibilityTests.cs b/src/ProtocolBuffers.Test/CompatTests/JsonCompatibilityTests.cs index 30a08398..23fa2638 100644 --- a/src/ProtocolBuffers.Test/CompatTests/JsonCompatibilityTests.cs +++ b/src/ProtocolBuffers.Test/CompatTests/JsonCompatibilityTests.cs @@ -11,7 +11,7 @@ namespace Google.ProtocolBuffers.CompatTests protected override object SerializeMessage(TMessage message) { StringWriter sw = new StringWriter(); - new JsonFormatWriter(sw) + JsonFormatWriter.CreateInstance(sw) .Formatted() .WriteMessage(message); return sw.ToString(); @@ -19,7 +19,7 @@ namespace Google.ProtocolBuffers.CompatTests protected override TBuilder DeerializeMessage(object message, TBuilder builder, ExtensionRegistry registry) { - new JsonFormatReader((string)message).Merge(builder); + JsonFormatReader.CreateInstance((string)message).Merge(builder); return builder; } } diff --git a/src/ProtocolBuffers.Test/CompatTests/XmlCompatibilityTests.cs b/src/ProtocolBuffers.Test/CompatTests/XmlCompatibilityTests.cs index e204200d..14616b74 100644 --- a/src/ProtocolBuffers.Test/CompatTests/XmlCompatibilityTests.cs +++ b/src/ProtocolBuffers.Test/CompatTests/XmlCompatibilityTests.cs @@ -10,14 +10,14 @@ namespace Google.ProtocolBuffers.CompatTests protected override object SerializeMessage(TMessage message) { StringWriter text = new StringWriter(); - XmlFormatWriter writer = new XmlFormatWriter(text); + XmlFormatWriter writer = XmlFormatWriter.CreateInstance(text); writer.WriteMessage("root", message); return text.ToString(); } protected override TBuilder DeerializeMessage(object message, TBuilder builder, ExtensionRegistry registry) { - XmlFormatReader reader = new XmlFormatReader((string)message); + XmlFormatReader reader = XmlFormatReader.CreateInstance((string)message); return reader.Merge("root", builder, registry); } } diff --git a/src/ProtocolBuffers.Test/TestWriterFormatJson.cs b/src/ProtocolBuffers.Test/TestWriterFormatJson.cs index 1c95d841..88c059d2 100644 --- a/src/ProtocolBuffers.Test/TestWriterFormatJson.cs +++ b/src/ProtocolBuffers.Test/TestWriterFormatJson.cs @@ -14,7 +14,7 @@ namespace Google.ProtocolBuffers protected void FormatterAssert(TMessage message, params string[] expecting) where TMessage : IMessageLite { StringWriter sw = new StringWriter(); - new JsonFormatWriter(sw).WriteMessage(message); + JsonFormatWriter.CreateInstance(sw).WriteMessage(message); Content = sw.ToString(); @@ -22,7 +22,7 @@ namespace Google.ProtocolBuffers UnitTestXmlSerializerTestProtoFile.RegisterAllExtensions(registry); IMessageLite copy = - new JsonFormatReader(Content) + JsonFormatReader.CreateInstance(Content) .Merge(message.WeakCreateBuilderForType(), registry).WeakBuild(); Assert.AreEqual(typeof(TMessage), copy.GetType()); @@ -44,12 +44,12 @@ namespace Google.ProtocolBuffers .Build(); StringWriter sw = new StringWriter(); - new JsonFormatWriter(sw).Formatted() + JsonFormatWriter.CreateInstance(sw).Formatted() .WriteMessage(message); string json = sw.ToString(); - TestXmlMessage copy = new JsonFormatReader(json) + TestXmlMessage copy = JsonFormatReader.CreateInstance(json) .Merge(TestXmlMessage.CreateBuilder()).Build(); Assert.AreEqual(message, copy); } @@ -240,11 +240,11 @@ namespace Google.ProtocolBuffers .ClearExtension(UnitTestXmlSerializerTestProtoFile.ExtensionEnum) .Build(); - JsonFormatWriter writer = new JsonFormatWriter(); + JsonFormatWriter writer = JsonFormatWriter.CreateInstance(); writer.WriteMessage(original); Content = writer.ToString(); - IMessageLite copy = new JsonFormatReader(Content) + IMessageLite copy = JsonFormatReader.CreateInstance(Content) .Merge(message.CreateBuilderForType()).Build(); Assert.AreNotEqual(original, message); @@ -255,8 +255,8 @@ namespace Google.ProtocolBuffers public void TestMergeFields() { TestXmlMessage.Builder builder = TestXmlMessage.CreateBuilder(); - builder.MergeFrom(new JsonFormatReader("\"valid\": true")); - builder.MergeFrom(new JsonFormatReader("\"text\": \"text\", \"number\": \"411\"")); + builder.MergeFrom(JsonFormatReader.CreateInstance("\"valid\": true")); + builder.MergeFrom(JsonFormatReader.CreateInstance("\"text\": \"text\", \"number\": \"411\"")); Assert.AreEqual(true, builder.Valid); Assert.AreEqual("text", builder.Text); Assert.AreEqual(411, builder.Number); @@ -264,7 +264,7 @@ namespace Google.ProtocolBuffers [Test] public void TestMessageArray() { - JsonFormatWriter writer = new JsonFormatWriter().Formatted(); + JsonFormatWriter writer = JsonFormatWriter.CreateInstance().Formatted(); using (writer.StartArray()) { writer.WriteMessage(TestXmlMessage.CreateBuilder().SetNumber(1).AddTextlines("a").Build()); @@ -272,7 +272,7 @@ namespace Google.ProtocolBuffers writer.WriteMessage(TestXmlMessage.CreateBuilder().SetNumber(3).AddTextlines("c").Build()); } string json = writer.ToString(); - JsonFormatReader reader = new JsonFormatReader(json); + JsonFormatReader reader = JsonFormatReader.CreateInstance(json); TestXmlMessage.Builder builder = TestXmlMessage.CreateBuilder(); int ordinal = 0; @@ -288,7 +288,7 @@ namespace Google.ProtocolBuffers [Test] public void TestNestedMessageArray() { - JsonFormatWriter writer = new JsonFormatWriter(); + JsonFormatWriter writer = JsonFormatWriter.CreateInstance(); using (writer.StartArray()) { using (writer.StartArray()) @@ -300,7 +300,7 @@ namespace Google.ProtocolBuffers writer.WriteMessage(TestXmlMessage.CreateBuilder().SetNumber(3).AddTextlines("c").Build()); } string json = writer.ToString(); - JsonFormatReader reader = new JsonFormatReader(json); + JsonFormatReader reader = JsonFormatReader.CreateInstance(json); TestXmlMessage.Builder builder = TestXmlMessage.CreateBuilder(); int ordinal = 0; @@ -317,25 +317,25 @@ namespace Google.ProtocolBuffers [Test, ExpectedException(typeof(FormatException))] public void FailWithEmptyText() { - new JsonFormatReader("") + JsonFormatReader.CreateInstance("") .Merge(TestXmlMessage.CreateBuilder()); } [Test, ExpectedException(typeof(FormatException))] public void FailWithUnexpectedValue() { - new JsonFormatReader("{{}}") + JsonFormatReader.CreateInstance("{{}}") .Merge(TestXmlMessage.CreateBuilder()); } [Test, ExpectedException(typeof(FormatException))] public void FailWithUnQuotedName() { - new JsonFormatReader("{name:{}}") + JsonFormatReader.CreateInstance("{name:{}}") .Merge(TestXmlMessage.CreateBuilder()); } [Test, ExpectedException(typeof(FormatException))] public void FailWithUnexpectedType() { - new JsonFormatReader("{\"valid\":{}}") + JsonFormatReader.CreateInstance("{\"valid\":{}}") .Merge(TestXmlMessage.CreateBuilder()); } } diff --git a/src/ProtocolBuffers.Test/TestWriterFormatXml.cs b/src/ProtocolBuffers.Test/TestWriterFormatXml.cs index a2def5e0..2ddf39e5 100644 --- a/src/ProtocolBuffers.Test/TestWriterFormatXml.cs +++ b/src/ProtocolBuffers.Test/TestWriterFormatXml.cs @@ -23,12 +23,12 @@ namespace Google.ProtocolBuffers //When we call message.WriteTo, we are responsible for the root element xw.WriteStartElement("root"); - message.WriteTo(new XmlFormatWriter(xw)); + message.WriteTo(XmlFormatWriter.CreateInstance(xw)); xw.WriteEndElement(); xw.Flush(); string xml = sw.ToString(); - XmlFormatReader rdr = new XmlFormatReader(xml); + XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); TestXmlChild copy = rdr.Merge(TestXmlChild.CreateBuilder()).Build(); Assert.AreEqual(message, copy); } @@ -42,10 +42,10 @@ namespace Google.ProtocolBuffers //Allow the writer to write the root element StringWriter sw = new StringWriter(); - new XmlFormatWriter(sw).WriteMessage("root", message); + XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message); string xml = sw.ToString(); - XmlFormatReader rdr = new XmlFormatReader(xml); + XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); TestXmlChild copy = rdr.Merge(TestXmlChild.CreateBuilder()).Build(); Assert.AreEqual(message, copy); } @@ -57,10 +57,10 @@ namespace Google.ProtocolBuffers .Build(); StringWriter sw = new StringWriter(); - new XmlFormatWriter(sw).WriteMessage("root", message); + XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message); string xml = sw.ToString(); - XmlFormatReader rdr = new XmlFormatReader(xml); + XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder()).Build(); Assert.AreEqual(message, copy); } @@ -72,10 +72,10 @@ namespace Google.ProtocolBuffers .Build(); StringWriter sw = new StringWriter(); - new XmlFormatWriter(sw).WriteMessage("root", message); + XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message); string xml = sw.ToString(); - XmlFormatReader rdr = new XmlFormatReader(xml); + XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder()).Build(); Assert.AreEqual(message, copy); } @@ -87,10 +87,10 @@ namespace Google.ProtocolBuffers .Build(); StringWriter sw = new StringWriter(); - new XmlFormatWriter(sw).WriteMessage("root", message); + XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message); string xml = sw.ToString(); - XmlFormatReader rdr = new XmlFormatReader(xml); + XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder()).Build(); Assert.AreEqual(message, copy); } @@ -113,11 +113,11 @@ namespace Google.ProtocolBuffers .Build(); StringWriter sw = new StringWriter(); - new XmlFormatWriter(sw).WriteMessage("root", message); + XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message); string xml = sw.ToString(); - XmlFormatReader rdr = new XmlFormatReader(xml); + XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder()).Build(); Assert.AreEqual(message, copy); } @@ -140,14 +140,13 @@ namespace Google.ProtocolBuffers .Build(); StringWriter sw = new StringWriter(); - new XmlFormatWriter(sw) - { - Options = XmlWriterOptions.OutputNestedArrays | XmlWriterOptions.OutputEnumValues - }.WriteMessage("root", message); + XmlFormatWriter.CreateInstance(sw) + .SetOptions(XmlWriterOptions.OutputNestedArrays | XmlWriterOptions.OutputEnumValues) + .WriteMessage("root", message); string xml = sw.ToString(); - XmlFormatReader rdr = new XmlFormatReader(xml); + XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); rdr.Options = XmlReaderOptions.ReadNestedArrays; TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder()).Build(); Assert.AreEqual(message, copy); @@ -174,10 +173,9 @@ namespace Google.ProtocolBuffers Assert.AreEqual(0, message.AllFields.Count); StringWriter sw = new StringWriter(); - new XmlFormatWriter(sw) - { - Options = XmlWriterOptions.OutputNestedArrays | XmlWriterOptions.OutputEnumValues - }.WriteMessage("root", message); + XmlFormatWriter.CreateInstance(sw) + .SetOptions(XmlWriterOptions.OutputNestedArrays | XmlWriterOptions.OutputEnumValues) + .WriteMessage("root", message); string xml = sw.ToString(); @@ -191,7 +189,7 @@ namespace Google.ProtocolBuffers ); } - XmlFormatReader rdr = new XmlFormatReader(xml); + XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); rdr.Options = XmlReaderOptions.ReadNestedArrays; TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder()).Build(); Assert.AreEqual(TestXmlMessage.DefaultInstance, copy); @@ -203,11 +201,11 @@ namespace Google.ProtocolBuffers .SetText("").Build(); StringWriter sw = new StringWriter(); - new XmlFormatWriter(sw).WriteMessage("root", message); + XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message); string xml = sw.ToString(); - XmlFormatReader rdr = new XmlFormatReader(xml); + XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder()).Build(); Assert.AreEqual(message, copy); } @@ -218,11 +216,11 @@ namespace Google.ProtocolBuffers .SetText(" \t <- leading space and trailing -> \r\n\t").Build(); StringWriter sw = new StringWriter(); - new XmlFormatWriter(sw).WriteMessage("root", message); + XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message); string xml = sw.ToString(); - XmlFormatReader rdr = new XmlFormatReader(xml); + XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder()).Build(); Assert.AreEqual(message, copy); } @@ -234,14 +232,14 @@ namespace Google.ProtocolBuffers .Build(); StringWriter sw = new StringWriter(); - new XmlFormatWriter(sw).WriteMessage("root", message); + XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message); string xml = sw.ToString(); ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); UnitTestXmlSerializerTestProtoFile.RegisterAllExtensions(registry); - XmlFormatReader rdr = new XmlFormatReader(xml); + XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder(), registry).Build(); Assert.AreEqual(message, copy); } @@ -253,14 +251,14 @@ namespace Google.ProtocolBuffers new TestXmlExtension.Builder().SetNumber(42).Build()).Build(); StringWriter sw = new StringWriter(); - new XmlFormatWriter(sw).WriteMessage("root", message); + XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message); string xml = sw.ToString(); ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); UnitTestXmlSerializerTestProtoFile.RegisterAllExtensions(registry); - XmlFormatReader rdr = new XmlFormatReader(xml); + XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder(), registry).Build(); Assert.AreEqual(message, copy); } @@ -274,14 +272,14 @@ namespace Google.ProtocolBuffers .Build(); StringWriter sw = new StringWriter(); - new XmlFormatWriter(sw).WriteMessage("root", message); + XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message); string xml = sw.ToString(); ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); UnitTestXmlSerializerTestProtoFile.RegisterAllExtensions(registry); - XmlFormatReader rdr = new XmlFormatReader(xml); + XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder(), registry).Build(); Assert.AreEqual(message, copy); } @@ -293,14 +291,14 @@ namespace Google.ProtocolBuffers .Build(); StringWriter sw = new StringWriter(); - new XmlFormatWriter(sw).WriteMessage("root", message); + XmlFormatWriter.CreateInstance(sw).WriteMessage("root", message); string xml = sw.ToString(); ExtensionRegistry registry = ExtensionRegistry.CreateInstance(); UnitTestXmlSerializerTestProtoFile.RegisterAllExtensions(registry); - XmlFormatReader rdr = new XmlFormatReader(xml); + XmlFormatReader rdr = XmlFormatReader.CreateInstance(xml); TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder(), registry).Build(); Assert.AreEqual(message, copy); } diff --git a/src/ProtocolBuffers/Serialization/DictionaryReader.cs b/src/ProtocolBuffers/Serialization/DictionaryReader.cs index f8ef1eda..d6e5c189 100644 --- a/src/ProtocolBuffers/Serialization/DictionaryReader.cs +++ b/src/ProtocolBuffers/Serialization/DictionaryReader.cs @@ -64,7 +64,7 @@ namespace Google.ProtocolBuffers.Serialization try { if (obj is IConvertible) - value = (T)Convert.ChangeType(obj, typeof(T)); + value = (T)Convert.ChangeType(obj, typeof(T), System.Globalization.CultureInfo.InvariantCulture); else value = (T)obj; } @@ -186,8 +186,17 @@ namespace Google.ProtocolBuffers.Serialization object[] array = null; if (GetValue(ref array)) { - foreach (T item in array) - items.Add(item); + if (typeof(T) == typeof(ByteString)) + { + ICollection output = (ICollection)items; + foreach (byte[] item in array) + output.Add(ByteString.CopyFrom(item)); + } + else + { + foreach (T item in array) + items.Add(item); + } return true; } return false; diff --git a/src/ProtocolBuffers/Serialization/JsonFormatReader.cs b/src/ProtocolBuffers/Serialization/JsonFormatReader.cs index e9df9138..2808ff5c 100644 --- a/src/ProtocolBuffers/Serialization/JsonFormatReader.cs +++ b/src/ProtocolBuffers/Serialization/JsonFormatReader.cs @@ -10,34 +10,50 @@ namespace Google.ProtocolBuffers.Serialization /// public class JsonFormatReader : AbstractTextReader { - private readonly JsonTextCursor _input; + private readonly JsonCursor _input; private readonly Stack _stopChar; enum ReaderState { Start, BeginValue, EndValue, BeginObject, BeginArray } string _current; ReaderState _state; + /// + /// Constructs a JsonFormatReader to parse Json into a message, this method does not use text encoding, all bytes MUST + /// represent ASCII character values. + /// + public static JsonFormatReader CreateInstance(Stream stream) { return new JsonFormatReader(JsonCursor.CreateInstance(stream)); } + /// + /// Constructs a JsonFormatReader to parse Json into a message, this method does not use text encoding, all bytes MUST + /// represent ASCII character values. + /// + public static JsonFormatReader CreateInstance(byte[] bytes) { return new JsonFormatReader(JsonCursor.CreateInstance(bytes)); } /// /// Constructs a JsonFormatReader to parse Json into a message /// - public JsonFormatReader(string jsonText) - { - _input = new JsonTextCursor(jsonText.ToCharArray()); - _stopChar = new Stack(); - _stopChar.Push(-1); - _state = ReaderState.Start; - } + public static JsonFormatReader CreateInstance(string jsonText) { return new JsonFormatReader(JsonCursor.CreateInstance(jsonText)); } /// /// Constructs a JsonFormatReader to parse Json into a message /// - public JsonFormatReader(TextReader input) + public static JsonFormatReader CreateInstance(TextReader input) { return new JsonFormatReader(JsonCursor.CreateInstance(input)); } + + /// + /// Constructs a JsonFormatReader to parse Json into a message + /// + internal JsonFormatReader(JsonCursor input) { - _input = new JsonTextCursor(input); + _input = input; _stopChar = new Stack(); _stopChar.Push(-1); _state = ReaderState.Start; } + /// + /// Constructs a JsonFormatReader to parse Json into a message + /// + protected JsonFormatReader(TextReader input) + : this(JsonCursor.CreateInstance(input)) + { } + /// /// Returns true if the reader is currently on an array element /// @@ -115,18 +131,18 @@ namespace Google.ProtocolBuffers.Serialization protected override bool ReadAsText(ref string value, Type typeInfo) { object temp; - JsonTextCursor.JsType type = _input.ReadVariant(out temp); + JsonCursor.JsType type = _input.ReadVariant(out temp); _state = ReaderState.EndValue; - _input.Assert(type != JsonTextCursor.JsType.Array && type != JsonTextCursor.JsType.Object, "Encountered {0} while expecting {1}", type, typeInfo); - if (type == JsonTextCursor.JsType.Null) + _input.Assert(type != JsonCursor.JsType.Array && type != JsonCursor.JsType.Object, "Encountered {0} while expecting {1}", type, typeInfo); + if (type == JsonCursor.JsType.Null) return false; - if (type == JsonTextCursor.JsType.True) value = "1"; - else if (type == JsonTextCursor.JsType.False) value = "0"; + if (type == JsonCursor.JsType.True) value = "1"; + else if (type == JsonCursor.JsType.False) value = "0"; else value = temp as string; //exponent representation of integer number: - if (value != null && type == JsonTextCursor.JsType.Number && + if (value != null && type == JsonCursor.JsType.Number && (typeInfo != typeof(double) && typeInfo != typeof(float)) && value.IndexOf("e", StringComparison.OrdinalIgnoreCase) > 0) { diff --git a/src/ProtocolBuffers/Serialization/JsonFormatWriter.cs b/src/ProtocolBuffers/Serialization/JsonFormatWriter.cs index 0baf6cac..b2057524 100644 --- a/src/ProtocolBuffers/Serialization/JsonFormatWriter.cs +++ b/src/ProtocolBuffers/Serialization/JsonFormatWriter.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Text; using Google.ProtocolBuffers.Descriptors; namespace Google.ProtocolBuffers.Serialization @@ -10,81 +11,178 @@ namespace Google.ProtocolBuffers.Serialization /// you may also use the XmlFormatWriter with an XmlWriter created by the /// JsonReaderWriterFactory. /// - public class JsonFormatWriter : AbstractTextWriter + public abstract class JsonFormatWriter : AbstractTextWriter { - private readonly char[] _buffer; - private readonly TextWriter _output; - private readonly List _counter; - private bool _isArray; - int _bufferPos; - /// - /// Constructs a JsonFormatWriter to output to a new instance of a StringWriter, use - /// the ToString() member to extract the final Json on completion. - /// - public JsonFormatWriter() : this(new StringWriter()) { } - /// - /// Constructs a JsonFormatWriter to output to the given text writer - /// - public JsonFormatWriter(TextWriter output) + #region buffering implementations + private class JsonTextWriter : JsonFormatWriter { - _buffer = new char[4096]; - _bufferPos = 0; - _output = output; - _counter = new List(); - _counter.Add(0); - } + private readonly char[] _buffer; + private TextWriter _output; + int _bufferPos; + public JsonTextWriter(TextWriter output) + { + _buffer = new char[4096]; + _bufferPos = 0; + _output = output; + _counter.Add(0); + } - private void WriteToOutput(string format, params object[] args) - { WriteToOutput(String.Format(format, args)); } + /// + /// Returns the output of TextWriter.ToString() where TextWriter is the ctor argument. + /// + public override string ToString() + { + Flush(); - private void WriteToOutput(string text) - { WriteToOutput(text.ToCharArray(), 0, text.Length); } + if (_output != null) + return _output.ToString(); - private void WriteToOutput(char[] chars, int offset, int len) - { - if (_bufferPos + len >= _buffer.Length) - Flush(); - if (len < _buffer.Length) + return new String(_buffer, 0, _bufferPos); + } + + protected override void WriteToOutput(char[] chars, int offset, int len) { - if (len <= 12) + if (_bufferPos + len >= _buffer.Length) + { + if (_output == null) + _output = new StringWriter(new System.Text.StringBuilder(_buffer.Length * 2 + len)); + Flush(); + } + + if (len < _buffer.Length) { - int stop = offset + len; - for (int i = offset; i < stop; i++) - _buffer[_bufferPos++] = chars[i]; + if (len <= 12) + { + int stop = offset + len; + for (int i = offset; i < stop; i++) + _buffer[_bufferPos++] = chars[i]; + } + else + { + Buffer.BlockCopy(chars, offset << 1, _buffer, _bufferPos << 1, len << 1); + _bufferPos += len; + } } else + _output.Write(chars, offset, len); + } + + protected override void WriteToOutput(char ch) + { + if (_bufferPos >= _buffer.Length) + Flush(); + _buffer[_bufferPos++] = ch; + } + + public override void Flush() + { + if (_bufferPos > 0 && _output != null) { - Buffer.BlockCopy(chars, offset << 1, _buffer, _bufferPos << 1, len << 1); - _bufferPos += len; + _output.Write(_buffer, 0, _bufferPos); + _bufferPos = 0; } + base.Flush(); } - else - _output.Write(chars, offset, len); } - - private void WriteToOutput(char ch) + private class JsonStreamWriter : JsonFormatWriter { - if (_bufferPos >= _buffer.Length) - Flush(); - _buffer[_bufferPos++] = ch; - } +#if SILVERLIGHT2 || COMPACT_FRAMEWORK_35 + static readonly Encoding Encoding = Encoding.UTF8; +#else + static readonly Encoding Encoding = Encoding.ASCII; +#endif + private readonly byte[] _buffer; + private Stream _output; + int _bufferPos; - public override void Flush() - { - if (_bufferPos > 0) + public JsonStreamWriter(Stream output) { - _output.Write(_buffer, 0, _bufferPos); + _buffer = new byte[8192]; _bufferPos = 0; + _output = output; + _counter.Add(0); + } + + protected override void WriteToOutput(char[] chars, int offset, int len) + { + if (_bufferPos + len >= _buffer.Length) + Flush(); + + if (len < _buffer.Length) + { + if (len <= 12) + { + int stop = offset + len; + for (int i = offset; i < stop; i++) + _buffer[_bufferPos++] = (byte)chars[i]; + } + else + { + _bufferPos += Encoding.GetBytes(chars, offset, len, _buffer, _bufferPos); + } + } + else + { + byte[] temp = Encoding.GetBytes(chars, offset, len); + _output.Write(temp, 0, temp.Length); + } + } + + protected override void WriteToOutput(char ch) + { + if (_bufferPos >= _buffer.Length) + Flush(); + _buffer[_bufferPos++] = (byte)ch; } - base.Flush(); + + public override void Flush() + { + if (_bufferPos > 0 && _output != null) + { + _output.Write(_buffer, 0, _bufferPos); + _bufferPos = 0; + } + base.Flush(); + } + } + #endregion + + private readonly List _counter; + private bool _isArray; + /// + /// Constructs a JsonFormatWriter, use the ToString() member to extract the final Json on completion. + /// + protected JsonFormatWriter() + { + _counter = new List(); } /// - /// Returns the output of TextWriter.ToString() where TextWriter is the ctor argument. + /// Constructs a JsonFormatWriter, use ToString() to extract the final output /// - public override string ToString() - { Flush(); return _output.ToString(); } + public static JsonFormatWriter CreateInstance() { return new JsonTextWriter(null); } + + /// + /// Constructs a JsonFormatWriter to output to the given text writer + /// + public static JsonFormatWriter CreateInstance(TextWriter output) { return new JsonTextWriter(output); } + + /// + /// Constructs a JsonFormatWriter to output to the given stream + /// + public static JsonFormatWriter CreateInstance(Stream output) { return new JsonStreamWriter(output); } + + /// Write to the output stream + protected void WriteToOutput(string format, params object[] args) + { WriteToOutput(String.Format(format, args)); } + /// Write to the output stream + protected void WriteToOutput(string text) + { WriteToOutput(text.ToCharArray(), 0, text.Length); } + /// Write to the output stream + protected abstract void WriteToOutput(char ch); + /// Write to the output stream + protected abstract void WriteToOutput(char[] chars, int offset, int len); /// Sets the output formatting to use Environment.NewLine with 4-character indentions public JsonFormatWriter Formatted() diff --git a/src/ProtocolBuffers/Serialization/JsonTextCursor.cs b/src/ProtocolBuffers/Serialization/JsonTextCursor.cs index 6a8652c8..a0b468f6 100644 --- a/src/ProtocolBuffers/Serialization/JsonTextCursor.cs +++ b/src/ProtocolBuffers/Serialization/JsonTextCursor.cs @@ -9,52 +9,115 @@ namespace Google.ProtocolBuffers.Serialization /// /// JSon Tokenizer used by JsonFormatReader /// - class JsonTextCursor + abstract class JsonCursor { public enum JsType { String, Number, Object, Array, True, False, Null } - private readonly char[] _buffer; - private int _bufferPos; - private readonly TextReader _input; - private int _lineNo, _linePos; - - public JsonTextCursor(char[] input) + #region Buffering implementations + class JsonStreamCursor : JsonCursor { - _input = null; - _buffer = input; - _bufferPos = 0; - _next = Peek(); - _lineNo = 1; - } + private readonly byte[] _buffer; + private int _bufferPos; + private readonly Stream _input; - public JsonTextCursor(TextReader input) - { - _input = input; - _next = Peek(); - _lineNo = 1; + public JsonStreamCursor(Stream input) + { + _input = input; + _next = _input.ReadByte(); + } + public JsonStreamCursor(byte[] input) + { + _input = null; + _buffer = input; + _next = _buffer[_bufferPos]; + } + + protected override int Peek() + { + if (_input != null) + return _next; + else if (_bufferPos < _buffer.Length) + return _buffer[_bufferPos]; + else + return -1; + } + + protected override int Read() + { + if (_input != null) + { + int result = _next; + _next = _input.ReadByte(); + return result; + } + else if (_bufferPos < _buffer.Length) + return _buffer[_bufferPos++]; + else + return -1; + } } - private int Peek() + class JsonTextCursor : JsonCursor { - if (_input != null) - return _input.Peek(); - else if (_bufferPos < _buffer.Length) - return _buffer[_bufferPos]; - else - return -1; + private readonly char[] _buffer; + private int _bufferPos; + private readonly TextReader _input; + + public JsonTextCursor(char[] input) + { + _input = null; + _buffer = input; + _bufferPos = 0; + _next = Peek(); + } + + public JsonTextCursor(TextReader input) + { + _input = input; + _next = Peek(); + } + + protected override int Peek() + { + if (_input != null) + return _input.Peek(); + else if (_bufferPos < _buffer.Length) + return _buffer[_bufferPos]; + else + return -1; + } + + protected override int Read() + { + if (_input != null) + return _input.Read(); + else if (_bufferPos < _buffer.Length) + return _buffer[_bufferPos++]; + else + return -1; + } } + #endregion + + protected int _next; + private int _lineNo, _linePos; - private int Read() + public static JsonCursor CreateInstance(byte[] input) { return new JsonStreamCursor(input); } + public static JsonCursor CreateInstance(Stream input) { return new JsonStreamCursor(input); } + public static JsonCursor CreateInstance(string input) { return new JsonTextCursor(input.ToCharArray()); } + public static JsonCursor CreateInstance(TextReader input) { return new JsonTextCursor(input); } + + protected JsonCursor() { - if (_input != null) - return _input.Read(); - else if (_bufferPos < _buffer.Length) - return _buffer[_bufferPos++]; - else - return -1; + _lineNo = 1; + _linePos = 0; } + + /// Returns the next character without actually 'reading' it + protected abstract int Peek(); + /// Reads the next character in the input + protected abstract int Read(); - int _next; public Char NextChar { get { SkipWhitespace(); return (char)_next; } } #region Assert(...) @@ -62,8 +125,8 @@ namespace Google.ProtocolBuffers.Serialization private string CharDisplay(int ch) { return ch == -1 ? "EOF" : - (ch > 32 && ch < 127) ? String.Format("'{0}'", (char)ch) : - String.Format("'\\u{0:x4}'", ch); + (ch > 32 && ch < 127) ? String.Format("'{0}'", (char)ch) : + String.Format("'\\u{0:x4}'", ch); } [System.Diagnostics.DebuggerNonUserCode] private void Assert(bool cond, char expected) diff --git a/src/ProtocolBuffers/Serialization/XmlFormatReader.cs b/src/ProtocolBuffers/Serialization/XmlFormatReader.cs index 671490e6..241c554a 100644 --- a/src/ProtocolBuffers/Serialization/XmlFormatReader.cs +++ b/src/ProtocolBuffers/Serialization/XmlFormatReader.cs @@ -25,33 +25,41 @@ namespace Google.ProtocolBuffers.Serialization /// /// Constructs the XmlFormatReader using the stream provided as the xml /// - public XmlFormatReader(Stream input) : this(XmlReader.Create(input, DefaultSettings)) { } + public static XmlFormatReader CreateInstance(byte[] input) { return new XmlFormatReader(XmlReader.Create(new MemoryStream(input, false), DefaultSettings)); } + /// + /// Constructs the XmlFormatReader using the stream provided as the xml + /// + public static XmlFormatReader CreateInstance(Stream input) { return new XmlFormatReader(XmlReader.Create(input, DefaultSettings)); } /// /// Constructs the XmlFormatReader using the string provided as the xml to be read /// - public XmlFormatReader(String input) : this(XmlReader.Create(new StringReader(input))) { } + public static XmlFormatReader CreateInstance(String input) { return new XmlFormatReader(XmlReader.Create(new StringReader(input), DefaultSettings)); } /// /// Constructs the XmlFormatReader using the xml in the TextReader /// - public XmlFormatReader(TextReader input) : this(XmlReader.Create(input)) { } + public static XmlFormatReader CreateInstance(TextReader input) { return new XmlFormatReader(XmlReader.Create(input, DefaultSettings)); } /// /// Constructs the XmlFormatReader with the XmlReader /// - public XmlFormatReader(XmlReader input) : this(input, XmlReaderOptions.None) { } + public static XmlFormatReader CreateInstance(XmlReader input) { return new XmlFormatReader(input); } /// /// Constructs the XmlFormatReader with the XmlReader and options /// - public XmlFormatReader(XmlReader input, XmlReaderOptions options) + protected XmlFormatReader(XmlReader input) { _input = input; _rootElementName = DefaultRootElementName; - Options = options; + Options = XmlReaderOptions.None; } /// /// Gets or sets the options to use when reading the xml /// public XmlReaderOptions Options { get; set; } + /// + /// Sets the options to use while generating the XML + /// + public XmlFormatReader SetOptions(XmlReaderOptions options) { Options = options; return this; } /// /// Gets or sets the default element name to use when using the Merge<TBuilder>() @@ -64,7 +72,7 @@ namespace Google.ProtocolBuffers.Serialization private XmlFormatReader CloneWith(XmlReader rdr) { - return new XmlFormatReader(rdr, Options); + return new XmlFormatReader(rdr).SetOptions(Options); } private void NextElement() { diff --git a/src/ProtocolBuffers/Serialization/XmlFormatWriter.cs b/src/ProtocolBuffers/Serialization/XmlFormatWriter.cs index b5dbf5fa..2bb4f159 100644 --- a/src/ProtocolBuffers/Serialization/XmlFormatWriter.cs +++ b/src/ProtocolBuffers/Serialization/XmlFormatWriter.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Text; using System.Xml; using Google.ProtocolBuffers.Descriptors; @@ -17,23 +18,29 @@ namespace Google.ProtocolBuffers.Serialization private readonly XmlWriter _output; private string _rootElementName; - static XmlWriterSettings DefaultSettings + static XmlWriterSettings DefaultSettings(Encoding encoding) { - get { return new XmlWriterSettings() {CheckCharacters = false, NewLineHandling = NewLineHandling.Entitize}; } + return new XmlWriterSettings() { CheckCharacters = false, NewLineHandling = NewLineHandling.Entitize, Encoding = encoding }; } /// /// Constructs the XmlFormatWriter to write to the given TextWriter /// - public XmlFormatWriter(TextWriter output) : this(XmlWriter.Create(output, DefaultSettings)) { } + public static XmlFormatWriter CreateInstance(TextWriter output) { return new XmlFormatWriter(XmlWriter.Create(output, DefaultSettings(output.Encoding))); } /// /// Constructs the XmlFormatWriter to write to the given stream /// - public XmlFormatWriter(Stream output) : this(XmlWriter.Create(output, DefaultSettings)) { } + public static XmlFormatWriter CreateInstance(Stream output) { return new XmlFormatWriter(XmlWriter.Create(output, DefaultSettings(Encoding.UTF8))); } + /// + /// Constructs the XmlFormatWriter to write to the given stream + /// + public static XmlFormatWriter CreateInstance(Stream output, Encoding encoding) { return new XmlFormatWriter(XmlWriter.Create(output, DefaultSettings(encoding))); } /// /// Constructs the XmlFormatWriter to write to the given XmlWriter /// - public XmlFormatWriter(XmlWriter output) + public static XmlFormatWriter CreateInstance(XmlWriter output) { return new XmlFormatWriter(output); } + + protected XmlFormatWriter(XmlWriter output) { _output = output; _rootElementName = DefaultRootElementName; @@ -61,6 +68,10 @@ namespace Google.ProtocolBuffers.Serialization /// Gets or sets the options to use while generating the XML /// public XmlWriterOptions Options { get; set; } + /// + /// Sets the options to use while generating the XML + /// + public XmlFormatWriter SetOptions(XmlWriterOptions options) { Options = options; return this; } private bool TestOption(XmlWriterOptions option) { return (Options & option) != 0; } -- cgit v1.2.3