using System;
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 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; }
/// 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
///
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
///
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);
///
/// Reads the root-message preamble specific to this formatter
///
public abstract void ReadMessageStart();
///
/// Reads the root-message close specific to this formatter
///
public abstract void ReadMessageEnd();
///
/// 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