static public int constructor(IntPtr l) { try { ProtoBuf.SubItemToken o; o = new ProtoBuf.SubItemToken(); pushValue(l, true); pushValue(l, o); return(2); } catch (Exception e) { return(error(l, e)); } }
// Token: 0x06000139 RID: 313 RVA: 0x0000CF44 File Offset: 0x0000B144 internal static void WriteObject(object value, int key, ProtoWriter writer, PrefixStyle style, int fieldNumber) { if (writer.model == null) { throw new InvalidOperationException("Cannot serialize sub-objects unless a model is provided"); } if (writer.wireType != WireType.None) { throw ProtoWriter.CreateException(writer); } if (style != PrefixStyle.Base128) { if (style - PrefixStyle.Fixed32 > 1) { throw new ArgumentOutOfRangeException("style"); } writer.fieldNumber = 0; writer.wireType = WireType.Fixed32; } else { writer.wireType = WireType.String; writer.fieldNumber = fieldNumber; if (fieldNumber > 0) { ProtoWriter.WriteHeaderCore(fieldNumber, WireType.String, writer); } } SubItemToken token = ProtoWriter.StartSubItem(value, writer, true); if (key < 0) { if (!writer.model.TrySerializeAuxiliaryType(writer, value.GetType(), DataFormat.Default, 1, value, false)) { TypeModel.ThrowUnexpectedType(value.GetType()); } } else { writer.model.Serialize(key, value, writer); } ProtoWriter.EndSubItem(token, writer, style); }
internal static object ReadTypedObject(object value, int key, ProtoReader reader, Type type) { if (reader.model == null) { throw AddErrorData(new InvalidOperationException("Cannot deserialize sub-objects unless a model is provided"), reader); } SubItemToken token = StartSubItem(reader); if (key >= 0) { value = reader.model.Deserialize(key, value, reader); } else if (!(type != (Type)null) || !reader.model.TryDeserializeAuxiliaryType(reader, DataFormat.Default, 1, type, ref value, true, false, true, false)) { TypeModel.ThrowUnexpectedType(type); } EndSubItem(token, reader); return(value); }
private static SubItemToken StartSubItem(object instance, ProtoWriter writer, bool allowFixed) { if (writer == null) { throw new ArgumentNullException("writer"); } if (++writer.depth > 25) { writer.CheckRecursionStackAndPush(instance); } if (writer.packedFieldNumber != 0) { throw new InvalidOperationException("Cannot begin a sub-item while performing packed encoding"); } switch (writer.wireType) { case WireType.String: writer.wireType = WireType.None; ProtoWriter.DemandSpace(32, writer); writer.flushLock++; writer.position++; return(new SubItemToken(writer.ioIndex++)); case WireType.StartGroup: writer.wireType = WireType.None; return(new SubItemToken(-writer.fieldNumber)); case WireType.Fixed32: { if (!allowFixed) { throw ProtoWriter.CreateException(writer); } ProtoWriter.DemandSpace(32, writer); writer.flushLock++; SubItemToken result = new SubItemToken(writer.ioIndex); ProtoWriter.IncrementedAndReset(4, writer); return(result); } } throw ProtoWriter.CreateException(writer); }
public static decimal ReadDecimal(ProtoReader reader) { ulong num = 0uL; uint num2 = 0u; uint num3 = 0u; SubItemToken token = ProtoReader.StartSubItem(reader); int num4; while ((num4 = reader.ReadFieldHeader()) > 0) { switch (num4) { case 1: num = reader.ReadUInt64(); break; case 2: num2 = reader.ReadUInt32(); break; case 3: num3 = reader.ReadUInt32(); break; default: reader.SkipField(); break; } } ProtoReader.EndSubItem(token, reader); if (num == 0uL && num2 == 0u) { return(0m); } int num5 = (int)(num & (ulong)-1); int num6 = (int)(num >> 32 & (ulong)-1); int num7 = (int)num2; bool flag = (num3 & 1u) == 1u; byte b = (byte)((num3 & 510u) >> 1); return(new decimal(num5, num6, num7, flag, b)); }
/// <summary> /// Parses a decimal from a protobuf stream /// </summary> public static decimal ReadDecimal(ProtoReader reader) { ulong low = 0; uint high = 0; uint signScale = 0; int fieldNumber; SubItemToken token = ProtoReader.StartSubItem(reader); while ((fieldNumber = reader.ReadFieldHeader()) > 0) { switch (fieldNumber) { case FieldDecimalLow: low = reader.ReadUInt64(); break; case FieldDecimalHigh: high = reader.ReadUInt32(); break; case FieldDecimalSignScale: signScale = reader.ReadUInt32(); break; default: reader.SkipField(); break; } } ProtoReader.EndSubItem(token, reader); if (low == 0 && high == 0) { return(decimal.Zero); } int lo = (int)(low & 0xFFFFFFFFL), mid = (int)((low >> 32) & 0xFFFFFFFFL), hi = (int)high; bool isNeg = (signScale & 0x0001) == 0x0001; byte scale = (byte)((signScale & 0x01FE) >> 1); return(new decimal(lo, mid, hi, isNeg, scale)); }
/// <summary> /// Write an encapsulated sub-object, using the supplied unique key (reprasenting a type). /// </summary> /// <param name="value">The object to write.</param> /// <param name="key">The key that uniquely identifies the type within the model.</param> /// <param name="writer">The destination.</param> public static void WriteObject(object value, int key, ProtoWriter writer) { #if FEAT_IKVM throw new NotSupportedException(); #else if (writer == null) { throw new ArgumentNullException("writer"); } if (writer.model == null) { throw new InvalidOperationException("Cannot serialize sub-objects unless a model is provided"); } SubItemToken token = StartSubItem(value, writer); if (key >= 0) { writer.model.Serialize(key, value, writer); } else if (writer.model != null && writer.model.TrySerializeAuxiliaryType(writer, value.GetType(), DataFormat.Default, Serializer.ListItemTag, value, false)) { // all ok } else { TypeModel.ThrowUnexpectedType(value.GetType()); } EndSubItem(token, writer); #endif }
public static decimal ReadDecimal(ProtoReader reader) { ulong num = 0uL; uint num2 = 0u; uint num3 = 0u; SubItemToken token = ProtoReader.StartSubItem(reader); int num4; while ((num4 = reader.ReadFieldHeader()) > 0) { switch (num4) { case 1: num = reader.ReadUInt64(); break; case 2: num2 = reader.ReadUInt32(); break; case 3: num3 = reader.ReadUInt32(); break; default: reader.SkipField(); break; } } ProtoReader.EndSubItem(token, reader); if (num == 0L && num2 == 0) { return(0m); } int lo = (int)(num & uint.MaxValue); int mid = (int)((num >> 32) & uint.MaxValue); int hi = (int)num2; bool isNegative = (num3 & 1) == 1; byte scale = (byte)((num3 & 0x1FE) >> 1); return(new decimal(lo, mid, hi, isNegative, scale)); }
/// <summary> /// Writes a decimal to a protobuf stream /// </summary> public static void WriteDecimal(decimal value, ProtoWriter writer) { int[] bits = decimal.GetBits(value); ulong a = ((ulong)bits[1]) << 32, b = ((ulong)bits[0]) & 0xFFFFFFFFL; ulong low = a | b; uint high = (uint)bits[2]; uint signScale = (uint)(((bits[3] >> 15) & 0x01FE) | ((bits[3] >> 31) & 0x0001)); SubItemToken token = ProtoWriter.StartSubItem(null, writer); if (low != 0) { ProtoWriter.WriteFieldHeader(FieldDecimalLow, WireType.Variant, writer); ProtoWriter.WriteUInt64(low, writer); } if (high != 0) { ProtoWriter.WriteFieldHeader(FieldDecimalHigh, WireType.Variant, writer); ProtoWriter.WriteUInt32(high, writer); } if (signScale != 0) { ProtoWriter.WriteFieldHeader(FieldDecimalSignScale, WireType.Variant, writer); ProtoWriter.WriteUInt32(signScale, writer); } ProtoWriter.EndSubItem(token, writer); }
/// <summary> /// Write an encapsulated sub-object, using the supplied unique key (reprasenting a type) - but the /// caller is asserting that this relationship is non-recursive; no recursion check will be /// performed. /// </summary> /// <param name="value">The object to write.</param> /// <param name="key">The key that uniquely identifies the type within the model.</param> /// <param name="writer">The destination.</param> public static void WriteRecursionSafeObject(object value, int key, ProtoWriter writer) { if (writer == null) { throw new ArgumentNullException("writer"); } if (writer.model == null) { throw new InvalidOperationException("Cannot serialize sub-objects unless a model is provided"); } SubItemToken token = StartSubItem(null, writer); writer.model.Serialize(key, value, writer); EndSubItem(token, writer); }
private static SubItemToken StartSubItem(object instance, ProtoWriter writer, bool allowFixed) { if (++writer.depth > RecursionCheckDepth) { writer.CheckRecursionStackAndPush(instance); } if (writer.packedFieldNumber != 0) { throw new InvalidOperationException("Cannot begin a sub-item while performing packed encoding"); } switch (writer.wireType) { case WireType.StartGroup: writer.wireType = WireType.None; return(new SubItemToken(-writer.fieldNumber)); case WireType.String: writer.wireType = WireType.None; DemandSpace(32, writer); // make some space in anticipation... writer.flushLock++; writer.position++; return(new SubItemToken(writer.ioIndex++)); // leave 1 space (optimistic) for length case WireType.Fixed32: { if (!allowFixed) { throw CreateException(writer); } DemandSpace(32, writer); // make some space in anticipation... writer.flushLock++; SubItemToken token = new SubItemToken(writer.ioIndex); ProtoWriter.IncrementedAndReset(4, writer); // leave 4 space (rigid) for length return(token); } default: throw CreateException(writer); } }
public static void WriteObject(object value, int key, ProtoWriter writer) { if (writer == null) { throw new ArgumentNullException("writer"); } if (writer.model == null) { throw new InvalidOperationException("Cannot serialize sub-objects unless a model is provided"); } SubItemToken subItemToken = ProtoWriter.StartSubItem(value, writer); if (key >= 0) { writer.model.Serialize(key, value, writer); } else if (writer.model == null || !writer.model.TrySerializeAuxiliaryType(writer, value.GetType(), DataFormat.Default, 1, value, false)) { TypeModel.ThrowUnexpectedType(value.GetType()); } ProtoWriter.EndSubItem(subItemToken, writer); }
private protected override SubItemToken ImplStartLengthPrefixedSubItem(ref State state, object instance, PrefixStyle style) { switch (WireType) { case WireType.String: WireType = WireType.None; DemandSpace(32, this, ref state); // make some space in anticipation... flushLock++; Advance(1); return(new SubItemToken((long)(ioIndex++))); // leave 1 space (optimistic) for length case WireType.Fixed32: DemandSpace(32, this, ref state); // make some space in anticipation... flushLock++; SubItemToken token = new SubItemToken((long)ioIndex); IncrementedAndReset(4, this); // leave 4 space (rigid) for length return(token); default: throw CreateException(this); } }
/// <summary> /// Parses a Guid from a protobuf stream /// </summary> public static Guid ReadGuid(ProtoReader source) { ulong low = 0, high = 0; int fieldNumber; SubItemToken token = ProtoReader.StartSubItem(source); while ((fieldNumber = source.ReadFieldHeader()) > 0) { switch (fieldNumber) { case FieldGuidLow: low = source.ReadUInt64(); break; case FieldGuidHigh: high = source.ReadUInt64(); break; default: source.SkipField(); break; } } ProtoReader.EndSubItem(token, source); if (low == 0 && high == 0) { return(Guid.Empty); } uint a = (uint)(low >> 32), b = (uint)low, c = (uint)(high >> 32), d = (uint)high; return(new Guid((int)b, (short)a, (short)(a >> 16), (byte)d, (byte)(d >> 8), (byte)(d >> 16), (byte)(d >> 24), (byte)c, (byte)(c >> 8), (byte)(c >> 16), (byte)(c >> 24))); }
public static Guid ReadGuid(ProtoReader source) { ulong num = 0uL; ulong num2 = 0uL; SubItemToken token = ProtoReader.StartSubItem(source); int num3; while ((num3 = source.ReadFieldHeader()) > 0) { int num4 = num3; if (num4 != 1) { if (num4 != 2) { source.SkipField(); } else { num2 = source.ReadUInt64(); } } else { num = source.ReadUInt64(); } } ProtoReader.EndSubItem(token, source); if (num == 0uL && num2 == 0uL) { return(Guid.Empty); } uint num5 = (uint)(num >> 32); uint num6 = (uint)num; uint num7 = (uint)(num2 >> 32); uint num8 = (uint)num2; return(new Guid((int)num6, (short)num5, (short)(num5 >> 16), (byte)num8, (byte)(num8 >> 8), (byte)(num8 >> 16), (byte)(num8 >> 24), (byte)num7, (byte)(num7 >> 8), (byte)(num7 >> 16), (byte)(num7 >> 24))); }
/// <summary> /// Writes a Guid to a protobuf stream /// </summary> public static void WriteGuid(Guid value, ProtoWriter dest) { byte[] blob = value.ToByteArray(); SubItemToken token = ProtoWriter.StartSubItem(null, dest); if (value != Guid.Empty) { ProtoWriter.WriteFieldHeader(FieldGuidLow, WireType.Fixed64, dest); ProtoWriter.WriteBytes(blob, 0, 8, dest); ProtoWriter.WriteFieldHeader(FieldGuidHigh, WireType.Fixed64, dest); ProtoWriter.WriteBytes(blob, 8, 8, dest); } ProtoWriter.EndSubItem(token, dest); }
private void AppendExtensionField(ProtoWriter writer) { //TODO: replace this with stream-based, buffered raw copying ProtoWriter.WriteFieldHeader(fieldNumber, wireType, writer); switch (wireType) { case WireType.Fixed32: ProtoWriter.WriteInt32(ReadInt32(), writer); return; case WireType.Variant: case WireType.SignedVariant: case WireType.Fixed64: ProtoWriter.WriteInt64(ReadInt64(), writer); return; case WireType.String: ProtoWriter.WriteBytes(AppendBytes(null, this), writer); return; case WireType.StartGroup: SubItemToken readerToken = StartSubItem(this), writerToken = ProtoWriter.StartSubItem(null, writer); while (ReadFieldHeader() > 0) { AppendExtensionField(writer); } EndSubItem(readerToken, this); ProtoWriter.EndSubItem(writerToken, writer); return; case WireType.None: // treat as explicit errorr case WireType.EndGroup: // treat as explicit error default: // treat as implicit error throw CreateException(); } }
/// <summary> /// Makes the end of consuming a nested message in the stream; the stream must be either at the correct EndGroup /// marker, or all fields of the sub-message must have been consumed (in either case, this means ReadFieldHeader /// should return zero) /// </summary> public static void EndSubItem(SubItemToken token, ProtoReader reader) { int value = token.value; switch (reader.wireType) { case WireType.EndGroup: if (value >= 0) { throw AddErrorData(new ArgumentException("token"), reader); } if (-value != reader.fieldNumber) { throw reader.CreateException(); // wrong group ended! } reader.wireType = WireType.None; // this releases ReadFieldHeader reader.depth--; break; // case WireType.None: // TODO reinstate once reads reset the wire-type default: if (value < reader.position) { throw reader.CreateException(); } if (reader.blockEnd != reader.position && reader.blockEnd != int.MaxValue) { throw reader.CreateException(); } reader.blockEnd = value; reader.depth--; break; /*default: * throw reader.BorkedIt(); */ } }
public static void EndSubItem(SubItemToken token, ProtoReader reader) { if (reader == null) { throw new ArgumentNullException("reader"); } int value = token.value; WireType wireType = reader.wireType; if (wireType != WireType.EndGroup) { if (value < reader.position) { throw reader.CreateException("Sub-message not read entirely"); } if (reader.blockEnd != reader.position && reader.blockEnd != 2147483647) { throw reader.CreateException("Sub-message not read correctly"); } reader.blockEnd = value; reader.depth--; } else { if (value >= 0) { throw ProtoReader.AddErrorData(new ArgumentException("token"), reader); } if (-value != reader.fieldNumber) { throw reader.CreateException("Wrong group was ended"); } reader.wireType = WireType.None; reader.depth--; } }
private void AppendExtensionField(ProtoWriter writer) { ProtoWriter.WriteFieldHeader(this.fieldNumber, this.wireType, writer); WireType wireType = this.wireType; switch (wireType + 1) { case WireType.Fixed64: case WireType.String: case (WireType)9: ProtoWriter.WriteInt64(this.ReadInt64(), writer); return; case WireType.StartGroup: ProtoWriter.WriteBytes(ProtoReader.AppendBytes(null, this), writer); return; case WireType.EndGroup: { SubItemToken token = ProtoReader.StartSubItem(this); SubItemToken token2 = ProtoWriter.StartSubItem(null, writer); while (this.ReadFieldHeader() > 0) { this.AppendExtensionField(writer); } ProtoReader.EndSubItem(token, this); ProtoWriter.EndSubItem(token2, writer); return; } case (WireType)6: ProtoWriter.WriteInt32(this.ReadInt32(), writer); return; } throw this.CreateWireTypeException(); }
internal static void WriteObject(object value, int key, ProtoWriter writer, PrefixStyle style, int fieldNumber) { if (writer.model == null) { throw new InvalidOperationException("Cannot serialize sub-objects unless a model is provided"); } if (writer.wireType != WireType.None) { throw ProtoWriter.CreateException(writer); } switch (style) { case PrefixStyle.Base128: writer.wireType = WireType.String; writer.fieldNumber = fieldNumber; if (fieldNumber > 0) { WriteHeaderCore(fieldNumber, WireType.String, writer); } break; case PrefixStyle.Fixed32: case PrefixStyle.Fixed32BigEndian: writer.fieldNumber = 0; writer.wireType = WireType.Fixed32; break; default: throw new ArgumentOutOfRangeException("style"); } SubItemToken token = StartSubItem(value, writer, true); writer.model.Serialize(key, value, writer); EndSubItem(token, writer, style); }
private void AppendExtensionField(ProtoWriter writer) { ProtoWriter.WriteFieldHeader(fieldNumber, wireType, writer); switch (wireType) { case WireType.Fixed32: ProtoWriter.WriteInt32(ReadInt32(), writer); break; case WireType.Variant: case WireType.Fixed64: case WireType.SignedVariant: ProtoWriter.WriteInt64(ReadInt64(), writer); break; case WireType.String: ProtoWriter.WriteBytes(AppendBytes(null, this), writer); break; case WireType.StartGroup: { SubItemToken token = StartSubItem(this); SubItemToken token2 = ProtoWriter.StartSubItem(null, writer); while (ReadFieldHeader() > 0) { AppendExtensionField(writer); } EndSubItem(token, this); ProtoWriter.EndSubItem(token2, writer); break; } default: throw CreateWireTypeException(); } }
public static Guid ReadGuid(ProtoReader source) { ulong num = 0uL; ulong num2 = 0uL; SubItemToken token = ProtoReader.StartSubItem(source); int num3; while ((num3 = source.ReadFieldHeader()) > 0) { switch (num3) { case 1: num = source.ReadUInt64(); break; case 2: num2 = source.ReadUInt64(); break; default: source.SkipField(); break; } } ProtoReader.EndSubItem(token, source); if (num == 0L && num2 == 0L) { return(Guid.Empty); } uint num4 = (uint)(num >> 32); int a = (int)num; uint num5 = (uint)(num2 >> 32); uint num6 = (uint)num2; return(new Guid(a, (short)num4, (short)(num4 >> 16), (byte)num6, (byte)(num6 >> 8), (byte)(num6 >> 16), (byte)(num6 >> 24), (byte)num5, (byte)(num5 >> 8), (byte)(num5 >> 16), (byte)(num5 >> 24))); }
/// <summary> /// Indicates the end of a nested record. /// </summary> /// <param name="token">The token obtained from StartubItem.</param> /// <param name="writer">The destination.</param> /// <param name="state">Writer state</param> public static void EndSubItem(SubItemToken token, ProtoWriter writer, ref State state) => writer.EndSubItem(ref state, token, PrefixStyle.Base128);
private static void WriteTimeSpanImpl(TimeSpan timeSpan, ProtoWriter dest, DateTimeKind kind) { if (dest == null) { throw new ArgumentNullException("dest"); } long value; switch (dest.WireType) { case WireType.String: case WireType.StartGroup: TimeSpanScale scale; value = timeSpan.Ticks; if (timeSpan == TimeSpan.MaxValue) { value = 1; scale = TimeSpanScale.MinMax; } else if (timeSpan == TimeSpan.MinValue) { value = -1; scale = TimeSpanScale.MinMax; } else if (value % TimeSpan.TicksPerDay == 0) { scale = TimeSpanScale.Days; value /= TimeSpan.TicksPerDay; } else if (value % TimeSpan.TicksPerHour == 0) { scale = TimeSpanScale.Hours; value /= TimeSpan.TicksPerHour; } else if (value % TimeSpan.TicksPerMinute == 0) { scale = TimeSpanScale.Minutes; value /= TimeSpan.TicksPerMinute; } else if (value % TimeSpan.TicksPerSecond == 0) { scale = TimeSpanScale.Seconds; value /= TimeSpan.TicksPerSecond; } else if (value % TimeSpan.TicksPerMillisecond == 0) { scale = TimeSpanScale.Milliseconds; value /= TimeSpan.TicksPerMillisecond; } else { scale = TimeSpanScale.Ticks; } SubItemToken token = ProtoWriter.StartSubItem(null, dest); if (value != 0) { ProtoWriter.WriteFieldHeader(FieldTimeSpanValue, WireType.SignedVariant, dest); ProtoWriter.WriteInt64(value, dest); } if (scale != TimeSpanScale.Days) { ProtoWriter.WriteFieldHeader(FieldTimeSpanScale, WireType.Variant, dest); ProtoWriter.WriteInt32((int)scale, dest); } if (kind != DateTimeKind.Unspecified) { ProtoWriter.WriteFieldHeader(FieldTimeSpanKind, WireType.Variant, dest); ProtoWriter.WriteInt32((int)kind, dest); } ProtoWriter.EndSubItem(token, dest); break; case WireType.Fixed64: ProtoWriter.WriteInt64(timeSpan.Ticks, dest); break; default: throw new ProtoException("Unexpected wire-type: " + dest.WireType.ToString()); } }
public static void EndSubItem(SubItemToken token, ProtoWriter writer) { State state = writer.DefaultState(); writer.EndSubItem(ref state, token, PrefixStyle.Base128); }
/// <summary> /// Reads an *implementation specific* bundled .NET object, including (as options) type-metadata, identity/re-use, etc. /// </summary> public static object ReadNetObject(object value, ProtoReader source, int key, Type type, NetObjectOptions options) { #if FEAT_IKVM throw new NotSupportedException(); #else SubItemToken token = ProtoReader.StartSubItem(source); int fieldNumber; int newObjectKey = -1, newTypeKey = -1, tmp; while ((fieldNumber = source.ReadFieldHeader()) > 0) { switch (fieldNumber) { case FieldExistingObjectKey: tmp = source.ReadInt32(); value = source.NetCache.GetKeyedObject(tmp); break; case FieldNewObjectKey: newObjectKey = source.ReadInt32(); break; case FieldExistingTypeKey: tmp = source.ReadInt32(); type = (Type)source.NetCache.GetKeyedObject(tmp); key = source.GetTypeKey(ref type); break; case FieldNewTypeKey: newTypeKey = source.ReadInt32(); break; case FieldTypeName: string typeName = source.ReadString(); type = source.DeserializeType(typeName); if (type == null) { throw new ProtoException("Unable to resolve type: " + typeName + " (you can use the TypeModel.DynamicTypeFormatting event to provide a custom mapping)"); } if (type == typeof(string)) { key = -1; } else { key = source.GetTypeKey(ref type); if (key < 0) { throw new InvalidOperationException("Dynamic type is not a contract-type: " + type.Name); } } break; case FieldObject: bool isString = type == typeof(string); bool wasNull = value == null; bool lateSet = wasNull && (isString || ((options & NetObjectOptions.LateSet) != 0)); if (newObjectKey >= 0 && !lateSet) { if (value == null) { source.TrapNextObject(newObjectKey); } else { source.NetCache.SetKeyedObject(newObjectKey, value); } if (newTypeKey >= 0) { source.NetCache.SetKeyedObject(newTypeKey, type); } } object oldValue = value; if (isString) { value = source.ReadString(); } else { value = ProtoReader.ReadTypedObject(oldValue, key, source, type); } if (newObjectKey >= 0) { if (wasNull && !lateSet) { // this both ensures (via exception) that it *was* set, and makes sure we don't shout // about changed references oldValue = source.NetCache.GetKeyedObject(newObjectKey); } if (lateSet) { source.NetCache.SetKeyedObject(newObjectKey, value); if (newTypeKey >= 0) { source.NetCache.SetKeyedObject(newTypeKey, type); } } } if (newObjectKey >= 0 && !lateSet && !ReferenceEquals(oldValue, value)) { throw new ProtoException("A reference-tracked object changed reference during deserialization"); } if (newObjectKey < 0 && newTypeKey >= 0) { // have a new type, but not a new object source.NetCache.SetKeyedObject(newTypeKey, type); } break; default: source.SkipField(); break; } } if (newObjectKey >= 0 && (options & NetObjectOptions.AsReference) == 0) { throw new ProtoException("Object key in input stream, but reference-tracking was not expected"); } ProtoReader.EndSubItem(token, source); return(value); #endif }
/// <summary> /// Writes an *implementation specific* bundled .NET object, including (as options) type-metadata, identity/re-use, etc. /// </summary> public static void WriteNetObject(object value, ProtoWriter dest, int key, NetObjectOptions options) { #if FEAT_IKVM throw new NotSupportedException(); #else if (dest == null) { throw new ArgumentNullException("dest"); } bool dynamicType = (options & NetObjectOptions.DynamicType) != 0, asReference = (options & NetObjectOptions.AsReference) != 0; WireType wireType = dest.WireType; SubItemToken token = ProtoWriter.StartSubItem(null, dest); bool writeObject = true; if (asReference) { bool existing; int objectKey = dest.NetCache.AddObjectKey(value, out existing); ProtoWriter.WriteFieldHeader(existing ? FieldExistingObjectKey : FieldNewObjectKey, WireType.Variant, dest); ProtoWriter.WriteInt32(objectKey, dest); if (existing) { writeObject = false; } } if (writeObject) { if (dynamicType) { bool existing; Type type = value.GetType(); if (!(value is string)) { key = dest.GetTypeKey(ref type); if (key < 0) { throw new InvalidOperationException("Dynamic type is not a contract-type: " + type.Name); } } int typeKey = dest.NetCache.AddObjectKey(type, out existing); ProtoWriter.WriteFieldHeader(existing ? FieldExistingTypeKey : FieldNewTypeKey, WireType.Variant, dest); ProtoWriter.WriteInt32(typeKey, dest); if (!existing) { ProtoWriter.WriteFieldHeader(FieldTypeName, WireType.String, dest); ProtoWriter.WriteString(dest.SerializeType(type), dest); } } ProtoWriter.WriteFieldHeader(FieldObject, wireType, dest); if (value is string) { ProtoWriter.WriteString((string)value, dest); } else { ProtoWriter.WriteObject(value, key, dest); } } ProtoWriter.EndSubItem(token, dest); #endif }
private static long ReadTimeSpanTicks(ProtoReader source, out DateTimeKind kind) { kind = DateTimeKind.Unspecified; switch (source.WireType) { case WireType.String: case WireType.StartGroup: SubItemToken token = ProtoReader.StartSubItem(source); int fieldNumber; TimeSpanScale scale = TimeSpanScale.Days; long value = 0; while ((fieldNumber = source.ReadFieldHeader()) > 0) { switch (fieldNumber) { case FieldTimeSpanScale: scale = (TimeSpanScale)source.ReadInt32(); break; case FieldTimeSpanValue: source.Assert(WireType.SignedVariant); value = source.ReadInt64(); break; case FieldTimeSpanKind: kind = (DateTimeKind)source.ReadInt32(); switch (kind) { case DateTimeKind.Unspecified: case DateTimeKind.Utc: case DateTimeKind.Local: break; // fine default: throw new ProtoException("Invalid date/time kind: " + kind.ToString()); } break; default: source.SkipField(); break; } } ProtoReader.EndSubItem(token, source); switch (scale) { case TimeSpanScale.Days: return(value * TimeSpan.TicksPerDay); case TimeSpanScale.Hours: return(value * TimeSpan.TicksPerHour); case TimeSpanScale.Minutes: return(value * TimeSpan.TicksPerMinute); case TimeSpanScale.Seconds: return(value * TimeSpan.TicksPerSecond); case TimeSpanScale.Milliseconds: return(value * TimeSpan.TicksPerMillisecond); case TimeSpanScale.Ticks: return(value); case TimeSpanScale.MinMax: switch (value) { case 1: return(long.MaxValue); case -1: return(long.MinValue); default: throw new ProtoException("Unknown min/max value: " + value.ToString()); } default: throw new ProtoException("Unknown timescale: " + scale.ToString()); } case WireType.Fixed64: return(source.ReadInt64()); default: throw new ProtoException("Unexpected wire-type: " + source.WireType.ToString()); } }
protected private abstract void ImplEndLengthPrefixedSubItem(ref State state, SubItemToken token, PrefixStyle style);
/// <summary> /// Indicates the end of a nested record. /// </summary> /// <param name="token">The token obtained from StartubItem.</param> /// <param name="writer">The destination.</param> public static void EndSubItem(SubItemToken token, ProtoWriter writer) { EndSubItem(token, writer, PrefixStyle.Base128); }
private static SubItemToken StartSubItem(object instance, ProtoWriter writer, bool allowFixed) { if (writer == null) { throw new ArgumentNullException("writer"); } if (++writer.depth > 25) { writer.CheckRecursionStackAndPush(instance); } if (writer.packedFieldNumber != 0) { throw new InvalidOperationException("Cannot begin a sub-item while performing packed encoding"); } switch (writer.wireType) { case WireType.String: writer.wireType = WireType.None; ProtoWriter.DemandSpace(32, writer); writer.flushLock++; writer.position++; return new SubItemToken(writer.ioIndex++); case WireType.StartGroup: writer.wireType = WireType.None; return new SubItemToken(-writer.fieldNumber); case WireType.Fixed32: { if (!allowFixed) { throw ProtoWriter.CreateException(writer); } ProtoWriter.DemandSpace(32, writer); writer.flushLock++; SubItemToken result = new SubItemToken(writer.ioIndex); ProtoWriter.IncrementedAndReset(4, writer); return result; } } throw ProtoWriter.CreateException(writer); }
private static SubItemToken StartSubItem(object instance, ProtoWriter writer, bool allowFixed) { if (++writer.depth > RecursionCheckDepth) { writer.CheckRecursionStackAndPush(instance); } if(writer.packedFieldNumber != 0) throw new InvalidOperationException("Cannot begin a sub-item while performing packed encoding"); switch (writer.wireType) { case WireType.StartGroup: writer.wireType = WireType.None; return new SubItemToken(-writer.fieldNumber); case WireType.String: writer.wireType = WireType.None; DemandSpace(32, writer); // make some space in anticipation... writer.flushLock++; writer.position++; return new SubItemToken(writer.ioIndex++); // leave 1 space (optimistic) for length case WireType.Fixed32: { if (!allowFixed) throw CreateException(writer); DemandSpace(32, writer); // make some space in anticipation... writer.flushLock++; SubItemToken token = new SubItemToken(writer.ioIndex); ProtoWriter.IncrementedAndReset(4, writer); // leave 4 space (rigid) for length return token; } default: throw CreateException(writer); } }
/// <summary> /// Makes the end of consuming a nested message in the stream; the stream must be either at the correct EndGroup /// marker, or all fields of the sub-message must have been consumed (in either case, this means ReadFieldHeader /// should return zero) /// </summary> public static void EndSubItem(SubItemToken token, ProtoReader reader) { int value = token.value; switch (reader.wireType) { case WireType.EndGroup: if (value >= 0) throw AddErrorData(new ArgumentException("token"), reader); if (-value != reader.fieldNumber) throw reader.CreateException(); // wrong group ended! reader.wireType = WireType.None; // this releases ReadFieldHeader reader.depth--; break; // case WireType.None: // TODO reinstate once reads reset the wire-type default: if (value < reader.position) throw reader.CreateException(); if (reader.blockEnd != reader.position && reader.blockEnd != int.MaxValue) throw reader.CreateException(); reader.blockEnd = value; reader.depth--; break; /*default: throw reader.BorkedIt(); */ } }
private static void EndSubItem(SubItemToken token, ProtoWriter writer, PrefixStyle style) { if (writer.wireType != WireType.None) { throw CreateException(writer); } int value = token.value; if (writer.depth <= 0) throw CreateException(writer); if (writer.depth-- > RecursionCheckDepth) { writer.PopRecursionStack(); } writer.packedFieldNumber = 0; // ending the sub-item always wipes packed encoding if (value < 0) { // group - very simple append WriteHeaderCore(-value, WireType.EndGroup, writer); writer.wireType = WireType.None; return; } // so we're backfilling the length into an existing sequence int len; switch(style) { case PrefixStyle.Fixed32: len = (int)((writer.ioIndex - value) - 4); ProtoWriter.WriteInt32ToBuffer(len, writer.ioBuffer, value); break; case PrefixStyle.Fixed32BigEndian: len = (int)((writer.ioIndex - value) - 4); byte[] buffer = writer.ioBuffer; ProtoWriter.WriteInt32ToBuffer(len, buffer, value); // and swap the byte order byte b = buffer[value]; buffer[value] = buffer[value + 3]; buffer[value + 3] = b; b = buffer[value + 1]; buffer[value + 1] = buffer[value + 2]; buffer[value + 2] = b; break; case PrefixStyle.Base128: // string - complicated because we only reserved one byte; // if the prefix turns out to need more than this then // we need to shuffle the existing data len = (int)((writer.ioIndex - value) - 1); int offset = 0; uint tmp = (uint)len; while ((tmp >>= 7) != 0) offset++; if (offset == 0) { writer.ioBuffer[value] = (byte)(len & 0x7F); } else { DemandSpace(offset, writer); byte[] blob = writer.ioBuffer; Helpers.BlockCopy(blob, value + 1, blob, value + 1 + offset, len); tmp = (uint)len; do { blob[value++] = (byte)((tmp & 0x7F) | 0x80); } while ((tmp >>= 7) != 0); blob[value - 1] = (byte)(blob[value - 1] & ~0x80); writer.position += offset; writer.ioIndex += offset; } break; default: throw new ArgumentOutOfRangeException("style"); } // and this object is no longer a blockage writer.flushLock--; }
private static void EndSubItem(SubItemToken token, ProtoWriter writer, PrefixStyle style) { if (writer == null) { throw new ArgumentNullException("writer"); } if (writer.wireType != WireType.None) { throw ProtoWriter.CreateException(writer); } int value = token.value; if (writer.depth <= 0) { throw ProtoWriter.CreateException(writer); } if (writer.depth-- > 25) { writer.PopRecursionStack(); } writer.packedFieldNumber = 0; if (value < 0) { ProtoWriter.WriteHeaderCore(-value, WireType.EndGroup, writer); writer.wireType = WireType.None; return; } switch (style) { case PrefixStyle.Base128: { int num = writer.ioIndex - value - 1; int num2 = 0; uint num3 = (uint)num; while ((num3 >>= 7) != 0u) { num2++; } if (num2 == 0) { writer.ioBuffer[value] = (byte)(num & 127); } else { ProtoWriter.DemandSpace(num2, writer); byte[] array = writer.ioBuffer; Helpers.BlockCopy(array, value + 1, array, value + 1 + num2, num); num3 = (uint)num; do { array[value++] = (byte)((num3 & 127u) | 128u); } while ((num3 >>= 7) != 0u); array[value - 1] = (byte)((int)array[value - 1] & -129); writer.position += num2; writer.ioIndex += num2; } break; } case PrefixStyle.Fixed32: { int num = writer.ioIndex - value - 4; ProtoWriter.WriteInt32ToBuffer(num, writer.ioBuffer, value); break; } case PrefixStyle.Fixed32BigEndian: { int num = writer.ioIndex - value - 4; byte[] array2 = writer.ioBuffer; ProtoWriter.WriteInt32ToBuffer(num, array2, value); byte b = array2[value]; array2[value] = array2[value + 3]; array2[value + 3] = b; b = array2[value + 1]; array2[value + 1] = array2[value + 2]; array2[value + 2] = b; break; } default: throw new ArgumentOutOfRangeException("style"); } if (--writer.flushLock == 0 && writer.ioIndex >= 1024) { ProtoWriter.Flush(writer); } }