/// <summary> /// Copies any extension data stored for the instance to the underlying stream /// </summary> public static void AppendExtensionData(IExtensible instance, ProtoWriter writer) { if (instance == null) { throw new ArgumentNullException("instance"); } if (writer == null) { throw new ArgumentNullException("writer"); } // we expect the writer to be raw here; the extension data will have the // header detail, so we'll copy it implicitly if (writer.wireType != WireType.None) { throw CreateException(writer); } IExtension extn = instance.GetExtensionObject(false); if (extn != null) { // unusually we *don't* want "using" here; the "finally" does that, with // the extension object being responsible for disposal etc Stream source = extn.BeginQuery(); try { CopyRawFromStream(source, writer); } finally { extn.EndQuery(source); } } }
public static void AppendExtensionData(IExtensible instance, ProtoWriter writer) { if (instance == null) { throw new ArgumentNullException("instance"); } if (writer == null) { throw new ArgumentNullException("writer"); } if (writer.wireType != WireType.None) { throw CreateException(writer); } IExtension extensionObject = instance.GetExtensionObject(createIfMissing: false); if (extensionObject != null) { Stream stream = extensionObject.BeginQuery(); try { CopyRawFromStream(stream, writer); } finally { extensionObject.EndQuery(stream); } } }
public static void AppendExtensionData(IExtensible instance, ProtoWriter writer) { if (instance == null) { throw new ArgumentNullException("instance"); } if (writer == null) { throw new ArgumentNullException("writer"); } if (writer.wireType != WireType.None) { throw ProtoWriter.CreateException(writer); } IExtension extn = instance.GetExtensionObject(false); if (extn != null) { Stream source = extn.BeginQuery(); try { ProtoWriter.CopyRawFromStream(source, writer); } finally { extn.EndQuery(source); } } }
internal static int Serialize(T instance, SerializationContext context) { // check for inheritance; if the instance is a subclass, then we // should serialize the sub-type first, allowing for more efficient // deserialization; note that we don't push the instance onto the // stack yet - we'll do that within each instance (otherwise deep // items could incorrectly count as cyclic). Type actualType = instance.GetType(); int total = 0, len; Callback(CallbackType.BeforeSerialization, instance); if (actualType != typeof(T)) { bool subclassFound = false; foreach (KeyValuePair <Type, Property <T, T> > subclass in subclasses) { if (subclass.Key.IsAssignableFrom(actualType)) { total += subclass.Value.Serialize(instance, context); subclassFound = true; break; } } if (!subclassFound) { throw new ProtoException("Unexpected type found during serialization; types must be included with ProtoIncludeAttribute; " + "found " + actualType.Name + " passed as " + typeof(T).Name); } } context.Push(instance); for (int i = 0; i < writeProps.Length; i++) { // note that this serialization includes the headers... total += writeProps[i].Serialize(instance, context); } IExtensible extensible = instance as IExtensible; IExtension extra = extensible == null ? null : extensible.GetExtensionObject(false); if (extra != null && (len = extra.GetLength()) > 0) { Stream extraStream = extra.BeginQuery(); try { context.WriteFrom(extraStream, len); total += len; } finally { extra.EndQuery(extraStream); } } context.Pop(instance); Callback(CallbackType.AfterSerialization, instance); return(total); }
#pragma warning disable RCS1163, IDE0060 // Unused parameter. /// <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) #pragma warning restore RCS1163, IDE0060 // Unused parameter. { model ??= TypeModel.DefaultModel; if (instance == null) { ThrowHelper.ThrowArgumentNullException(nameof(instance)); } if (tag <= 0) { ThrowHelper.ThrowArgumentOutOfRangeException(nameof(tag)); } #pragma warning disable RCS1227 // Validate arguments correctly. IExtension extn = instance.GetExtensionObject(false); #pragma warning restore RCS1227 // Validate arguments correctly. if (extn == null) { yield break; } Stream stream = extn.BeginQuery(); try { object value = null; SerializationContext ctx = new SerializationContext(); var state = ProtoReader.State.Create(stream, model, ctx, ProtoReader.TO_EOF).Solidify(); try { while (model.TryDeserializeAuxiliaryType(ref state, format, tag, type, ref value, true, true, false, false, null) && value != null) { if (!singleton) { yield return(value); value = null; // fresh item each time } } if (singleton && value != null) { yield return(value); } } finally { state.Dispose(); } } finally { extn.EndQuery(stream); } }
private Dictionary <string, string> DumpOptions(dynamic options) { Dictionary <string, string> options_kv = new Dictionary <string, string>(); if (options == null) { return(options_kv); } // generate precompiled options foreach (PropertyInfo propInfo in options.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) { string name; string value = GetValueForProp(propInfo, options, false, out name); if (value != null) { options_kv.Add(name, value); } } // generate reflected options (extensions to this type) IExtension extend = ((IExtensible)options).GetExtensionObject(false); List <Type> extensions = new List <Type>(); if (extend != null && protobufExtensions.TryGetValue(options.GetType().FullName, out extensions)) { foreach (var extension in extensions) { Stream ms = extend.BeginQuery(); object deserialized = RuntimeTypeModel.Default.Deserialize(ms, null, extension); foreach (var fieldInfo in extension.GetFields(BindingFlags.Instance | BindingFlags.Public)) { string name; string value = GetValueForProp(fieldInfo, deserialized, true, out name); if (value != null) { options_kv.Add(name, value); } } extend.EndQuery(ms); } } return(options_kv); }
internal static IEnumerable GetExtendedValues(TypeModel model, Type type, IExtensible instance, int tag, DataFormat format, bool singleton, bool allowDefinedTag) { if (instance == null) { throw new ArgumentNullException("instance"); } if (tag <= 0) { throw new ArgumentOutOfRangeException("tag"); } IExtension extensionObject = instance.GetExtensionObject(false); if (extensionObject != null) { Stream stream = extensionObject.BeginQuery(); object obj = null; ProtoReader protoReader = null; try { SerializationContext serializationContext = new SerializationContext(); protoReader = ProtoReader.Create(stream, model, serializationContext, -1); while (model.TryDeserializeAuxiliaryType(protoReader, format, tag, type, ref obj, true, false, false, false) && obj != null) { if (singleton) { continue; } yield return(obj); obj = null; } if (!singleton || obj == null) { goto Label0; } yield return(obj); } finally { ProtoReader.Recycle(protoReader); extensionObject.EndQuery(stream); } } Label0: yield break; }
/// <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 (instance == null) { throw new ArgumentNullException(nameof(instance)); } if (tag <= 0) { throw new ArgumentOutOfRangeException(nameof(tag)); } IExtension extn = instance.GetExtensionObject(false); if (extn == null) { yield break; } 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, null) && value != null) { if (!singleton) { yield return(value); value = null; // fresh item each time } } if (singleton && value != null) { yield return(value); } } finally { ProtoReader.Recycle(reader); extn.EndQuery(stream); } }
internal static IEnumerable GetExtendedValues(TypeModel model, Type type, IExtensible instance, int tag, DataFormat format, bool singleton, bool allowDefinedTag) { if (instance == null) { throw new ArgumentNullException("instance"); } if (tag <= 0) { throw new ArgumentOutOfRangeException("tag"); } IExtension extn = instance.GetExtensionObject(createIfMissing: false); if (extn != null) { Stream stream = extn.BeginQuery(); object value = null; ProtoReader reader = null; try { SerializationContext context = new SerializationContext(); reader = ProtoReader.Create(stream, model, context, -1); while (model.TryDeserializeAuxiliaryType(reader, format, tag, type, ref value, skipOtherFields: true, asListItem: false, autoCreate: false, insideList: false) && value != null) { if (!singleton) { yield return(value); value = null; } } if (singleton && value != null) { yield return(value); } } finally { ProtoReader.Recycle(reader); extn.EndQuery(stream); } } }
static byte[] GetExtensionBytes(IExtensible obj) { Assert.IsNotNull(obj, "null extensible"); IExtension extn = obj.GetExtensionObject(false); Assert.IsNotNull(extn, "no extension object"); Stream s = extn.BeginQuery(); try { using (MemoryStream ms = new MemoryStream()) { int b; // really lazy clone... while ((b = s.ReadByte()) >= 0) { ms.WriteByte((byte)b); } return(ms.ToArray()); } } finally { extn.EndQuery(s); } }
/// <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 }
/// <summary> /// Reads the given value(s) from the instance's stream; the serializer /// is inferred from TValue and format. For singletons, each occurrence /// is merged [only applies for sub-objects], and the composed /// value if yielded once; otherwise ("repeated") each occurrence /// is yielded separately. /// </summary> /// <remarks>Needs to be public to be callable thru reflection in Silverlight</remarks> public static IEnumerable <TValue> GetExtendedValuesTyped <TSource, TValue>( TSource instance, int tag, DataFormat format, bool singleton, bool allowDefinedTag) where TSource : class, IExtensible { if (instance == null) { throw new ArgumentNullException("instance"); } if (!allowDefinedTag) { Serializer <TSource> .CheckTagNotInUse(tag); } Property <TValue, TValue> prop = PropertyFactory.CreatePassThru <TValue>(tag, ref format); List <Property <TValue, TValue> > props = new List <Property <TValue, TValue> >(); foreach (Property <TValue, TValue> altProp in prop.GetCompatibleReaders()) { props.Add(altProp); } IExtension extn = instance.GetExtensionObject(false); if (extn == null) { yield break; } Stream stream = extn.BeginQuery(); TValue lastValue = default(TValue); bool hasValue = false; try { SerializationContext ctx = new SerializationContext(stream, null); uint fieldPrefix; while (ctx.TryReadFieldPrefix(out fieldPrefix)) { WireType a; int b; Serializer.ParseFieldToken(fieldPrefix, out a, out b); Property <TValue, TValue> actProp = null; if (fieldPrefix == prop.FieldPrefix) { actProp = prop; } else { foreach (Property <TValue, TValue> x in props) { if (x.FieldPrefix == fieldPrefix) { actProp = x; break; } } } if (actProp != null) { TValue value = actProp.DeserializeImpl(lastValue, ctx); hasValue = true; if (singleton) { // merge with later values before returning lastValue = value; } else { // return immediately; no merge yield return(value); } } else { int readTag; WireType wireType; Serializer.ParseFieldToken(fieldPrefix, out wireType, out readTag); if (readTag == tag) { // we can't deserialize data of that type - for example, // have received Fixed32 for a string, etc throw new ProtoException(string.Format( "Unexpected wire-type ({0}) found for tag {1}.", wireType, readTag)); } // skip all other tags Serializer.SkipData(ctx, readTag, wireType); } } } finally { extn.EndQuery(stream); } if (singleton && hasValue) { yield return(lastValue); } }
private Dictionary <string, string> DumpOptions(dynamic options) { Dictionary <string, string> options_kv = new Dictionary <string, string>(); if (options == null) { return(options_kv); } var optionsType = options.GetType(); // generate precompiled options var propertySearchBindingFlags = BindingFlags.Public | BindingFlags.Instance; foreach (PropertyInfo propInfo in optionsType.GetProperties(propertySearchBindingFlags)) { var propertySpecifiedSuffix = "Specified"; var propName = propInfo.Name; if (propName.EndsWith(propertySpecifiedSuffix)) { continue; } var specifiedProp = optionsType.GetProperty(propName + propertySpecifiedSuffix, propertySearchBindingFlags); if (specifiedProp != null) { var isSpecified = specifiedProp.GetValue(options); if (!isSpecified) { continue; } } string name; string value = GetValueForProp(propInfo, options, false, out name); if (value != null) { options_kv.Add(name, value); } } // generate reflected options (extensions to this type) IExtension extend = ((IExtensible)options).GetExtensionObject(false); List <Type> extensions = new List <Type>(); if (extend != null && protobufExtensions.TryGetValue(options.GetType().FullName, out extensions)) { foreach (var extension in extensions) { Stream ms = extend.BeginQuery(); object deserialized = RuntimeTypeModel.Default.Deserialize(ms, null, extension); foreach (var fieldInfo in extension.GetFields(BindingFlags.Instance | BindingFlags.Public)) { string name; string value = GetValueForProp(fieldInfo, deserialized, true, out name); if (value != null) { options_kv.Add(name, value); } } extend.EndQuery(ms); } } return(options_kv); }