private static WireType GetDateTimeWireType(ProtoBuf.DataFormat format) { switch (format) { case ProtoBuf.DataFormat.Default: { return(WireType.String); } case ProtoBuf.DataFormat.ZigZag: case ProtoBuf.DataFormat.TwosComplement: { throw new InvalidOperationException(); } case ProtoBuf.DataFormat.FixedSize: { return(WireType.Fixed64); } case ProtoBuf.DataFormat.Group: { return(WireType.StartGroup); } default: { throw new InvalidOperationException(); } } }
private static WireType GetIntWireType(ProtoBuf.DataFormat format, int width) { switch (format) { case ProtoBuf.DataFormat.Default: case ProtoBuf.DataFormat.TwosComplement: { return(WireType.Variant); } case ProtoBuf.DataFormat.ZigZag: { return(WireType.SignedVariant); } case ProtoBuf.DataFormat.FixedSize: { if (width != 32) { return(WireType.Fixed64); } return(WireType.Fixed32); } } throw new InvalidOperationException(); }
internal static ProtoBuf.WireType GetIntWireType(ProtoBuf.DataFormat format, int width) { switch (format) { case ProtoBuf.DataFormat.ZigZag: return(ProtoBuf.WireType.SignedVariant); case ProtoBuf.DataFormat.FixedSize: return(width == 32 ? ProtoBuf.WireType.Fixed32 : ProtoBuf.WireType.Fixed64); case ProtoBuf.DataFormat.TwosComplement: case ProtoBuf.DataFormat.Default: return(ProtoBuf.WireType.Variant); default: throw new InvalidOperationException(); } }
internal ValueMember(RuntimeTypeModel model, int fieldNumber, Type memberType, Type itemType, Type defaultType, ProtoBuf.DataFormat dataFormat) { if (memberType == null) { throw new ArgumentNullException("memberType"); } if (model == null) { throw new ArgumentNullException("model"); } this.fieldNumber = fieldNumber; this.memberType = memberType; this.itemType = itemType; this.defaultType = defaultType; this.model = model; this.dataFormat = dataFormat; }
/// <summary> /// Queries an extensible object for an additional (unexpected) data-field for the instance. /// Each occurrence of the field is yielded separately, making this usage suitable for "repeated" /// (list) fields. /// </summary> /// <remarks>The extended data is processed lazily as the enumerator is iterated.</remarks> /// <typeparam name="TValue">The data-type of the field.</typeparam> /// <param name="instance">The extensible object to obtain the value from.</param> /// <param name="tag">The field identifier; the tag should not be defined as a known data-field for the instance.</param> /// <param name="format">The data-format to use when decoding the value.</param> /// <returns>An enumerator that yields each occurrence of the field.</returns> public static IEnumerable <TValue> GetValues <TValue>(IExtensible instance, int tag, DataFormat format) { return(ExtensibleUtil.GetExtendedValues <TValue>(instance, tag, format, false, false)); }
public ValueMember(RuntimeTypeModel model, Type parentType, int fieldNumber, MemberInfo member, Type memberType, Type itemType, Type defaultType, ProtoBuf.DataFormat dataFormat, object defaultValue) : this(model, fieldNumber, memberType, itemType, defaultType, dataFormat) { if (member == null) { throw new ArgumentNullException("member"); } if (parentType == null) { throw new ArgumentNullException("parentType"); } if (fieldNumber < 1 && !Helpers.IsEnum(parentType)) { throw new ArgumentOutOfRangeException("fieldNumber"); } this.member = member; this.parentType = parentType; if (fieldNumber < 1 && !Helpers.IsEnum(parentType)) { throw new ArgumentOutOfRangeException("fieldNumber"); } if (defaultValue != null && model.MapType(defaultValue.GetType()) != memberType) { defaultValue = ValueMember.ParseDefaultValue(memberType, defaultValue); } this.defaultValue = defaultValue; MetaType metaType = model.FindWithoutAdd(memberType); if (metaType != null) { this.asReference = metaType.AsReferenceDefault; return; } this.asReference = MetaType.GetAsReferenceDefault(model, memberType); }
/// <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> /// Queries an extensible object for an additional (unexpected) data-field for the instance. /// The value returned (in "value") is the composed value after merging any duplicated content; /// if the value is "repeated" (a list), then use GetValues instead. /// </summary> /// <typeparam name="TValue">The data-type of the field.</typeparam> /// <param name="value">The effective value of the field, or the default value if not found.</param> /// <param name="instance">The extensible object to obtain the value from.</param> /// <param name="tag">The field identifier; the tag should not be defined as a known data-field for the instance.</param> /// <param name="format">The data-format to use when decoding the value.</param> /// <returns>True if data for the field was present, false otherwise.</returns> public static bool TryGetValue <TValue>(IExtensible instance, int tag, DataFormat format, out TValue value) { return(TryGetValue <TValue>(instance, tag, format, false, out value)); }
public static bool TryGetValue(TypeModel model, Type type, IExtensible instance, int tag, DataFormat format, bool allowDefinedTag, out object value) { value = null; bool flag = false; foreach (object extendedValue in ExtensibleUtil.GetExtendedValues(model, type, instance, tag, format, true, allowDefinedTag)) { value = extendedValue; flag = true; } return(flag); }
} // 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); } }
internal static IProtoSerializer TryGetCoreSerializer(RuntimeTypeModel model, ProtoBuf.DataFormat dataFormat, Type type, out WireType defaultWireType, bool asReference, bool dynamicType, bool overwriteList, bool allowComplexTypes) { IProtoSerializer protoSerializer; Type underlyingType = Helpers.GetUnderlyingType(type); if (underlyingType != null) { type = underlyingType; } if (Helpers.IsEnum(type)) { if (!allowComplexTypes || model == null) { defaultWireType = WireType.None; return(null); } defaultWireType = WireType.Variant; return(new EnumSerializer(type, model.GetEnumMap(type))); } ProtoTypeCode typeCode = Helpers.GetTypeCode(type); switch (typeCode) { case ProtoTypeCode.Boolean: { defaultWireType = WireType.Variant; return(new BooleanSerializer(model)); } case ProtoTypeCode.Char: { defaultWireType = WireType.Variant; return(new CharSerializer(model)); } case ProtoTypeCode.SByte: { defaultWireType = ValueMember.GetIntWireType(dataFormat, 32); return(new SByteSerializer(model)); } case ProtoTypeCode.Byte: { defaultWireType = ValueMember.GetIntWireType(dataFormat, 32); return(new ByteSerializer(model)); } case ProtoTypeCode.Int16: { defaultWireType = ValueMember.GetIntWireType(dataFormat, 32); return(new Int16Serializer(model)); } case ProtoTypeCode.UInt16: { defaultWireType = ValueMember.GetIntWireType(dataFormat, 32); return(new UInt16Serializer(model)); } case ProtoTypeCode.Int32: { defaultWireType = ValueMember.GetIntWireType(dataFormat, 32); return(new Int32Serializer(model)); } case ProtoTypeCode.UInt32: { defaultWireType = ValueMember.GetIntWireType(dataFormat, 32); return(new UInt32Serializer(model)); } case ProtoTypeCode.Int64: { defaultWireType = ValueMember.GetIntWireType(dataFormat, 64); return(new Int64Serializer(model)); } case ProtoTypeCode.UInt64: { defaultWireType = ValueMember.GetIntWireType(dataFormat, 64); return(new UInt64Serializer(model)); } case ProtoTypeCode.Single: { defaultWireType = WireType.Fixed32; return(new SingleSerializer(model)); } case ProtoTypeCode.Double: { defaultWireType = WireType.Fixed64; return(new DoubleSerializer(model)); } case ProtoTypeCode.Decimal: { defaultWireType = WireType.String; return(new DecimalSerializer(model)); } case ProtoTypeCode.DateTime: { defaultWireType = ValueMember.GetDateTimeWireType(dataFormat); return(new DateTimeSerializer(model)); } case ProtoTypeCode.Unknown | ProtoTypeCode.DateTime: { Label0: if (model.AllowParseableTypes) { protoSerializer = ParseableSerializer.TryCreate(type, model); } else { protoSerializer = null; } IProtoSerializer protoSerializer1 = protoSerializer; if (protoSerializer1 != null) { defaultWireType = WireType.String; return(protoSerializer1); } if (allowComplexTypes && model != null) { int key = model.GetKey(type, false, true); if (asReference || dynamicType) { defaultWireType = (dataFormat == ProtoBuf.DataFormat.Group ? WireType.StartGroup : WireType.String); BclHelpers.NetObjectOptions netObjectOption = BclHelpers.NetObjectOptions.None; if (asReference) { netObjectOption = (BclHelpers.NetObjectOptions)((byte)(netObjectOption | BclHelpers.NetObjectOptions.AsReference)); } if (dynamicType) { netObjectOption = (BclHelpers.NetObjectOptions)((byte)(netObjectOption | BclHelpers.NetObjectOptions.DynamicType)); } if (key >= 0) { if (asReference && Helpers.IsValueType(type)) { string str = "AsReference cannot be used with value-types"; str = (type.Name != "KeyValuePair`2" ? string.Concat(str, ": ", type.FullName) : string.Concat(str, "; please see http://stackoverflow.com/q/14436606/")); throw new InvalidOperationException(str); } MetaType item = model[type]; if (asReference && item.IsAutoTuple) { netObjectOption = (BclHelpers.NetObjectOptions)((byte)(netObjectOption | BclHelpers.NetObjectOptions.LateSet)); } if (item.UseConstructor) { netObjectOption = (BclHelpers.NetObjectOptions)((byte)(netObjectOption | BclHelpers.NetObjectOptions.UseConstructor)); } } return(new NetObjectSerializer(model, type, key, netObjectOption)); } if (key >= 0) { defaultWireType = (dataFormat == ProtoBuf.DataFormat.Group ? WireType.StartGroup : WireType.String); return(new SubItemSerializer(type, key, model[type], true)); } } defaultWireType = WireType.None; return(null); } case ProtoTypeCode.String: { defaultWireType = WireType.String; if (!asReference) { return(new StringSerializer(model)); } return(new NetObjectSerializer(model, model.MapType(typeof(string)), 0, BclHelpers.NetObjectOptions.AsReference)); } default: { switch (typeCode) { case ProtoTypeCode.TimeSpan: { defaultWireType = ValueMember.GetDateTimeWireType(dataFormat); return(new TimeSpanSerializer(model)); } case ProtoTypeCode.ByteArray: { defaultWireType = WireType.String; return(new BlobSerializer(model, overwriteList)); } case ProtoTypeCode.Guid: { defaultWireType = WireType.String; return(new GuidSerializer(model)); } case ProtoTypeCode.Uri: { defaultWireType = WireType.String; return(new StringSerializer(model)); } case ProtoTypeCode.Type: { defaultWireType = WireType.String; return(new SystemTypeSerializer(model)); } default: { goto Label0; } } 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 <TValue> GetExtendedValues <TValue>(IExtensible instance, int tag, DataFormat format, bool singleton, bool allowDefinedTag) { throw new NotImplementedException();//TODO: NotImplementedException /*if (instance == null) throw new ArgumentNullException("instance"); * return (IEnumerable<TValue>)typeof(ExtensibleUtil) * .GetMethod("GetExtendedValuesTyped", BindingFlags.Public | BindingFlags.Static) * .MakeGenericMethod(instance.GetType(), typeof(TValue)) * .Invoke(null, new object[] { instance, tag, format, singleton, allowDefinedTag });*/ }
internal static IEnumerable <TValue> GetExtendedValues <TValue>(IExtensible instance, int tag, DataFormat format, bool singleton, bool allowDefinedTag) { ExtensibleUtil.< GetExtendedValues > c__Iterator11 <TValue> < GetExtendedValues > c__Iterator = new ExtensibleUtil.< GetExtendedValues > c__Iterator11 <TValue>();
/// <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); } }
/// <summary> /// Appends the value as an additional (unexpected) data-field for the instance. /// Note that for non-repeated sub-objects, this equates to a merge operation; /// for repeated sub-objects this adds a new instance to the set; for simple /// values the new value supercedes the old value. /// </summary> /// <remarks>Note that appending a value does not remove the old value from /// the stream; avoid repeatedly appending values for the same field.</remarks> /// <typeparam name="TValue">The data-type of the field.</typeparam> /// <param name="format">The data-format to use when encoding the value.</param> /// <param name="instance">The extensible object to append the value to.</param> /// <param name="tag">The field identifier; the tag should not be defined as a known data-field for the instance.</param> /// <param name="value">The value to append.</param> public static void AppendValue <TValue>(IExtensible instance, int tag, DataFormat format, TValue value) { ExtensibleUtil.AppendExtendValue <TValue>(RuntimeTypeModel.Default, instance, tag, format, value); }
/// <summary> /// Appends the value as an additional (unexpected) data-field for the instance. /// Note that for non-repeated sub-objects, this equates to a merge operation; /// for repeated sub-objects this adds a new instance to the set; for simple /// values the new value supercedes the old value. /// </summary> /// <remarks>Note that appending a value does not remove the old value from /// the stream; avoid repeatedly appending values for the same field.</remarks> /// <typeparam name="TValue">The data-type of the field.</typeparam> /// <param name="model">The model that represents the data.</param> /// <param name="format">The data-format to use when encoding the value.</param> /// <param name="instance">The extensible object to append the value to.</param> /// <param name="tag">The field identifier; the tag should not be defined as a known data-field for the instance.</param> /// <param name="value">The value to append.</param> public static void AppendValue <TValue>(TypeModel model, IExtensible instance, int tag, DataFormat format, TValue value) { ExtensibleUtil.AppendExtendValue <TValue>(model, instance, tag, format, value); }
public static IEnumerable GetValues(TypeModel model, Type type, IExtensible instance, int tag, DataFormat format) { return(ExtensibleUtil.GetExtendedValues(model, type, instance, tag, format, false, false)); }
/// <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 { throw new NotImplementedException();//TODO: NotImplementedException //if (instance == null) throw new ArgumentNullException("instance"); //if (!allowDefinedTag) { Serializer.CheckTagNotInUse(typeof(TSource),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; //} }
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 }
#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)); } IExtension extn = instance.GetExtensionObject(false); 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); } }
public static bool TryGetValue(TypeModel model, Type type, IExtensible instance, int tag, DataFormat format, bool allowDefinedTag, out object value) { value = null; bool result = false; IEnumerator enumerator = ExtensibleUtil.GetExtendedValues(model, type, instance, tag, format, true, allowDefinedTag).GetEnumerator(); try { while (enumerator.MoveNext()) { object current = enumerator.get_Current(); value = current; result = true; } } finally { IDisposable disposable = enumerator as IDisposable; if (disposable != null) { disposable.Dispose(); } } return(result); }
internal static void AppendExtendValue(TypeModel model, IExtensible instance, int tag, DataFormat format, object value) { model ??= TypeModel.DefaultModel; if (instance == null) { ThrowHelper.ThrowArgumentNullException(nameof(instance)); } if (value == null) { ThrowHelper.ThrowArgumentNullException(nameof(value)); } // TODO //model.CheckTagNotInUse(tag); // obtain the extension object and prepare to write IExtension extn = instance.GetExtensionObject(true); if (extn == null) { ThrowHelper.ThrowInvalidOperationException("No extension object available; appended data would be lost."); } bool commit = false; Stream stream = extn.BeginAppend(); try { var state = ProtoWriter.State.Create(stream, model, null); try { model.TrySerializeAuxiliaryType(ref state, null, format, tag, value, false, null); state.Close(); } catch { state.Abandon(); throw; } finally { state.Dispose(); } commit = true; } finally { extn.EndAppend(stream, commit); } }
/// <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 <TValue>(model, instance, tag, format, value); }