/// <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 }
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); }
/// <summary> /// Writes a TimeSpan to a protobuf stream /// </summary> public static void WriteTimeSpan(TimeSpan timeSpan, ProtoWriter dest) { TimeSpanScale scale; long 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); } ProtoWriter.EndSubItem(token, dest); }
/// <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.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); }
static public int get_Model(IntPtr l) { try { ProtoBuf.ProtoWriter self = (ProtoBuf.ProtoWriter)checkSelf(l); pushValue(l, true); pushValue(l, self.Model); return(2); } catch (Exception e) { return(error(l, e)); } }
static public int Close(IntPtr l) { try { ProtoBuf.ProtoWriter self = (ProtoBuf.ProtoWriter)checkSelf(l); self.Close(); pushValue(l, true); return(1); } catch (Exception e) { return(error(l, e)); } }
public void Serialize(Stream destination, object clsObj) { SInstance sInstance = clsObj as SInstance; if (sInstance == null) { throw new ArgumentNullException("无效CSLight脚本对象: " + clsObj); } using (ProtoWriter writer = new ProtoWriter(destination, null, null)) { WriteSInstance(writer, sInstance); writer.Close(); } }
static public int SetRootObject(IntPtr l) { try { ProtoBuf.ProtoWriter self = (ProtoBuf.ProtoWriter)checkSelf(l); System.Object a1; checkType(l, 2, out a1); self.SetRootObject(a1); pushValue(l, true); return(1); } catch (Exception e) { return(error(l, e)); } }
static ProtoReader GetReader() { var model = TypeModel.Create(); model.Add(typeof(Foo), true); model.CompileInPlace(); var ms = new MemoryStream(); var obj = new Foo { Bar = "abc", Blap = "abc" }; using (var writer = new ProtoWriter(ms, model, null)) { writer.Model.Serialize(writer, obj); } ms.Position = 0; return new ProtoReader(ms, model, null); }
// Use this for initialization void Start() { InitData(data); InitData(data2); InitData(data3); InitData(data4); msSend = new MemoryStream(sendBuffer, 0, SENF_BUFFER_LEN, true, true); msRecive = new MemoryStream(reciveBuffer, 0, REVIVE_BUFFER_LEN, true, true); bwWriter = new BinaryWriter(msSend); bwReader = new BinaryReader(msRecive); // ********只是为了测试,外部最好不要直接使用ProtoWriter和ProtoReader pbWriter = new ProtoBuf.ProtoWriter(msSend, ProtoBuf.Meta.RuntimeTypeModel.Default, null); pbReader = new ProtoBuf.ProtoReader(msRecive, ProtoBuf.Meta.RuntimeTypeModel.Default, null); pbWriter2 = new ProtoBuf.ProtoWriter(msSend, ProtoBuf.Meta.RuntimeTypeModel.Default, null); pbReader2 = new ProtoBuf.ProtoReader(msRecive, ProtoBuf.Meta.RuntimeTypeModel.Default, null); }
/// <summary> /// The serialize. /// </summary> /// <param name="num"> /// The num. /// </param> /// <param name="obj"> /// The obj. /// </param> /// <param name="protoWriter"> /// The proto writer. /// </param> protected override void Serialize(int num, object obj, ProtoWriter protoWriter) { switch (num) { case 0: Write((CompiledAsset)obj, protoWriter); return; case 1: Write((PlatformData)obj, protoWriter); return; case 2: Write((TargetPlatform)obj, protoWriter); return; default: return; } }
/// <summary> /// Writes a field-header, indicating the format of the next data we plan to write. /// </summary> public static void WriteFieldHeader(int fieldNumber, WireType wireType, ProtoWriter writer) { if (writer.wireType != WireType.None) throw new InvalidOperationException("Cannot write a " + wireType + " header until the " + writer.wireType + " data has been written"); if(fieldNumber < 0) throw new ArgumentOutOfRangeException("fieldNumber"); #if DEBUG switch (wireType) { // validate requested header-type case WireType.Fixed32: case WireType.Fixed64: case WireType.String: case WireType.StartGroup: case WireType.SignedVariant: case WireType.Variant: break; // fine case WireType.None: case WireType.EndGroup: default: throw new ArgumentException("Invalid wire-type: " + wireType, "wireType"); } #endif if (writer.packedFieldNumber == 0) { writer.fieldNumber = fieldNumber; writer.wireType = wireType; WriteHeaderCore(fieldNumber, wireType, writer); } else if (writer.packedFieldNumber == fieldNumber) { // we'll set things up, but note we *don't* actually write the header here switch (wireType) { case WireType.Fixed32: case WireType.Fixed64: case WireType.Variant: case WireType.SignedVariant: break; // fine default: throw new InvalidOperationException("Wire-type cannot be encoded as packed: " + wireType); } writer.fieldNumber = fieldNumber; writer.wireType = wireType; } else { throw new InvalidOperationException("Field mismatch during packed encoding; expected " + writer.packedFieldNumber + " but received " + fieldNumber); } }
static public int constructor(IntPtr l) { try { ProtoBuf.ProtoWriter o; System.IO.Stream a1; checkType(l, 2, out a1); ProtoBuf.Meta.TypeModel a2; checkType(l, 3, out a2); ProtoBuf.SerializationContext a3; checkType(l, 4, out a3); o = new ProtoBuf.ProtoWriter(a1, a2, a3); pushValue(l, true); pushValue(l, o); return(2); } catch (Exception e) { return(error(l, e)); } }
internal static void WriteObject(object value, int key, ProtoWriter writer, PrefixStyle style, int fieldNumber) { #if FEAT_IKVM throw new NotSupportedException(); #else 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); if (key < 0) { if (!writer.model.TrySerializeAuxiliaryType(writer, value.GetType(), DataFormat.Default, Serializer.ListItemTag, value, false)) { TypeModel.ThrowUnexpectedType(value.GetType()); } } else { writer.model.Serialize(key, value, writer); } EndSubItem(token, writer, style); #endif }
/// <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"); // 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); } } }
static void WriteSingle(float value, ProtoWriter writer) { switch (writer.wireType) { case WireType.Fixed32: #if FEAT_SAFE ProtoWriter.WriteInt32(BitConverter.ToInt32(BitConverter.GetBytes(value), 0), writer); #else ProtoWriter.WriteInt32(*(int*)&value, writer); #endif return; case WireType.Fixed64: ProtoWriter.WriteDouble((double)value, writer); return; default: throw CreateException(writer); } }
// general purpose serialization exception message internal static Exception CreateException(ProtoWriter writer) { return new ProtoException("Invalid serialization operation with wire-type " + writer.wireType + " at position " + writer.position); }
public static void WriteInt16(short value, ProtoWriter writer) { WriteInt32(value, writer); }
public static void WriteInt16(short value, ProtoWriter writer) { ProtoWriter.WriteInt32((int)value, writer); }
/// <summary> /// Writes a signed 32-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant /// </summary> public static void WriteInt32(int value, ProtoWriter writer) { byte[] buffer; int index; if (writer == null) { throw new ArgumentNullException("writer"); } switch (writer.wireType) { case WireType.Fixed32: DemandSpace(4, writer); WriteInt32ToBuffer(value, writer.ioBuffer, writer.ioIndex); IncrementedAndReset(4, writer); return; case WireType.Fixed64: DemandSpace(8, writer); buffer = writer.ioBuffer; index = writer.ioIndex; buffer[index] = (byte)value; buffer[index + 1] = (byte)(value >> 8); buffer[index + 2] = (byte)(value >> 16); buffer[index + 3] = (byte)(value >> 24); buffer[index + 4] = buffer[index + 5] = buffer[index + 6] = buffer[index + 7] = 0; IncrementedAndReset(8, writer); return; case WireType.SignedVariant: WriteUInt32Variant(Zig(value), writer); writer.wireType = WireType.None; return; case WireType.Variant: if (value >= 0) { WriteUInt32Variant((uint)value, writer); writer.wireType = WireType.None; } else { DemandSpace(10, writer); buffer = writer.ioBuffer; index = writer.ioIndex; buffer[index] = (byte)(value | 0x80); buffer[index + 1] = (byte)((value >> 7) | 0x80); buffer[index + 2] = (byte)((value >> 14) | 0x80); buffer[index + 3] = (byte)((value >> 21) | 0x80); buffer[index + 4] = (byte)((value >> 28) | 0x80); buffer[index + 5] = buffer[index + 6] = buffer[index + 7] = buffer[index + 8] = (byte)0xFF; buffer[index + 9] = (byte)0x01; IncrementedAndReset(10, writer); } return; default: throw CreateException(writer); } }
public static void WriteBoolean(bool value, ProtoWriter writer) { WriteUInt32((uint)(value ? 1 : 0), writer); }
private static void DemandSpace(int required, ProtoWriter writer) { // check for enough space if ((writer.ioBuffer.Length - writer.ioIndex) < required) { if (writer.flushLock == 0) { Flush(writer); // try emptying the buffer if ((writer.ioBuffer.Length - writer.ioIndex) >= required) return; } // either can't empty the buffer, or that didn't help; need more space BufferPool.ResizeAndFlushLeft(ref writer.ioBuffer, required + writer.ioIndex, 0, writer.ioIndex); } }
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); } }
private static void IncrementedAndReset(int length, ProtoWriter writer) { writer.ioIndex += length; writer.position += length; writer.wireType = WireType.None; }
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--; }
/// <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 }
public static void WriteBoolean(bool value, ProtoWriter writer) { ProtoWriter.WriteUInt32((!value) ? 0u : 1u, writer); }
public static void WriteInt32(int value, ProtoWriter writer) { if (writer == null) { throw new ArgumentNullException("writer"); } WireType wireType = writer.wireType; switch (wireType) { case WireType.Variant: if (value >= 0) { ProtoWriter.WriteUInt32Variant((uint)value, writer); writer.wireType = WireType.None; } else { ProtoWriter.DemandSpace(10, writer); byte[] array = writer.ioBuffer; int num = writer.ioIndex; array[num] = (byte)(value | 128); array[num + 1] = (byte)(value >> 7 | 128); array[num + 2] = (byte)(value >> 14 | 128); array[num + 3] = (byte)(value >> 21 | 128); array[num + 4] = (byte)(value >> 28 | 128); array[num + 5] = (array[num + 6] = (array[num + 7] = (array[num + 8] = 255))); array[num + 9] = 1; ProtoWriter.IncrementedAndReset(10, writer); } return; case WireType.Fixed64: { ProtoWriter.DemandSpace(8, writer); byte[] array = writer.ioBuffer; int num = writer.ioIndex; array[num] = (byte)value; array[num + 1] = (byte)(value >> 8); array[num + 2] = (byte)(value >> 16); array[num + 3] = (byte)(value >> 24); array[num + 4] = (array[num + 5] = (array[num + 6] = (array[num + 7] = 0))); ProtoWriter.IncrementedAndReset(8, writer); return; } case WireType.String: case WireType.StartGroup: case WireType.EndGroup: IL_36: if (wireType != WireType.SignedVariant) { throw ProtoWriter.CreateException(writer); } ProtoWriter.WriteUInt32Variant(ProtoWriter.Zig(value), writer); writer.wireType = WireType.None; return; case WireType.Fixed32: ProtoWriter.DemandSpace(4, writer); ProtoWriter.WriteInt32ToBuffer(value, writer.ioBuffer, writer.ioIndex); ProtoWriter.IncrementedAndReset(4, writer); return; } goto IL_36; }
internal static void WriteHeaderCore(int fieldNumber, WireType wireType, ProtoWriter writer) { uint value = (uint)(fieldNumber << 3 | (int)(wireType & (WireType)7)); ProtoWriter.WriteUInt32Variant(value, writer); }
public static void WriteInt64(long value, ProtoWriter writer) { if (writer == null) { throw new ArgumentNullException("writer"); } switch (writer.wireType) { case WireType.Fixed64: { DemandSpace(8, writer); byte[] array2 = writer.ioBuffer; int num = writer.ioIndex; array2[num] = (byte)value; array2[num + 1] = (byte)(value >> 8); array2[num + 2] = (byte)(value >> 16); array2[num + 3] = (byte)(value >> 24); array2[num + 4] = (byte)(value >> 32); array2[num + 5] = (byte)(value >> 40); array2[num + 6] = (byte)(value >> 48); array2[num + 7] = (byte)(value >> 56); IncrementedAndReset(8, writer); break; } case WireType.SignedVariant: WriteUInt64Variant(Zig(value), writer); writer.wireType = WireType.None; break; case WireType.Variant: if (value >= 0) { WriteUInt64Variant((ulong)value, writer); writer.wireType = WireType.None; } else { DemandSpace(10, writer); byte[] array = writer.ioBuffer; int num = writer.ioIndex; array[num] = (byte)(value | 0x80); array[num + 1] = (byte)((int)(value >> 7) | 0x80); array[num + 2] = (byte)((int)(value >> 14) | 0x80); array[num + 3] = (byte)((int)(value >> 21) | 0x80); array[num + 4] = (byte)((int)(value >> 28) | 0x80); array[num + 5] = (byte)((int)(value >> 35) | 0x80); array[num + 6] = (byte)((int)(value >> 42) | 0x80); array[num + 7] = (byte)((int)(value >> 49) | 0x80); array[num + 8] = (byte)((int)(value >> 56) | 0x80); array[num + 9] = 1; IncrementedAndReset(10, writer); } break; case WireType.Fixed32: WriteInt32(checked ((int)value), writer); break; default: throw CreateException(writer); } }
/// <summary> /// Writes a signed 8-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant /// </summary> public static void WriteSByte(sbyte value, ProtoWriter writer) { ProtoWriter.WriteInt32(value, writer); }
/// <summary> /// Writes an unsigned 16-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 /// </summary> public static void WriteUInt32(uint value, ProtoWriter writer) { switch (writer.wireType) { case WireType.Fixed32: ProtoWriter.WriteInt32((int)value, writer); return; case WireType.Fixed64: ProtoWriter.WriteInt64((int)value, writer); return; case WireType.Variant: WriteUInt32Variant(value, writer); writer.wireType = WireType.None; return; default: throw CreateException(writer); } }
public static void WriteSingle(float value, ProtoWriter writer) { }
/// <summary> /// Writes an unsigned 8-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 /// </summary> public static void WriteByte(byte value, ProtoWriter writer) { ProtoWriter.WriteUInt32(value, writer); }
public static void WriteInt32(int value, ProtoWriter writer) { if (writer == null) { throw new ArgumentNullException("writer"); } switch (writer.wireType) { case WireType.Fixed32: DemandSpace(4, writer); WriteInt32ToBuffer(value, writer.ioBuffer, writer.ioIndex); IncrementedAndReset(4, writer); break; case WireType.Fixed64: { DemandSpace(8, writer); byte[] array = writer.ioBuffer; int num = writer.ioIndex; array[num] = (byte)value; array[num + 1] = (byte)(value >> 8); array[num + 2] = (byte)(value >> 16); array[num + 3] = (byte)(value >> 24); byte[] array5 = array; int num5 = num + 4; byte[] array6 = array; int num6 = num + 5; byte b; array[num + 6] = (b = (array[num + 7] = 0)); array6[num6] = b; array5[num5] = b; IncrementedAndReset(8, writer); break; } case WireType.SignedVariant: WriteUInt32Variant(Zig(value), writer); writer.wireType = WireType.None; break; case WireType.Variant: if (value >= 0) { WriteUInt32Variant((uint)value, writer); writer.wireType = WireType.None; } else { DemandSpace(10, writer); byte[] array = writer.ioBuffer; int num = writer.ioIndex; array[num] = (byte)(value | 0x80); array[num + 1] = (byte)(value >> 7 | 0x80); array[num + 2] = (byte)(value >> 14 | 0x80); array[num + 3] = (byte)(value >> 21 | 0x80); array[num + 4] = (byte)(value >> 28 | 0x80); byte[] array2 = array; int num2 = num + 5; byte[] array3 = array; int num3 = num + 6; byte[] array4 = array; int num4 = num + 7; byte b; array[num + 8] = (b = byte.MaxValue); array4[num4] = b; array3[num3] = b; array2[num2] = b; array[num + 9] = 1; IncrementedAndReset(10, writer); } break; default: throw CreateException(writer); } }
/// <summary> /// Writes a signed 32-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant /// </summary> public static void WriteInt32(int value, ProtoWriter writer) { byte[] buffer; int index; switch (writer.wireType) { case WireType.Fixed32: DemandSpace(4, writer); WriteInt32ToBuffer(value, writer.ioBuffer, writer.ioIndex); IncrementedAndReset(4, writer); return; case WireType.Fixed64: DemandSpace(8, writer); buffer = writer.ioBuffer; index = writer.ioIndex; buffer[index] = (byte)value; buffer[index + 1] = (byte)(value >> 8); buffer[index + 2] = (byte)(value >> 16); buffer[index + 3] = (byte)(value >> 24); buffer[index + 4] = buffer[index + 5] = buffer[index + 6] = buffer[index + 7] = 0; IncrementedAndReset(8, writer); return; case WireType.SignedVariant: WriteUInt32Variant(Zig(value), writer); writer.wireType = WireType.None; return; case WireType.Variant: if (value >= 0) { WriteUInt32Variant((uint)value, writer); writer.wireType = WireType.None; } else { DemandSpace(10, writer); buffer = writer.ioBuffer; index = writer.ioIndex; buffer[index] = (byte)(value | 0x80); buffer[index + 1] = (byte)((value >> 7) | 0x80); buffer[index + 2] = (byte)((value >> 14) | 0x80); buffer[index + 3] = (byte)((value >> 21) | 0x80); buffer[index + 4] = (byte)((value >> 28) | 0x80); buffer[index + 5] = buffer[index + 6] = buffer[index + 7] = buffer[index + 8] = (byte)0xFF; buffer[index + 9] = (byte)0x01; IncrementedAndReset(10, writer); } return; default: throw CreateException(writer); } }
private static void WriteUInt64Variant(ulong value, ProtoWriter writer) { DemandSpace(10, writer); int count = 0; do { writer.ioBuffer[writer.ioIndex++] = (byte)((value & 0x7F) | 0x80); count++; } while ((value >>= 7) != 0); writer.ioBuffer[writer.ioIndex - 1] &= 0x7F; writer.position += count; }
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); } }
/// <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 void EndSubItem(SubItemToken token, ProtoWriter writer, PrefixStyle style) { if (writer == null) { throw new ArgumentNullException("writer"); } if (writer.wireType != WireType.None) { throw CreateException(writer); } int num = token.value; if (writer.depth <= 0) { throw CreateException(writer); } if (writer.depth-- > 25) { writer.PopRecursionStack(); } writer.packedFieldNumber = 0; if (num < 0) { WriteHeaderCore(-num, WireType.EndGroup, writer); writer.wireType = WireType.None; } else { switch (style) { case PrefixStyle.Fixed32: { int num2 = writer.ioIndex - num - 4; WriteInt32ToBuffer(num2, writer.ioBuffer, num); break; } case PrefixStyle.Fixed32BigEndian: { int num2 = writer.ioIndex - num - 4; byte[] array2 = writer.ioBuffer; WriteInt32ToBuffer(num2, array2, num); byte b = array2[num]; array2[num] = array2[num + 3]; array2[num + 3] = b; b = array2[num + 1]; array2[num + 1] = array2[num + 2]; array2[num + 2] = b; break; } case PrefixStyle.Base128: { int num2 = writer.ioIndex - num - 1; int num3 = 0; uint num4 = (uint)num2; while ((num4 >>= 7) != 0) { num3++; } if (num3 == 0) { writer.ioBuffer[num] = (byte)(num2 & 0x7F); } else { DemandSpace(num3, writer); byte[] array = writer.ioBuffer; Helpers.BlockCopy(array, num + 1, array, num + 1 + num3, num2); num4 = (uint)num2; do { array[num++] = (byte)((num4 & 0x7F) | 0x80); }while ((num4 >>= 7) != 0); array[num - 1] = (byte)(array[num - 1] & -129); writer.position += num3; writer.ioIndex += num3; } break; } default: throw new ArgumentOutOfRangeException("style"); } if (--writer.flushLock == 0 && writer.ioIndex >= 1024) { Flush(writer); } } }
internal static int GetPosition(ProtoWriter writer) { return writer.position; }
/// <summary> /// Writes a TimeSpan to a protobuf stream /// </summary> public static void WriteTimeSpan(TimeSpan timeSpan, ProtoWriter 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); } ProtoWriter.EndSubItem(token, dest); break; case WireType.Fixed64: ProtoWriter.WriteInt64(timeSpan.Ticks, dest); break; default: throw new ProtoException("Unexpected wire-type: " + dest.WireType.ToString()); } }
/// <summary> /// Writes any buffered data (if possible) to the underlying stream. /// </summary> /// <param name="writer">The writer to flush</param> /// <remarks>It is not always possible to fully flush, since some sequences /// may require values to be back-filled into the byte-stream.</remarks> private static void Flush(ProtoWriter writer) { if (writer.flushLock == 0 && writer.ioIndex != 0) { writer.dest.Write(writer.ioBuffer, 0, writer.ioIndex); writer.ioIndex = 0; } }
public static void WriteTimeSpan(TimeSpan timeSpan, ProtoWriter dest) { var state = dest.DefaultState(); WriteTimeSpanImpl(ref state, timeSpan, DateTimeKind.Unspecified); }
/// <summary> /// Writes a string to the stream; supported wire-types: String /// </summary> public static void WriteString(string value, ProtoWriter writer) { if (writer.wireType != WireType.String) throw CreateException(writer); if (value == null) throw new ArgumentNullException("value"); // written header; now what? int len = value.Length; if (len == 0) { WriteUInt32Variant(0, writer); writer.wireType = WireType.None; return; // just a header } #if MF byte[] bytes = encoding.GetBytes(value); int actual = bytes.Length; writer.WriteUInt32Variant((uint)actual); writer.Ensure(actual); Helpers.BlockCopy(bytes, 0, writer.ioBuffer, writer.ioIndex, actual); #else int predicted = encoding.GetByteCount(value); WriteUInt32Variant((uint)predicted, writer); DemandSpace(predicted, writer); int actual = encoding.GetBytes(value, 0, value.Length, writer.ioBuffer, writer.ioIndex); Helpers.DebugAssert(predicted == actual); #endif IncrementedAndReset(actual, writer); }
public static void WriteTimeSpan(TimeSpan timeSpan, ProtoWriter dest) { if (dest == null) { throw new ArgumentNullException("dest"); } WireType wireType = dest.WireType; if (wireType != WireType.Fixed64) { if ((uint)(wireType - 2) <= 1u) { long num = timeSpan.Ticks; TimeSpanScale timeSpanScale; if (timeSpan == TimeSpan.MaxValue) { num = 1L; timeSpanScale = TimeSpanScale.MinMax; } else if (timeSpan == TimeSpan.MinValue) { num = -1L; timeSpanScale = TimeSpanScale.MinMax; } else if (num % 864000000000L == 0L) { timeSpanScale = TimeSpanScale.Days; num /= 864000000000L; } else if (num % 36000000000L == 0L) { timeSpanScale = TimeSpanScale.Hours; num /= 36000000000L; } else if (num % 600000000 == 0L) { timeSpanScale = TimeSpanScale.Minutes; num /= 600000000; } else if (num % 10000000 == 0L) { timeSpanScale = TimeSpanScale.Seconds; num /= 10000000; } else if (num % 10000 == 0L) { timeSpanScale = TimeSpanScale.Milliseconds; num /= 10000; } else { timeSpanScale = TimeSpanScale.Ticks; } SubItemToken token = ProtoWriter.StartSubItem(null, dest); if (num != 0L) { ProtoWriter.WriteFieldHeader(1, WireType.SignedVariant, dest); ProtoWriter.WriteInt64(num, dest); } if (timeSpanScale != 0) { ProtoWriter.WriteFieldHeader(2, WireType.Variant, dest); ProtoWriter.WriteInt32((int)timeSpanScale, dest); } ProtoWriter.EndSubItem(token, dest); return; } wireType = dest.WireType; throw new ProtoException("Unexpected wire-type: " + wireType.ToString()); } ProtoWriter.WriteInt64(timeSpan.Ticks, dest); }
/// <summary> /// Writes a signed 64-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant /// </summary> public static void WriteInt64(long value, ProtoWriter writer) { byte[] buffer; int index; switch (writer.wireType) { case WireType.Fixed64: DemandSpace(8, writer); buffer = writer.ioBuffer; index = writer.ioIndex; buffer[index] = (byte)value; buffer[index + 1] = (byte)(value >> 8); buffer[index + 2] = (byte)(value >> 16); buffer[index + 3] = (byte)(value >> 24); buffer[index + 4] = (byte)(value >> 32); buffer[index + 5] = (byte)(value >> 40); buffer[index + 6] = (byte)(value >> 48); buffer[index + 7] = (byte)(value >> 56); IncrementedAndReset(8, writer); return; case WireType.SignedVariant: WriteUInt64Variant(Zig(value), writer); writer.wireType = WireType.None; return; case WireType.Variant: if (value >= 0) { WriteUInt64Variant((ulong)value, writer); writer.wireType = WireType.None; } else { DemandSpace(10, writer); buffer = writer.ioBuffer; index = writer.ioIndex; buffer[index] = (byte)(value | 0x80); buffer[index + 1] = (byte)((int)(value >> 7) | 0x80); buffer[index + 2] = (byte)((int)(value >> 14) | 0x80); buffer[index + 3] = (byte)((int)(value >> 21) | 0x80); buffer[index + 4] = (byte)((int)(value >> 28) | 0x80); buffer[index + 5] = (byte)((int)(value >> 35) | 0x80); buffer[index + 6] = (byte)((int)(value >> 42) | 0x80); buffer[index + 7] = (byte)((int)(value >> 49) | 0x80); buffer[index + 8] = (byte)((int)(value >> 56) | 0x80); buffer[index + 9] = 0x01; // sign bit IncrementedAndReset(10, writer); } return; case WireType.Fixed32: checked { WriteInt32((int)value, writer); } return; default: throw CreateException(writer); } }
/// <summary> /// Writes a boolean to the stream; supported wire-types: Variant, Fixed32, Fixed64 /// </summary> public static void WriteBoolean(bool value, ProtoWriter writer) { ProtoWriter.WriteUInt32(value ? (uint)1 : (uint)0, writer); }
/// <summary> /// Writes an unsigned 16-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 /// </summary> public static void WriteUInt16(ushort value, ProtoWriter writer) { ProtoWriter.WriteUInt32(value, writer); }
/// <summary> /// Indicates the start of a nested record. /// </summary> /// <param name="instance">The instance to write.</param> /// <param name="writer">The destination.</param> /// <returns>A token representing the state of the stream; this token is given to EndSubItem.</returns> public static SubItemToken StartSubItem(object instance, ProtoWriter writer) { return(StartSubItem(instance, writer, false)); }
/// <summary> /// Writes a signed 8-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64, SignedVariant /// </summary> public static void WriteSByte(sbyte value, ProtoWriter writer) { ProtoWriter.WriteInt32(value, writer); }
/// <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); }
static void WriteDouble(double value, ProtoWriter writer) { switch (writer.wireType) { case WireType.Fixed32: float f = (float)value; if (Helpers.IsInfinity(f) && !Helpers.IsInfinity(value)) { throw new OverflowException(); } ProtoWriter.WriteSingle(f, writer); return; case WireType.Fixed64: #if FEAT_SAFE ProtoWriter.WriteInt64(BitConverter.ToInt64(BitConverter.GetBytes(value), 0), writer); #else ProtoWriter.WriteInt64(*(long*)&value, writer); #endif return; default: throw CreateException(writer); } }
private static void EndSubItem(SubItemToken token, ProtoWriter writer, PrefixStyle style) { if (writer == null) { throw new ArgumentNullException("writer"); } 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 - also flush if sensible const int ADVISORY_FLUSH_SIZE = 1024; if (--writer.flushLock == 0 && writer.ioIndex >= ADVISORY_FLUSH_SIZE) { ProtoWriter.Flush(writer); } }
/// <summary> /// Throws an exception indicating that the given enum cannot be mapped to a serialized value. /// </summary> public static void ThrowEnumException(ProtoWriter writer, object enumValue) { string rhs = enumValue == null ? "<null>" : (enumValue.GetType().FullName + "." + enumValue.ToString()); throw new ProtoException("No wire-value is mapped to the enum " + rhs); }
// note that this is used by some of the unit tests and should not be removed internal static int GetPosition(ProtoWriter writer) { return(writer.position); }
/// <summary> /// Writes a boolean to the stream; supported wire-types: Variant, Fixed32, Fixed64 /// </summary> public static void WriteBoolean(bool value, ProtoWriter writer) { ProtoWriter.WriteUInt32(value ? (uint)1 : (uint)0, writer); }
/// <summary> /// Writes an unsigned 16-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 /// </summary> public static void WriteUInt16(ushort value, ProtoWriter writer) { ProtoWriter.WriteUInt32(value, writer); }
/// <summary> /// Used for packed encoding; indicates that the next field should be skipped rather than /// a field header written. Note that the field number must match, else an exception is thrown /// when the attempt is made to write the (incorrect) field. The wire-type is taken from the /// subsequent call to WriteFieldHeader. Only primitive types can be packed. /// </summary> public static void SetPackedField(int fieldNumber, ProtoWriter writer) { if (fieldNumber <= 0) throw new ArgumentOutOfRangeException("fieldNumber"); writer.packedFieldNumber = fieldNumber; }
/// <summary> /// Writes an unsigned 8-bit integer to the stream; supported wire-types: Variant, Fixed32, Fixed64 /// </summary> public static void WriteByte(byte value, ProtoWriter writer) { ProtoWriter.WriteUInt32(value, writer); }