123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701 |
- 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
- {
- /// <summary>
- /// Provides a base-class that provides some basic functionality for handling type dispatching
- /// </summary>
- public abstract class AbstractReader : ICodedInputStream
- {
- private const int DefaultMaxDepth = 64;
- private int _depth;
-
- /// <summary> Constructs a new reader </summary>
- protected AbstractReader() { MaxDepth = DefaultMaxDepth; }
- /// <summary> Gets or sets the maximum recursion depth allowed </summary>
- public int MaxDepth { get; set; }
- /// <summary>
- /// Merges the contents of stream into the provided message builder
- /// </summary>
- public TBuilder Merge<TBuilder>(TBuilder builder) where TBuilder : IBuilderLite
- {
- return Merge(builder, ExtensionRegistry.Empty);
- }
- /// <summary>
- /// Merges the contents of stream into the provided message builder
- /// </summary>
- public abstract TBuilder Merge<TBuilder>(TBuilder builder, ExtensionRegistry registry)
- where TBuilder : IBuilderLite;
- /// <summary>
- /// Peeks at the next field in the input stream and returns what information is available.
- /// </summary>
- /// <remarks>
- /// 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.
- /// </remarks>
- protected abstract bool PeekNext(out string field);
- /// <summary>
- /// Causes the reader to skip past this field
- /// </summary>
- protected abstract void Skip();
- /// <summary>
- /// Returns true if it was able to read a Boolean from the input
- /// </summary>
- protected abstract bool Read(ref bool value);
- /// <summary>
- /// Returns true if it was able to read a Int32 from the input
- /// </summary>
- protected abstract bool Read(ref int value);
- /// <summary>
- /// Returns true if it was able to read a UInt32 from the input
- /// </summary>
- [CLSCompliant(false)]
- protected abstract bool Read(ref uint value);
- /// <summary>
- /// Returns true if it was able to read a Int64 from the input
- /// </summary>
- protected abstract bool Read(ref long value);
- /// <summary>
- /// Returns true if it was able to read a UInt64 from the input
- /// </summary>
- [CLSCompliant(false)]
- protected abstract bool Read(ref ulong value);
- /// <summary>
- /// Returns true if it was able to read a Single from the input
- /// </summary>
- protected abstract bool Read(ref float value);
- /// <summary>
- /// Returns true if it was able to read a Double from the input
- /// </summary>
- protected abstract bool Read(ref double value);
- /// <summary>
- /// Returns true if it was able to read a String from the input
- /// </summary>
- protected abstract bool Read(ref string value);
- /// <summary>
- /// Returns true if it was able to read a ByteString from the input
- /// </summary>
- protected abstract bool Read(ref ByteString value);
- /// <summary>
- /// 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.
- /// </summary>
- protected abstract bool ReadEnum(ref object value);
- /// <summary>
- /// Merges the input stream into the provided IBuilderLite
- /// </summary>
- protected abstract bool ReadMessage(IBuilderLite builder, ExtensionRegistry registry);
-
- /// <summary>
- /// Reads the root-message preamble specific to this formatter
- /// </summary>
- public abstract void ReadMessageStart();
- /// <summary>
- /// Reads the root-message close specific to this formatter
- /// </summary>
- public abstract void ReadMessageEnd();
- /// <summary>
- /// Merges the input stream into the provided IBuilderLite
- /// </summary>
- public virtual bool ReadGroup(IBuilderLite value, ExtensionRegistry registry)
- {
- return ReadMessage(value, registry);
- }
- /// <summary>
- /// Cursors through the array elements and stops at the end of the array
- /// </summary>
- protected virtual IEnumerable<string> ForeachArrayItem(string field)
- {
- string next = field;
- while (true)
- {
- yield return next;
- if (!PeekNext(out next) || next != field)
- {
- break;
- }
- }
- }
- /// <summary>
- /// Reads an array of T messages
- /// </summary>
- public virtual bool ReadMessageArray<T>(string field, ICollection<T> 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;
- }
- /// <summary>
- /// Reads an array of T messages as a proto-buffer group
- /// </summary>
- public virtual bool ReadGroupArray<T>(string field, ICollection<T> 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;
- }
- /// <summary>
- /// Reads an array of System.Enum type T and adds them to the collection
- /// </summary>
- public virtual bool ReadEnumArray(string field, ICollection<object> items)
- {
- bool success = false;
- foreach (string next in ForeachArrayItem(field))
- {
- object temp = null;
- if (ReadEnum(ref temp))
- {
- items.Add(temp);
- success |= true;
- }
- }
- return success;
- }
- /// <summary>
- /// Reads an array of T, where T is a primitive type defined by FieldType
- /// </summary>
- public virtual bool ReadArray<T>(FieldType type, string field, ICollection<T> 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;
- }
- /// <summary>
- /// returns true if it was able to read a single primitive value of FieldType into the value reference
- /// </summary>
- 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<T>(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<object> list)
- {
- ReadArray(fieldType, fieldName, list);
- }
- void ICodedInputStream.ReadEnumArray(uint fieldTag, string fieldName, ICollection<IEnumLite> list,
- out ICollection<object> unknown, IEnumLiteMap mapping)
- {
- unknown = null;
- List<object> array = new List<object>();
- 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<object>();
- }
- unknown.Add(rawValue);
- }
- }
- }
- }
- void ICodedInputStream.ReadEnumArray<T>(uint fieldTag, string fieldName, ICollection<T> list,
- out ICollection<object> unknown)
- {
- unknown = null;
- List<object> array = new List<object>();
- 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<object>();
- }
- unknown.Add(rawValue);
- }
- }
- }
- }
- void ICodedInputStream.ReadMessageArray<T>(uint fieldTag, string fieldName, ICollection<T> list, T messageType,
- ExtensionRegistry registry)
- {
- if (_depth++ > MaxDepth)
- {
- throw new RecursionLimitExceededException();
- }
- ReadMessageArray(fieldName, list, messageType, registry);
- _depth--;
- }
- void ICodedInputStream.ReadGroupArray<T>(uint fieldTag, string fieldName, ICollection<T> 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<string> list)
- {
- ReadArray(FieldType.String, fieldName, list);
- }
- void ICodedInputStream.ReadBytesArray(uint fieldTag, string fieldName, ICollection<ByteString> list)
- {
- ReadArray(FieldType.Bytes, fieldName, list);
- }
- void ICodedInputStream.ReadBoolArray(uint fieldTag, string fieldName, ICollection<bool> list)
- {
- ReadArray(FieldType.Bool, fieldName, list);
- }
- void ICodedInputStream.ReadInt32Array(uint fieldTag, string fieldName, ICollection<int> list)
- {
- ReadArray(FieldType.Int32, fieldName, list);
- }
- void ICodedInputStream.ReadSInt32Array(uint fieldTag, string fieldName, ICollection<int> list)
- {
- ReadArray(FieldType.SInt32, fieldName, list);
- }
- void ICodedInputStream.ReadUInt32Array(uint fieldTag, string fieldName, ICollection<uint> list)
- {
- ReadArray(FieldType.UInt32, fieldName, list);
- }
- void ICodedInputStream.ReadFixed32Array(uint fieldTag, string fieldName, ICollection<uint> list)
- {
- ReadArray(FieldType.Fixed32, fieldName, list);
- }
- void ICodedInputStream.ReadSFixed32Array(uint fieldTag, string fieldName, ICollection<int> list)
- {
- ReadArray(FieldType.SFixed32, fieldName, list);
- }
- void ICodedInputStream.ReadInt64Array(uint fieldTag, string fieldName, ICollection<long> list)
- {
- ReadArray(FieldType.Int64, fieldName, list);
- }
- void ICodedInputStream.ReadSInt64Array(uint fieldTag, string fieldName, ICollection<long> list)
- {
- ReadArray(FieldType.SInt64, fieldName, list);
- }
- void ICodedInputStream.ReadUInt64Array(uint fieldTag, string fieldName, ICollection<ulong> list)
- {
- ReadArray(FieldType.UInt64, fieldName, list);
- }
- void ICodedInputStream.ReadFixed64Array(uint fieldTag, string fieldName, ICollection<ulong> list)
- {
- ReadArray(FieldType.Fixed64, fieldName, list);
- }
- void ICodedInputStream.ReadSFixed64Array(uint fieldTag, string fieldName, ICollection<long> list)
- {
- ReadArray(FieldType.SFixed64, fieldName, list);
- }
- void ICodedInputStream.ReadDoubleArray(uint fieldTag, string fieldName, ICollection<double> list)
- {
- ReadArray(FieldType.Double, fieldName, list);
- }
- void ICodedInputStream.ReadFloatArray(uint fieldTag, string fieldName, ICollection<float> list)
- {
- ReadArray(FieldType.Float, fieldName, list);
- }
- #endregion
- }
- }
|