From 0f3540e24b7b5cf66b59b97cb824fd5449fb77b4 Mon Sep 17 00:00:00 2001 From: csharptest Date: Fri, 5 Aug 2011 20:40:14 -0500 Subject: Split off the Serialization namespace into a new assembly. --- src/ProtoBench/ProtoBench.csproj | 5 + .../AbstractReader.cs | 697 +++++++++++++++++++++ .../AbstractTextReader.cs | 181 ++++++ .../AbstractTextWriter.cs | 106 ++++ .../AbstractWriter.cs | 504 +++++++++++++++ .../DictionaryReader.cs | 255 ++++++++ .../DictionaryWriter.cs | 189 ++++++ src/ProtocolBuffers.Serialization/Extensions.cs | 100 +++ .../JsonFormatReader.cs | 245 ++++++++ .../JsonFormatWriter.cs | 521 +++++++++++++++ .../JsonTextCursor.cs | 442 +++++++++++++ .../Properties/AssemblyInfo.cs | 76 +++ .../ProtocolBuffers.Serialization.csproj | 152 +++++ .../RecursionLimitExceeded.cs | 28 + .../XmlFormatReader.cs | 296 +++++++++ .../XmlFormatWriter.cs | 243 +++++++ .../XmlReaderOptions.cs | 17 + .../XmlWriterOptions.cs | 24 + .../ProtocolBuffers.Test.csproj | 4 + src/ProtocolBuffers.Test/TestWriterFormatJson.cs | 8 +- src/ProtocolBuffers.Test/TestWriterFormatXml.cs | 8 +- src/ProtocolBuffers.sln | 13 +- src/ProtocolBuffers/AbstractMessage.cs | 22 - src/ProtocolBuffers/GeneratedMessage.cs | 38 -- src/ProtocolBuffers/IMessage.cs | 18 - src/ProtocolBuffers/ProtocolBuffers.csproj | 14 - .../Serialization/AbstractReader.cs | 685 -------------------- .../Serialization/AbstractTextReader.cs | 174 ----- .../Serialization/AbstractTextWriter.cs | 106 ---- .../Serialization/AbstractWriter.cs | 504 --------------- .../Serialization/DictionaryReader.cs | 255 -------- .../Serialization/DictionaryWriter.cs | 189 ------ .../Serialization/JsonFormatReader.cs | 245 -------- .../Serialization/JsonFormatWriter.cs | 521 --------------- .../Serialization/JsonTextCursor.cs | 442 ------------- .../Serialization/XmlFormatReader.cs | 287 --------- .../Serialization/XmlFormatWriter.cs | 243 ------- .../Serialization/XmlReaderOptions.cs | 17 - .../Serialization/XmlWriterOptions.cs | 24 - src/ProtocolBuffers2008.sln | 10 + 40 files changed, 4114 insertions(+), 3794 deletions(-) create mode 100644 src/ProtocolBuffers.Serialization/AbstractReader.cs create mode 100644 src/ProtocolBuffers.Serialization/AbstractTextReader.cs create mode 100644 src/ProtocolBuffers.Serialization/AbstractTextWriter.cs create mode 100644 src/ProtocolBuffers.Serialization/AbstractWriter.cs create mode 100644 src/ProtocolBuffers.Serialization/DictionaryReader.cs create mode 100644 src/ProtocolBuffers.Serialization/DictionaryWriter.cs create mode 100644 src/ProtocolBuffers.Serialization/Extensions.cs create mode 100644 src/ProtocolBuffers.Serialization/JsonFormatReader.cs create mode 100644 src/ProtocolBuffers.Serialization/JsonFormatWriter.cs create mode 100644 src/ProtocolBuffers.Serialization/JsonTextCursor.cs create mode 100644 src/ProtocolBuffers.Serialization/Properties/AssemblyInfo.cs create mode 100644 src/ProtocolBuffers.Serialization/ProtocolBuffers.Serialization.csproj create mode 100644 src/ProtocolBuffers.Serialization/RecursionLimitExceeded.cs create mode 100644 src/ProtocolBuffers.Serialization/XmlFormatReader.cs create mode 100644 src/ProtocolBuffers.Serialization/XmlFormatWriter.cs create mode 100644 src/ProtocolBuffers.Serialization/XmlReaderOptions.cs create mode 100644 src/ProtocolBuffers.Serialization/XmlWriterOptions.cs delete mode 100644 src/ProtocolBuffers/Serialization/AbstractReader.cs delete mode 100644 src/ProtocolBuffers/Serialization/AbstractTextReader.cs delete mode 100644 src/ProtocolBuffers/Serialization/AbstractTextWriter.cs delete mode 100644 src/ProtocolBuffers/Serialization/AbstractWriter.cs delete mode 100644 src/ProtocolBuffers/Serialization/DictionaryReader.cs delete mode 100644 src/ProtocolBuffers/Serialization/DictionaryWriter.cs delete mode 100644 src/ProtocolBuffers/Serialization/JsonFormatReader.cs delete mode 100644 src/ProtocolBuffers/Serialization/JsonFormatWriter.cs delete mode 100644 src/ProtocolBuffers/Serialization/JsonTextCursor.cs delete mode 100644 src/ProtocolBuffers/Serialization/XmlFormatReader.cs delete mode 100644 src/ProtocolBuffers/Serialization/XmlFormatWriter.cs delete mode 100644 src/ProtocolBuffers/Serialization/XmlReaderOptions.cs delete mode 100644 src/ProtocolBuffers/Serialization/XmlWriterOptions.cs (limited to 'src') diff --git a/src/ProtoBench/ProtoBench.csproj b/src/ProtoBench/ProtoBench.csproj index 7722f8d2..d2c526dc 100644 --- a/src/ProtoBench/ProtoBench.csproj +++ b/src/ProtoBench/ProtoBench.csproj @@ -72,6 +72,11 @@ + + {231391AF-449C-4a39-986C-AD7F270F4750} + ProtocolBuffers.Serialization + True + {6908BDCE-D925-43F3-94AC-A531E6DF2591} ProtocolBuffers diff --git a/src/ProtocolBuffers.Serialization/AbstractReader.cs b/src/ProtocolBuffers.Serialization/AbstractReader.cs new file mode 100644 index 00000000..f54c2707 --- /dev/null +++ b/src/ProtocolBuffers.Serialization/AbstractReader.cs @@ -0,0 +1,697 @@ +using System; +using System.Collections.Generic; +using Google.ProtocolBuffers.Descriptors; + +//Disable CS3011: only CLS-compliant members can be abstract +#pragma warning disable 3011 + +namespace Google.ProtocolBuffers.Serialization +{ + /// + /// Provides a base-class that provides some basic functionality for handling type dispatching + /// + public abstract class AbstractReader : ICodedInputStream + { + private const int DefaultMaxDepth = 64; + private int _depth; + + /// Constructs a new reader + protected AbstractReader() { MaxDepth = DefaultMaxDepth; } + /// Constructs a new child reader + protected AbstractReader(AbstractReader copyFrom) + { + _depth = copyFrom._depth + 1; + MaxDepth = copyFrom.MaxDepth; + } + + /// Gets or sets the maximum recursion depth allowed + public int MaxDepth { get; set; } + + /// + /// Merges the contents of stream into the provided message builder + /// + public TBuilder Merge(TBuilder builder) where TBuilder : IBuilderLite + { + return Merge(builder, ExtensionRegistry.Empty); + } + + /// + /// Merges the contents of stream into the provided message builder + /// + public abstract TBuilder Merge(TBuilder builder, ExtensionRegistry registry) + where TBuilder : IBuilderLite; + + /// + /// Peeks at the next field in the input stream and returns what information is available. + /// + /// + /// This may be called multiple times without actually reading the field. Only after the field + /// is either read, or skipped, should PeekNext return a different value. + /// + protected abstract bool PeekNext(out string field); + + /// + /// Causes the reader to skip past this field + /// + protected abstract void Skip(); + + /// + /// Returns true if it was able to read a Boolean from the input + /// + protected abstract bool Read(ref bool value); + + /// + /// Returns true if it was able to read a Int32 from the input + /// + protected abstract bool Read(ref int value); + + /// + /// Returns true if it was able to read a UInt32 from the input + /// + [CLSCompliant(false)] + protected abstract bool Read(ref uint value); + + /// + /// Returns true if it was able to read a Int64 from the input + /// + protected abstract bool Read(ref long value); + + /// + /// Returns true if it was able to read a UInt64 from the input + /// + [CLSCompliant(false)] + protected abstract bool Read(ref ulong value); + + /// + /// Returns true if it was able to read a Single from the input + /// + protected abstract bool Read(ref float value); + + /// + /// Returns true if it was able to read a Double from the input + /// + protected abstract bool Read(ref double value); + + /// + /// Returns true if it was able to read a String from the input + /// + protected abstract bool Read(ref string value); + + /// + /// Returns true if it was able to read a ByteString from the input + /// + protected abstract bool Read(ref ByteString value); + + /// + /// returns true if it was able to read a single value into the value reference. The value + /// stored may be of type System.String, System.Int32, or an IEnumLite from the IEnumLiteMap. + /// + protected abstract bool ReadEnum(ref object value); + + /// + /// Merges the input stream into the provided IBuilderLite + /// + protected abstract bool ReadMessage(IBuilderLite builder, ExtensionRegistry registry); + + /// + /// Merges the input stream into the provided IBuilderLite + /// + public virtual bool ReadGroup(IBuilderLite value, ExtensionRegistry registry) + { + return ReadMessage(value, registry); + } + + /// + /// Cursors through the array elements and stops at the end of the array + /// + protected virtual IEnumerable ForeachArrayItem(string field) + { + string next = field; + while (true) + { + yield return next; + + if (!PeekNext(out next) || next != field) + { + break; + } + } + } + + /// + /// Reads an array of T messages + /// + public virtual bool ReadMessageArray(string field, ICollection items, IMessageLite messageType, + ExtensionRegistry registry) + { + bool success = false; + foreach (string next in ForeachArrayItem(field)) + { + IBuilderLite builder = messageType.WeakCreateBuilderForType(); + if (ReadMessage(builder, registry)) + { + items.Add((T) builder.WeakBuild()); + success |= true; + } + } + return success; + } + + /// + /// Reads an array of T messages as a proto-buffer group + /// + public virtual bool ReadGroupArray(string field, ICollection items, IMessageLite messageType, + ExtensionRegistry registry) + { + bool success = false; + foreach (string next in ForeachArrayItem(field)) + { + IBuilderLite builder = messageType.WeakCreateBuilderForType(); + if (ReadGroup(builder, registry)) + { + items.Add((T) builder.WeakBuild()); + success |= true; + } + } + return success; + } + + /// + /// Reads an array of System.Enum type T and adds them to the collection + /// + public virtual bool ReadEnumArray(string field, ICollection items) + { + bool success = false; + foreach (string next in ForeachArrayItem(field)) + { + object temp = null; + if (ReadEnum(ref temp)) + { + items.Add(temp); + success |= true; + } + } + return success; + } + + /// + /// Reads an array of T, where T is a primitive type defined by FieldType + /// + public virtual bool ReadArray(FieldType type, string field, ICollection items) + { + bool success = false; + foreach (string next in ForeachArrayItem(field)) + { + object temp = null; + if (ReadField(type, ref temp)) + { + items.Add((T) temp); + success |= true; + } + } + return success; + } + + /// + /// returns true if it was able to read a single primitive value of FieldType into the value reference + /// + public virtual bool ReadField(FieldType type, ref object value) + { + switch (type) + { + case FieldType.Bool: + { + bool temp = false; + if (Read(ref temp)) + { + value = temp; + } + else + { + return false; + } + break; + } + case FieldType.Int64: + case FieldType.SInt64: + case FieldType.SFixed64: + { + long temp = 0; + if (Read(ref temp)) + { + value = temp; + } + else + { + return false; + } + break; + } + case FieldType.UInt64: + case FieldType.Fixed64: + { + ulong temp = 0; + if (Read(ref temp)) + { + value = temp; + } + else + { + return false; + } + break; + } + case FieldType.Int32: + case FieldType.SInt32: + case FieldType.SFixed32: + { + int temp = 0; + if (Read(ref temp)) + { + value = temp; + } + else + { + return false; + } + break; + } + case FieldType.UInt32: + case FieldType.Fixed32: + { + uint temp = 0; + if (Read(ref temp)) + { + value = temp; + } + else + { + return false; + } + break; + } + case FieldType.Float: + { + float temp = float.NaN; + if (Read(ref temp)) + { + value = temp; + } + else + { + return false; + } + break; + } + case FieldType.Double: + { + double temp = float.NaN; + if (Read(ref temp)) + { + value = temp; + } + else + { + return false; + } + break; + } + case FieldType.String: + { + string temp = null; + if (Read(ref temp)) + { + value = temp; + } + else + { + return false; + } + break; + } + case FieldType.Bytes: + { + ByteString temp = null; + if (Read(ref temp)) + { + value = temp; + } + else + { + return false; + } + break; + } + default: + throw InvalidProtocolBufferException.InvalidTag(); + } + return true; + } + + #region ICodedInputStream Members + + bool ICodedInputStream.ReadTag(out uint fieldTag, out string fieldName) + { + fieldTag = 0; + if (PeekNext(out fieldName)) + { + return true; + } + return false; + } + + bool ICodedInputStream.ReadDouble(ref double value) + { + return Read(ref value); + } + + bool ICodedInputStream.ReadFloat(ref float value) + { + return Read(ref value); + } + + bool ICodedInputStream.ReadUInt64(ref ulong value) + { + return Read(ref value); + } + + bool ICodedInputStream.ReadInt64(ref long value) + { + return Read(ref value); + } + + bool ICodedInputStream.ReadInt32(ref int value) + { + return Read(ref value); + } + + bool ICodedInputStream.ReadFixed64(ref ulong value) + { + return Read(ref value); + } + + bool ICodedInputStream.ReadFixed32(ref uint value) + { + return Read(ref value); + } + + bool ICodedInputStream.ReadBool(ref bool value) + { + return Read(ref value); + } + + bool ICodedInputStream.ReadString(ref string value) + { + return Read(ref value); + } + + void ICodedInputStream.ReadGroup(int fieldNumber, IBuilderLite builder, ExtensionRegistry extensionRegistry) + { + if (_depth++ > MaxDepth) + { + throw new RecursionLimitExceededException(); + } + ReadGroup(builder, extensionRegistry); + _depth--; + } + + void ICodedInputStream.ReadUnknownGroup(int fieldNumber, IBuilderLite builder) + { + throw new NotSupportedException(); + } + + void ICodedInputStream.ReadMessage(IBuilderLite builder, ExtensionRegistry extensionRegistry) + { + if (_depth++ > MaxDepth) + { + throw new RecursionLimitExceededException(); + } + ReadMessage(builder, extensionRegistry); + _depth--; + } + + bool ICodedInputStream.ReadBytes(ref ByteString value) + { + return Read(ref value); + } + + bool ICodedInputStream.ReadUInt32(ref uint value) + { + return Read(ref value); + } + + bool ICodedInputStream.ReadEnum(ref IEnumLite value, out object unknown, IEnumLiteMap mapping) + { + value = null; + unknown = null; + if (ReadEnum(ref unknown)) + { + if (unknown is int) + { + value = mapping.FindValueByNumber((int) unknown); + } + else if (unknown is string) + { + value = mapping.FindValueByName((string) unknown); + } + return value != null; + } + return false; + } + + bool ICodedInputStream.ReadEnum(ref T value, out object rawValue) + { + rawValue = null; + if (ReadEnum(ref rawValue)) + { + if (Enum.IsDefined(typeof (T), rawValue)) + { + if (rawValue is int) + { + value = (T) rawValue; + } + else if (rawValue is string) + { + value = (T) Enum.Parse(typeof (T), (string) rawValue, false); + } + else + { + value = default(T); + return false; + } + return true; + } + } + return false; + } + + bool ICodedInputStream.ReadSFixed32(ref int value) + { + return Read(ref value); + } + + bool ICodedInputStream.ReadSFixed64(ref long value) + { + return Read(ref value); + } + + bool ICodedInputStream.ReadSInt32(ref int value) + { + return Read(ref value); + } + + bool ICodedInputStream.ReadSInt64(ref long value) + { + return Read(ref value); + } + + void ICodedInputStream.ReadPrimitiveArray(FieldType fieldType, uint fieldTag, string fieldName, + ICollection list) + { + ReadArray(fieldType, fieldName, list); + } + + void ICodedInputStream.ReadEnumArray(uint fieldTag, string fieldName, ICollection list, + out ICollection unknown, IEnumLiteMap mapping) + { + unknown = null; + List array = new List(); + if (ReadEnumArray(fieldName, array)) + { + foreach (object rawValue in array) + { + IEnumLite item = null; + if (rawValue is int) + { + item = mapping.FindValueByNumber((int) rawValue); + } + else if (rawValue is string) + { + item = mapping.FindValueByName((string) rawValue); + } + + if (item != null) + { + list.Add(item); + } + else + { + if (unknown == null) + { + unknown = new List(); + } + unknown.Add(rawValue); + } + } + } + } + + void ICodedInputStream.ReadEnumArray(uint fieldTag, string fieldName, ICollection list, + out ICollection unknown) + { + unknown = null; + List array = new List(); + if (ReadEnumArray(fieldName, array)) + { + foreach (object rawValue in array) + { + if (rawValue is int) + { + list.Add((T) rawValue); + } + else if (rawValue is string) + { + list.Add((T) Enum.Parse(typeof (T), (string) rawValue, false)); + } + else + { + if (unknown == null) + { + unknown = new List(); + } + unknown.Add(rawValue); + } + } + } + } + + void ICodedInputStream.ReadMessageArray(uint fieldTag, string fieldName, ICollection list, T messageType, + ExtensionRegistry registry) + { + if (_depth++ > MaxDepth) + { + throw new RecursionLimitExceededException(); + } + ReadMessageArray(fieldName, list, messageType, registry); + _depth--; + } + + void ICodedInputStream.ReadGroupArray(uint fieldTag, string fieldName, ICollection list, T messageType, + ExtensionRegistry registry) + { + if (_depth++ > MaxDepth) + { + throw new RecursionLimitExceededException(); + } + ReadGroupArray(fieldName, list, messageType, registry); + _depth--; + } + + bool ICodedInputStream.ReadPrimitiveField(FieldType fieldType, ref object value) + { + return ReadField(fieldType, ref value); + } + + bool ICodedInputStream.IsAtEnd + { + get + { + string next; + return PeekNext(out next) == false; + } + } + + bool ICodedInputStream.SkipField() + { + Skip(); + return true; + } + + void ICodedInputStream.ReadStringArray(uint fieldTag, string fieldName, ICollection list) + { + ReadArray(FieldType.String, fieldName, list); + } + + void ICodedInputStream.ReadBytesArray(uint fieldTag, string fieldName, ICollection list) + { + ReadArray(FieldType.Bytes, fieldName, list); + } + + void ICodedInputStream.ReadBoolArray(uint fieldTag, string fieldName, ICollection list) + { + ReadArray(FieldType.Bool, fieldName, list); + } + + void ICodedInputStream.ReadInt32Array(uint fieldTag, string fieldName, ICollection list) + { + ReadArray(FieldType.Int32, fieldName, list); + } + + void ICodedInputStream.ReadSInt32Array(uint fieldTag, string fieldName, ICollection list) + { + ReadArray(FieldType.SInt32, fieldName, list); + } + + void ICodedInputStream.ReadUInt32Array(uint fieldTag, string fieldName, ICollection list) + { + ReadArray(FieldType.UInt32, fieldName, list); + } + + void ICodedInputStream.ReadFixed32Array(uint fieldTag, string fieldName, ICollection list) + { + ReadArray(FieldType.Fixed32, fieldName, list); + } + + void ICodedInputStream.ReadSFixed32Array(uint fieldTag, string fieldName, ICollection list) + { + ReadArray(FieldType.SFixed32, fieldName, list); + } + + void ICodedInputStream.ReadInt64Array(uint fieldTag, string fieldName, ICollection list) + { + ReadArray(FieldType.Int64, fieldName, list); + } + + void ICodedInputStream.ReadSInt64Array(uint fieldTag, string fieldName, ICollection list) + { + ReadArray(FieldType.SInt64, fieldName, list); + } + + void ICodedInputStream.ReadUInt64Array(uint fieldTag, string fieldName, ICollection list) + { + ReadArray(FieldType.UInt64, fieldName, list); + } + + void ICodedInputStream.ReadFixed64Array(uint fieldTag, string fieldName, ICollection list) + { + ReadArray(FieldType.Fixed64, fieldName, list); + } + + void ICodedInputStream.ReadSFixed64Array(uint fieldTag, string fieldName, ICollection list) + { + ReadArray(FieldType.SFixed64, fieldName, list); + } + + void ICodedInputStream.ReadDoubleArray(uint fieldTag, string fieldName, ICollection list) + { + ReadArray(FieldType.Double, fieldName, list); + } + + void ICodedInputStream.ReadFloatArray(uint fieldTag, string fieldName, ICollection list) + { + ReadArray(FieldType.Float, fieldName, list); + } + + #endregion + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Serialization/AbstractTextReader.cs b/src/ProtocolBuffers.Serialization/AbstractTextReader.cs new file mode 100644 index 00000000..59b9057b --- /dev/null +++ b/src/ProtocolBuffers.Serialization/AbstractTextReader.cs @@ -0,0 +1,181 @@ +using System; +using System.Globalization; +using System.Xml; + +namespace Google.ProtocolBuffers.Serialization +{ + /// + /// Provides a base class for text-parsing readers + /// + public abstract class AbstractTextReader : AbstractReader + { + /// Constructs a new reader + protected AbstractTextReader() { } + /// Constructs a new child reader + protected AbstractTextReader(AbstractTextReader copyFrom) + : base(copyFrom) + { } + + /// + /// Reads a typed field as a string + /// + protected abstract bool ReadAsText(ref string textValue, Type type); + + /// + /// Returns true if it was able to read a String from the input + /// + protected override bool Read(ref string value) + { + string text = null; + if (ReadAsText(ref text, typeof (string))) + { + value = text; + return true; + } + return false; + } + + /// + /// Returns true if it was able to read a Boolean from the input + /// + protected override bool Read(ref bool value) + { + string text = null; + if (ReadAsText(ref text, typeof (bool))) + { + value = XmlConvert.ToBoolean(text); + return true; + } + return false; + } + + /// + /// Returns true if it was able to read a Int32 from the input + /// + protected override bool Read(ref int value) + { + string text = null; + if (ReadAsText(ref text, typeof (int))) + { + value = XmlConvert.ToInt32(text); + return true; + } + return false; + } + + /// + /// Returns true if it was able to read a UInt32 from the input + /// + [CLSCompliant(false)] + protected override bool Read(ref uint value) + { + string text = null; + if (ReadAsText(ref text, typeof (uint))) + { + value = XmlConvert.ToUInt32(text); + return true; + } + return false; + } + + /// + /// Returns true if it was able to read a Int64 from the input + /// + protected override bool Read(ref long value) + { + string text = null; + if (ReadAsText(ref text, typeof (long))) + { + value = XmlConvert.ToInt64(text); + return true; + } + return false; + } + + /// + /// Returns true if it was able to read a UInt64 from the input + /// + [CLSCompliant(false)] + protected override bool Read(ref ulong value) + { + string text = null; + if (ReadAsText(ref text, typeof (ulong))) + { + value = XmlConvert.ToUInt64(text); + return true; + } + return false; + } + + /// + /// Returns true if it was able to read a Single from the input + /// + protected override bool Read(ref float value) + { + string text = null; + if (ReadAsText(ref text, typeof (float))) + { + value = XmlConvert.ToSingle(text); + return true; + } + return false; + } + + /// + /// Returns true if it was able to read a Double from the input + /// + protected override bool Read(ref double value) + { + string text = null; + if (ReadAsText(ref text, typeof (double))) + { + value = XmlConvert.ToDouble(text); + return true; + } + return false; + } + + /// + /// Provides decoding of bytes read from the input stream + /// + protected virtual ByteString DecodeBytes(string bytes) + { + return ByteString.FromBase64(bytes); + } + + /// + /// Returns true if it was able to read a ByteString from the input + /// + protected override bool Read(ref ByteString value) + { + string text = null; + if (ReadAsText(ref text, typeof (ByteString))) + { + value = DecodeBytes(text); + return true; + } + return false; + } + + /// + /// returns true if it was able to read a single value into the value reference. The value + /// stored may be of type System.String, System.Int32, or an IEnumLite from the IEnumLiteMap. + /// + protected override bool ReadEnum(ref object value) + { + string text = null; + if (ReadAsText(ref text, typeof (Enum))) + { + int number; + if (int.TryParse(text, NumberStyles.Integer, CultureInfo.InvariantCulture, out number)) + { + value = number; + return true; + } + value = text; + return true; + } + return false; + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Serialization/AbstractTextWriter.cs b/src/ProtocolBuffers.Serialization/AbstractTextWriter.cs new file mode 100644 index 00000000..2c778dfc --- /dev/null +++ b/src/ProtocolBuffers.Serialization/AbstractTextWriter.cs @@ -0,0 +1,106 @@ +using System; +using System.Xml; + +namespace Google.ProtocolBuffers.Serialization +{ + /// + /// Provides a base class for text writers + /// + public abstract class AbstractTextWriter : AbstractWriter + { + /// + /// Encodes raw bytes to be written to the stream + /// + protected virtual string EncodeBytes(ByteString bytes) + { + return bytes.ToBase64(); + } + + /// + /// Writes a typed field as a text value + /// + protected abstract void WriteAsText(string field, string textValue, object typedValue); + + /// + /// Writes a String value + /// + protected override void Write(string field, string value) + { + WriteAsText(field, value, value); + } + + /// + /// Writes a Boolean value + /// + protected override void Write(string field, bool value) + { + WriteAsText(field, XmlConvert.ToString(value), value); + } + + /// + /// Writes a Int32 value + /// + protected override void Write(string field, int value) + { + WriteAsText(field, XmlConvert.ToString(value), value); + } + + /// + /// Writes a UInt32 value + /// + [CLSCompliant(false)] + protected override void Write(string field, uint value) + { + WriteAsText(field, XmlConvert.ToString(value), value); + } + + /// + /// Writes a Int64 value + /// + protected override void Write(string field, long value) + { + WriteAsText(field, XmlConvert.ToString(value), value); + } + + /// + /// Writes a UInt64 value + /// + [CLSCompliant(false)] + protected override void Write(string field, ulong value) + { + WriteAsText(field, XmlConvert.ToString(value), value); + } + + /// + /// Writes a Single value + /// + protected override void Write(string field, float value) + { + WriteAsText(field, XmlConvert.ToString(value), value); + } + + /// + /// Writes a Double value + /// + protected override void Write(string field, double value) + { + WriteAsText(field, XmlConvert.ToString(value), value); + } + + /// + /// Writes a set of bytes + /// + protected override void Write(string field, ByteString value) + { + WriteAsText(field, EncodeBytes(value), value); + } + + /// + /// Writes a System.Enum by the numeric and textual value + /// + protected override void WriteEnum(string field, int number, string name) + { + WriteAsText(field, name, number); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Serialization/AbstractWriter.cs b/src/ProtocolBuffers.Serialization/AbstractWriter.cs new file mode 100644 index 00000000..6592c1dd --- /dev/null +++ b/src/ProtocolBuffers.Serialization/AbstractWriter.cs @@ -0,0 +1,504 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using Google.ProtocolBuffers.Descriptors; + +//Disable CS3011: only CLS-compliant members can be abstract +#pragma warning disable 3011 + +namespace Google.ProtocolBuffers.Serialization +{ + /// + /// Provides a base class for writers that performs some basic type dispatching + /// + public abstract class AbstractWriter : ICodedOutputStream, IDisposable + { + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + GC.SuppressFinalize(this); + Flush(); + Dispose(true); + } + + /// + /// Completes any pending write operations + /// + public virtual void Flush() + { + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + protected virtual void Dispose(bool disposing) + { + } + + /// + /// Writes the message to the the formatted stream. + /// + public abstract void WriteMessage(IMessageLite message); + + /// + /// Writes a Boolean value + /// + protected abstract void Write(string field, Boolean value); + + /// + /// Writes a Int32 value + /// + protected abstract void Write(string field, Int32 value); + + /// + /// Writes a UInt32 value + /// + [CLSCompliant(false)] + protected abstract void Write(string field, UInt32 value); + + /// + /// Writes a Int64 value + /// + protected abstract void Write(string field, Int64 value); + + /// + /// Writes a UInt64 value + /// + [CLSCompliant(false)] + protected abstract void Write(string field, UInt64 value); + + /// + /// Writes a Single value + /// + protected abstract void Write(string field, Single value); + + /// + /// Writes a Double value + /// + protected abstract void Write(string field, Double value); + + /// + /// Writes a String value + /// + protected abstract void Write(string field, String value); + + /// + /// Writes a set of bytes + /// + protected abstract void Write(string field, ByteString value); + + /// + /// Writes a message or group as a field + /// + protected abstract void WriteMessageOrGroup(string field, IMessageLite message); + + /// + /// Writes a System.Enum by the numeric and textual value + /// + protected abstract void WriteEnum(string field, int number, string name); + + /// + /// Writes a field of the type determined by field.FieldType + /// + protected virtual void WriteField(FieldType fieldType, string field, object value) + { + switch (fieldType) + { + case FieldType.Bool: + Write(field, (bool) value); + break; + case FieldType.Int64: + case FieldType.SInt64: + case FieldType.SFixed64: + Write(field, (long) value); + break; + case FieldType.UInt64: + case FieldType.Fixed64: + Write(field, (ulong) value); + break; + case FieldType.Int32: + case FieldType.SInt32: + case FieldType.SFixed32: + Write(field, (int) value); + break; + case FieldType.UInt32: + case FieldType.Fixed32: + Write(field, (uint) value); + break; + case FieldType.Float: + Write(field, (float) value); + break; + case FieldType.Double: + Write(field, (double) value); + break; + case FieldType.String: + Write(field, (string) value); + break; + case FieldType.Bytes: + Write(field, (ByteString) value); + break; + case FieldType.Group: + WriteMessageOrGroup(field, (IMessageLite) value); + break; + case FieldType.Message: + WriteMessageOrGroup(field, (IMessageLite) value); + break; + case FieldType.Enum: + { + if (value is IEnumLite) + { + WriteEnum(field, ((IEnumLite) value).Number, ((IEnumLite) value).Name); + } + else if (value is IConvertible) + { + WriteEnum(field, ((IConvertible) value).ToInt32(CultureInfo.InvariantCulture), + ((IConvertible) value).ToString(CultureInfo.InvariantCulture)); + } + else + { + throw new ArgumentException("Expected an Enum type for field " + field); + } + break; + } + default: + throw InvalidProtocolBufferException.InvalidTag(); + } + } + + /// + /// Writes an array of field values + /// + protected virtual void WriteArray(FieldType fieldType, string field, IEnumerable items) + { + foreach (object obj in items) + { + WriteField(fieldType, field, obj); + } + } + + /// + /// Writes a numeric unknown field of wire type: Fixed32, Fixed64, or Variant + /// + [CLSCompliant(false)] + protected virtual void WriteUnknown(WireFormat.WireType wireType, int fieldNumber, ulong value) + { + } + + /// + /// Writes an unknown field, Expect WireType of GroupStart or LengthPrefix + /// + [CLSCompliant(false)] + protected virtual void WriteUnknown(WireFormat.WireType wireType, int fieldNumber, ByteString value) + { + } + + #region ICodedOutputStream Members + + void ICodedOutputStream.WriteUnknownGroup(int fieldNumber, IMessageLite value) + { + } + + void ICodedOutputStream.WriteUnknownBytes(int fieldNumber, ByteString value) + { + } + + void ICodedOutputStream.WriteUnknownField(int fieldNumber, WireFormat.WireType type, ulong value) + { + } + + void ICodedOutputStream.WriteMessageSetExtension(int fieldNumber, string fieldName, IMessageLite value) + { + } + + void ICodedOutputStream.WriteMessageSetExtension(int fieldNumber, string fieldName, ByteString value) + { + } + + void ICodedOutputStream.WriteField(FieldType fieldType, int fieldNumber, string fieldName, object value) + { + WriteField(fieldType, fieldName, value); + } + + void ICodedOutputStream.WriteDouble(int fieldNumber, string fieldName, double value) + { + Write(fieldName, value); + } + + void ICodedOutputStream.WriteFloat(int fieldNumber, string fieldName, float value) + { + Write(fieldName, value); + } + + void ICodedOutputStream.WriteUInt64(int fieldNumber, string fieldName, ulong value) + { + Write(fieldName, value); + } + + void ICodedOutputStream.WriteInt64(int fieldNumber, string fieldName, long value) + { + Write(fieldName, value); + } + + void ICodedOutputStream.WriteInt32(int fieldNumber, string fieldName, int value) + { + Write(fieldName, value); + } + + void ICodedOutputStream.WriteFixed64(int fieldNumber, string fieldName, ulong value) + { + Write(fieldName, value); + } + + void ICodedOutputStream.WriteFixed32(int fieldNumber, string fieldName, uint value) + { + Write(fieldName, value); + } + + void ICodedOutputStream.WriteBool(int fieldNumber, string fieldName, bool value) + { + Write(fieldName, value); + } + + void ICodedOutputStream.WriteString(int fieldNumber, string fieldName, string value) + { + Write(fieldName, value); + } + + void ICodedOutputStream.WriteGroup(int fieldNumber, string fieldName, IMessageLite value) + { + WriteMessageOrGroup(fieldName, value); + } + + void ICodedOutputStream.WriteMessage(int fieldNumber, string fieldName, IMessageLite value) + { + WriteMessageOrGroup(fieldName, value); + } + + void ICodedOutputStream.WriteBytes(int fieldNumber, string fieldName, ByteString value) + { + Write(fieldName, value); + } + + void ICodedOutputStream.WriteUInt32(int fieldNumber, string fieldName, uint value) + { + Write(fieldName, value); + } + + void ICodedOutputStream.WriteEnum(int fieldNumber, string fieldName, int value, object rawValue) + { + WriteEnum(fieldName, value, rawValue.ToString()); + } + + void ICodedOutputStream.WriteSFixed32(int fieldNumber, string fieldName, int value) + { + Write(fieldName, value); + } + + void ICodedOutputStream.WriteSFixed64(int fieldNumber, string fieldName, long value) + { + Write(fieldName, value); + } + + void ICodedOutputStream.WriteSInt32(int fieldNumber, string fieldName, int value) + { + Write(fieldName, value); + } + + void ICodedOutputStream.WriteSInt64(int fieldNumber, string fieldName, long value) + { + Write(fieldName, value); + } + + + void ICodedOutputStream.WriteArray(FieldType fieldType, int fieldNumber, string fieldName, IEnumerable list) + { + WriteArray(fieldType, fieldName, list); + } + + void ICodedOutputStream.WriteGroupArray(int fieldNumber, string fieldName, IEnumerable list) + { + WriteArray(FieldType.Group, fieldName, list); + } + + void ICodedOutputStream.WriteMessageArray(int fieldNumber, string fieldName, IEnumerable list) + { + WriteArray(FieldType.Message, fieldName, list); + } + + void ICodedOutputStream.WriteStringArray(int fieldNumber, string fieldName, IEnumerable list) + { + WriteArray(FieldType.String, fieldName, list); + } + + void ICodedOutputStream.WriteBytesArray(int fieldNumber, string fieldName, IEnumerable list) + { + WriteArray(FieldType.Bytes, fieldName, list); + } + + void ICodedOutputStream.WriteBoolArray(int fieldNumber, string fieldName, IEnumerable list) + { + WriteArray(FieldType.Bool, fieldName, list); + } + + void ICodedOutputStream.WriteInt32Array(int fieldNumber, string fieldName, IEnumerable list) + { + WriteArray(FieldType.Int32, fieldName, list); + } + + void ICodedOutputStream.WriteSInt32Array(int fieldNumber, string fieldName, IEnumerable list) + { + WriteArray(FieldType.SInt32, fieldName, list); + } + + void ICodedOutputStream.WriteUInt32Array(int fieldNumber, string fieldName, IEnumerable list) + { + WriteArray(FieldType.UInt32, fieldName, list); + } + + void ICodedOutputStream.WriteFixed32Array(int fieldNumber, string fieldName, IEnumerable list) + { + WriteArray(FieldType.Fixed32, fieldName, list); + } + + void ICodedOutputStream.WriteSFixed32Array(int fieldNumber, string fieldName, IEnumerable list) + { + WriteArray(FieldType.SFixed32, fieldName, list); + } + + void ICodedOutputStream.WriteInt64Array(int fieldNumber, string fieldName, IEnumerable list) + { + WriteArray(FieldType.Int64, fieldName, list); + } + + void ICodedOutputStream.WriteSInt64Array(int fieldNumber, string fieldName, IEnumerable list) + { + WriteArray(FieldType.SInt64, fieldName, list); + } + + void ICodedOutputStream.WriteUInt64Array(int fieldNumber, string fieldName, IEnumerable list) + { + WriteArray(FieldType.UInt64, fieldName, list); + } + + void ICodedOutputStream.WriteFixed64Array(int fieldNumber, string fieldName, IEnumerable list) + { + WriteArray(FieldType.Fixed64, fieldName, list); + } + + void ICodedOutputStream.WriteSFixed64Array(int fieldNumber, string fieldName, IEnumerable list) + { + WriteArray(FieldType.SFixed64, fieldName, list); + } + + void ICodedOutputStream.WriteDoubleArray(int fieldNumber, string fieldName, IEnumerable list) + { + WriteArray(FieldType.Double, fieldName, list); + } + + void ICodedOutputStream.WriteFloatArray(int fieldNumber, string fieldName, IEnumerable list) + { + WriteArray(FieldType.Float, fieldName, list); + } + + void ICodedOutputStream.WriteEnumArray(int fieldNumber, string fieldName, IEnumerable list) + { + WriteArray(FieldType.Enum, fieldName, list); + } + + void ICodedOutputStream.WritePackedArray(FieldType fieldType, int fieldNumber, string fieldName, + IEnumerable list) + { + WriteArray(fieldType, fieldName, list); + } + + + void ICodedOutputStream.WritePackedBoolArray(int fieldNumber, string fieldName, int computedSize, + IEnumerable list) + { + WriteArray(FieldType.Bool, fieldName, list); + } + + void ICodedOutputStream.WritePackedInt32Array(int fieldNumber, string fieldName, int computedSize, + IEnumerable list) + { + WriteArray(FieldType.Int32, fieldName, list); + } + + void ICodedOutputStream.WritePackedSInt32Array(int fieldNumber, string fieldName, int computedSize, + IEnumerable list) + { + WriteArray(FieldType.SInt32, fieldName, list); + } + + void ICodedOutputStream.WritePackedUInt32Array(int fieldNumber, string fieldName, int computedSize, + IEnumerable list) + { + WriteArray(FieldType.UInt32, fieldName, list); + } + + void ICodedOutputStream.WritePackedFixed32Array(int fieldNumber, string fieldName, int computedSize, + IEnumerable list) + { + WriteArray(FieldType.Fixed32, fieldName, list); + } + + void ICodedOutputStream.WritePackedSFixed32Array(int fieldNumber, string fieldName, int computedSize, + IEnumerable list) + { + WriteArray(FieldType.SFixed32, fieldName, list); + } + + void ICodedOutputStream.WritePackedInt64Array(int fieldNumber, string fieldName, int computedSize, + IEnumerable list) + { + WriteArray(FieldType.Int64, fieldName, list); + } + + void ICodedOutputStream.WritePackedSInt64Array(int fieldNumber, string fieldName, int computedSize, + IEnumerable list) + { + WriteArray(FieldType.SInt64, fieldName, list); + } + + void ICodedOutputStream.WritePackedUInt64Array(int fieldNumber, string fieldName, int computedSize, + IEnumerable list) + { + WriteArray(FieldType.UInt64, fieldName, list); + } + + void ICodedOutputStream.WritePackedFixed64Array(int fieldNumber, string fieldName, int computedSize, + IEnumerable list) + { + WriteArray(FieldType.Fixed64, fieldName, list); + } + + void ICodedOutputStream.WritePackedSFixed64Array(int fieldNumber, string fieldName, int computedSize, + IEnumerable list) + { + WriteArray(FieldType.SFixed64, fieldName, list); + } + + void ICodedOutputStream.WritePackedDoubleArray(int fieldNumber, string fieldName, int computedSize, + IEnumerable list) + { + WriteArray(FieldType.Double, fieldName, list); + } + + void ICodedOutputStream.WritePackedFloatArray(int fieldNumber, string fieldName, int computedSize, + IEnumerable list) + { + WriteArray(FieldType.Float, fieldName, list); + } + + void ICodedOutputStream.WritePackedEnumArray(int fieldNumber, string fieldName, int computedSize, + IEnumerable list) + { + WriteArray(FieldType.Enum, fieldName, list); + } + + #endregion + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Serialization/DictionaryReader.cs b/src/ProtocolBuffers.Serialization/DictionaryReader.cs new file mode 100644 index 00000000..cc5c680c --- /dev/null +++ b/src/ProtocolBuffers.Serialization/DictionaryReader.cs @@ -0,0 +1,255 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using Google.ProtocolBuffers.Descriptors; + +namespace Google.ProtocolBuffers.Serialization +{ + /// + /// Allows reading messages from a name/value dictionary + /// + public class DictionaryReader : AbstractReader + { + private readonly IEnumerator> _input; + private bool _ready; + + /// + /// Creates a dictionary reader from an enumeration of KeyValuePair data, like an IDictionary + /// + public DictionaryReader(IEnumerable> input) + { + _input = input.GetEnumerator(); + _ready = _input.MoveNext(); + } + + /// + /// Merges the contents of stream into the provided message builder + /// + public override TBuilder Merge(TBuilder builder, ExtensionRegistry registry) + { + builder.WeakMergeFrom(this, registry); + return builder; + } + + /// + /// Peeks at the next field in the input stream and returns what information is available. + /// + /// + /// This may be called multiple times without actually reading the field. Only after the field + /// is either read, or skipped, should PeekNext return a different value. + /// + protected override bool PeekNext(out string field) + { + field = _ready ? _input.Current.Key : null; + return _ready; + } + + /// + /// Causes the reader to skip past this field + /// + protected override void Skip() + { + _ready = _input.MoveNext(); + } + + private bool GetValue(ref T value) + { + if (!_ready) + { + return false; + } + + object obj = _input.Current.Value; + if (obj is T) + { + value = (T) obj; + } + else + { + try + { + if (obj is IConvertible) + { + value = (T) Convert.ChangeType(obj, typeof (T), CultureInfo.InvariantCulture); + } + else + { + value = (T) obj; + } + } + catch + { + _ready = _input.MoveNext(); + return false; + } + } + _ready = _input.MoveNext(); + return true; + } + + /// + /// Returns true if it was able to read a Boolean from the input + /// + protected override bool Read(ref bool value) + { + return GetValue(ref value); + } + + /// + /// Returns true if it was able to read a Int32 from the input + /// + protected override bool Read(ref int value) + { + return GetValue(ref value); + } + + /// + /// Returns true if it was able to read a UInt32 from the input + /// + [CLSCompliant(false)] + protected override bool Read(ref uint value) + { + return GetValue(ref value); + } + + /// + /// Returns true if it was able to read a Int64 from the input + /// + protected override bool Read(ref long value) + { + return GetValue(ref value); + } + + /// + /// Returns true if it was able to read a UInt64 from the input + /// + [CLSCompliant(false)] + protected override bool Read(ref ulong value) + { + return GetValue(ref value); + } + + /// + /// Returns true if it was able to read a Single from the input + /// + protected override bool Read(ref float value) + { + return GetValue(ref value); + } + + /// + /// Returns true if it was able to read a Double from the input + /// + protected override bool Read(ref double value) + { + return GetValue(ref value); + } + + /// + /// Returns true if it was able to read a String from the input + /// + protected override bool Read(ref string value) + { + return GetValue(ref value); + } + + /// + /// Returns true if it was able to read a ByteString from the input + /// + protected override bool Read(ref ByteString value) + { + byte[] rawbytes = null; + if (GetValue(ref rawbytes)) + { + value = ByteString.CopyFrom(rawbytes); + return true; + } + return false; + } + + /// + /// returns true if it was able to read a single value into the value reference. The value + /// stored may be of type System.String, System.Int32, or an IEnumLite from the IEnumLiteMap. + /// + protected override bool ReadEnum(ref object value) + { + return GetValue(ref value); + } + + /// + /// Merges the input stream into the provided IBuilderLite + /// + protected override bool ReadMessage(IBuilderLite builder, ExtensionRegistry registry) + { + IDictionary values = null; + if (GetValue(ref values)) + { + new DictionaryReader(values).Merge(builder, registry); + return true; + } + return false; + } + + public override bool ReadArray(FieldType type, string field, ICollection items) + { + object[] array = null; + if (GetValue(ref array)) + { + 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; + } + + public override bool ReadEnumArray(string field, ICollection items) + { + object[] array = null; + if (GetValue(ref array)) + { + foreach (object item in array) + { + items.Add(item); + } + return true; + } + return false; + } + + public override bool ReadMessageArray(string field, ICollection items, IMessageLite messageType, + ExtensionRegistry registry) + { + object[] array = null; + if (GetValue(ref array)) + { + foreach (IDictionary item in array) + { + IBuilderLite builder = messageType.WeakCreateBuilderForType(); + new DictionaryReader(item).Merge(builder); + items.Add((T) builder.WeakBuild()); + } + return true; + } + return false; + } + + public override bool ReadGroupArray(string field, ICollection items, IMessageLite messageType, + ExtensionRegistry registry) + { + return ReadMessageArray(field, items, messageType, registry); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Serialization/DictionaryWriter.cs b/src/ProtocolBuffers.Serialization/DictionaryWriter.cs new file mode 100644 index 00000000..96175a7e --- /dev/null +++ b/src/ProtocolBuffers.Serialization/DictionaryWriter.cs @@ -0,0 +1,189 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using Google.ProtocolBuffers.Descriptors; + +namespace Google.ProtocolBuffers.Serialization +{ + /// + /// Allows writing messages to a name/value dictionary + /// + public class DictionaryWriter : AbstractWriter + { + private readonly IDictionary _output; + + /// + /// Constructs a writer using a new dictionary + /// + public DictionaryWriter() + : this(new Dictionary(StringComparer.Ordinal)) + { + } + + /// + /// Constructs a writer using an existing dictionary + /// + public DictionaryWriter(IDictionary output) + { + ThrowHelper.ThrowIfNull(output, "output"); + _output = output; + } + + /// + /// Creates the dictionary instance for a child message. + /// + protected virtual DictionaryWriter Create() + { + return new DictionaryWriter(); + } + + /// + /// Accesses the dictionary that is backing this writer + /// + public IDictionary ToDictionary() + { + return _output; + } + + /// + /// Writes the message to the the formatted stream. + /// + public override void WriteMessage(IMessageLite message) + { + message.WriteTo(this); + } + + /// + /// Writes a Boolean value + /// + protected override void Write(string field, bool value) + { + _output[field] = value; + } + + /// + /// Writes a Int32 value + /// + protected override void Write(string field, int value) + { + _output[field] = value; + } + + /// + /// Writes a UInt32 value + /// + [CLSCompliant(false)] + protected override void Write(string field, uint value) + { + _output[field] = value; + } + + /// + /// Writes a Int64 value + /// + protected override void Write(string field, long value) + { + _output[field] = value; + } + + /// + /// Writes a UInt64 value + /// + [CLSCompliant(false)] + protected override void Write(string field, ulong value) + { + _output[field] = value; + } + + /// + /// Writes a Single value + /// + protected override void Write(string field, float value) + { + _output[field] = value; + } + + /// + /// Writes a Double value + /// + protected override void Write(string field, double value) + { + _output[field] = value; + } + + /// + /// Writes a String value + /// + protected override void Write(string field, string value) + { + _output[field] = value; + } + + /// + /// Writes a set of bytes + /// + protected override void Write(string field, ByteString value) + { + _output[field] = value.ToByteArray(); + } + + /// + /// Writes a message or group as a field + /// + protected override void WriteMessageOrGroup(string field, IMessageLite message) + { + DictionaryWriter writer = Create(); + writer.WriteMessage(message); + + _output[field] = writer.ToDictionary(); + } + + /// + /// Writes a System.Enum by the numeric and textual value + /// + protected override void WriteEnum(string field, int number, string name) + { + _output[field] = number; + } + + /// + /// Writes an array of field values + /// + protected override void WriteArray(FieldType fieldType, string field, IEnumerable items) + { + List objects = new List(); + foreach (object o in items) + { + switch (fieldType) + { + case FieldType.Group: + case FieldType.Message: + { + DictionaryWriter writer = Create(); + writer.WriteMessage((IMessageLite) o); + objects.Add(writer.ToDictionary()); + } + break; + case FieldType.Bytes: + objects.Add(((ByteString) o).ToByteArray()); + break; + case FieldType.Enum: + if (o is IEnumLite) + { + objects.Add(((IEnumLite) o).Number); + } + else + { + objects.Add((int) o); + } + break; + default: + objects.Add(o); + break; + } + } + + _output[field] = objects.ToArray(); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Serialization/Extensions.cs b/src/ProtocolBuffers.Serialization/Extensions.cs new file mode 100644 index 00000000..2050c911 --- /dev/null +++ b/src/ProtocolBuffers.Serialization/Extensions.cs @@ -0,0 +1,100 @@ +using System; +using System.Text; +using System.IO; +using System.Xml; +using Google.ProtocolBuffers.Serialization; + +namespace Google.ProtocolBuffers +{ + /// + /// Extension methods for using serializers on instances of IMessageLite/IBuilderLite + /// + public static class Extensions + { + #region IMessageLite Extension + /// + /// Serializes the message to JSON text. This is a trivial wrapper + /// around Serialization.JsonFormatWriter.WriteMessage. + /// + public static string ToJson(this IMessageLite message) + { + JsonFormatWriter w = JsonFormatWriter.CreateInstance(); + w.WriteMessage(message); + return w.ToString(); + } + /// + /// Serializes the message to XML text. This is a trivial wrapper + /// around Serialization.XmlFormatWriter.WriteMessage. + /// + public static string ToXml(this IMessageLite message) + { + StringWriter w = new StringWriter(new StringBuilder(4096)); + XmlFormatWriter.CreateInstance(w).WriteMessage(message); + return w.ToString(); + } + /// + /// Serializes the message to XML text using the element name provided. + /// This is a trivial wrapper around Serialization.XmlFormatWriter.WriteMessage. + /// + public static string ToXml(this IMessageLite message, string rootElementName) + { + StringWriter w = new StringWriter(new StringBuilder(4096)); + XmlFormatWriter.CreateInstance(w).WriteMessage(rootElementName, message); + return w.ToString(); + } + + #endregion + #region IBuilderLite Extensions + /// + /// Merges a JSON object into this builder and returns + /// + public static TBuilder MergeFromJson(this TBuilder builder, string jsonText) where TBuilder : IBuilderLite + { + return JsonFormatReader.CreateInstance(jsonText) + .Merge(builder); + } + /// + /// Merges a JSON object into this builder and returns + /// + public static TBuilder MergeFromJson(this TBuilder builder, TextReader reader) where TBuilder : IBuilderLite + { + return MergeFromJson(builder, reader, ExtensionRegistry.Empty); + } + /// + /// Merges a JSON object into this builder using the extensions provided and returns + /// + public static TBuilder MergeFromJson(this TBuilder builder, TextReader reader, ExtensionRegistry extensionRegistry) where TBuilder : IBuilderLite + { + return JsonFormatReader.CreateInstance(reader) + .Merge(builder, extensionRegistry); + } + + /// + /// Merges an XML object into this builder and returns + /// + public static TBuilder MergeFromXml(this TBuilder builder, XmlReader reader) where TBuilder : IBuilderLite + { + return MergeFromXml(builder, XmlFormatReader.DefaultRootElementName, reader, ExtensionRegistry.Empty); + } + + /// + /// Merges an XML object into this builder and returns + /// + public static TBuilder MergeFromXml(this TBuilder builder, string rootElementName, XmlReader reader) where TBuilder : IBuilderLite + { + return MergeFromXml(builder, rootElementName, reader, ExtensionRegistry.Empty); + } + + /// + /// Merges an XML object into this builder using the extensions provided and returns + /// + public static TBuilder MergeFromXml(this TBuilder builder, string rootElementName, XmlReader reader, + ExtensionRegistry extensionRegistry) where TBuilder : IBuilderLite + { + return XmlFormatReader.CreateInstance(reader) + .Merge(rootElementName, builder, extensionRegistry); + } + + #endregion + } +} diff --git a/src/ProtocolBuffers.Serialization/JsonFormatReader.cs b/src/ProtocolBuffers.Serialization/JsonFormatReader.cs new file mode 100644 index 00000000..d4505d70 --- /dev/null +++ b/src/ProtocolBuffers.Serialization/JsonFormatReader.cs @@ -0,0 +1,245 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Xml; + +namespace Google.ProtocolBuffers.Serialization +{ + /// + /// JsonFormatReader is used to parse Json into a message or an array of messages + /// + public class JsonFormatReader : AbstractTextReader + { + private readonly JsonCursor _input; + private readonly Stack _stopChar; + + private enum ReaderState + { + Start, + BeginValue, + EndValue, + BeginObject, + BeginArray + } + + private string _current; + private 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 static JsonFormatReader CreateInstance(string jsonText) + { + return new JsonFormatReader(JsonCursor.CreateInstance(jsonText)); + } + + /// + /// Constructs a JsonFormatReader to parse Json into a message + /// + 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 = 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 + /// + public bool IsArrayMessage + { + get { return _input.NextChar == '['; } + } + + /// + /// Returns an enumerator that is used to cursor over an array of messages + /// + /// + /// This is generally used when receiving an array of messages rather than a single root message + /// + public IEnumerable EnumerateArray() + { + foreach (string ignored in ForeachArrayItem(_current)) + { + yield return this; + } + } + + /// + /// Merges the contents of stream into the provided message builder + /// + public override TBuilder Merge(TBuilder builder, ExtensionRegistry registry) + { + _input.Consume('{'); + _stopChar.Push('}'); + + _state = ReaderState.BeginObject; + builder.WeakMergeFrom(this, registry); + _input.Consume((char) _stopChar.Pop()); + _state = ReaderState.EndValue; + return builder; + } + + /// + /// Causes the reader to skip past this field + /// + protected override void Skip() + { + object temp; + _input.ReadVariant(out temp); + _state = ReaderState.EndValue; + } + + /// + /// Peeks at the next field in the input stream and returns what information is available. + /// + /// + /// This may be called multiple times without actually reading the field. Only after the field + /// is either read, or skipped, should PeekNext return a different value. + /// + protected override bool PeekNext(out string field) + { + field = _current; + if (_state == ReaderState.BeginValue) + { + return true; + } + + int next = _input.NextChar; + if (next == _stopChar.Peek()) + { + return false; + } + + _input.Assert(next != -1, "Unexpected end of file."); + + //not sure about this yet, it will allow {, "a":true } + if (_state == ReaderState.EndValue && !_input.TryConsume(',')) + { + return false; + } + + field = _current = _input.ReadString(); + _input.Consume(':'); + _state = ReaderState.BeginValue; + return true; + } + + /// + /// Returns true if it was able to read a String from the input + /// + protected override bool ReadAsText(ref string value, Type typeInfo) + { + object temp; + JsonCursor.JsType type = _input.ReadVariant(out temp); + _state = ReaderState.EndValue; + + _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 == 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 == JsonCursor.JsType.Number && + (typeInfo != typeof (double) && typeInfo != typeof (float)) && + value.IndexOf("e", StringComparison.OrdinalIgnoreCase) > 0) + { + value = XmlConvert.ToString((long) Math.Round(XmlConvert.ToDouble(value), 0)); + } + return value != null; + } + + /// + /// Returns true if it was able to read a ByteString from the input + /// + protected override bool Read(ref ByteString value) + { + string bytes = null; + if (Read(ref bytes)) + { + value = ByteString.FromBase64(bytes); + return true; + } + return false; + } + + /// + /// Cursors through the array elements and stops at the end of the array + /// + protected override IEnumerable ForeachArrayItem(string field) + { + _input.Consume('['); + _stopChar.Push(']'); + _state = ReaderState.BeginArray; + while (_input.NextChar != ']') + { + _current = field; + yield return field; + if (!_input.TryConsume(',')) + { + break; + } + } + _input.Consume((char) _stopChar.Pop()); + _state = ReaderState.EndValue; + } + + /// + /// Merges the input stream into the provided IBuilderLite + /// + protected override bool ReadMessage(IBuilderLite builder, ExtensionRegistry registry) + { + Merge(builder, registry); + return true; + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Serialization/JsonFormatWriter.cs b/src/ProtocolBuffers.Serialization/JsonFormatWriter.cs new file mode 100644 index 00000000..d54507cc --- /dev/null +++ b/src/ProtocolBuffers.Serialization/JsonFormatWriter.cs @@ -0,0 +1,521 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Text; +using Google.ProtocolBuffers.Descriptors; + +namespace Google.ProtocolBuffers.Serialization +{ + /// + /// JsonFormatWriter is a .NET 2.0 friendly json formatter for proto buffer messages. For .NET 3.5 + /// you may also use the XmlFormatWriter with an XmlWriter created by the + /// JsonReaderWriterFactory. + /// + public abstract class JsonFormatWriter : AbstractTextWriter + { + #region buffering implementations + + private class JsonTextWriter : JsonFormatWriter + { + private readonly char[] _buffer; + private TextWriter _output; + private int _bufferPos; + + public JsonTextWriter(TextWriter output) + { + _buffer = new char[4096]; + _bufferPos = 0; + _output = output; + _counter.Add(0); + } + + /// + /// Returns the output of TextWriter.ToString() where TextWriter is the ctor argument. + /// + public override string ToString() + { + Flush(); + + if (_output != null) + { + return _output.ToString(); + } + + return new String(_buffer, 0, _bufferPos); + } + + protected override void WriteToOutput(char[] chars, int offset, int len) + { + if (_bufferPos + len >= _buffer.Length) + { + if (_output == null) + { + _output = new StringWriter(new StringBuilder(_buffer.Length*2 + len)); + } + Flush(); + } + + if (len < _buffer.Length) + { + 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) + { + _output.Write(_buffer, 0, _bufferPos); + _bufferPos = 0; + } + base.Flush(); + } + } + + private class JsonStreamWriter : JsonFormatWriter + { +#if SILVERLIGHT2 || COMPACT_FRAMEWORK_35 + static readonly Encoding Encoding = Encoding.UTF8; +#else + private static readonly Encoding Encoding = Encoding.ASCII; +#endif + private readonly byte[] _buffer; + private Stream _output; + private int _bufferPos; + + public JsonStreamWriter(Stream output) + { + _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; + } + + 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(); + } + + /// + /// Constructs a JsonFormatWriter, use ToString() to extract the final output + /// + 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() + { + NewLine = Environment.NewLine; + Indent = " "; + Whitespace = " "; + return this; + } + + /// Gets or sets the characters to use for the new-line, default = empty + public string NewLine { get; set; } + + /// Gets or sets the text to use for indenting, default = empty + public string Indent { get; set; } + + /// Gets or sets the whitespace to use to separate the text, default = empty + public string Whitespace { get; set; } + + private void Seperator() + { + if (_counter.Count == 0) + { + throw new InvalidOperationException("Missmatched open/close in Json writer."); + } + + int index = _counter.Count - 1; + if (_counter[index] > 0) + { + WriteToOutput(','); + } + + WriteLine(String.Empty); + _counter[index] = _counter[index] + 1; + } + + private void WriteLine(string content) + { + if (!String.IsNullOrEmpty(NewLine)) + { + WriteToOutput(NewLine); + for (int i = 1; i < _counter.Count; i++) + { + WriteToOutput(Indent); + } + } + else if (!String.IsNullOrEmpty(Whitespace)) + { + WriteToOutput(Whitespace); + } + + WriteToOutput(content); + } + + private void WriteName(string field) + { + Seperator(); + if (!String.IsNullOrEmpty(field)) + { + WriteToOutput('"'); + WriteToOutput(field); + WriteToOutput('"'); + WriteToOutput(':'); + if (!String.IsNullOrEmpty(Whitespace)) + { + WriteToOutput(Whitespace); + } + } + } + + private void EncodeText(string value) + { + char[] text = value.ToCharArray(); + int len = text.Length; + int pos = 0; + + while (pos < len) + { + int next = pos; + while (next < len && text[next] >= 32 && text[next] < 127 && text[next] != '\\' && text[next] != '/' && + text[next] != '"') + { + next++; + } + WriteToOutput(text, pos, next - pos); + if (next < len) + { + switch (text[next]) + { + case '"': + WriteToOutput(@"\"""); + break; + case '\\': + WriteToOutput(@"\\"); + break; + //odd at best to escape '/', most Json implementations don't, but it is defined in the rfc-4627 + case '/': + WriteToOutput(@"\/"); + break; + case '\b': + WriteToOutput(@"\b"); + break; + case '\f': + WriteToOutput(@"\f"); + break; + case '\n': + WriteToOutput(@"\n"); + break; + case '\r': + WriteToOutput(@"\r"); + break; + case '\t': + WriteToOutput(@"\t"); + break; + default: + WriteToOutput(@"\u{0:x4}", (int) text[next]); + break; + } + next++; + } + pos = next; + } + } + + /// + /// Writes a String value + /// + protected override void WriteAsText(string field, string textValue, object typedValue) + { + WriteName(field); + if (typedValue is bool || typedValue is int || typedValue is uint || typedValue is long || + typedValue is ulong || typedValue is double || typedValue is float) + { + WriteToOutput(textValue); + } + else + { + WriteToOutput('"'); + if (typedValue is string) + { + EncodeText(textValue); + } + else + { + WriteToOutput(textValue); + } + WriteToOutput('"'); + } + } + + /// + /// Writes a Double value + /// + protected override void Write(string field, double value) + { + if (double.IsNaN(value) || double.IsNegativeInfinity(value) || double.IsPositiveInfinity(value)) + { + throw new InvalidOperationException("This format does not support NaN, Infinity, or -Infinity"); + } + base.Write(field, value); + } + + /// + /// Writes a Single value + /// + protected override void Write(string field, float value) + { + if (float.IsNaN(value) || float.IsNegativeInfinity(value) || float.IsPositiveInfinity(value)) + { + throw new InvalidOperationException("This format does not support NaN, Infinity, or -Infinity"); + } + base.Write(field, value); + } + + // Treat enum as string + protected override void WriteEnum(string field, int number, string name) + { + Write(field, name); + } + + /// + /// Writes an array of field values + /// + protected override void WriteArray(FieldType type, string field, IEnumerable items) + { + IEnumerator enumerator = items.GetEnumerator(); + try + { + if (!enumerator.MoveNext()) + { + return; + } + } + finally + { + if (enumerator is IDisposable) + { + ((IDisposable) enumerator).Dispose(); + } + } + + WriteName(field); + WriteToOutput("["); + _counter.Add(0); + + base.WriteArray(type, String.Empty, items); + + _counter.RemoveAt(_counter.Count - 1); + WriteLine("]"); + } + + /// + /// Writes a message + /// + protected override void WriteMessageOrGroup(string field, IMessageLite message) + { + WriteName(field); + WriteMessage(message); + } + + /// + /// Writes the message to the the formatted stream. + /// + public override void WriteMessage(IMessageLite message) + { + if (_isArray) + { + Seperator(); + } + WriteToOutput("{"); + _counter.Add(0); + message.WriteTo(this); + _counter.RemoveAt(_counter.Count - 1); + WriteLine("}"); + Flush(); + } + + /// + /// Used in streaming arrays of objects to the writer + /// + /// + /// + /// using(writer.StartArray()) + /// foreach(IMessageLite m in messages) + /// writer.WriteMessage(m); + /// + /// + public sealed class JsonArray : IDisposable + { + private JsonFormatWriter _writer; + + internal JsonArray(JsonFormatWriter writer) + { + _writer = writer; + _writer.WriteToOutput("["); + _writer._counter.Add(0); + } + + /// + /// Causes the end of the array character to be written. + /// + private void EndArray() + { + if (_writer != null) + { + _writer._counter.RemoveAt(_writer._counter.Count - 1); + _writer.WriteLine("]"); + _writer.Flush(); + } + _writer = null; + } + + void IDisposable.Dispose() + { + EndArray(); + } + } + + /// + /// Used to write an array of messages as the output rather than a single message. + /// + /// + /// + /// using(writer.StartArray()) + /// foreach(IMessageLite m in messages) + /// writer.WriteMessage(m); + /// + /// + public JsonArray StartArray() + { + if (_isArray) + { + Seperator(); + } + _isArray = true; + return new JsonArray(this); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Serialization/JsonTextCursor.cs b/src/ProtocolBuffers.Serialization/JsonTextCursor.cs new file mode 100644 index 00000000..48e84ccc --- /dev/null +++ b/src/ProtocolBuffers.Serialization/JsonTextCursor.cs @@ -0,0 +1,442 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.IO; + +namespace Google.ProtocolBuffers.Serialization +{ + /// + /// JSon Tokenizer used by JsonFormatReader + /// + internal abstract class JsonCursor + { + public enum JsType + { + String, + Number, + Object, + Array, + True, + False, + Null + } + + #region Buffering implementations + + private class JsonStreamCursor : JsonCursor + { + private readonly byte[] _buffer; + private int _bufferPos; + private readonly Stream _input; + + 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 class JsonTextCursor : JsonCursor + { + 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; + + 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() + { + _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(); + + public Char NextChar + { + get + { + SkipWhitespace(); + return (char) _next; + } + } + + #region Assert(...) + + [DebuggerNonUserCode] + private string CharDisplay(int ch) + { + return ch == -1 + ? "EOF" + : (ch > 32 && ch < 127) + ? String.Format("'{0}'", (char) ch) + : String.Format("'\\u{0:x4}'", ch); + } + + [DebuggerNonUserCode] + private void Assert(bool cond, char expected) + { + if (!cond) + { + throw new FormatException( + String.Format(CultureInfo.InvariantCulture, + "({0}:{1}) error: Unexpected token {2}, expected: {3}.", + _lineNo, _linePos, + CharDisplay(_next), + CharDisplay(expected) + )); + } + } + + [DebuggerNonUserCode] + public void Assert(bool cond, string message) + { + if (!cond) + { + throw new FormatException( + String.Format(CultureInfo.InvariantCulture, + "({0},{1}) error: {2}", _lineNo, _linePos, message)); + } + } + + [DebuggerNonUserCode] + public void Assert(bool cond, string format, params object[] args) + { + if (!cond) + { + if (args != null && args.Length > 0) + { + format = String.Format(format, args); + } + throw new FormatException( + String.Format(CultureInfo.InvariantCulture, + "({0},{1}) error: {2}", _lineNo, _linePos, format)); + } + } + + #endregion + + private char ReadChar() + { + int ch = Read(); + Assert(ch != -1, "Unexpected end of file."); + if (ch == '\n') + { + _lineNo++; + _linePos = 0; + } + else if (ch != '\r') + { + _linePos++; + } + _next = Peek(); + return (char) ch; + } + + public void Consume(char ch) + { + Assert(TryConsume(ch), ch); + } + + public bool TryConsume(char ch) + { + SkipWhitespace(); + if (_next == ch) + { + ReadChar(); + return true; + } + return false; + } + + public void Consume(string sequence) + { + SkipWhitespace(); + + foreach (char ch in sequence) + { + Assert(ch == ReadChar(), "Expected token '{0}'.", sequence); + } + } + + public void SkipWhitespace() + { + int chnext = _next; + while (chnext != -1) + { + if (!Char.IsWhiteSpace((char) chnext)) + { + break; + } + ReadChar(); + chnext = _next; + } + } + + public string ReadString() + { + SkipWhitespace(); + Consume('"'); + List sb = new List(100); + while (_next != '"') + { + if (_next == '\\') + { + Consume('\\'); //skip the escape + char ch = ReadChar(); + switch (ch) + { + case 'b': + sb.Add('\b'); + break; + case 'f': + sb.Add('\f'); + break; + case 'n': + sb.Add('\n'); + break; + case 'r': + sb.Add('\r'); + break; + case 't': + sb.Add('\t'); + break; + case 'u': + { + string hex = new string(new char[] {ReadChar(), ReadChar(), ReadChar(), ReadChar()}); + int result; + Assert( + int.TryParse(hex, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, + out result), + "Expected a 4-character hex specifier."); + sb.Add((char) result); + break; + } + default: + sb.Add(ch); + break; + } + } + else + { + Assert(_next != '\n' && _next != '\r' && _next != '\f' && _next != -1, '"'); + sb.Add(ReadChar()); + } + } + Consume('"'); + return new String(sb.ToArray()); + } + + public string ReadNumber() + { + SkipWhitespace(); + List sb = new List(24); + if (_next == '-') + { + sb.Add(ReadChar()); + } + Assert(_next >= '0' && _next <= '9', "Expected a numeric type."); + while ((_next >= '0' && _next <= '9') || _next == '.') + { + sb.Add(ReadChar()); + } + if (_next == 'e' || _next == 'E') + { + sb.Add(ReadChar()); + if (_next == '-' || _next == '+') + { + sb.Add(ReadChar()); + } + Assert(_next >= '0' && _next <= '9', "Expected a numeric type."); + while (_next >= '0' && _next <= '9') + { + sb.Add(ReadChar()); + } + } + return new String(sb.ToArray()); + } + + public JsType ReadVariant(out object value) + { + SkipWhitespace(); + switch (_next) + { + case 'n': + Consume("null"); + value = null; + return JsType.Null; + case 't': + Consume("true"); + value = true; + return JsType.True; + case 'f': + Consume("false"); + value = false; + return JsType.False; + case '"': + value = ReadString(); + return JsType.String; + case '{': + { + Consume('{'); + while (NextChar != '}') + { + ReadString(); + Consume(':'); + object tmp; + ReadVariant(out tmp); + if (!TryConsume(',')) + { + break; + } + } + Consume('}'); + value = null; + return JsType.Object; + } + case '[': + { + Consume('['); + List values = new List(); + while (NextChar != ']') + { + object tmp; + ReadVariant(out tmp); + values.Add(tmp); + if (!TryConsume(',')) + { + break; + } + } + Consume(']'); + value = values.ToArray(); + return JsType.Array; + } + default: + if ((_next >= '0' && _next <= '9') || _next == '-') + { + value = ReadNumber(); + return JsType.Number; + } + Assert(false, "Expected a value."); + throw new FormatException(); + } + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Serialization/Properties/AssemblyInfo.cs b/src/ProtocolBuffers.Serialization/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..fdae52b8 --- /dev/null +++ b/src/ProtocolBuffers.Serialization/Properties/AssemblyInfo.cs @@ -0,0 +1,76 @@ +// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +using System; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. + +[assembly: AssemblyTitle("ProtocolBuffers")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ProtocolBuffers")] +[assembly: AssemblyCopyright("Copyright © 2008")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. + +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM + +[assembly: Guid("279b643d-70e8-47ae-9eb1-500d1c48bab6")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("2.3.0.277")] + +[assembly: AssemblyVersion("2.3.0.277")] +#if !COMPACT_FRAMEWORK_35 + +[assembly: AssemblyFileVersion("2.3.0.277")] +#endif + +[assembly: CLSCompliant(true)] \ No newline at end of file diff --git a/src/ProtocolBuffers.Serialization/ProtocolBuffers.Serialization.csproj b/src/ProtocolBuffers.Serialization/ProtocolBuffers.Serialization.csproj new file mode 100644 index 00000000..0c53577c --- /dev/null +++ b/src/ProtocolBuffers.Serialization/ProtocolBuffers.Serialization.csproj @@ -0,0 +1,152 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {231391AF-449C-4A39-986C-AD7F270F4750} + Library + Properties + Google.ProtocolBuffers.Serialization + Google.ProtocolBuffers.Serialization + v2.0 + 512 + true + ..\..\keys\Google.ProtocolBuffers.snk + + + + + 3.5 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + $(OutputPath)\$(AssemblyName).xml + 1591, 1570, 1571, 1572, 1573, 1574 + DEBUG;TRACE + prompt + 4 + true + AllRules.ruleset + + + pdbonly + true + bin\Release\ + $(OutputPath)\$(AssemblyName).xml + 1591, 1570, 1571, 1572, 1573, 1574 + TRACE + prompt + 4 + true + AllRules.ruleset + + + true + full + false + bin\Debug_Silverlight2\ + $(OutputPath)\$(AssemblyName).xml + 1591, 1570, 1571, 1572, 1573, 1574 + DEBUG;TRACE;SILVERLIGHT2 + prompt + 4 + true + AllRules.ruleset + + + pdbonly + true + bin\Release_Silverlight2\ + $(OutputPath)\$(AssemblyName).xml + 1591, 1570, 1571, 1572, 1573, 1574 + TRACE;SILVERLIGHT2 + prompt + 4 + true + AllRules.ruleset + + + + + + + + False + ..\..\lib\System.Core\System.Core.dll + False + + + + + + + + + + + + + + + + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + {6908BDCE-D925-43F3-94AC-A531E6DF2591} + ProtocolBuffers + False + + + + + + + + \ No newline at end of file diff --git a/src/ProtocolBuffers.Serialization/RecursionLimitExceeded.cs b/src/ProtocolBuffers.Serialization/RecursionLimitExceeded.cs new file mode 100644 index 00000000..cdecb525 --- /dev/null +++ b/src/ProtocolBuffers.Serialization/RecursionLimitExceeded.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Google.ProtocolBuffers.Serialization +{ + /// + /// The exception raised when a recursion limit is reached while parsing input. + /// +#if !SILVERLIGHT2 + [Serializable] +#endif + public sealed class RecursionLimitExceededException : FormatException + { + const string message = "Possible malicious message had too many levels of nesting."; + + internal RecursionLimitExceededException() : base(message) + { + } + +#if !SILVERLIGHT2 + private RecursionLimitExceededException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) + : base(info, context) + { + } +#endif + } +} diff --git a/src/ProtocolBuffers.Serialization/XmlFormatReader.cs b/src/ProtocolBuffers.Serialization/XmlFormatReader.cs new file mode 100644 index 00000000..cb2cb2ea --- /dev/null +++ b/src/ProtocolBuffers.Serialization/XmlFormatReader.cs @@ -0,0 +1,296 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Xml; + +namespace Google.ProtocolBuffers.Serialization +{ + /// + /// Parses a proto buffer from an XML document or fragment. .NET 3.5 users may also + /// use this class to process Json by setting the options to support Json and providing + /// an XmlReader obtained from . + /// + public class XmlFormatReader : AbstractTextReader + { + public const string DefaultRootElementName = XmlFormatWriter.DefaultRootElementName; + private readonly XmlReader _input; + private string _rootElementName; + + private static XmlReaderSettings DefaultSettings + { + get + { + return new XmlReaderSettings() + {CheckCharacters = false, IgnoreComments = true, IgnoreProcessingInstructions = true}; + } + } + + /// + /// Constructs the XmlFormatReader using the stream provided as the xml + /// + 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 static XmlFormatReader CreateInstance(String input) + { + return new XmlFormatReader(XmlReader.Create(new StringReader(input), DefaultSettings)); + } + + /// + /// Constructs the XmlFormatReader using the xml in the TextReader + /// + public static XmlFormatReader CreateInstance(TextReader input) + { + return new XmlFormatReader(XmlReader.Create(input, DefaultSettings)); + } + + /// + /// Constructs the XmlFormatReader with the XmlReader + /// + public static XmlFormatReader CreateInstance(XmlReader input) + { + return new XmlFormatReader(input); + } + + /// + /// Constructs the XmlFormatReader with the XmlReader and options + /// + protected XmlFormatReader(XmlReader input) + { + _input = input; + _rootElementName = DefaultRootElementName; + Options = XmlReaderOptions.None; + } + + /// + /// Constructs the XmlFormatReader with the XmlReader and options + /// + protected XmlFormatReader(XmlFormatReader copyFrom, XmlReader input) + : base(copyFrom) + { + _input = input; + _rootElementName = copyFrom._rootElementName; + Options = copyFrom.Options; + } + + /// + /// 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>() + /// + public string RootElementName + { + get { return _rootElementName; } + set + { + ThrowHelper.ThrowIfNull(value, "RootElementName"); + _rootElementName = value; + } + } + + private XmlFormatReader CloneWith(XmlReader rdr) + { + XmlFormatReader copy = new XmlFormatReader(this, rdr); + return copy; + } + + private void NextElement() + { + while (!_input.IsStartElement() && _input.Read()) + { + continue; + } + } + + private static void Assert(bool cond) + { + if (!cond) + { + throw new FormatException(); + } + } + + /// + /// Merge the provided builder as an element named in the current context + /// + public override TBuilder Merge(TBuilder builder, ExtensionRegistry registry) + { + return Merge(_rootElementName, builder, registry); + } + + /// + /// Merge the provided builder as an element of the current context + /// + public TBuilder Merge(string element, TBuilder builder) where TBuilder : IBuilderLite + { + return Merge(element, builder, ExtensionRegistry.Empty); + } + + /// + /// Merge the provided builder as an element of the current context + /// + public TBuilder Merge(string element, TBuilder builder, ExtensionRegistry registry) + where TBuilder : IBuilderLite + { + string field; + Assert(PeekNext(out field) && field == element); + ReadMessage(builder, registry); + return builder; + } + + /// + /// Peeks at the next field in the input stream and returns what information is available. + /// + /// + /// This may be called multiple times without actually reading the field. Only after the field + /// is either read, or skipped, should PeekNext return a different value. + /// + protected override bool PeekNext(out string field) + { + NextElement(); + if (_input.IsStartElement()) + { + field = _input.LocalName; + return true; + } + field = null; + return false; + } + + /// + /// Causes the reader to skip past this field + /// + protected override void Skip() + { + if (_input.IsStartElement()) + { + if (!_input.IsEmptyElement) + { + int depth = _input.Depth; + while (_input.Depth >= depth && _input.NodeType != XmlNodeType.EndElement) + { + Assert(_input.Read()); + } + } + _input.Read(); + } + } + + /// + /// returns true if it was able to read a single value into the value reference. The value + /// stored may be of type System.String, System.Int32, or an IEnumLite from the IEnumLiteMap. + /// + protected override bool ReadEnum(ref object value) + { + int number; + string temp; + if (null != (temp = _input.GetAttribute("value")) && int.TryParse(temp, out number)) + { + Skip(); + value = number; + return true; + } + return base.ReadEnum(ref value); + } + + /// + /// Returns true if it was able to read a String from the input + /// + protected override bool ReadAsText(ref string value, Type type) + { + Assert(_input.NodeType == XmlNodeType.Element); + value = _input.ReadElementContentAsString(); + + return true; + } + + /// + /// Merges the input stream into the provided IBuilderLite + /// + protected override bool ReadMessage(IBuilderLite builder, ExtensionRegistry registry) + { + Assert(_input.IsStartElement()); + + if (!_input.IsEmptyElement) + { + int depth = _input.Depth; + XmlReader child = _input.ReadSubtree(); + while (!child.IsStartElement() && child.Read()) + { + continue; + } + child.Read(); + builder.WeakMergeFrom(CloneWith(child), registry); + Assert(depth == _input.Depth && _input.NodeType == XmlNodeType.EndElement); + } + _input.Read(); + return true; + } + + private IEnumerable NonNestedArrayItems(string field) + { + return base.ForeachArrayItem(field); + } + + /// + /// Cursors through the array elements and stops at the end of the array + /// + protected override IEnumerable ForeachArrayItem(string field) + { + bool isNested = (Options & XmlReaderOptions.ReadNestedArrays) != 0; + + if (!isNested) + { + foreach (string item in NonNestedArrayItems(field)) + { + yield return item; + } + yield break; + } + if (!_input.IsEmptyElement) + { + int depth = _input.Depth; + XmlReader child = _input.ReadSubtree(); + + while (!child.IsStartElement() && child.Read()) + { + continue; + } + child.Read(); + + foreach (string item in CloneWith(child).NonNestedArrayItems("item")) + { + yield return item; + } + Assert(depth == _input.Depth && _input.NodeType == XmlNodeType.EndElement); + } + _input.Read(); + yield break; + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Serialization/XmlFormatWriter.cs b/src/ProtocolBuffers.Serialization/XmlFormatWriter.cs new file mode 100644 index 00000000..fd36c1de --- /dev/null +++ b/src/ProtocolBuffers.Serialization/XmlFormatWriter.cs @@ -0,0 +1,243 @@ +using System; +using System.Collections; +using System.IO; +using System.Text; +using System.Xml; +using Google.ProtocolBuffers.Descriptors; + +namespace Google.ProtocolBuffers.Serialization +{ + /// + /// Writes a proto buffer to an XML document or fragment. .NET 3.5 users may also + /// use this class to produce Json by setting the options to support Json and providing + /// an XmlWriter obtained from . + /// + public class XmlFormatWriter : AbstractTextWriter + { + public const string DefaultRootElementName = "root"; + private const int NestedArrayFlag = 0x0001; + private readonly XmlWriter _output; + private string _rootElementName; + + private static XmlWriterSettings DefaultSettings(Encoding encoding) + { + return new XmlWriterSettings() + { + CheckCharacters = false, + NewLineHandling = NewLineHandling.Entitize, + OmitXmlDeclaration = true, + Encoding = encoding, + }; + } + + /// + /// Constructs the XmlFormatWriter to write to the given TextWriter + /// + 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 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 static XmlFormatWriter CreateInstance(XmlWriter output) + { + return new XmlFormatWriter(output); + } + + protected XmlFormatWriter(XmlWriter output) + { + _output = output; + _rootElementName = DefaultRootElementName; + } + + /// + /// Closes the underlying XmlTextWriter + /// + protected override void Dispose(bool disposing) + { + if (disposing) + { + _output.Close(); + } + } + + /// + /// Gets or sets the default element name to use when using the Merge<TBuilder>() + /// + public string RootElementName + { + get { return _rootElementName; } + set + { + ThrowHelper.ThrowIfNull(value, "RootElementName"); + _rootElementName = value; + } + } + + /// + /// 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; + } + + /// + /// Writes a message as an element using the name defined in + /// + public override void WriteMessage(IMessageLite message) + { + WriteMessage(_rootElementName, message); + } + + /// + /// Writes a message as an element with the given name + /// + public void WriteMessage(string elementName, IMessageLite message) + { + if (TestOption(XmlWriterOptions.OutputJsonTypes)) + { + _output.WriteStartElement("root"); // json requires this is the root-element + _output.WriteAttributeString("type", "object"); + } + else + { + _output.WriteStartElement(elementName); + } + + message.WriteTo(this); + _output.WriteEndElement(); + _output.Flush(); + } + + /// + /// Writes a message + /// + protected override void WriteMessageOrGroup(string field, IMessageLite message) + { + _output.WriteStartElement(field); + + if (TestOption(XmlWriterOptions.OutputJsonTypes)) + { + _output.WriteAttributeString("type", "object"); + } + + message.WriteTo(this); + _output.WriteEndElement(); + } + + /// + /// Writes a String value + /// + protected override void WriteAsText(string field, string textValue, object typedValue) + { + _output.WriteStartElement(field); + + if (TestOption(XmlWriterOptions.OutputJsonTypes)) + { + if (typedValue is int || typedValue is uint || typedValue is long || typedValue is ulong || + typedValue is double || typedValue is float) + { + _output.WriteAttributeString("type", "number"); + } + else if (typedValue is bool) + { + _output.WriteAttributeString("type", "boolean"); + } + } + _output.WriteString(textValue); + + //Empty strings should not be written as empty elements '', rather as '' + if (_output.WriteState == WriteState.Element) + { + _output.WriteRaw(""); + } + + _output.WriteEndElement(); + } + + /// + /// Writes an array of field values + /// + protected override void WriteArray(FieldType fieldType, string field, IEnumerable items) + { + //see if it's empty + IEnumerator eitems = items.GetEnumerator(); + try + { + if (!eitems.MoveNext()) + { + return; + } + } + finally + { + if (eitems is IDisposable) + { + ((IDisposable) eitems).Dispose(); + } + } + + if (TestOption(XmlWriterOptions.OutputNestedArrays | XmlWriterOptions.OutputJsonTypes)) + { + _output.WriteStartElement(field); + if (TestOption(XmlWriterOptions.OutputJsonTypes)) + { + _output.WriteAttributeString("type", "array"); + } + + base.WriteArray(fieldType, "item", items); + _output.WriteEndElement(); + } + else + { + base.WriteArray(fieldType, field, items); + } + } + + /// + /// Writes a System.Enum by the numeric and textual value + /// + protected override void WriteEnum(string field, int number, string name) + { + _output.WriteStartElement(field); + + if (!TestOption(XmlWriterOptions.OutputJsonTypes) && TestOption(XmlWriterOptions.OutputEnumValues)) + { + _output.WriteAttributeString("value", XmlConvert.ToString(number)); + } + + _output.WriteString(name); + _output.WriteEndElement(); + } + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Serialization/XmlReaderOptions.cs b/src/ProtocolBuffers.Serialization/XmlReaderOptions.cs new file mode 100644 index 00000000..f7eca1d7 --- /dev/null +++ b/src/ProtocolBuffers.Serialization/XmlReaderOptions.cs @@ -0,0 +1,17 @@ +using System; + +namespace Google.ProtocolBuffers.Serialization +{ + /// + /// Options available for the xml reader output + /// + [Flags] + public enum XmlReaderOptions + { + /// Simple xml formatting with no attributes + None, + + /// Requires that arrays items are nested in an <item> element + ReadNestedArrays = 1, + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Serialization/XmlWriterOptions.cs b/src/ProtocolBuffers.Serialization/XmlWriterOptions.cs new file mode 100644 index 00000000..7d740ee3 --- /dev/null +++ b/src/ProtocolBuffers.Serialization/XmlWriterOptions.cs @@ -0,0 +1,24 @@ +using System; + +namespace Google.ProtocolBuffers.Serialization +{ + /// + /// Options available for the xml writer output + /// + [Flags] + public enum XmlWriterOptions + { + /// Simple xml formatting with no attributes + None, + + /// Writes the 'value' attribute on all enumerations with the numeric identifier + OutputEnumValues = 0x1, + + /// Embeds array items into child <item> elements + OutputNestedArrays = 0x4, + + /// Outputs the 'type' attribute for compatibility with the JsonReaderWriterFactory + /// This option must, by nessessity, also enable NestedArrayItems + OutputJsonTypes = 0x8, + } +} \ No newline at end of file diff --git a/src/ProtocolBuffers.Test/ProtocolBuffers.Test.csproj b/src/ProtocolBuffers.Test/ProtocolBuffers.Test.csproj index 5e319875..bf224264 100644 --- a/src/ProtocolBuffers.Test/ProtocolBuffers.Test.csproj +++ b/src/ProtocolBuffers.Test/ProtocolBuffers.Test.csproj @@ -124,6 +124,10 @@ + + {231391AF-449C-4a39-986C-AD7F270F4750} + ProtocolBuffers.Serialization + {6908BDCE-D925-43F3-94AC-A531E6DF2591} ProtocolBuffers diff --git a/src/ProtocolBuffers.Test/TestWriterFormatJson.cs b/src/ProtocolBuffers.Test/TestWriterFormatJson.cs index fe6c22b4..3f534fc0 100644 --- a/src/ProtocolBuffers.Test/TestWriterFormatJson.cs +++ b/src/ProtocolBuffers.Test/TestWriterFormatJson.cs @@ -38,7 +38,7 @@ namespace Google.ProtocolBuffers TestAllTypes msg = new TestAllTypes.Builder().SetDefaultBool(true).Build(); string json = msg.ToJson(); Assert.AreEqual("{\"default_bool\":true}", json); - TestAllTypes copy = TestAllTypes.ParseFromJson(json); + TestAllTypes copy = new TestAllTypes.Builder().MergeFromJson(json).Build(); Assert.IsTrue(copy.HasDefaultBool && copy.DefaultBool); Assert.AreEqual(msg, copy); } @@ -49,7 +49,7 @@ namespace Google.ProtocolBuffers TestAllTypes msg = new TestAllTypes.Builder().SetDefaultBool(true).Build(); string json = msg.ToJson(); Assert.AreEqual("{\"default_bool\":true}", json); - TestAllTypes copy = TestAllTypes.ParseFromJson(new StringReader(json)); + TestAllTypes copy = new TestAllTypes.Builder().MergeFromJson(new StringReader(json)).Build(); Assert.IsTrue(copy.HasDefaultBool && copy.DefaultBool); Assert.AreEqual(msg, copy); } @@ -337,13 +337,13 @@ namespace Google.ProtocolBuffers Assert.AreEqual(3, ordinal); Assert.AreEqual(3, builder.TextlinesCount); } - [Test,ExpectedException(typeof(InvalidProtocolBufferException))] + [Test,ExpectedException(typeof(RecursionLimitExceededException))] public void TestRecursiveLimit() { StringBuilder sb = new StringBuilder(8192); for (int i = 0; i < 80; i++) sb.Append("{\"child\":"); - TestXmlRescursive msg = TestXmlRescursive.ParseFromJson(sb.ToString()); + TestXmlRescursive msg = new TestXmlRescursive.Builder().MergeFromJson(sb.ToString()).Build(); } [Test, ExpectedException(typeof(FormatException))] public void FailWithEmptyText() diff --git a/src/ProtocolBuffers.Test/TestWriterFormatXml.cs b/src/ProtocolBuffers.Test/TestWriterFormatXml.cs index acad6f13..2ffca9fb 100644 --- a/src/ProtocolBuffers.Test/TestWriterFormatXml.cs +++ b/src/ProtocolBuffers.Test/TestWriterFormatXml.cs @@ -18,7 +18,7 @@ namespace Google.ProtocolBuffers TestAllTypes msg = new TestAllTypes.Builder().SetDefaultBool(true).Build(); string xml = msg.ToXml(); Assert.AreEqual("true", xml); - TestAllTypes copy = TestAllTypes.ParseFromXml(XmlReader.Create(new StringReader(xml))); + TestAllTypes copy = new TestAllTypes.Builder().MergeFromXml(XmlReader.Create(new StringReader(xml))).Build(); Assert.IsTrue(copy.HasDefaultBool && copy.DefaultBool); Assert.AreEqual(msg, copy); } @@ -29,7 +29,7 @@ namespace Google.ProtocolBuffers TestAllTypes msg = new TestAllTypes.Builder().SetDefaultBool(true).Build(); string xml = msg.ToXml("message"); Assert.AreEqual("true", xml); - TestAllTypes copy = TestAllTypes.ParseFromXml("message", XmlReader.Create(new StringReader(xml))); + TestAllTypes copy = new TestAllTypes.Builder().MergeFromXml("message", XmlReader.Create(new StringReader(xml))).Build(); Assert.IsTrue(copy.HasDefaultBool && copy.DefaultBool); Assert.AreEqual(msg, copy); } @@ -324,13 +324,13 @@ namespace Google.ProtocolBuffers TestXmlMessage copy = rdr.Merge(TestXmlMessage.CreateBuilder(), registry).Build(); Assert.AreEqual(message, copy); } - [Test, ExpectedException(typeof(InvalidProtocolBufferException))] + [Test, ExpectedException(typeof(RecursionLimitExceededException))] public void TestRecursiveLimit() { StringBuilder sb = new StringBuilder(8192); for (int i = 0; i < 80; i++) sb.Append(""); - TestXmlRescursive msg = TestXmlRescursive.ParseFromXml("child", XmlReader.Create(new StringReader(sb.ToString()))); + TestXmlRescursive msg = new TestXmlRescursive.Builder().MergeFromXml("child", XmlReader.Create(new StringReader(sb.ToString()))).Build(); } } } diff --git a/src/ProtocolBuffers.sln b/src/ProtocolBuffers.sln index a7323db1..04e1c9cd 100644 --- a/src/ProtocolBuffers.sln +++ b/src/ProtocolBuffers.sln @@ -1,5 +1,4 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 +Microsoft Visual Studio Solution File, Format Version 11.00 # Visual Studio 2010 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "proto", "proto", "{1F896D5C-5FC2-4671-9216-781CB8187EC7}" ProjectSection(SolutionItems) = preProject @@ -67,6 +66,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{66ED1950 ..\build\RunBenchmarks.bat = ..\build\RunBenchmarks.bat EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProtocolBuffers.Serialization", "ProtocolBuffers.Serialization\ProtocolBuffers.Serialization.csproj", "{231391AF-449C-4a39-986C-AD7F270F4750}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug_Silverlight2|Any CPU = Debug_Silverlight2|Any CPU @@ -145,6 +146,14 @@ Global {EEFFED24-3750-4567-9A23-1DB676A15610}.Release_Silverlight2|Any CPU.ActiveCfg = Release|Any CPU {EEFFED24-3750-4567-9A23-1DB676A15610}.Release|Any CPU.ActiveCfg = Release|Any CPU {EEFFED24-3750-4567-9A23-1DB676A15610}.Release|Any CPU.Build.0 = Release|Any CPU + {231391AF-449C-4a39-986C-AD7F270F4750}.Debug_Silverlight2|Any CPU.ActiveCfg = Debug_Silverlight2|Any CPU + {231391AF-449C-4a39-986C-AD7F270F4750}.Debug_Silverlight2|Any CPU.Build.0 = Debug_Silverlight2|Any CPU + {231391AF-449C-4a39-986C-AD7F270F4750}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {231391AF-449C-4a39-986C-AD7F270F4750}.Debug|Any CPU.Build.0 = Debug|Any CPU + {231391AF-449C-4a39-986C-AD7F270F4750}.Release_Silverlight2|Any CPU.ActiveCfg = Release_Silverlight2|Any CPU + {231391AF-449C-4a39-986C-AD7F270F4750}.Release_Silverlight2|Any CPU.Build.0 = Release_Silverlight2|Any CPU + {231391AF-449C-4a39-986C-AD7F270F4750}.Release|Any CPU.ActiveCfg = Release|Any CPU + {231391AF-449C-4a39-986C-AD7F270F4750}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/ProtocolBuffers/AbstractMessage.cs b/src/ProtocolBuffers/AbstractMessage.cs index 0c898c70..13443b1c 100644 --- a/src/ProtocolBuffers/AbstractMessage.cs +++ b/src/ProtocolBuffers/AbstractMessage.cs @@ -40,7 +40,6 @@ using System.IO; using System.Text; using Google.ProtocolBuffers.Collections; using Google.ProtocolBuffers.Descriptors; -using Google.ProtocolBuffers.Serialization; namespace Google.ProtocolBuffers { @@ -123,27 +122,6 @@ namespace Google.ProtocolBuffers return TextFormat.PrintToString(this); } - public string ToJson() - { - JsonFormatWriter w = JsonFormatWriter.CreateInstance(); - w.WriteMessage(this); - return w.ToString(); - } - - public string ToXml() - { - StringWriter w = new StringWriter(new StringBuilder(4096)); - XmlFormatWriter.CreateInstance(w).WriteMessage(this); - return w.ToString(); - } - - public string ToXml(string rootElementName) - { - StringWriter w = new StringWriter(new StringBuilder(4096)); - XmlFormatWriter.CreateInstance(w).WriteMessage(rootElementName, this); - return w.ToString(); - } - public override sealed void PrintTo(TextWriter writer) { TextFormat.Print(this, writer); diff --git a/src/ProtocolBuffers/GeneratedMessage.cs b/src/ProtocolBuffers/GeneratedMessage.cs index 8147a88b..ce755bed 100644 --- a/src/ProtocolBuffers/GeneratedMessage.cs +++ b/src/ProtocolBuffers/GeneratedMessage.cs @@ -42,7 +42,6 @@ using System.Xml; using Google.ProtocolBuffers.Collections; using Google.ProtocolBuffers.Descriptors; using Google.ProtocolBuffers.FieldAccess; -using Google.ProtocolBuffers.Serialization; namespace Google.ProtocolBuffers { @@ -178,42 +177,5 @@ namespace Google.ProtocolBuffers { unknownFields = fieldSet; } - - public static TMessage ParseFromJson(string jsonText) - { - return JsonFormatReader.CreateInstance(jsonText) - .Merge(new TBuilder()) - .Build(); - } - - public static TMessage ParseFromJson(TextReader reader) - { - return ParseFromJson(reader, ExtensionRegistry.Empty); - } - - public static TMessage ParseFromJson(TextReader reader, ExtensionRegistry extensionRegistry) - { - return JsonFormatReader.CreateInstance(reader) - .Merge(new TBuilder(), extensionRegistry) - .Build(); - } - - public static TMessage ParseFromXml(XmlReader reader) - { - return ParseFromXml(XmlFormatReader.DefaultRootElementName, reader, ExtensionRegistry.Empty); - } - - public static TMessage ParseFromXml(string rootElementName, XmlReader reader) - { - return ParseFromXml(rootElementName, reader, ExtensionRegistry.Empty); - } - - public static TMessage ParseFromXml(string rootElementName, XmlReader reader, - ExtensionRegistry extensionRegistry) - { - return XmlFormatReader.CreateInstance(reader) - .Merge(rootElementName, new TBuilder(), extensionRegistry) - .Build(); - } } } \ No newline at end of file diff --git a/src/ProtocolBuffers/IMessage.cs b/src/ProtocolBuffers/IMessage.cs index 514c4bf8..c23bc3f7 100644 --- a/src/ProtocolBuffers/IMessage.cs +++ b/src/ProtocolBuffers/IMessage.cs @@ -184,24 +184,6 @@ namespace Google.ProtocolBuffers /// new byte[] ToByteArray(); - /// - /// Serializes the message to JSON text. This is a trivial wrapper - /// around Serialization.JsonFormatWriter.WriteMessage. - /// - string ToJson(); - - /// - /// Serializes the message to XML text. This is a trivial wrapper - /// around Serialization.XmlFormatWriter.WriteMessage. - /// - string ToXml(); - - /// - /// Serializes the message to XML text using the element name provided. - /// This is a trivial wrapper around Serialization.XmlFormatWriter.WriteMessage. - /// - string ToXml(string rootElementName); - /// /// Serializes the message and writes it to the given stream. /// This is just a wrapper around WriteTo(ICodedOutputStream). This diff --git a/src/ProtocolBuffers/ProtocolBuffers.csproj b/src/ProtocolBuffers/ProtocolBuffers.csproj index d278d8a3..336b387f 100644 --- a/src/ProtocolBuffers/ProtocolBuffers.csproj +++ b/src/ProtocolBuffers/ProtocolBuffers.csproj @@ -88,7 +88,6 @@ - @@ -181,19 +180,6 @@ - - - - - - - - - - - - - diff --git a/src/ProtocolBuffers/Serialization/AbstractReader.cs b/src/ProtocolBuffers/Serialization/AbstractReader.cs deleted file mode 100644 index bc1fa6cd..00000000 --- a/src/ProtocolBuffers/Serialization/AbstractReader.cs +++ /dev/null @@ -1,685 +0,0 @@ -using System; -using System.Collections.Generic; -using Google.ProtocolBuffers.Descriptors; - -//Disable CS3011: only CLS-compliant members can be abstract -#pragma warning disable 3011 - -namespace Google.ProtocolBuffers.Serialization -{ - /// - /// Provides a base-class that provides some basic functionality for handling type dispatching - /// - public abstract class AbstractReader : ICodedInputStream - { - private const int MaxDepth = CodedInputStream.DefaultRecursionLimit; - protected int Depth; - - /// - /// Merges the contents of stream into the provided message builder - /// - public TBuilder Merge(TBuilder builder) where TBuilder : IBuilderLite - { - return Merge(builder, ExtensionRegistry.Empty); - } - - /// - /// Merges the contents of stream into the provided message builder - /// - public abstract TBuilder Merge(TBuilder builder, ExtensionRegistry registry) - where TBuilder : IBuilderLite; - - /// - /// Peeks at the next field in the input stream and returns what information is available. - /// - /// - /// This may be called multiple times without actually reading the field. Only after the field - /// is either read, or skipped, should PeekNext return a different value. - /// - protected abstract bool PeekNext(out string field); - - /// - /// Causes the reader to skip past this field - /// - protected abstract void Skip(); - - /// - /// Returns true if it was able to read a Boolean from the input - /// - protected abstract bool Read(ref bool value); - - /// - /// Returns true if it was able to read a Int32 from the input - /// - protected abstract bool Read(ref int value); - - /// - /// Returns true if it was able to read a UInt32 from the input - /// - [CLSCompliant(false)] - protected abstract bool Read(ref uint value); - - /// - /// Returns true if it was able to read a Int64 from the input - /// - protected abstract bool Read(ref long value); - - /// - /// Returns true if it was able to read a UInt64 from the input - /// - [CLSCompliant(false)] - protected abstract bool Read(ref ulong value); - - /// - /// Returns true if it was able to read a Single from the input - /// - protected abstract bool Read(ref float value); - - /// - /// Returns true if it was able to read a Double from the input - /// - protected abstract bool Read(ref double value); - - /// - /// Returns true if it was able to read a String from the input - /// - protected abstract bool Read(ref string value); - - /// - /// Returns true if it was able to read a ByteString from the input - /// - protected abstract bool Read(ref ByteString value); - - /// - /// returns true if it was able to read a single value into the value reference. The value - /// stored may be of type System.String, System.Int32, or an IEnumLite from the IEnumLiteMap. - /// - protected abstract bool ReadEnum(ref object value); - - /// - /// Merges the input stream into the provided IBuilderLite - /// - protected abstract bool ReadMessage(IBuilderLite builder, ExtensionRegistry registry); - - /// - /// Merges the input stream into the provided IBuilderLite - /// - public virtual bool ReadGroup(IBuilderLite value, ExtensionRegistry registry) - { - return ReadMessage(value, registry); - } - - /// - /// Cursors through the array elements and stops at the end of the array - /// - protected virtual IEnumerable ForeachArrayItem(string field) - { - string next = field; - while (true) - { - yield return next; - - if (!PeekNext(out next) || next != field) - { - break; - } - } - } - - /// - /// Reads an array of T messages - /// - public virtual bool ReadMessageArray(string field, ICollection items, IMessageLite messageType, - ExtensionRegistry registry) - { - bool success = false; - foreach (string next in ForeachArrayItem(field)) - { - IBuilderLite builder = messageType.WeakCreateBuilderForType(); - if (ReadMessage(builder, registry)) - { - items.Add((T) builder.WeakBuild()); - success |= true; - } - } - return success; - } - - /// - /// Reads an array of T messages as a proto-buffer group - /// - public virtual bool ReadGroupArray(string field, ICollection items, IMessageLite messageType, - ExtensionRegistry registry) - { - bool success = false; - foreach (string next in ForeachArrayItem(field)) - { - IBuilderLite builder = messageType.WeakCreateBuilderForType(); - if (ReadGroup(builder, registry)) - { - items.Add((T) builder.WeakBuild()); - success |= true; - } - } - return success; - } - - /// - /// Reads an array of System.Enum type T and adds them to the collection - /// - public virtual bool ReadEnumArray(string field, ICollection items) - { - bool success = false; - foreach (string next in ForeachArrayItem(field)) - { - object temp = null; - if (ReadEnum(ref temp)) - { - items.Add(temp); - success |= true; - } - } - return success; - } - - /// - /// Reads an array of T, where T is a primitive type defined by FieldType - /// - public virtual bool ReadArray(FieldType type, string field, ICollection items) - { - bool success = false; - foreach (string next in ForeachArrayItem(field)) - { - object temp = null; - if (ReadField(type, ref temp)) - { - items.Add((T) temp); - success |= true; - } - } - return success; - } - - /// - /// returns true if it was able to read a single primitive value of FieldType into the value reference - /// - public virtual bool ReadField(FieldType type, ref object value) - { - switch (type) - { - case FieldType.Bool: - { - bool temp = false; - if (Read(ref temp)) - { - value = temp; - } - else - { - return false; - } - break; - } - case FieldType.Int64: - case FieldType.SInt64: - case FieldType.SFixed64: - { - long temp = 0; - if (Read(ref temp)) - { - value = temp; - } - else - { - return false; - } - break; - } - case FieldType.UInt64: - case FieldType.Fixed64: - { - ulong temp = 0; - if (Read(ref temp)) - { - value = temp; - } - else - { - return false; - } - break; - } - case FieldType.Int32: - case FieldType.SInt32: - case FieldType.SFixed32: - { - int temp = 0; - if (Read(ref temp)) - { - value = temp; - } - else - { - return false; - } - break; - } - case FieldType.UInt32: - case FieldType.Fixed32: - { - uint temp = 0; - if (Read(ref temp)) - { - value = temp; - } - else - { - return false; - } - break; - } - case FieldType.Float: - { - float temp = float.NaN; - if (Read(ref temp)) - { - value = temp; - } - else - { - return false; - } - break; - } - case FieldType.Double: - { - double temp = float.NaN; - if (Read(ref temp)) - { - value = temp; - } - else - { - return false; - } - break; - } - case FieldType.String: - { - string temp = null; - if (Read(ref temp)) - { - value = temp; - } - else - { - return false; - } - break; - } - case FieldType.Bytes: - { - ByteString temp = null; - if (Read(ref temp)) - { - value = temp; - } - else - { - return false; - } - break; - } - default: - throw InvalidProtocolBufferException.InvalidTag(); - } - return true; - } - - #region ICodedInputStream Members - - bool ICodedInputStream.ReadTag(out uint fieldTag, out string fieldName) - { - fieldTag = 0; - if (PeekNext(out fieldName)) - { - return true; - } - return false; - } - - bool ICodedInputStream.ReadDouble(ref double value) - { - return Read(ref value); - } - - bool ICodedInputStream.ReadFloat(ref float value) - { - return Read(ref value); - } - - bool ICodedInputStream.ReadUInt64(ref ulong value) - { - return Read(ref value); - } - - bool ICodedInputStream.ReadInt64(ref long value) - { - return Read(ref value); - } - - bool ICodedInputStream.ReadInt32(ref int value) - { - return Read(ref value); - } - - bool ICodedInputStream.ReadFixed64(ref ulong value) - { - return Read(ref value); - } - - bool ICodedInputStream.ReadFixed32(ref uint value) - { - return Read(ref value); - } - - bool ICodedInputStream.ReadBool(ref bool value) - { - return Read(ref value); - } - - bool ICodedInputStream.ReadString(ref string value) - { - return Read(ref value); - } - - void ICodedInputStream.ReadGroup(int fieldNumber, IBuilderLite builder, ExtensionRegistry extensionRegistry) - { - if (Depth++ > MaxDepth) - { - throw InvalidProtocolBufferException.RecursionLimitExceeded(); - } - ReadGroup(builder, extensionRegistry); - Depth--; - } - - void ICodedInputStream.ReadUnknownGroup(int fieldNumber, IBuilderLite builder) - { - throw new NotSupportedException(); - } - - void ICodedInputStream.ReadMessage(IBuilderLite builder, ExtensionRegistry extensionRegistry) - { - if (Depth++ > MaxDepth) - { - throw InvalidProtocolBufferException.RecursionLimitExceeded(); - } - ReadMessage(builder, extensionRegistry); - Depth--; - } - - bool ICodedInputStream.ReadBytes(ref ByteString value) - { - return Read(ref value); - } - - bool ICodedInputStream.ReadUInt32(ref uint value) - { - return Read(ref value); - } - - bool ICodedInputStream.ReadEnum(ref IEnumLite value, out object unknown, IEnumLiteMap mapping) - { - value = null; - unknown = null; - if (ReadEnum(ref unknown)) - { - if (unknown is int) - { - value = mapping.FindValueByNumber((int) unknown); - } - else if (unknown is string) - { - value = mapping.FindValueByName((string) unknown); - } - return value != null; - } - return false; - } - - bool ICodedInputStream.ReadEnum(ref T value, out object rawValue) - { - rawValue = null; - if (ReadEnum(ref rawValue)) - { - if (Enum.IsDefined(typeof (T), rawValue)) - { - if (rawValue is int) - { - value = (T) rawValue; - } - else if (rawValue is string) - { - value = (T) Enum.Parse(typeof (T), (string) rawValue, false); - } - else - { - value = default(T); - return false; - } - return true; - } - } - return false; - } - - bool ICodedInputStream.ReadSFixed32(ref int value) - { - return Read(ref value); - } - - bool ICodedInputStream.ReadSFixed64(ref long value) - { - return Read(ref value); - } - - bool ICodedInputStream.ReadSInt32(ref int value) - { - return Read(ref value); - } - - bool ICodedInputStream.ReadSInt64(ref long value) - { - return Read(ref value); - } - - void ICodedInputStream.ReadPrimitiveArray(FieldType fieldType, uint fieldTag, string fieldName, - ICollection list) - { - ReadArray(fieldType, fieldName, list); - } - - void ICodedInputStream.ReadEnumArray(uint fieldTag, string fieldName, ICollection list, - out ICollection unknown, IEnumLiteMap mapping) - { - unknown = null; - List array = new List(); - if (ReadEnumArray(fieldName, array)) - { - foreach (object rawValue in array) - { - IEnumLite item = null; - if (rawValue is int) - { - item = mapping.FindValueByNumber((int) rawValue); - } - else if (rawValue is string) - { - item = mapping.FindValueByName((string) rawValue); - } - - if (item != null) - { - list.Add(item); - } - else - { - if (unknown == null) - { - unknown = new List(); - } - unknown.Add(rawValue); - } - } - } - } - - void ICodedInputStream.ReadEnumArray(uint fieldTag, string fieldName, ICollection list, - out ICollection unknown) - { - unknown = null; - List array = new List(); - if (ReadEnumArray(fieldName, array)) - { - foreach (object rawValue in array) - { - if (rawValue is int) - { - list.Add((T) rawValue); - } - else if (rawValue is string) - { - list.Add((T) Enum.Parse(typeof (T), (string) rawValue, false)); - } - else - { - if (unknown == null) - { - unknown = new List(); - } - unknown.Add(rawValue); - } - } - } - } - - void ICodedInputStream.ReadMessageArray(uint fieldTag, string fieldName, ICollection list, T messageType, - ExtensionRegistry registry) - { - if (Depth++ > MaxDepth) - { - throw InvalidProtocolBufferException.RecursionLimitExceeded(); - } - ReadMessageArray(fieldName, list, messageType, registry); - Depth--; - } - - void ICodedInputStream.ReadGroupArray(uint fieldTag, string fieldName, ICollection list, T messageType, - ExtensionRegistry registry) - { - if (Depth++ > MaxDepth) - { - throw InvalidProtocolBufferException.RecursionLimitExceeded(); - } - ReadGroupArray(fieldName, list, messageType, registry); - Depth--; - } - - bool ICodedInputStream.ReadPrimitiveField(FieldType fieldType, ref object value) - { - return ReadField(fieldType, ref value); - } - - bool ICodedInputStream.IsAtEnd - { - get - { - string next; - return PeekNext(out next) == false; - } - } - - bool ICodedInputStream.SkipField() - { - Skip(); - return true; - } - - void ICodedInputStream.ReadStringArray(uint fieldTag, string fieldName, ICollection list) - { - ReadArray(FieldType.String, fieldName, list); - } - - void ICodedInputStream.ReadBytesArray(uint fieldTag, string fieldName, ICollection list) - { - ReadArray(FieldType.Bytes, fieldName, list); - } - - void ICodedInputStream.ReadBoolArray(uint fieldTag, string fieldName, ICollection list) - { - ReadArray(FieldType.Bool, fieldName, list); - } - - void ICodedInputStream.ReadInt32Array(uint fieldTag, string fieldName, ICollection list) - { - ReadArray(FieldType.Int32, fieldName, list); - } - - void ICodedInputStream.ReadSInt32Array(uint fieldTag, string fieldName, ICollection list) - { - ReadArray(FieldType.SInt32, fieldName, list); - } - - void ICodedInputStream.ReadUInt32Array(uint fieldTag, string fieldName, ICollection list) - { - ReadArray(FieldType.UInt32, fieldName, list); - } - - void ICodedInputStream.ReadFixed32Array(uint fieldTag, string fieldName, ICollection list) - { - ReadArray(FieldType.Fixed32, fieldName, list); - } - - void ICodedInputStream.ReadSFixed32Array(uint fieldTag, string fieldName, ICollection list) - { - ReadArray(FieldType.SFixed32, fieldName, list); - } - - void ICodedInputStream.ReadInt64Array(uint fieldTag, string fieldName, ICollection list) - { - ReadArray(FieldType.Int64, fieldName, list); - } - - void ICodedInputStream.ReadSInt64Array(uint fieldTag, string fieldName, ICollection list) - { - ReadArray(FieldType.SInt64, fieldName, list); - } - - void ICodedInputStream.ReadUInt64Array(uint fieldTag, string fieldName, ICollection list) - { - ReadArray(FieldType.UInt64, fieldName, list); - } - - void ICodedInputStream.ReadFixed64Array(uint fieldTag, string fieldName, ICollection list) - { - ReadArray(FieldType.Fixed64, fieldName, list); - } - - void ICodedInputStream.ReadSFixed64Array(uint fieldTag, string fieldName, ICollection list) - { - ReadArray(FieldType.SFixed64, fieldName, list); - } - - void ICodedInputStream.ReadDoubleArray(uint fieldTag, string fieldName, ICollection list) - { - ReadArray(FieldType.Double, fieldName, list); - } - - void ICodedInputStream.ReadFloatArray(uint fieldTag, string fieldName, ICollection list) - { - ReadArray(FieldType.Float, fieldName, list); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/ProtocolBuffers/Serialization/AbstractTextReader.cs b/src/ProtocolBuffers/Serialization/AbstractTextReader.cs deleted file mode 100644 index 83a8dca5..00000000 --- a/src/ProtocolBuffers/Serialization/AbstractTextReader.cs +++ /dev/null @@ -1,174 +0,0 @@ -using System; -using System.Globalization; -using System.Xml; - -namespace Google.ProtocolBuffers.Serialization -{ - /// - /// Provides a base class for text-parsing readers - /// - public abstract class AbstractTextReader : AbstractReader - { - /// - /// Reads a typed field as a string - /// - protected abstract bool ReadAsText(ref string textValue, Type type); - - /// - /// Returns true if it was able to read a String from the input - /// - protected override bool Read(ref string value) - { - string text = null; - if (ReadAsText(ref text, typeof (string))) - { - value = text; - return true; - } - return false; - } - - /// - /// Returns true if it was able to read a Boolean from the input - /// - protected override bool Read(ref bool value) - { - string text = null; - if (ReadAsText(ref text, typeof (bool))) - { - value = XmlConvert.ToBoolean(text); - return true; - } - return false; - } - - /// - /// Returns true if it was able to read a Int32 from the input - /// - protected override bool Read(ref int value) - { - string text = null; - if (ReadAsText(ref text, typeof (int))) - { - value = XmlConvert.ToInt32(text); - return true; - } - return false; - } - - /// - /// Returns true if it was able to read a UInt32 from the input - /// - [CLSCompliant(false)] - protected override bool Read(ref uint value) - { - string text = null; - if (ReadAsText(ref text, typeof (uint))) - { - value = XmlConvert.ToUInt32(text); - return true; - } - return false; - } - - /// - /// Returns true if it was able to read a Int64 from the input - /// - protected override bool Read(ref long value) - { - string text = null; - if (ReadAsText(ref text, typeof (long))) - { - value = XmlConvert.ToInt64(text); - return true; - } - return false; - } - - /// - /// Returns true if it was able to read a UInt64 from the input - /// - [CLSCompliant(false)] - protected override bool Read(ref ulong value) - { - string text = null; - if (ReadAsText(ref text, typeof (ulong))) - { - value = XmlConvert.ToUInt64(text); - return true; - } - return false; - } - - /// - /// Returns true if it was able to read a Single from the input - /// - protected override bool Read(ref float value) - { - string text = null; - if (ReadAsText(ref text, typeof (float))) - { - value = XmlConvert.ToSingle(text); - return true; - } - return false; - } - - /// - /// Returns true if it was able to read a Double from the input - /// - protected override bool Read(ref double value) - { - string text = null; - if (ReadAsText(ref text, typeof (double))) - { - value = XmlConvert.ToDouble(text); - return true; - } - return false; - } - - /// - /// Provides decoding of bytes read from the input stream - /// - protected virtual ByteString DecodeBytes(string bytes) - { - return ByteString.FromBase64(bytes); - } - - /// - /// Returns true if it was able to read a ByteString from the input - /// - protected override bool Read(ref ByteString value) - { - string text = null; - if (ReadAsText(ref text, typeof (ByteString))) - { - value = DecodeBytes(text); - return true; - } - return false; - } - - /// - /// returns true if it was able to read a single value into the value reference. The value - /// stored may be of type System.String, System.Int32, or an IEnumLite from the IEnumLiteMap. - /// - protected override bool ReadEnum(ref object value) - { - string text = null; - if (ReadAsText(ref text, typeof (Enum))) - { - int number; - if (int.TryParse(text, NumberStyles.Integer, CultureInfo.InvariantCulture, out number)) - { - value = number; - return true; - } - value = text; - return true; - } - return false; - } - } -} \ No newline at end of file diff --git a/src/ProtocolBuffers/Serialization/AbstractTextWriter.cs b/src/ProtocolBuffers/Serialization/AbstractTextWriter.cs deleted file mode 100644 index 2c778dfc..00000000 --- a/src/ProtocolBuffers/Serialization/AbstractTextWriter.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System; -using System.Xml; - -namespace Google.ProtocolBuffers.Serialization -{ - /// - /// Provides a base class for text writers - /// - public abstract class AbstractTextWriter : AbstractWriter - { - /// - /// Encodes raw bytes to be written to the stream - /// - protected virtual string EncodeBytes(ByteString bytes) - { - return bytes.ToBase64(); - } - - /// - /// Writes a typed field as a text value - /// - protected abstract void WriteAsText(string field, string textValue, object typedValue); - - /// - /// Writes a String value - /// - protected override void Write(string field, string value) - { - WriteAsText(field, value, value); - } - - /// - /// Writes a Boolean value - /// - protected override void Write(string field, bool value) - { - WriteAsText(field, XmlConvert.ToString(value), value); - } - - /// - /// Writes a Int32 value - /// - protected override void Write(string field, int value) - { - WriteAsText(field, XmlConvert.ToString(value), value); - } - - /// - /// Writes a UInt32 value - /// - [CLSCompliant(false)] - protected override void Write(string field, uint value) - { - WriteAsText(field, XmlConvert.ToString(value), value); - } - - /// - /// Writes a Int64 value - /// - protected override void Write(string field, long value) - { - WriteAsText(field, XmlConvert.ToString(value), value); - } - - /// - /// Writes a UInt64 value - /// - [CLSCompliant(false)] - protected override void Write(string field, ulong value) - { - WriteAsText(field, XmlConvert.ToString(value), value); - } - - /// - /// Writes a Single value - /// - protected override void Write(string field, float value) - { - WriteAsText(field, XmlConvert.ToString(value), value); - } - - /// - /// Writes a Double value - /// - protected override void Write(string field, double value) - { - WriteAsText(field, XmlConvert.ToString(value), value); - } - - /// - /// Writes a set of bytes - /// - protected override void Write(string field, ByteString value) - { - WriteAsText(field, EncodeBytes(value), value); - } - - /// - /// Writes a System.Enum by the numeric and textual value - /// - protected override void WriteEnum(string field, int number, string name) - { - WriteAsText(field, name, number); - } - } -} \ No newline at end of file diff --git a/src/ProtocolBuffers/Serialization/AbstractWriter.cs b/src/ProtocolBuffers/Serialization/AbstractWriter.cs deleted file mode 100644 index 6592c1dd..00000000 --- a/src/ProtocolBuffers/Serialization/AbstractWriter.cs +++ /dev/null @@ -1,504 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Globalization; -using Google.ProtocolBuffers.Descriptors; - -//Disable CS3011: only CLS-compliant members can be abstract -#pragma warning disable 3011 - -namespace Google.ProtocolBuffers.Serialization -{ - /// - /// Provides a base class for writers that performs some basic type dispatching - /// - public abstract class AbstractWriter : ICodedOutputStream, IDisposable - { - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - GC.SuppressFinalize(this); - Flush(); - Dispose(true); - } - - /// - /// Completes any pending write operations - /// - public virtual void Flush() - { - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - protected virtual void Dispose(bool disposing) - { - } - - /// - /// Writes the message to the the formatted stream. - /// - public abstract void WriteMessage(IMessageLite message); - - /// - /// Writes a Boolean value - /// - protected abstract void Write(string field, Boolean value); - - /// - /// Writes a Int32 value - /// - protected abstract void Write(string field, Int32 value); - - /// - /// Writes a UInt32 value - /// - [CLSCompliant(false)] - protected abstract void Write(string field, UInt32 value); - - /// - /// Writes a Int64 value - /// - protected abstract void Write(string field, Int64 value); - - /// - /// Writes a UInt64 value - /// - [CLSCompliant(false)] - protected abstract void Write(string field, UInt64 value); - - /// - /// Writes a Single value - /// - protected abstract void Write(string field, Single value); - - /// - /// Writes a Double value - /// - protected abstract void Write(string field, Double value); - - /// - /// Writes a String value - /// - protected abstract void Write(string field, String value); - - /// - /// Writes a set of bytes - /// - protected abstract void Write(string field, ByteString value); - - /// - /// Writes a message or group as a field - /// - protected abstract void WriteMessageOrGroup(string field, IMessageLite message); - - /// - /// Writes a System.Enum by the numeric and textual value - /// - protected abstract void WriteEnum(string field, int number, string name); - - /// - /// Writes a field of the type determined by field.FieldType - /// - protected virtual void WriteField(FieldType fieldType, string field, object value) - { - switch (fieldType) - { - case FieldType.Bool: - Write(field, (bool) value); - break; - case FieldType.Int64: - case FieldType.SInt64: - case FieldType.SFixed64: - Write(field, (long) value); - break; - case FieldType.UInt64: - case FieldType.Fixed64: - Write(field, (ulong) value); - break; - case FieldType.Int32: - case FieldType.SInt32: - case FieldType.SFixed32: - Write(field, (int) value); - break; - case FieldType.UInt32: - case FieldType.Fixed32: - Write(field, (uint) value); - break; - case FieldType.Float: - Write(field, (float) value); - break; - case FieldType.Double: - Write(field, (double) value); - break; - case FieldType.String: - Write(field, (string) value); - break; - case FieldType.Bytes: - Write(field, (ByteString) value); - break; - case FieldType.Group: - WriteMessageOrGroup(field, (IMessageLite) value); - break; - case FieldType.Message: - WriteMessageOrGroup(field, (IMessageLite) value); - break; - case FieldType.Enum: - { - if (value is IEnumLite) - { - WriteEnum(field, ((IEnumLite) value).Number, ((IEnumLite) value).Name); - } - else if (value is IConvertible) - { - WriteEnum(field, ((IConvertible) value).ToInt32(CultureInfo.InvariantCulture), - ((IConvertible) value).ToString(CultureInfo.InvariantCulture)); - } - else - { - throw new ArgumentException("Expected an Enum type for field " + field); - } - break; - } - default: - throw InvalidProtocolBufferException.InvalidTag(); - } - } - - /// - /// Writes an array of field values - /// - protected virtual void WriteArray(FieldType fieldType, string field, IEnumerable items) - { - foreach (object obj in items) - { - WriteField(fieldType, field, obj); - } - } - - /// - /// Writes a numeric unknown field of wire type: Fixed32, Fixed64, or Variant - /// - [CLSCompliant(false)] - protected virtual void WriteUnknown(WireFormat.WireType wireType, int fieldNumber, ulong value) - { - } - - /// - /// Writes an unknown field, Expect WireType of GroupStart or LengthPrefix - /// - [CLSCompliant(false)] - protected virtual void WriteUnknown(WireFormat.WireType wireType, int fieldNumber, ByteString value) - { - } - - #region ICodedOutputStream Members - - void ICodedOutputStream.WriteUnknownGroup(int fieldNumber, IMessageLite value) - { - } - - void ICodedOutputStream.WriteUnknownBytes(int fieldNumber, ByteString value) - { - } - - void ICodedOutputStream.WriteUnknownField(int fieldNumber, WireFormat.WireType type, ulong value) - { - } - - void ICodedOutputStream.WriteMessageSetExtension(int fieldNumber, string fieldName, IMessageLite value) - { - } - - void ICodedOutputStream.WriteMessageSetExtension(int fieldNumber, string fieldName, ByteString value) - { - } - - void ICodedOutputStream.WriteField(FieldType fieldType, int fieldNumber, string fieldName, object value) - { - WriteField(fieldType, fieldName, value); - } - - void ICodedOutputStream.WriteDouble(int fieldNumber, string fieldName, double value) - { - Write(fieldName, value); - } - - void ICodedOutputStream.WriteFloat(int fieldNumber, string fieldName, float value) - { - Write(fieldName, value); - } - - void ICodedOutputStream.WriteUInt64(int fieldNumber, string fieldName, ulong value) - { - Write(fieldName, value); - } - - void ICodedOutputStream.WriteInt64(int fieldNumber, string fieldName, long value) - { - Write(fieldName, value); - } - - void ICodedOutputStream.WriteInt32(int fieldNumber, string fieldName, int value) - { - Write(fieldName, value); - } - - void ICodedOutputStream.WriteFixed64(int fieldNumber, string fieldName, ulong value) - { - Write(fieldName, value); - } - - void ICodedOutputStream.WriteFixed32(int fieldNumber, string fieldName, uint value) - { - Write(fieldName, value); - } - - void ICodedOutputStream.WriteBool(int fieldNumber, string fieldName, bool value) - { - Write(fieldName, value); - } - - void ICodedOutputStream.WriteString(int fieldNumber, string fieldName, string value) - { - Write(fieldName, value); - } - - void ICodedOutputStream.WriteGroup(int fieldNumber, string fieldName, IMessageLite value) - { - WriteMessageOrGroup(fieldName, value); - } - - void ICodedOutputStream.WriteMessage(int fieldNumber, string fieldName, IMessageLite value) - { - WriteMessageOrGroup(fieldName, value); - } - - void ICodedOutputStream.WriteBytes(int fieldNumber, string fieldName, ByteString value) - { - Write(fieldName, value); - } - - void ICodedOutputStream.WriteUInt32(int fieldNumber, string fieldName, uint value) - { - Write(fieldName, value); - } - - void ICodedOutputStream.WriteEnum(int fieldNumber, string fieldName, int value, object rawValue) - { - WriteEnum(fieldName, value, rawValue.ToString()); - } - - void ICodedOutputStream.WriteSFixed32(int fieldNumber, string fieldName, int value) - { - Write(fieldName, value); - } - - void ICodedOutputStream.WriteSFixed64(int fieldNumber, string fieldName, long value) - { - Write(fieldName, value); - } - - void ICodedOutputStream.WriteSInt32(int fieldNumber, string fieldName, int value) - { - Write(fieldName, value); - } - - void ICodedOutputStream.WriteSInt64(int fieldNumber, string fieldName, long value) - { - Write(fieldName, value); - } - - - void ICodedOutputStream.WriteArray(FieldType fieldType, int fieldNumber, string fieldName, IEnumerable list) - { - WriteArray(fieldType, fieldName, list); - } - - void ICodedOutputStream.WriteGroupArray(int fieldNumber, string fieldName, IEnumerable list) - { - WriteArray(FieldType.Group, fieldName, list); - } - - void ICodedOutputStream.WriteMessageArray(int fieldNumber, string fieldName, IEnumerable list) - { - WriteArray(FieldType.Message, fieldName, list); - } - - void ICodedOutputStream.WriteStringArray(int fieldNumber, string fieldName, IEnumerable list) - { - WriteArray(FieldType.String, fieldName, list); - } - - void ICodedOutputStream.WriteBytesArray(int fieldNumber, string fieldName, IEnumerable list) - { - WriteArray(FieldType.Bytes, fieldName, list); - } - - void ICodedOutputStream.WriteBoolArray(int fieldNumber, string fieldName, IEnumerable list) - { - WriteArray(FieldType.Bool, fieldName, list); - } - - void ICodedOutputStream.WriteInt32Array(int fieldNumber, string fieldName, IEnumerable list) - { - WriteArray(FieldType.Int32, fieldName, list); - } - - void ICodedOutputStream.WriteSInt32Array(int fieldNumber, string fieldName, IEnumerable list) - { - WriteArray(FieldType.SInt32, fieldName, list); - } - - void ICodedOutputStream.WriteUInt32Array(int fieldNumber, string fieldName, IEnumerable list) - { - WriteArray(FieldType.UInt32, fieldName, list); - } - - void ICodedOutputStream.WriteFixed32Array(int fieldNumber, string fieldName, IEnumerable list) - { - WriteArray(FieldType.Fixed32, fieldName, list); - } - - void ICodedOutputStream.WriteSFixed32Array(int fieldNumber, string fieldName, IEnumerable list) - { - WriteArray(FieldType.SFixed32, fieldName, list); - } - - void ICodedOutputStream.WriteInt64Array(int fieldNumber, string fieldName, IEnumerable list) - { - WriteArray(FieldType.Int64, fieldName, list); - } - - void ICodedOutputStream.WriteSInt64Array(int fieldNumber, string fieldName, IEnumerable list) - { - WriteArray(FieldType.SInt64, fieldName, list); - } - - void ICodedOutputStream.WriteUInt64Array(int fieldNumber, string fieldName, IEnumerable list) - { - WriteArray(FieldType.UInt64, fieldName, list); - } - - void ICodedOutputStream.WriteFixed64Array(int fieldNumber, string fieldName, IEnumerable list) - { - WriteArray(FieldType.Fixed64, fieldName, list); - } - - void ICodedOutputStream.WriteSFixed64Array(int fieldNumber, string fieldName, IEnumerable list) - { - WriteArray(FieldType.SFixed64, fieldName, list); - } - - void ICodedOutputStream.WriteDoubleArray(int fieldNumber, string fieldName, IEnumerable list) - { - WriteArray(FieldType.Double, fieldName, list); - } - - void ICodedOutputStream.WriteFloatArray(int fieldNumber, string fieldName, IEnumerable list) - { - WriteArray(FieldType.Float, fieldName, list); - } - - void ICodedOutputStream.WriteEnumArray(int fieldNumber, string fieldName, IEnumerable list) - { - WriteArray(FieldType.Enum, fieldName, list); - } - - void ICodedOutputStream.WritePackedArray(FieldType fieldType, int fieldNumber, string fieldName, - IEnumerable list) - { - WriteArray(fieldType, fieldName, list); - } - - - void ICodedOutputStream.WritePackedBoolArray(int fieldNumber, string fieldName, int computedSize, - IEnumerable list) - { - WriteArray(FieldType.Bool, fieldName, list); - } - - void ICodedOutputStream.WritePackedInt32Array(int fieldNumber, string fieldName, int computedSize, - IEnumerable list) - { - WriteArray(FieldType.Int32, fieldName, list); - } - - void ICodedOutputStream.WritePackedSInt32Array(int fieldNumber, string fieldName, int computedSize, - IEnumerable list) - { - WriteArray(FieldType.SInt32, fieldName, list); - } - - void ICodedOutputStream.WritePackedUInt32Array(int fieldNumber, string fieldName, int computedSize, - IEnumerable list) - { - WriteArray(FieldType.UInt32, fieldName, list); - } - - void ICodedOutputStream.WritePackedFixed32Array(int fieldNumber, string fieldName, int computedSize, - IEnumerable list) - { - WriteArray(FieldType.Fixed32, fieldName, list); - } - - void ICodedOutputStream.WritePackedSFixed32Array(int fieldNumber, string fieldName, int computedSize, - IEnumerable list) - { - WriteArray(FieldType.SFixed32, fieldName, list); - } - - void ICodedOutputStream.WritePackedInt64Array(int fieldNumber, string fieldName, int computedSize, - IEnumerable list) - { - WriteArray(FieldType.Int64, fieldName, list); - } - - void ICodedOutputStream.WritePackedSInt64Array(int fieldNumber, string fieldName, int computedSize, - IEnumerable list) - { - WriteArray(FieldType.SInt64, fieldName, list); - } - - void ICodedOutputStream.WritePackedUInt64Array(int fieldNumber, string fieldName, int computedSize, - IEnumerable list) - { - WriteArray(FieldType.UInt64, fieldName, list); - } - - void ICodedOutputStream.WritePackedFixed64Array(int fieldNumber, string fieldName, int computedSize, - IEnumerable list) - { - WriteArray(FieldType.Fixed64, fieldName, list); - } - - void ICodedOutputStream.WritePackedSFixed64Array(int fieldNumber, string fieldName, int computedSize, - IEnumerable list) - { - WriteArray(FieldType.SFixed64, fieldName, list); - } - - void ICodedOutputStream.WritePackedDoubleArray(int fieldNumber, string fieldName, int computedSize, - IEnumerable list) - { - WriteArray(FieldType.Double, fieldName, list); - } - - void ICodedOutputStream.WritePackedFloatArray(int fieldNumber, string fieldName, int computedSize, - IEnumerable list) - { - WriteArray(FieldType.Float, fieldName, list); - } - - void ICodedOutputStream.WritePackedEnumArray(int fieldNumber, string fieldName, int computedSize, - IEnumerable list) - { - WriteArray(FieldType.Enum, fieldName, list); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/ProtocolBuffers/Serialization/DictionaryReader.cs b/src/ProtocolBuffers/Serialization/DictionaryReader.cs deleted file mode 100644 index 70028958..00000000 --- a/src/ProtocolBuffers/Serialization/DictionaryReader.cs +++ /dev/null @@ -1,255 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using Google.ProtocolBuffers.Descriptors; - -namespace Google.ProtocolBuffers.Serialization -{ - /// - /// Allows reading messages from a name/value dictionary - /// - public class DictionaryReader : AbstractReader - { - private readonly IEnumerator> _input; - private bool _ready; - - /// - /// Creates a dictionary reader from an enumeration of KeyValuePair data, like an IDictionary - /// - public DictionaryReader(IEnumerable> input) - { - _input = input.GetEnumerator(); - _ready = _input.MoveNext(); - } - - /// - /// Merges the contents of stream into the provided message builder - /// - public override TBuilder Merge(TBuilder builder, ExtensionRegistry registry) - { - builder.WeakMergeFrom(this, registry); - return builder; - } - - /// - /// Peeks at the next field in the input stream and returns what information is available. - /// - /// - /// This may be called multiple times without actually reading the field. Only after the field - /// is either read, or skipped, should PeekNext return a different value. - /// - protected override bool PeekNext(out string field) - { - field = _ready ? _input.Current.Key : null; - return _ready; - } - - /// - /// Causes the reader to skip past this field - /// - protected override void Skip() - { - _ready = _input.MoveNext(); - } - - private bool GetValue(ref T value) - { - if (!_ready) - { - return false; - } - - object obj = _input.Current.Value; - if (obj is T) - { - value = (T) obj; - } - else - { - try - { - if (obj is IConvertible) - { - value = (T) Convert.ChangeType(obj, typeof (T), CultureInfo.InvariantCulture); - } - else - { - value = (T) obj; - } - } - catch - { - _ready = _input.MoveNext(); - return false; - } - } - _ready = _input.MoveNext(); - return true; - } - - /// - /// Returns true if it was able to read a Boolean from the input - /// - protected override bool Read(ref bool value) - { - return GetValue(ref value); - } - - /// - /// Returns true if it was able to read a Int32 from the input - /// - protected override bool Read(ref int value) - { - return GetValue(ref value); - } - - /// - /// Returns true if it was able to read a UInt32 from the input - /// - [CLSCompliant(false)] - protected override bool Read(ref uint value) - { - return GetValue(ref value); - } - - /// - /// Returns true if it was able to read a Int64 from the input - /// - protected override bool Read(ref long value) - { - return GetValue(ref value); - } - - /// - /// Returns true if it was able to read a UInt64 from the input - /// - [CLSCompliant(false)] - protected override bool Read(ref ulong value) - { - return GetValue(ref value); - } - - /// - /// Returns true if it was able to read a Single from the input - /// - protected override bool Read(ref float value) - { - return GetValue(ref value); - } - - /// - /// Returns true if it was able to read a Double from the input - /// - protected override bool Read(ref double value) - { - return GetValue(ref value); - } - - /// - /// Returns true if it was able to read a String from the input - /// - protected override bool Read(ref string value) - { - return GetValue(ref value); - } - - /// - /// Returns true if it was able to read a ByteString from the input - /// - protected override bool Read(ref ByteString value) - { - byte[] rawbytes = null; - if (GetValue(ref rawbytes)) - { - value = ByteString.AttachBytes(rawbytes); - return true; - } - return false; - } - - /// - /// returns true if it was able to read a single value into the value reference. The value - /// stored may be of type System.String, System.Int32, or an IEnumLite from the IEnumLiteMap. - /// - protected override bool ReadEnum(ref object value) - { - return GetValue(ref value); - } - - /// - /// Merges the input stream into the provided IBuilderLite - /// - protected override bool ReadMessage(IBuilderLite builder, ExtensionRegistry registry) - { - IDictionary values = null; - if (GetValue(ref values)) - { - new DictionaryReader(values).Merge(builder, registry); - return true; - } - return false; - } - - public override bool ReadArray(FieldType type, string field, ICollection items) - { - object[] array = null; - if (GetValue(ref array)) - { - 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; - } - - public override bool ReadEnumArray(string field, ICollection items) - { - object[] array = null; - if (GetValue(ref array)) - { - foreach (object item in array) - { - items.Add(item); - } - return true; - } - return false; - } - - public override bool ReadMessageArray(string field, ICollection items, IMessageLite messageType, - ExtensionRegistry registry) - { - object[] array = null; - if (GetValue(ref array)) - { - foreach (IDictionary item in array) - { - IBuilderLite builder = messageType.WeakCreateBuilderForType(); - new DictionaryReader(item).Merge(builder); - items.Add((T) builder.WeakBuild()); - } - return true; - } - return false; - } - - public override bool ReadGroupArray(string field, ICollection items, IMessageLite messageType, - ExtensionRegistry registry) - { - return ReadMessageArray(field, items, messageType, registry); - } - } -} \ No newline at end of file diff --git a/src/ProtocolBuffers/Serialization/DictionaryWriter.cs b/src/ProtocolBuffers/Serialization/DictionaryWriter.cs deleted file mode 100644 index 96175a7e..00000000 --- a/src/ProtocolBuffers/Serialization/DictionaryWriter.cs +++ /dev/null @@ -1,189 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using Google.ProtocolBuffers.Descriptors; - -namespace Google.ProtocolBuffers.Serialization -{ - /// - /// Allows writing messages to a name/value dictionary - /// - public class DictionaryWriter : AbstractWriter - { - private readonly IDictionary _output; - - /// - /// Constructs a writer using a new dictionary - /// - public DictionaryWriter() - : this(new Dictionary(StringComparer.Ordinal)) - { - } - - /// - /// Constructs a writer using an existing dictionary - /// - public DictionaryWriter(IDictionary output) - { - ThrowHelper.ThrowIfNull(output, "output"); - _output = output; - } - - /// - /// Creates the dictionary instance for a child message. - /// - protected virtual DictionaryWriter Create() - { - return new DictionaryWriter(); - } - - /// - /// Accesses the dictionary that is backing this writer - /// - public IDictionary ToDictionary() - { - return _output; - } - - /// - /// Writes the message to the the formatted stream. - /// - public override void WriteMessage(IMessageLite message) - { - message.WriteTo(this); - } - - /// - /// Writes a Boolean value - /// - protected override void Write(string field, bool value) - { - _output[field] = value; - } - - /// - /// Writes a Int32 value - /// - protected override void Write(string field, int value) - { - _output[field] = value; - } - - /// - /// Writes a UInt32 value - /// - [CLSCompliant(false)] - protected override void Write(string field, uint value) - { - _output[field] = value; - } - - /// - /// Writes a Int64 value - /// - protected override void Write(string field, long value) - { - _output[field] = value; - } - - /// - /// Writes a UInt64 value - /// - [CLSCompliant(false)] - protected override void Write(string field, ulong value) - { - _output[field] = value; - } - - /// - /// Writes a Single value - /// - protected override void Write(string field, float value) - { - _output[field] = value; - } - - /// - /// Writes a Double value - /// - protected override void Write(string field, double value) - { - _output[field] = value; - } - - /// - /// Writes a String value - /// - protected override void Write(string field, string value) - { - _output[field] = value; - } - - /// - /// Writes a set of bytes - /// - protected override void Write(string field, ByteString value) - { - _output[field] = value.ToByteArray(); - } - - /// - /// Writes a message or group as a field - /// - protected override void WriteMessageOrGroup(string field, IMessageLite message) - { - DictionaryWriter writer = Create(); - writer.WriteMessage(message); - - _output[field] = writer.ToDictionary(); - } - - /// - /// Writes a System.Enum by the numeric and textual value - /// - protected override void WriteEnum(string field, int number, string name) - { - _output[field] = number; - } - - /// - /// Writes an array of field values - /// - protected override void WriteArray(FieldType fieldType, string field, IEnumerable items) - { - List objects = new List(); - foreach (object o in items) - { - switch (fieldType) - { - case FieldType.Group: - case FieldType.Message: - { - DictionaryWriter writer = Create(); - writer.WriteMessage((IMessageLite) o); - objects.Add(writer.ToDictionary()); - } - break; - case FieldType.Bytes: - objects.Add(((ByteString) o).ToByteArray()); - break; - case FieldType.Enum: - if (o is IEnumLite) - { - objects.Add(((IEnumLite) o).Number); - } - else - { - objects.Add((int) o); - } - break; - default: - objects.Add(o); - break; - } - } - - _output[field] = objects.ToArray(); - } - } -} \ No newline at end of file diff --git a/src/ProtocolBuffers/Serialization/JsonFormatReader.cs b/src/ProtocolBuffers/Serialization/JsonFormatReader.cs deleted file mode 100644 index d4505d70..00000000 --- a/src/ProtocolBuffers/Serialization/JsonFormatReader.cs +++ /dev/null @@ -1,245 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Xml; - -namespace Google.ProtocolBuffers.Serialization -{ - /// - /// JsonFormatReader is used to parse Json into a message or an array of messages - /// - public class JsonFormatReader : AbstractTextReader - { - private readonly JsonCursor _input; - private readonly Stack _stopChar; - - private enum ReaderState - { - Start, - BeginValue, - EndValue, - BeginObject, - BeginArray - } - - private string _current; - private 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 static JsonFormatReader CreateInstance(string jsonText) - { - return new JsonFormatReader(JsonCursor.CreateInstance(jsonText)); - } - - /// - /// Constructs a JsonFormatReader to parse Json into a message - /// - 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 = 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 - /// - public bool IsArrayMessage - { - get { return _input.NextChar == '['; } - } - - /// - /// Returns an enumerator that is used to cursor over an array of messages - /// - /// - /// This is generally used when receiving an array of messages rather than a single root message - /// - public IEnumerable EnumerateArray() - { - foreach (string ignored in ForeachArrayItem(_current)) - { - yield return this; - } - } - - /// - /// Merges the contents of stream into the provided message builder - /// - public override TBuilder Merge(TBuilder builder, ExtensionRegistry registry) - { - _input.Consume('{'); - _stopChar.Push('}'); - - _state = ReaderState.BeginObject; - builder.WeakMergeFrom(this, registry); - _input.Consume((char) _stopChar.Pop()); - _state = ReaderState.EndValue; - return builder; - } - - /// - /// Causes the reader to skip past this field - /// - protected override void Skip() - { - object temp; - _input.ReadVariant(out temp); - _state = ReaderState.EndValue; - } - - /// - /// Peeks at the next field in the input stream and returns what information is available. - /// - /// - /// This may be called multiple times without actually reading the field. Only after the field - /// is either read, or skipped, should PeekNext return a different value. - /// - protected override bool PeekNext(out string field) - { - field = _current; - if (_state == ReaderState.BeginValue) - { - return true; - } - - int next = _input.NextChar; - if (next == _stopChar.Peek()) - { - return false; - } - - _input.Assert(next != -1, "Unexpected end of file."); - - //not sure about this yet, it will allow {, "a":true } - if (_state == ReaderState.EndValue && !_input.TryConsume(',')) - { - return false; - } - - field = _current = _input.ReadString(); - _input.Consume(':'); - _state = ReaderState.BeginValue; - return true; - } - - /// - /// Returns true if it was able to read a String from the input - /// - protected override bool ReadAsText(ref string value, Type typeInfo) - { - object temp; - JsonCursor.JsType type = _input.ReadVariant(out temp); - _state = ReaderState.EndValue; - - _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 == 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 == JsonCursor.JsType.Number && - (typeInfo != typeof (double) && typeInfo != typeof (float)) && - value.IndexOf("e", StringComparison.OrdinalIgnoreCase) > 0) - { - value = XmlConvert.ToString((long) Math.Round(XmlConvert.ToDouble(value), 0)); - } - return value != null; - } - - /// - /// Returns true if it was able to read a ByteString from the input - /// - protected override bool Read(ref ByteString value) - { - string bytes = null; - if (Read(ref bytes)) - { - value = ByteString.FromBase64(bytes); - return true; - } - return false; - } - - /// - /// Cursors through the array elements and stops at the end of the array - /// - protected override IEnumerable ForeachArrayItem(string field) - { - _input.Consume('['); - _stopChar.Push(']'); - _state = ReaderState.BeginArray; - while (_input.NextChar != ']') - { - _current = field; - yield return field; - if (!_input.TryConsume(',')) - { - break; - } - } - _input.Consume((char) _stopChar.Pop()); - _state = ReaderState.EndValue; - } - - /// - /// Merges the input stream into the provided IBuilderLite - /// - protected override bool ReadMessage(IBuilderLite builder, ExtensionRegistry registry) - { - Merge(builder, registry); - return true; - } - } -} \ No newline at end of file diff --git a/src/ProtocolBuffers/Serialization/JsonFormatWriter.cs b/src/ProtocolBuffers/Serialization/JsonFormatWriter.cs deleted file mode 100644 index d54507cc..00000000 --- a/src/ProtocolBuffers/Serialization/JsonFormatWriter.cs +++ /dev/null @@ -1,521 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.IO; -using System.Text; -using Google.ProtocolBuffers.Descriptors; - -namespace Google.ProtocolBuffers.Serialization -{ - /// - /// JsonFormatWriter is a .NET 2.0 friendly json formatter for proto buffer messages. For .NET 3.5 - /// you may also use the XmlFormatWriter with an XmlWriter created by the - /// JsonReaderWriterFactory. - /// - public abstract class JsonFormatWriter : AbstractTextWriter - { - #region buffering implementations - - private class JsonTextWriter : JsonFormatWriter - { - private readonly char[] _buffer; - private TextWriter _output; - private int _bufferPos; - - public JsonTextWriter(TextWriter output) - { - _buffer = new char[4096]; - _bufferPos = 0; - _output = output; - _counter.Add(0); - } - - /// - /// Returns the output of TextWriter.ToString() where TextWriter is the ctor argument. - /// - public override string ToString() - { - Flush(); - - if (_output != null) - { - return _output.ToString(); - } - - return new String(_buffer, 0, _bufferPos); - } - - protected override void WriteToOutput(char[] chars, int offset, int len) - { - if (_bufferPos + len >= _buffer.Length) - { - if (_output == null) - { - _output = new StringWriter(new StringBuilder(_buffer.Length*2 + len)); - } - Flush(); - } - - if (len < _buffer.Length) - { - 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) - { - _output.Write(_buffer, 0, _bufferPos); - _bufferPos = 0; - } - base.Flush(); - } - } - - private class JsonStreamWriter : JsonFormatWriter - { -#if SILVERLIGHT2 || COMPACT_FRAMEWORK_35 - static readonly Encoding Encoding = Encoding.UTF8; -#else - private static readonly Encoding Encoding = Encoding.ASCII; -#endif - private readonly byte[] _buffer; - private Stream _output; - private int _bufferPos; - - public JsonStreamWriter(Stream output) - { - _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; - } - - 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(); - } - - /// - /// Constructs a JsonFormatWriter, use ToString() to extract the final output - /// - 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() - { - NewLine = Environment.NewLine; - Indent = " "; - Whitespace = " "; - return this; - } - - /// Gets or sets the characters to use for the new-line, default = empty - public string NewLine { get; set; } - - /// Gets or sets the text to use for indenting, default = empty - public string Indent { get; set; } - - /// Gets or sets the whitespace to use to separate the text, default = empty - public string Whitespace { get; set; } - - private void Seperator() - { - if (_counter.Count == 0) - { - throw new InvalidOperationException("Missmatched open/close in Json writer."); - } - - int index = _counter.Count - 1; - if (_counter[index] > 0) - { - WriteToOutput(','); - } - - WriteLine(String.Empty); - _counter[index] = _counter[index] + 1; - } - - private void WriteLine(string content) - { - if (!String.IsNullOrEmpty(NewLine)) - { - WriteToOutput(NewLine); - for (int i = 1; i < _counter.Count; i++) - { - WriteToOutput(Indent); - } - } - else if (!String.IsNullOrEmpty(Whitespace)) - { - WriteToOutput(Whitespace); - } - - WriteToOutput(content); - } - - private void WriteName(string field) - { - Seperator(); - if (!String.IsNullOrEmpty(field)) - { - WriteToOutput('"'); - WriteToOutput(field); - WriteToOutput('"'); - WriteToOutput(':'); - if (!String.IsNullOrEmpty(Whitespace)) - { - WriteToOutput(Whitespace); - } - } - } - - private void EncodeText(string value) - { - char[] text = value.ToCharArray(); - int len = text.Length; - int pos = 0; - - while (pos < len) - { - int next = pos; - while (next < len && text[next] >= 32 && text[next] < 127 && text[next] != '\\' && text[next] != '/' && - text[next] != '"') - { - next++; - } - WriteToOutput(text, pos, next - pos); - if (next < len) - { - switch (text[next]) - { - case '"': - WriteToOutput(@"\"""); - break; - case '\\': - WriteToOutput(@"\\"); - break; - //odd at best to escape '/', most Json implementations don't, but it is defined in the rfc-4627 - case '/': - WriteToOutput(@"\/"); - break; - case '\b': - WriteToOutput(@"\b"); - break; - case '\f': - WriteToOutput(@"\f"); - break; - case '\n': - WriteToOutput(@"\n"); - break; - case '\r': - WriteToOutput(@"\r"); - break; - case '\t': - WriteToOutput(@"\t"); - break; - default: - WriteToOutput(@"\u{0:x4}", (int) text[next]); - break; - } - next++; - } - pos = next; - } - } - - /// - /// Writes a String value - /// - protected override void WriteAsText(string field, string textValue, object typedValue) - { - WriteName(field); - if (typedValue is bool || typedValue is int || typedValue is uint || typedValue is long || - typedValue is ulong || typedValue is double || typedValue is float) - { - WriteToOutput(textValue); - } - else - { - WriteToOutput('"'); - if (typedValue is string) - { - EncodeText(textValue); - } - else - { - WriteToOutput(textValue); - } - WriteToOutput('"'); - } - } - - /// - /// Writes a Double value - /// - protected override void Write(string field, double value) - { - if (double.IsNaN(value) || double.IsNegativeInfinity(value) || double.IsPositiveInfinity(value)) - { - throw new InvalidOperationException("This format does not support NaN, Infinity, or -Infinity"); - } - base.Write(field, value); - } - - /// - /// Writes a Single value - /// - protected override void Write(string field, float value) - { - if (float.IsNaN(value) || float.IsNegativeInfinity(value) || float.IsPositiveInfinity(value)) - { - throw new InvalidOperationException("This format does not support NaN, Infinity, or -Infinity"); - } - base.Write(field, value); - } - - // Treat enum as string - protected override void WriteEnum(string field, int number, string name) - { - Write(field, name); - } - - /// - /// Writes an array of field values - /// - protected override void WriteArray(FieldType type, string field, IEnumerable items) - { - IEnumerator enumerator = items.GetEnumerator(); - try - { - if (!enumerator.MoveNext()) - { - return; - } - } - finally - { - if (enumerator is IDisposable) - { - ((IDisposable) enumerator).Dispose(); - } - } - - WriteName(field); - WriteToOutput("["); - _counter.Add(0); - - base.WriteArray(type, String.Empty, items); - - _counter.RemoveAt(_counter.Count - 1); - WriteLine("]"); - } - - /// - /// Writes a message - /// - protected override void WriteMessageOrGroup(string field, IMessageLite message) - { - WriteName(field); - WriteMessage(message); - } - - /// - /// Writes the message to the the formatted stream. - /// - public override void WriteMessage(IMessageLite message) - { - if (_isArray) - { - Seperator(); - } - WriteToOutput("{"); - _counter.Add(0); - message.WriteTo(this); - _counter.RemoveAt(_counter.Count - 1); - WriteLine("}"); - Flush(); - } - - /// - /// Used in streaming arrays of objects to the writer - /// - /// - /// - /// using(writer.StartArray()) - /// foreach(IMessageLite m in messages) - /// writer.WriteMessage(m); - /// - /// - public sealed class JsonArray : IDisposable - { - private JsonFormatWriter _writer; - - internal JsonArray(JsonFormatWriter writer) - { - _writer = writer; - _writer.WriteToOutput("["); - _writer._counter.Add(0); - } - - /// - /// Causes the end of the array character to be written. - /// - private void EndArray() - { - if (_writer != null) - { - _writer._counter.RemoveAt(_writer._counter.Count - 1); - _writer.WriteLine("]"); - _writer.Flush(); - } - _writer = null; - } - - void IDisposable.Dispose() - { - EndArray(); - } - } - - /// - /// Used to write an array of messages as the output rather than a single message. - /// - /// - /// - /// using(writer.StartArray()) - /// foreach(IMessageLite m in messages) - /// writer.WriteMessage(m); - /// - /// - public JsonArray StartArray() - { - if (_isArray) - { - Seperator(); - } - _isArray = true; - return new JsonArray(this); - } - } -} \ No newline at end of file diff --git a/src/ProtocolBuffers/Serialization/JsonTextCursor.cs b/src/ProtocolBuffers/Serialization/JsonTextCursor.cs deleted file mode 100644 index 48e84ccc..00000000 --- a/src/ProtocolBuffers/Serialization/JsonTextCursor.cs +++ /dev/null @@ -1,442 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Globalization; -using System.IO; - -namespace Google.ProtocolBuffers.Serialization -{ - /// - /// JSon Tokenizer used by JsonFormatReader - /// - internal abstract class JsonCursor - { - public enum JsType - { - String, - Number, - Object, - Array, - True, - False, - Null - } - - #region Buffering implementations - - private class JsonStreamCursor : JsonCursor - { - private readonly byte[] _buffer; - private int _bufferPos; - private readonly Stream _input; - - 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 class JsonTextCursor : JsonCursor - { - 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; - - 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() - { - _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(); - - public Char NextChar - { - get - { - SkipWhitespace(); - return (char) _next; - } - } - - #region Assert(...) - - [DebuggerNonUserCode] - private string CharDisplay(int ch) - { - return ch == -1 - ? "EOF" - : (ch > 32 && ch < 127) - ? String.Format("'{0}'", (char) ch) - : String.Format("'\\u{0:x4}'", ch); - } - - [DebuggerNonUserCode] - private void Assert(bool cond, char expected) - { - if (!cond) - { - throw new FormatException( - String.Format(CultureInfo.InvariantCulture, - "({0}:{1}) error: Unexpected token {2}, expected: {3}.", - _lineNo, _linePos, - CharDisplay(_next), - CharDisplay(expected) - )); - } - } - - [DebuggerNonUserCode] - public void Assert(bool cond, string message) - { - if (!cond) - { - throw new FormatException( - String.Format(CultureInfo.InvariantCulture, - "({0},{1}) error: {2}", _lineNo, _linePos, message)); - } - } - - [DebuggerNonUserCode] - public void Assert(bool cond, string format, params object[] args) - { - if (!cond) - { - if (args != null && args.Length > 0) - { - format = String.Format(format, args); - } - throw new FormatException( - String.Format(CultureInfo.InvariantCulture, - "({0},{1}) error: {2}", _lineNo, _linePos, format)); - } - } - - #endregion - - private char ReadChar() - { - int ch = Read(); - Assert(ch != -1, "Unexpected end of file."); - if (ch == '\n') - { - _lineNo++; - _linePos = 0; - } - else if (ch != '\r') - { - _linePos++; - } - _next = Peek(); - return (char) ch; - } - - public void Consume(char ch) - { - Assert(TryConsume(ch), ch); - } - - public bool TryConsume(char ch) - { - SkipWhitespace(); - if (_next == ch) - { - ReadChar(); - return true; - } - return false; - } - - public void Consume(string sequence) - { - SkipWhitespace(); - - foreach (char ch in sequence) - { - Assert(ch == ReadChar(), "Expected token '{0}'.", sequence); - } - } - - public void SkipWhitespace() - { - int chnext = _next; - while (chnext != -1) - { - if (!Char.IsWhiteSpace((char) chnext)) - { - break; - } - ReadChar(); - chnext = _next; - } - } - - public string ReadString() - { - SkipWhitespace(); - Consume('"'); - List sb = new List(100); - while (_next != '"') - { - if (_next == '\\') - { - Consume('\\'); //skip the escape - char ch = ReadChar(); - switch (ch) - { - case 'b': - sb.Add('\b'); - break; - case 'f': - sb.Add('\f'); - break; - case 'n': - sb.Add('\n'); - break; - case 'r': - sb.Add('\r'); - break; - case 't': - sb.Add('\t'); - break; - case 'u': - { - string hex = new string(new char[] {ReadChar(), ReadChar(), ReadChar(), ReadChar()}); - int result; - Assert( - int.TryParse(hex, NumberStyles.AllowHexSpecifier, CultureInfo.InvariantCulture, - out result), - "Expected a 4-character hex specifier."); - sb.Add((char) result); - break; - } - default: - sb.Add(ch); - break; - } - } - else - { - Assert(_next != '\n' && _next != '\r' && _next != '\f' && _next != -1, '"'); - sb.Add(ReadChar()); - } - } - Consume('"'); - return new String(sb.ToArray()); - } - - public string ReadNumber() - { - SkipWhitespace(); - List sb = new List(24); - if (_next == '-') - { - sb.Add(ReadChar()); - } - Assert(_next >= '0' && _next <= '9', "Expected a numeric type."); - while ((_next >= '0' && _next <= '9') || _next == '.') - { - sb.Add(ReadChar()); - } - if (_next == 'e' || _next == 'E') - { - sb.Add(ReadChar()); - if (_next == '-' || _next == '+') - { - sb.Add(ReadChar()); - } - Assert(_next >= '0' && _next <= '9', "Expected a numeric type."); - while (_next >= '0' && _next <= '9') - { - sb.Add(ReadChar()); - } - } - return new String(sb.ToArray()); - } - - public JsType ReadVariant(out object value) - { - SkipWhitespace(); - switch (_next) - { - case 'n': - Consume("null"); - value = null; - return JsType.Null; - case 't': - Consume("true"); - value = true; - return JsType.True; - case 'f': - Consume("false"); - value = false; - return JsType.False; - case '"': - value = ReadString(); - return JsType.String; - case '{': - { - Consume('{'); - while (NextChar != '}') - { - ReadString(); - Consume(':'); - object tmp; - ReadVariant(out tmp); - if (!TryConsume(',')) - { - break; - } - } - Consume('}'); - value = null; - return JsType.Object; - } - case '[': - { - Consume('['); - List values = new List(); - while (NextChar != ']') - { - object tmp; - ReadVariant(out tmp); - values.Add(tmp); - if (!TryConsume(',')) - { - break; - } - } - Consume(']'); - value = values.ToArray(); - return JsType.Array; - } - default: - if ((_next >= '0' && _next <= '9') || _next == '-') - { - value = ReadNumber(); - return JsType.Number; - } - Assert(false, "Expected a value."); - throw new FormatException(); - } - } - } -} \ No newline at end of file diff --git a/src/ProtocolBuffers/Serialization/XmlFormatReader.cs b/src/ProtocolBuffers/Serialization/XmlFormatReader.cs deleted file mode 100644 index 112910a7..00000000 --- a/src/ProtocolBuffers/Serialization/XmlFormatReader.cs +++ /dev/null @@ -1,287 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Xml; - -namespace Google.ProtocolBuffers.Serialization -{ - /// - /// Parses a proto buffer from an XML document or fragment. .NET 3.5 users may also - /// use this class to process Json by setting the options to support Json and providing - /// an XmlReader obtained from . - /// - public class XmlFormatReader : AbstractTextReader - { - public const string DefaultRootElementName = XmlFormatWriter.DefaultRootElementName; - private readonly XmlReader _input; - private string _rootElementName; - - private static XmlReaderSettings DefaultSettings - { - get - { - return new XmlReaderSettings() - {CheckCharacters = false, IgnoreComments = true, IgnoreProcessingInstructions = true}; - } - } - - /// - /// Constructs the XmlFormatReader using the stream provided as the xml - /// - 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 static XmlFormatReader CreateInstance(String input) - { - return new XmlFormatReader(XmlReader.Create(new StringReader(input), DefaultSettings)); - } - - /// - /// Constructs the XmlFormatReader using the xml in the TextReader - /// - public static XmlFormatReader CreateInstance(TextReader input) - { - return new XmlFormatReader(XmlReader.Create(input, DefaultSettings)); - } - - /// - /// Constructs the XmlFormatReader with the XmlReader - /// - public static XmlFormatReader CreateInstance(XmlReader input) - { - return new XmlFormatReader(input); - } - - /// - /// Constructs the XmlFormatReader with the XmlReader and options - /// - protected XmlFormatReader(XmlReader input) - { - _input = input; - _rootElementName = DefaultRootElementName; - 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>() - /// - public string RootElementName - { - get { return _rootElementName; } - set - { - ThrowHelper.ThrowIfNull(value, "RootElementName"); - _rootElementName = value; - } - } - - private XmlFormatReader CloneWith(XmlReader rdr) - { - XmlFormatReader copy = new XmlFormatReader(rdr).SetOptions(Options); - copy._rootElementName = _rootElementName; - copy.Depth = Depth; - return copy; - } - - private void NextElement() - { - while (!_input.IsStartElement() && _input.Read()) - { - continue; - } - } - - private static void Assert(bool cond) - { - if (!cond) - { - throw new FormatException(); - } - } - - /// - /// Merge the provided builder as an element named in the current context - /// - public override TBuilder Merge(TBuilder builder, ExtensionRegistry registry) - { - return Merge(_rootElementName, builder, registry); - } - - /// - /// Merge the provided builder as an element of the current context - /// - public TBuilder Merge(string element, TBuilder builder) where TBuilder : IBuilderLite - { - return Merge(element, builder, ExtensionRegistry.Empty); - } - - /// - /// Merge the provided builder as an element of the current context - /// - public TBuilder Merge(string element, TBuilder builder, ExtensionRegistry registry) - where TBuilder : IBuilderLite - { - string field; - Assert(PeekNext(out field) && field == element); - ReadMessage(builder, registry); - return builder; - } - - /// - /// Peeks at the next field in the input stream and returns what information is available. - /// - /// - /// This may be called multiple times without actually reading the field. Only after the field - /// is either read, or skipped, should PeekNext return a different value. - /// - protected override bool PeekNext(out string field) - { - NextElement(); - if (_input.IsStartElement()) - { - field = _input.LocalName; - return true; - } - field = null; - return false; - } - - /// - /// Causes the reader to skip past this field - /// - protected override void Skip() - { - if (_input.IsStartElement()) - { - if (!_input.IsEmptyElement) - { - int depth = _input.Depth; - while (_input.Depth >= depth && _input.NodeType != XmlNodeType.EndElement) - { - Assert(_input.Read()); - } - } - _input.Read(); - } - } - - /// - /// returns true if it was able to read a single value into the value reference. The value - /// stored may be of type System.String, System.Int32, or an IEnumLite from the IEnumLiteMap. - /// - protected override bool ReadEnum(ref object value) - { - int number; - string temp; - if (null != (temp = _input.GetAttribute("value")) && int.TryParse(temp, out number)) - { - Skip(); - value = number; - return true; - } - return base.ReadEnum(ref value); - } - - /// - /// Returns true if it was able to read a String from the input - /// - protected override bool ReadAsText(ref string value, Type type) - { - Assert(_input.NodeType == XmlNodeType.Element); - value = _input.ReadElementContentAsString(); - - return true; - } - - /// - /// Merges the input stream into the provided IBuilderLite - /// - protected override bool ReadMessage(IBuilderLite builder, ExtensionRegistry registry) - { - Assert(_input.IsStartElement()); - - if (!_input.IsEmptyElement) - { - int depth = _input.Depth; - XmlReader child = _input.ReadSubtree(); - while (!child.IsStartElement() && child.Read()) - { - continue; - } - child.Read(); - builder.WeakMergeFrom(CloneWith(child), registry); - Assert(depth == _input.Depth && _input.NodeType == XmlNodeType.EndElement); - } - _input.Read(); - return true; - } - - private IEnumerable NonNestedArrayItems(string field) - { - return base.ForeachArrayItem(field); - } - - /// - /// Cursors through the array elements and stops at the end of the array - /// - protected override IEnumerable ForeachArrayItem(string field) - { - bool isNested = (Options & XmlReaderOptions.ReadNestedArrays) != 0; - - if (!isNested) - { - foreach (string item in NonNestedArrayItems(field)) - { - yield return item; - } - yield break; - } - if (!_input.IsEmptyElement) - { - int depth = _input.Depth; - XmlReader child = _input.ReadSubtree(); - - while (!child.IsStartElement() && child.Read()) - { - continue; - } - child.Read(); - - foreach (string item in CloneWith(child).NonNestedArrayItems("item")) - { - yield return item; - } - Assert(depth == _input.Depth && _input.NodeType == XmlNodeType.EndElement); - } - _input.Read(); - yield break; - } - } -} \ No newline at end of file diff --git a/src/ProtocolBuffers/Serialization/XmlFormatWriter.cs b/src/ProtocolBuffers/Serialization/XmlFormatWriter.cs deleted file mode 100644 index fd36c1de..00000000 --- a/src/ProtocolBuffers/Serialization/XmlFormatWriter.cs +++ /dev/null @@ -1,243 +0,0 @@ -using System; -using System.Collections; -using System.IO; -using System.Text; -using System.Xml; -using Google.ProtocolBuffers.Descriptors; - -namespace Google.ProtocolBuffers.Serialization -{ - /// - /// Writes a proto buffer to an XML document or fragment. .NET 3.5 users may also - /// use this class to produce Json by setting the options to support Json and providing - /// an XmlWriter obtained from . - /// - public class XmlFormatWriter : AbstractTextWriter - { - public const string DefaultRootElementName = "root"; - private const int NestedArrayFlag = 0x0001; - private readonly XmlWriter _output; - private string _rootElementName; - - private static XmlWriterSettings DefaultSettings(Encoding encoding) - { - return new XmlWriterSettings() - { - CheckCharacters = false, - NewLineHandling = NewLineHandling.Entitize, - OmitXmlDeclaration = true, - Encoding = encoding, - }; - } - - /// - /// Constructs the XmlFormatWriter to write to the given TextWriter - /// - 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 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 static XmlFormatWriter CreateInstance(XmlWriter output) - { - return new XmlFormatWriter(output); - } - - protected XmlFormatWriter(XmlWriter output) - { - _output = output; - _rootElementName = DefaultRootElementName; - } - - /// - /// Closes the underlying XmlTextWriter - /// - protected override void Dispose(bool disposing) - { - if (disposing) - { - _output.Close(); - } - } - - /// - /// Gets or sets the default element name to use when using the Merge<TBuilder>() - /// - public string RootElementName - { - get { return _rootElementName; } - set - { - ThrowHelper.ThrowIfNull(value, "RootElementName"); - _rootElementName = value; - } - } - - /// - /// 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; - } - - /// - /// Writes a message as an element using the name defined in - /// - public override void WriteMessage(IMessageLite message) - { - WriteMessage(_rootElementName, message); - } - - /// - /// Writes a message as an element with the given name - /// - public void WriteMessage(string elementName, IMessageLite message) - { - if (TestOption(XmlWriterOptions.OutputJsonTypes)) - { - _output.WriteStartElement("root"); // json requires this is the root-element - _output.WriteAttributeString("type", "object"); - } - else - { - _output.WriteStartElement(elementName); - } - - message.WriteTo(this); - _output.WriteEndElement(); - _output.Flush(); - } - - /// - /// Writes a message - /// - protected override void WriteMessageOrGroup(string field, IMessageLite message) - { - _output.WriteStartElement(field); - - if (TestOption(XmlWriterOptions.OutputJsonTypes)) - { - _output.WriteAttributeString("type", "object"); - } - - message.WriteTo(this); - _output.WriteEndElement(); - } - - /// - /// Writes a String value - /// - protected override void WriteAsText(string field, string textValue, object typedValue) - { - _output.WriteStartElement(field); - - if (TestOption(XmlWriterOptions.OutputJsonTypes)) - { - if (typedValue is int || typedValue is uint || typedValue is long || typedValue is ulong || - typedValue is double || typedValue is float) - { - _output.WriteAttributeString("type", "number"); - } - else if (typedValue is bool) - { - _output.WriteAttributeString("type", "boolean"); - } - } - _output.WriteString(textValue); - - //Empty strings should not be written as empty elements '', rather as '' - if (_output.WriteState == WriteState.Element) - { - _output.WriteRaw(""); - } - - _output.WriteEndElement(); - } - - /// - /// Writes an array of field values - /// - protected override void WriteArray(FieldType fieldType, string field, IEnumerable items) - { - //see if it's empty - IEnumerator eitems = items.GetEnumerator(); - try - { - if (!eitems.MoveNext()) - { - return; - } - } - finally - { - if (eitems is IDisposable) - { - ((IDisposable) eitems).Dispose(); - } - } - - if (TestOption(XmlWriterOptions.OutputNestedArrays | XmlWriterOptions.OutputJsonTypes)) - { - _output.WriteStartElement(field); - if (TestOption(XmlWriterOptions.OutputJsonTypes)) - { - _output.WriteAttributeString("type", "array"); - } - - base.WriteArray(fieldType, "item", items); - _output.WriteEndElement(); - } - else - { - base.WriteArray(fieldType, field, items); - } - } - - /// - /// Writes a System.Enum by the numeric and textual value - /// - protected override void WriteEnum(string field, int number, string name) - { - _output.WriteStartElement(field); - - if (!TestOption(XmlWriterOptions.OutputJsonTypes) && TestOption(XmlWriterOptions.OutputEnumValues)) - { - _output.WriteAttributeString("value", XmlConvert.ToString(number)); - } - - _output.WriteString(name); - _output.WriteEndElement(); - } - } -} \ No newline at end of file diff --git a/src/ProtocolBuffers/Serialization/XmlReaderOptions.cs b/src/ProtocolBuffers/Serialization/XmlReaderOptions.cs deleted file mode 100644 index f7eca1d7..00000000 --- a/src/ProtocolBuffers/Serialization/XmlReaderOptions.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Google.ProtocolBuffers.Serialization -{ - /// - /// Options available for the xml reader output - /// - [Flags] - public enum XmlReaderOptions - { - /// Simple xml formatting with no attributes - None, - - /// Requires that arrays items are nested in an <item> element - ReadNestedArrays = 1, - } -} \ No newline at end of file diff --git a/src/ProtocolBuffers/Serialization/XmlWriterOptions.cs b/src/ProtocolBuffers/Serialization/XmlWriterOptions.cs deleted file mode 100644 index 7d740ee3..00000000 --- a/src/ProtocolBuffers/Serialization/XmlWriterOptions.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; - -namespace Google.ProtocolBuffers.Serialization -{ - /// - /// Options available for the xml writer output - /// - [Flags] - public enum XmlWriterOptions - { - /// Simple xml formatting with no attributes - None, - - /// Writes the 'value' attribute on all enumerations with the numeric identifier - OutputEnumValues = 0x1, - - /// Embeds array items into child <item> elements - OutputNestedArrays = 0x4, - - /// Outputs the 'type' attribute for compatibility with the JsonReaderWriterFactory - /// This option must, by nessessity, also enable NestedArrayItems - OutputJsonTypes = 0x8, - } -} \ No newline at end of file diff --git a/src/ProtocolBuffers2008.sln b/src/ProtocolBuffers2008.sln index 8172c7b9..fc0bf81d 100644 --- a/src/ProtocolBuffers2008.sln +++ b/src/ProtocolBuffers2008.sln @@ -67,6 +67,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{66ED1950 ..\build\RunBenchmarks.bat = ..\build\RunBenchmarks.bat EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProtocolBuffers.Serialization", "ProtocolBuffers.Serialization\ProtocolBuffers.Serialization.csproj", "{231391AF-449C-4a39-986C-AD7F270F4750}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug_Silverlight2|Any CPU = Debug_Silverlight2|Any CPU @@ -145,6 +147,14 @@ Global {EEFFED24-3750-4567-9A23-1DB676A15610}.Release_Silverlight2|Any CPU.ActiveCfg = Release|Any CPU {EEFFED24-3750-4567-9A23-1DB676A15610}.Release|Any CPU.ActiveCfg = Release|Any CPU {EEFFED24-3750-4567-9A23-1DB676A15610}.Release|Any CPU.Build.0 = Release|Any CPU + {231391AF-449C-4a39-986C-AD7F270F4750}.Debug_Silverlight2|Any CPU.ActiveCfg = Debug_Silverlight2|Any CPU + {231391AF-449C-4a39-986C-AD7F270F4750}.Debug_Silverlight2|Any CPU.Build.0 = Debug_Silverlight2|Any CPU + {231391AF-449C-4a39-986C-AD7F270F4750}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {231391AF-449C-4a39-986C-AD7F270F4750}.Debug|Any CPU.Build.0 = Debug|Any CPU + {231391AF-449C-4a39-986C-AD7F270F4750}.Release_Silverlight2|Any CPU.ActiveCfg = Release_Silverlight2|Any CPU + {231391AF-449C-4a39-986C-AD7F270F4750}.Release_Silverlight2|Any CPU.Build.0 = Release_Silverlight2|Any CPU + {231391AF-449C-4a39-986C-AD7F270F4750}.Release|Any CPU.ActiveCfg = Release|Any CPU + {231391AF-449C-4a39-986C-AD7F270F4750}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE -- cgit v1.2.3