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 != ProtoBuf.WireType.None)
            {
                throw ProtoWriter.CreateException(writer);
            }
            IExtension extensionObject = instance.GetExtensionObject(false);

            if (extensionObject != null)
            {
                Stream stream = extensionObject.BeginQuery();
                try
                {
                    ProtoWriter.CopyRawFromStream(stream, writer);
                }
                finally
                {
                    extensionObject.EndQuery(stream);
                }
            }
        }
Example #2
0
        /// <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); }
            }
        }
Example #3
0
        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);
        }
Example #4
0
#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);
            }
        }
Example #5
0
        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;
        }
Example #7
0
        /// <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);
            }
        }
Example #8
0
        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);
                }
            }
        }
Example #9
0
        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);
            }
        }
Example #10
0
        /// <summary>
        /// Copies any extension data stored for the instance to the underlying stream
        /// </summary>
        public static void AppendExtensionData(IExtensible instance, ProtoWriter writer, ref State state)
        {
            if (instance == null)
            {
                throw new ArgumentNullException(nameof(instance));
            }
            if (writer == null)
            {
                throw new ArgumentNullException(nameof(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
                {
                    if (ProtoReader.TryConsumeSegmentRespectingPosition(source, out var data, ProtoReader.TO_EOF))
                    {
                        writer.ImplWriteBytes(ref state, data.Array, data.Offset, data.Count);
                        writer.Advance(data.Count);
                    }
                    else
                    {
                        writer.ImplCopyRawFromStream(ref state, source);
                    }
                }
Example #11
0
        /// <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);
            }
        }
Example #13
0
        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);
        }