123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- using System;
- using System.Collections;
- #if !NO_GENERICS
- using System.Collections.Generic;
- #endif
- using System.IO;
- using ProtoBuf.Meta;
- namespace ProtoBuf
- {
- /// <summary>
- /// This class acts as an internal wrapper allowing us to do a dynamic
- /// methodinfo invoke; an't put into Serializer as don't want on public
- /// API; can't put into Serializer<T> since we need to invoke
- /// accross classes, which isn't allowed in Silverlight)
- /// </summary>
- internal
- #if FX11
- sealed
- #else
- static
- #endif
- class ExtensibleUtil
- {
- #if FX11
- private ExtensibleUtil() { } // not a static class for C# 1.2 reasons
- #endif
- #if !NO_RUNTIME && !NO_GENERICS
- /// <summary>
- /// All this does is call GetExtendedValuesTyped with the correct type for "instance";
- /// this ensures that we don't get issues with subclasses declaring conflicting types -
- /// the caller must respect the fields defined for the type they pass in.
- /// </summary>
- internal static IEnumerable<TValue> GetExtendedValues<TValue>(IExtensible instance, int tag, DataFormat format, bool singleton, bool allowDefinedTag)
- {
- foreach (TValue value in GetExtendedValues(RuntimeTypeModel.Default, typeof(TValue), instance, tag, format, singleton, allowDefinedTag))
- {
- yield return value;
- }
- }
- #endif
- /// <summary>
- /// All this does is call GetExtendedValuesTyped with the correct type for "instance";
- /// this ensures that we don't get issues with subclasses declaring conflicting types -
- /// the caller must respect the fields defined for the type they pass in.
- /// </summary>
- internal static IEnumerable GetExtendedValues(TypeModel model, Type type, IExtensible instance, int tag, DataFormat format, bool singleton, bool allowDefinedTag)
- {
- #if FEAT_IKVM
- throw new NotSupportedException();
- #else
- if (instance == null) throw new ArgumentNullException("instance");
- if (tag <= 0) throw new ArgumentOutOfRangeException("tag");
- IExtension extn = instance.GetExtensionObject(false);
- if (extn == null)
- {
- #if FX11
- return new object[0];
- #else
- yield break;
- #endif
- }
- #if FX11
- BasicList result = new BasicList();
- #endif
- Stream stream = extn.BeginQuery();
- object value = null;
- ProtoReader reader = null;
- try {
- SerializationContext ctx = new SerializationContext();
- reader = ProtoReader.Create(stream, model, ctx, ProtoReader.TO_EOF);
- while (model.TryDeserializeAuxiliaryType(reader, format, tag, type, ref value, true, false, false, false) && value != null)
- {
- if (!singleton)
- {
- #if FX11
- result.Add(value);
- #else
- yield return value;
- #endif
- value = null; // fresh item each time
- }
- }
- if (singleton && value != null)
- {
- #if FX11
- result.Add(value);
- #else
- yield return value;
- #endif
- }
- #if FX11
- object[] resultArr = new object[result.Count];
- result.CopyTo(resultArr, 0);
- return resultArr;
- #endif
- } finally {
- ProtoReader.Recycle(reader);
- extn.EndQuery(stream);
- }
- #endif
- }
- internal static void AppendExtendValue(TypeModel model, IExtensible instance, int tag, DataFormat format, object value)
- {
- #if FEAT_IKVM
- throw new NotSupportedException();
- #else
- if(instance == null) throw new ArgumentNullException("instance");
- if(value == null) throw new ArgumentNullException("value");
- // TODO
- //model.CheckTagNotInUse(tag);
- // obtain the extension object and prepare to write
- IExtension extn = instance.GetExtensionObject(true);
- if (extn == null) throw new InvalidOperationException("No extension object available; appended data would be lost.");
- bool commit = false;
- Stream stream = extn.BeginAppend();
- try {
- using(ProtoWriter writer = new ProtoWriter(stream, model, null)) {
- model.TrySerializeAuxiliaryType(writer, null, format, tag, value, false);
- writer.Close();
- }
- commit = true;
- }
- finally {
- extn.EndAppend(stream, commit);
- }
- #endif
- }
- //#if !NO_GENERICS
- // /// <summary>
- // /// Stores the given value into the instance's stream; the serializer
- // /// is inferred from TValue and format.
- // /// </summary>
- // /// <remarks>Needs to be public to be callable thru reflection in Silverlight</remarks>
- // public static void AppendExtendValueTyped<TSource, TValue>(
- // TypeModel model, TSource instance, int tag, DataFormat format, TValue value)
- // where TSource : class, IExtensible
- // {
- // AppendExtendValue(model, instance, tag, format, value);
- // }
- //#endif
- }
- }
|