public IProtoSerializerWithWireType TryGetSimpleCoreSerializer(BinaryDataFormat dataFormat, Type type, out WireType defaultWireType) { object dummy = null; ValueFormat format = ValueFormat.Compact; return(TryGetCoreSerializer(dataFormat, type, out defaultWireType, ref format, false, false, false, false, ref dummy)); }
/// <summary> /// Dynamic type /// </summary> public NetObjectValueDecorator(Type dynamicBase, bool asReference, BinaryDataFormat dataFormatForDynamicBuiltins, bool allowNullWireType, RuntimeTypeModel model) : this(type : dynamicBase, asReference : asReference, asLateReference : false, allowNullWireType : allowNullWireType, model : model) { _dataFormatForDynamicBuiltins = dataFormatForDynamicBuiltins; _options |= BclHelpers.NetObjectOptions.DynamicType; // for late reference with dynamic type we need to get base type key from concrete // bacause dynamic types work with concrete type keys // but late reference - with bases // may be support later... }
WireType GetDateTimeWireType(BinaryDataFormat format) { switch (format) { case BinaryDataFormat.Group: return(WireType.StartGroup); case BinaryDataFormat.FixedSize: return(WireType.Fixed64); case BinaryDataFormat.Default: return(WireType.String); default: throw new InvalidOperationException(); } }
WireType GetIntWireType(BinaryDataFormat format, int width) { switch (format) { case BinaryDataFormat.ZigZag: return(WireType.SignedVariant); case BinaryDataFormat.FixedSize: return(width == 32 ? WireType.Fixed32 : WireType.Fixed64); case BinaryDataFormat.TwosComplement: case BinaryDataFormat.Default: return(WireType.Variant); default: throw new InvalidOperationException(); } }
public static WireType GetWireType(ProtoTypeCode code, BinaryDataFormat format) { switch (code) { case ProtoTypeCode.Int64: case ProtoTypeCode.UInt64: { return(format == BinaryDataFormat.FixedSize ? WireType.Fixed64 : WireType.Variant); } case ProtoTypeCode.Int16: case ProtoTypeCode.Int32: case ProtoTypeCode.UInt16: case ProtoTypeCode.UInt32: case ProtoTypeCode.Boolean: case ProtoTypeCode.SByte: case ProtoTypeCode.Byte: case ProtoTypeCode.Char: { return(format == BinaryDataFormat.FixedSize ? WireType.Fixed32 : WireType.Variant); } case ProtoTypeCode.Double: { return(WireType.Fixed64); } case ProtoTypeCode.Single: { return(WireType.Fixed32); } case ProtoTypeCode.String: case ProtoTypeCode.DateTime: case ProtoTypeCode.Decimal: case ProtoTypeCode.ByteArray: case ProtoTypeCode.TimeSpan: case ProtoTypeCode.Guid: case ProtoTypeCode.Uri: case ProtoTypeCode.Type: { return(WireType.String); } } return(WireType.None); }
public void SaveBinary(BinaryDataFormat format) { ExtensionFilter[] extensions; switch (format) { case BinaryDataFormat.Wii: extensions = new ExtensionFilter[] { wiiFilter }; break; case BinaryDataFormat.BringMiiToLife: extensions = new ExtensionFilter[] { superBinFilter }; break; default: throw new System.NotImplementedException("Binary format " + format + " is not implemented!"); } string path = StandaloneFileBrowser.SaveFilePanel("Save Mii from the nothing I've become...", Application.dataPath, this.data.basics.nickname, extensions); // Binary FileStream stream = new FileStream(path, FileMode.Create); BinaryFormatter formatter = new BinaryFormatter(); switch (format) { case BinaryDataFormat.BringMiiToLife: formatter.Serialize(stream, this.data); break; default: throw new System.NotImplementedException("Binary format " + format + " is not implemented!"); } stream.Close(); }
IProtoSerializerWithWireType TryGetBasicTypeSerializer(BinaryDataFormat dataFormat, Type type, out WireType defaultWireType, bool overwriteList) { ProtoTypeCode code = Helpers.GetTypeCode(type); switch (code) { case ProtoTypeCode.Int32: defaultWireType = GetIntWireType(dataFormat, 32); return(new WireTypeDecorator(defaultWireType, new Int32Serializer(_model))); case ProtoTypeCode.UInt32: defaultWireType = GetIntWireType(dataFormat, 32); return(new WireTypeDecorator(defaultWireType, new UInt32Serializer(_model))); case ProtoTypeCode.Int64: defaultWireType = GetIntWireType(dataFormat, 64); return(new WireTypeDecorator(defaultWireType, new Int64Serializer(_model))); case ProtoTypeCode.UInt64: defaultWireType = GetIntWireType(dataFormat, 64); return(new WireTypeDecorator(defaultWireType, new UInt64Serializer(_model))); case ProtoTypeCode.Single: defaultWireType = WireType.Fixed32; return(new WireTypeDecorator(defaultWireType, new SingleSerializer(_model))); case ProtoTypeCode.Double: defaultWireType = WireType.Fixed64; return(new WireTypeDecorator(defaultWireType, new DoubleSerializer(_model))); case ProtoTypeCode.Boolean: defaultWireType = WireType.Variant; return(new WireTypeDecorator(defaultWireType, new BooleanSerializer(_model))); case ProtoTypeCode.DateTime: defaultWireType = GetDateTimeWireType(dataFormat); return(new WireTypeDecorator(defaultWireType, new DateTimeSerializer(_model))); case ProtoTypeCode.Decimal: defaultWireType = WireType.String; return(new WireTypeDecorator(defaultWireType, new DecimalSerializer(_model))); case ProtoTypeCode.Byte: defaultWireType = GetIntWireType(dataFormat, 32); return(new WireTypeDecorator(defaultWireType, new ByteSerializer(_model))); case ProtoTypeCode.SByte: defaultWireType = GetIntWireType(dataFormat, 32); return(new WireTypeDecorator(defaultWireType, new SByteSerializer(_model))); case ProtoTypeCode.Char: defaultWireType = WireType.Variant; return(new WireTypeDecorator(defaultWireType, new CharSerializer(_model))); case ProtoTypeCode.Int16: defaultWireType = GetIntWireType(dataFormat, 32); return(new WireTypeDecorator(defaultWireType, new Int16Serializer(_model))); case ProtoTypeCode.UInt16: defaultWireType = GetIntWireType(dataFormat, 32); return(new WireTypeDecorator(defaultWireType, new UInt16Serializer(_model))); case ProtoTypeCode.TimeSpan: defaultWireType = GetDateTimeWireType(dataFormat); return(new WireTypeDecorator(defaultWireType, new TimeSpanSerializer(_model))); case ProtoTypeCode.Guid: defaultWireType = WireType.String; return(new WireTypeDecorator(defaultWireType, new GuidSerializer(_model))); case ProtoTypeCode.ByteArray: defaultWireType = WireType.String; return(new WireTypeDecorator(defaultWireType, new BlobSerializer(_model, overwriteList))); case ProtoTypeCode.Uri: // treat uri as string; wrapped in decorator later case ProtoTypeCode.String: defaultWireType = WireType.String; return(new WireTypeDecorator(defaultWireType, new StringSerializer(_model))); case ProtoTypeCode.Type: defaultWireType = WireType.String; return(new WireTypeDecorator(defaultWireType, new SystemTypeSerializer(_model))); } defaultWireType = WireType.None; return(null); }
/// <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> public IEnumerable GetExtendedValues(TypeModel model, Type type, IExtensible instance, int tag, BinaryDataFormat format, bool singleton, bool allowDefinedTag) { #if FEAT_IKVM throw new NotSupportedException(); #else if (instance == null) { throw new ArgumentNullException(nameof(instance)); } if (tag <= 0) { throw new ArgumentOutOfRangeException(nameof(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, true) && 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 }
public IProtoSerializerWithWireType TryGetCoreSerializer(BinaryDataFormat dataFormat, Type type, out WireType defaultWireType, ref ValueFormat format, bool dynamicType, bool appendCollection, bool isPackedCollection, bool allowComplexTypes, ref object defaultValue) { if (format == ValueFormat.NotSpecified) { throw new ArgumentException("Format should be specified for TryGetCoreSerializer", nameof(format)); } if (format != ValueFormat.Compact && _model.ProtoCompatibility.SuppressValueEnhancedFormat) { throw new InvalidOperationException("TryGetCoreSerializer should receive final format with ProtoCompatibility already taken into account"); } Type originalType = type; #if !NO_GENERICS { Type tmp = Helpers.GetNullableUnderlyingType(type); if (tmp != null) { type = tmp; } } #endif defaultWireType = WireType.None; IProtoSerializerWithWireType ser = null; if (Helpers.IsEnum(type)) { if (allowComplexTypes && _model != null) { // need to do this before checking the typecode; an int enum will report Int32 etc defaultWireType = WireType.Variant; ser = new WireTypeDecorator(defaultWireType, new EnumSerializer(type, _model.GetEnumMap(type))); } else { // enum is fine for adding as a meta-type defaultWireType = WireType.None; return(null); } } if (ser == null) { ser = TryGetBasicTypeSerializer(dataFormat, type, out defaultWireType, !appendCollection); if (ser != null && Helpers.GetTypeCode(type) == ProtoTypeCode.Uri) { // should be after uri but uri should always be before collection if (defaultValue != null) { ser = new DefaultValueDecorator(_model, defaultValue, ser); defaultValue = null; } } } if (ser == null) { var parseable = _model.AllowParseableTypes ? ParseableSerializer.TryCreate(type, _model) : null; if (parseable != null) { defaultWireType = WireType.String; ser = new WireTypeDecorator(defaultWireType, parseable); } } if (ser != null) { return((isPackedCollection || !allowComplexTypes) ? ser : DecorateValueSerializer(originalType, dynamicType ? dataFormat : (BinaryDataFormat?)null, ref format, ser)); } if (allowComplexTypes) { int baseKey = _model.GetKey(type, false, true); defaultWireType = WireType.StartGroup; if (baseKey >= 0 || dynamicType) { if (dynamicType) { return(new NetObjectValueDecorator(originalType, format == ValueFormat.Reference || format == ValueFormat.LateReference, dataFormat, !_model.ProtoCompatibility.SuppressNullWireType, _model)); } else if (format == ValueFormat.LateReference && CanTypeBeAsLateReferenceOnBuildStage(baseKey, _model)) { return(new NetObjectValueDecorator(originalType, baseKey, true, true, _model[type], !_model.ProtoCompatibility.SuppressNullWireType, _model)); } else if (MetaType.IsNetObjectValueDecoratorNecessary(_model, format)) { return(new NetObjectValueDecorator(originalType, baseKey, format == ValueFormat.Reference || format == ValueFormat.LateReference, false, _model[type], !_model.ProtoCompatibility.SuppressNullWireType, _model)); } else { return(new ModelTypeSerializer(type, baseKey, _model[type], _model)); } } } defaultWireType = WireType.None; return(null); }
/// <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, BinaryDataFormat format, TValue value) { AppendValue(RuntimeTypeModel.Default, instance, tag, format, value); }
public MemberHandlerResult TryRead(AttributeMap attribute, MemberState s, MemberInfo member, RuntimeTypeModel model) { if (s.Input.IsEnumValueMember) { return(MemberHandlerResult.NotFound); } var main = s.MainValue; try { MemberLevelSettingsValue level = s.SerializationSettings.GetSettingsCopy(0).Basic; level.DefaultsMode = MemberDefaultsMode.Legacy; if (main.Tag <= 0) { attribute.TryGetNotDefault("Tag", ref main.Tag); } if (string.IsNullOrEmpty(main.Name)) { attribute.TryGetNotEmpty("Name", ref main.Name); } if (!main.IsRequiredInSchema) { attribute.TryGetNotDefault("IsRequired", ref main.IsRequiredInSchema); } var type = Helpers.GetMemberType(member); BinaryDataFormat dataFormat = 0; attribute.TryGetNotDefault("DataFormat", ref dataFormat); level.ContentBinaryFormatHint = dataFormat; bool isPacked = false; attribute.TryGetNotDefault("IsPacked", ref isPacked); level.Collection.Format = isPacked ? CollectionFormat.Protobuf : (model.ProtoCompatibility.SuppressCollectionEnhancedFormat ? CollectionFormat.ProtobufNotPacked : CollectionFormat.NotSpecified ); bool overwriteList = false; attribute.TryGetNotDefault("OverwriteList", ref overwriteList); level.Collection.Append = !overwriteList; if (!level.WriteAsDynamicType.GetValueOrDefault()) { attribute.TryGetNotDefault("DynamicType", ref level.WriteAsDynamicType); } bool dynamicType = level.WriteAsDynamicType.GetValueOrDefault(); bool asRefHasValue = false; bool notAsReference = false; #if !FEAT_IKVM // IKVM can't access AsReferenceHasValue, but conveniently, AsReference will only be returned if set via ctor or property attribute.TryGetNotDefault("AsReferenceHasValue", ref asRefHasValue, publicOnly: false); if (asRefHasValue) #endif { bool value = false; asRefHasValue = attribute.TryGetNotDefault("AsReference", ref value); if (asRefHasValue) // if AsReference = true - use defaults { notAsReference = !value; } } if (!asRefHasValue) { if (level.Format == ValueFormat.NotSpecified) { SetLegacyFormat(ref level, member, model); } } else { level.Format = notAsReference ? ValueSerializerBuilder.GetDefaultLegacyFormat(type, model) : ValueFormat.Reference; } s.TagIsPinned = main.Tag > 0; var dl = s.SerializationSettings.DefaultLevel.GetValueOrDefault(new ValueSerializationSettings.LevelValue(level.MakeDefaultNestedLevelForLegacyMember())); if (isPacked) { dl.Basic.Format = ValueFormat.Compact; } if (dynamicType) { // apply dynamic type to items Type itemType = null; Type defaultType = null; MetaType.ResolveListTypes(model, Helpers.GetMemberType(s.Member), ref itemType, ref defaultType); if (itemType != null) { dl.Basic.WriteAsDynamicType = true; dl.Basic.Format = ValueFormat.Reference; if (level.Format == ValueFormat.Compact || level.Format == ValueFormat.MinimalEnhancement) { level.WriteAsDynamicType = false; } } } s.SerializationSettings.DefaultLevel = dl; s.SerializationSettings.SetSettings(level, 0); return(s.TagIsPinned ? MemberHandlerResult.Done : MemberHandlerResult.Partial); // note minAcceptFieldNumber only applies to non-proto } finally { s.MainValue = main; } }
/// <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> /// <param name="allowDefinedTag">Allow tags that are present as part of the definition; for example, to query unknown enum values.</param> /// <returns>True if data for the field was present, false otherwise.</returns> public static bool TryGetValue <TValue>(IExtensible instance, int tag, BinaryDataFormat format, bool allowDefinedTag, out TValue value) { return(TryGetValue(RuntimeTypeModel.Default, instance, tag, format, allowDefinedTag, out value)); }
/// <summary> /// Queries an extensible object for an additional (unexpected) data-field for the instance. /// The value returned 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="model"></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>The effective value of the field, or the default value if not found.</returns> public static TValue GetValue <TValue>(TypeModel model, IExtensible instance, int tag, BinaryDataFormat format) { TValue value; TryGetValue(model, instance, tag, format, out value); return(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> /// <param name="model">The model to use for configuration.</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(TypeModel model, IExtensible instance, int tag, BinaryDataFormat format, object value) { model.ExtensibleUtil.AppendExtendValue(model, instance, tag, format, value); }
internal string GetSchemaTypeName(Type effectiveType, BinaryDataFormat dataFormat, bool asReference, bool dynamicType, ref bool requiresBclImport) { Type tmp = Helpers.GetNullableUnderlyingType(effectiveType); if (tmp != null) { effectiveType = tmp; } if (effectiveType == this.MapType(typeof(byte[]))) { return("bytes"); } WireType wireType; IProtoSerializer ser = this.ValueSerializerBuilder.TryGetSimpleCoreSerializer(dataFormat, effectiveType, out wireType); if (ser == null) { // model type if (asReference || dynamicType) { requiresBclImport = true; return("bcl.NetObjectProxy"); } return(this[effectiveType].GetSurrogateOrBaseOrSelf(true).GetSchemaTypeName()); } if (ser is ParseableSerializer) { if (asReference) { requiresBclImport = true; } return(asReference ? "bcl.NetObjectProxy" : "string"); } switch (Helpers.GetTypeCode(effectiveType)) { case ProtoTypeCode.Boolean: return("bool"); case ProtoTypeCode.Single: return("float"); case ProtoTypeCode.Double: return("double"); case ProtoTypeCode.Type: case ProtoTypeCode.String: if (asReference) { requiresBclImport = true; } return(asReference ? "bcl.NetObjectProxy" : "string"); case ProtoTypeCode.Byte: case ProtoTypeCode.Char: case ProtoTypeCode.UInt16: case ProtoTypeCode.UInt32: switch (dataFormat) { case BinaryDataFormat.FixedSize: return("fixed32"); default: return("uint32"); } case ProtoTypeCode.SByte: case ProtoTypeCode.Int16: case ProtoTypeCode.Int32: switch (dataFormat) { case BinaryDataFormat.ZigZag: return("sint32"); case BinaryDataFormat.FixedSize: return("sfixed32"); default: return("int32"); } case ProtoTypeCode.UInt64: switch (dataFormat) { case BinaryDataFormat.FixedSize: return("fixed64"); default: return("uint64"); } case ProtoTypeCode.Int64: switch (dataFormat) { case BinaryDataFormat.ZigZag: return("sint64"); case BinaryDataFormat.FixedSize: return("sfixed64"); default: return("int64"); } case ProtoTypeCode.DateTime: requiresBclImport = true; return("bcl.DateTime"); case ProtoTypeCode.TimeSpan: requiresBclImport = true; return("bcl.TimeSpan"); case ProtoTypeCode.Decimal: requiresBclImport = true; return("bcl.Decimal"); case ProtoTypeCode.Guid: requiresBclImport = true; return("bcl.Guid"); default: throw new NotSupportedException("No .proto map found for: " + effectiveType.FullName); } }
/// <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> /// <param name="type">The data-type of the field.</param> /// <param name="model">The model to use for configuration.</param> /// <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> /// <param name="allowDefinedTag">Allow tags that are present as part of the definition; for example, to query unknown enum values.</param> /// <returns>True if data for the field was present, false otherwise.</returns> public static bool TryGetValue(TypeModel model, System.Type type, IExtensible instance, int tag, BinaryDataFormat format, bool allowDefinedTag, out object value) { value = null; bool set = false; foreach (object val in model.ExtensibleUtil.GetExtendedValues(model, type, instance, tag, format, true, allowDefinedTag)) { // expecting at most one yield... // but don't break; need to read entire stream value = val; set = true; } return(set); }
public void AppendExtendValue(TypeModel model, IExtensible instance, int tag, BinaryDataFormat format, object value) { #if FEAT_IKVM throw new NotSupportedException(); #else if (instance == null) { throw new ArgumentNullException(nameof(instance)); } if (value == null) { throw new ArgumentNullException(nameof(value)); } // 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, true); writer.Close(); } commit = true; } finally { extn.EndAppend(stream, commit); } #endif }
/// <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="model"></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>An enumerator that yields each occurrence of the field.</returns> public static IEnumerable <TValue> GetValues <TValue>(TypeModel model, IExtensible instance, int tag, BinaryDataFormat format) { return(model.ExtensibleUtil.GetExtendedValues <TValue>(instance, tag, format, false, false)); }
/// <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, BinaryDataFormat format) { return(GetValues <TValue>(RuntimeTypeModel.Default, instance, tag, format)); }
/// <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="model"></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> /// <param name="allowDefinedTag">Allow tags that are present as part of the definition; for example, to query unknown enum values.</param> /// <returns>True if data for the field was present, false otherwise.</returns> public static bool TryGetValue <TValue>(TypeModel model, IExtensible instance, int tag, BinaryDataFormat format, bool allowDefinedTag, out TValue value) { value = default(TValue); bool set = false; foreach (TValue val in model.ExtensibleUtil.GetExtendedValues <TValue>(instance, tag, format, true, allowDefinedTag)) { // expecting at most one yield... // but don't break; need to read entire stream value = val; set = true; } return(set); }
/// <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> public IEnumerable <TValue> GetExtendedValues <TValue>(IExtensible instance, int tag, BinaryDataFormat format, bool singleton, bool allowDefinedTag) { foreach (TValue value in GetExtendedValues(_typeModel, typeof(TValue), instance, tag, format, singleton, allowDefinedTag)) { yield return(value); } }
private bool TryDeserializeList(TypeModel model, ProtoReader reader, BinaryDataFormat format, int tag, Type listType, Type itemType, bool isRoot, ref object value) { bool isList; MethodInfo addMethod = TypeModel.ResolveListAdd(model, listType, itemType, out isList); if (addMethod == null) { throw new NotSupportedException("Unknown list variant: " + listType.FullName); } bool found = false; object nextItem = null; IList list = value as IList; object[] args = isList ? null : new object[1]; BasicList arraySurrogate = listType.IsArray ? new BasicList() : null; while (TryDeserializeAuxiliaryType(reader, format, tag, itemType, ref nextItem, true, true, true, true, isRoot)) { found = true; if (value == null && arraySurrogate == null) { value = CreateListInstance(listType, itemType); if (value != null) { ProtoReader.NoteObject(value, reader); } list = value as IList; } if (list != null) { list.Add(nextItem); } else if (arraySurrogate != null) { arraySurrogate.Add(nextItem); } else { args[0] = nextItem; addMethod.Invoke(value, args); } nextItem = null; } if (arraySurrogate != null) { Array newArray; if (value != null) { if (arraySurrogate.Count == 0) { // we'll stay with what we had, thanks } else { Array existing = (Array)value; newArray = Array.CreateInstance(itemType, existing.Length + arraySurrogate.Count); Array.Copy(existing, newArray, existing.Length); arraySurrogate.CopyTo(newArray, existing.Length); value = newArray; } } else { newArray = Array.CreateInstance(itemType, arraySurrogate.Count); arraySurrogate.CopyTo(newArray, 0); value = newArray; ProtoReader.NoteObject(value, reader); } } return(found); }
/// <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> /// <param name="model">The model to use for configuration.</param> /// <param name="type">The data-type of the field.</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>An enumerator that yields each occurrence of the field.</returns> public static IEnumerable GetValues(TypeModel model, System.Type type, IExtensible instance, int tag, BinaryDataFormat format) { return(model.ExtensibleUtil.GetExtendedValues(model, type, instance, tag, format, false, false)); }
/// <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="model"></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>(TypeModel model, IExtensible instance, int tag, BinaryDataFormat format, out TValue value) { return(TryGetValue(model, instance, tag, format, false, out value)); }