public void WriteTo(BinaryWriter writer) { if (!this.Frozen) { this.CloneAsEditable(true).WriteTo(writer); return; } if (this.IsNull) { writer.Write(new byte[this.Schema.FixedSize]); int sizeWidth = EditablePrimitive.SizeWidthForSize(this.SerializedSize); EditablePrimitive.WriteSize(writer, this.SerializedSize, sizeWidth); writer.Write(new byte[this.SerializedSize - this.Schema.FixedSize - sizeWidth]); // fill variable offset slot with zero bytes } else { writer.Write((int)dataSchema.Id); // schema field bool dataIsNull = dataCursor.IsNull && data == null; byte nullBitmap = dataIsNull ? (byte)1 : (byte)3; writer.Write(nullBitmap); int sizeWidth = EditablePrimitive.SizeWidthForSize(serializedSize); EditablePrimitive.WriteSize(writer, serializedSize, sizeWidth); // write total serialized size int offset = 5 + 2 * sizeWidth; // set offset behind variable size offset slots EditablePrimitive.WriteSize(writer, offset, sizeWidth); // variable field offset slot // write size of data EditablePrimitive.WriteSize(writer, EditablePrimitive.GetTotalFieldSize(this.DataSize)); if (!dataCursor.IsNull) { var segment = dataCursor.GetFieldSegment(); writer.Write(segment.Array, segment.Offset, segment.Count); } else if (data != null) { data.WriteTo(writer); } } }
public void WriteTo(BinaryWriter writer) { if (!this.Frozen) { this.CloneAsEditable(true).WriteTo(writer); return; } if (this.IsNull) { EditablePrimitive.WriteSize(writer, 1); } else { int serializedSize = this.SerializedSize; int sizeWidth = EditablePrimitive.SizeWidthForSize(serializedSize); EditablePrimitive.WriteSize(writer, serializedSize, sizeWidth); EditablePrimitive.WriteSize(writer, this.Count, sizeWidth); if (itemNullable) { var nullBitmap = new byte[(list.Count + 7) / 8]; for (int i = 0; i < list.Count; ++i) { if (!list[i].IsNull) { nullBitmap[(i / 8)] |= (byte)(1 << (i % 8)); } } writer.Write(nullBitmap); } foreach (var i in this) { i.WriteTo(writer); } } }
public virtual void WriteTo(BinaryWriter writer) { if (!this.Frozen) { this.CloneAsEditable(true).WriteTo(writer); return; } int serializedSize; if (this.IsNull) { serializedSize = this.SerializedSize; writer.Write(new byte[schema.FixedSize]); if (this.Schema.VariableSize) { int sizeWidth = EditablePrimitive.SizeWidthForSize(serializedSize); EditablePrimitive.WriteSize(writer, serializedSize, sizeWidth); writer.Write(new byte[serializedSize - schema.FixedSize - sizeWidth]); // pad after skip size with zero bytes (object is null) } return; } int i = 0, offset = 0; #if DEBUG serializedSize = this.SerializedSize; //long start = writer.Seek(0, SeekOrigin.Current); #endif // fixed size part for (; i < fields.Length; ++i) { var f = fields[i]; if (f.Schema.VariableSize) { break; } offset += f.SerializedSize; f.WriteTo(writer); //#if DEBUG // Debug.Assert((writer.Seek(0, SeekOrigin.Current) - start) == offset); //#endif } Debug.Assert(schema.variableFieldCount == fields.Length - i); Debug.Assert(schema.NullBitmapOffset < 0 || schema.NullBitmapOffset == offset); if (schema.NullBitmap) { byte[] nullBitmap = new byte[(fields.Length + 7) / 8]; // write null bitmap for (int k = 0; k < fields.Length; ++k) { var f = fields[k]; Debug.Assert(!f.IsNull || schema.fields[k].Nullable); if (!f.IsNull) { nullBitmap[k / 8] |= (byte)(1 << (k % 8)); } } offset += nullBitmap.Length; writer.Write(nullBitmap); } if (schema.VariableSize) { Debug.Assert(schema.VariableSizeOffset == offset); #if !DEBUG serializedSize = this.SerializedSize; #endif int sizeWidth = EditablePrimitive.SizeWidthForSize(serializedSize); EditablePrimitive.WriteSize(writer, serializedSize, sizeWidth); offset += (1 + schema.variableFieldCount) * sizeWidth; // set offset behind variable size offset slots // store variable field offsets int[] variableOffsets = new int[schema.variableFieldCount]; int j = i; for (; i < fields.Length; ++i) { var f = fields[i]; Debug.Assert(f.Schema.VariableSize); Debug.Assert(!f.IsNull || schema.fields[i].Nullable); EditablePrimitive.WriteSize(writer, offset, sizeWidth); variableOffsets[i - j] = offset; if (!f.IsNull) { offset += f.SerializedSize; } } // write variable field data for (i = j; i < fields.Length; ++i) { //#if DEBUG // Debug.Assert((writer.Seek(0, SeekOrigin.Current) - start) == variableOffsets[i - j]); //#endif var f = fields[i]; if (!f.IsNull) { f.WriteTo(writer); } } } #if DEBUG Debug.Assert(offset == serializedSize); //Debug.Assert((writer.Seek(0, SeekOrigin.Current) - start) == serializedSize); #endif }