/// <summary> /// Adds a field to the holder. /// </summary> /// <param name="id">The identifier.</param> /// <param name="offset">The offset.</param> public void PushField(int id, int offset) { if (_idx == _fields.Length) Array.Resize(ref _fields, _fields.Length * 2); _fields[_idx] = new BinaryObjectSchemaField(id, offset); _idx++; }
/// <summary> /// Adds a field to the holder. /// </summary> /// <param name="id">The identifier.</param> /// <param name="offset">The offset.</param> public void PushField(int id, int offset) { if (_idx == _fields.Length) { Array.Resize(ref _fields, _fields.Length * 2); } _fields[_idx] = new BinaryObjectSchemaField(id, offset); _idx++; }
/// <summary> /// Reads the schema according to this header data. /// </summary> /// <param name="stream">The stream.</param> /// <param name="position">The position.</param> /// <returns>Schema.</returns> public BinaryObjectSchemaField[] ReadSchema(IBinaryStream stream, int position) { Debug.Assert(stream != null); ThrowIfUnsupported(); var schemaSize = SchemaFieldCount; if (schemaSize == 0) { return(null); } stream.Seek(position + SchemaOffset, SeekOrigin.Begin); var schema = new BinaryObjectSchemaField[schemaSize]; var offsetSize = SchemaFieldOffsetSize; if (offsetSize == 1) { for (var i = 0; i < schemaSize; i++) { schema[i] = new BinaryObjectSchemaField(stream.ReadInt(), stream.ReadByte()); } } else if (offsetSize == 2) { for (var i = 0; i < schemaSize; i++) { schema[i] = new BinaryObjectSchemaField(stream.ReadInt(), stream.ReadShort()); } } else { for (var i = 0; i < schemaSize; i++) { schema[i] = new BinaryObjectSchemaField(stream.ReadInt(), stream.ReadInt()); } } return(schema); }
/// <summary> /// Reads the schema according to this header data. /// </summary> /// <param name="stream">The stream.</param> /// <param name="position">The position.</param> /// <param name="hdr">The header.</param> /// <param name="fieldIdsFunc">The field ids function.</param> /// <returns> /// Schema. /// </returns> public static unsafe BinaryObjectSchemaField[] ReadSchema(IBinaryStream stream, int position, BinaryObjectHeader hdr, Func <int[]> fieldIdsFunc) { Debug.Assert(stream != null); Debug.Assert(fieldIdsFunc != null); var schemaSize = hdr.SchemaFieldCount; if (schemaSize == 0) { return(null); } stream.Seek(position + hdr.SchemaOffset, SeekOrigin.Begin); var res = new BinaryObjectSchemaField[schemaSize]; var offsetSize = hdr.SchemaFieldOffsetSize; if (hdr.IsCompactFooter) { var fieldIds = fieldIdsFunc(); Debug.Assert(fieldIds.Length == schemaSize); if (offsetSize == 1) { for (var i = 0; i < schemaSize; i++) { res[i] = new BinaryObjectSchemaField(fieldIds[i], stream.ReadByte()); } } else if (offsetSize == 2) { for (var i = 0; i < schemaSize; i++) { res[i] = new BinaryObjectSchemaField(fieldIds[i], (ushort)stream.ReadShort()); } } else { for (var i = 0; i < schemaSize; i++) { res[i] = new BinaryObjectSchemaField(fieldIds[i], stream.ReadInt()); } } } else { if (offsetSize == 1) { for (var i = 0; i < schemaSize; i++) { res[i] = new BinaryObjectSchemaField(stream.ReadInt(), stream.ReadByte()); } } else if (offsetSize == 2) { for (var i = 0; i < schemaSize; i++) { res[i] = new BinaryObjectSchemaField(stream.ReadInt(), (ushort)stream.ReadShort()); } } else { if (BitConverter.IsLittleEndian) { fixed(BinaryObjectSchemaField *ptr = &res[0]) { stream.Read((byte *)ptr, schemaSize * BinaryObjectSchemaField.Size); } } else { for (var i = 0; i < schemaSize; i++) { res[i] = new BinaryObjectSchemaField(stream.ReadInt(), stream.ReadInt()); } } } } return(res); }
/// <summary> /// Reads the schema according to this header data. /// </summary> /// <param name="stream">The stream.</param> /// <param name="position">The position.</param> /// <param name="hdr">The header.</param> /// <param name="fieldIdsFunc">The field ids function.</param> /// <returns> /// Schema. /// </returns> public static BinaryObjectSchemaField[] ReadSchema(IBinaryStream stream, int position, BinaryObjectHeader hdr, Func<int[]> fieldIdsFunc) { Debug.Assert(stream != null); Debug.Assert(fieldIdsFunc != null); var schemaSize = hdr.SchemaFieldCount; if (schemaSize == 0) return null; stream.Seek(position + hdr.SchemaOffset, SeekOrigin.Begin); var res = new BinaryObjectSchemaField[schemaSize]; var offsetSize = hdr.SchemaFieldOffsetSize; if (hdr.IsCompactFooter) { var fieldIds = fieldIdsFunc(); Debug.Assert(fieldIds.Length == schemaSize); if (offsetSize == 1) { for (var i = 0; i < schemaSize; i++) res[i] = new BinaryObjectSchemaField(fieldIds[i], stream.ReadByte()); } else if (offsetSize == 2) { for (var i = 0; i < schemaSize; i++) res[i] = new BinaryObjectSchemaField(fieldIds[i], stream.ReadShort()); } else { for (var i = 0; i < schemaSize; i++) res[i] = new BinaryObjectSchemaField(fieldIds[i], stream.ReadInt()); } } else { if (offsetSize == 1) { for (var i = 0; i < schemaSize; i++) res[i] = new BinaryObjectSchemaField(stream.ReadInt(), stream.ReadByte()); } else if (offsetSize == 2) { for (var i = 0; i < schemaSize; i++) res[i] = new BinaryObjectSchemaField(stream.ReadInt(), stream.ReadShort()); } else { for (var i = 0; i < schemaSize; i++) res[i] = new BinaryObjectSchemaField(stream.ReadInt(), stream.ReadInt()); } } return res; }
/// <summary> /// Writes an array of fields to a stream. /// </summary> /// <param name="fields">Fields.</param> /// <param name="stream">Stream.</param> /// <param name="offset">Offset in the array.</param> /// <param name="count">Field count to write.</param> /// <param name="compact">Compact mode without field ids.</param> /// <returns> /// Flags according to offset sizes: <see cref="BinaryObjectHeader.Flag.OffsetOneByte" />, /// <see cref="BinaryObjectHeader.Flag.OffsetTwoBytes" />, or 0. /// </returns> public static unsafe BinaryObjectHeader.Flag WriteSchema(BinaryObjectSchemaField[] fields, IBinaryStream stream, int offset, int count, bool compact) { Debug.Assert(fields != null); Debug.Assert(stream != null); Debug.Assert(count > 0); Debug.Assert(offset >= 0); Debug.Assert(offset < fields.Length); unchecked { // Last field is the farthest in the stream var maxFieldOffset = fields[offset + count - 1].Offset; if (compact) { if (maxFieldOffset <= byte.MaxValue) { for (int i = offset; i < count + offset; i++) stream.WriteByte((byte)fields[i].Offset); return BinaryObjectHeader.Flag.OffsetOneByte; } if (maxFieldOffset <= ushort.MaxValue) { for (int i = offset; i < count + offset; i++) stream.WriteShort((short)fields[i].Offset); return BinaryObjectHeader.Flag.OffsetTwoBytes; } for (int i = offset; i < count + offset; i++) stream.WriteInt(fields[i].Offset); } else { if (maxFieldOffset <= byte.MaxValue) { for (int i = offset; i < count + offset; i++) { var field = fields[i]; stream.WriteInt(field.Id); stream.WriteByte((byte)field.Offset); } return BinaryObjectHeader.Flag.OffsetOneByte; } if (maxFieldOffset <= ushort.MaxValue) { for (int i = offset; i < count + offset; i++) { var field = fields[i]; stream.WriteInt(field.Id); stream.WriteShort((short)field.Offset); } return BinaryObjectHeader.Flag.OffsetTwoBytes; } if (BitConverter.IsLittleEndian) { fixed (BinaryObjectSchemaField* ptr = &fields[offset]) { stream.Write((byte*)ptr, count / BinaryObjectSchemaField.Size); } } else { for (int i = offset; i < count + offset; i++) { var field = fields[i]; stream.WriteInt(field.Id); stream.WriteInt(field.Offset); } } } return BinaryObjectHeader.Flag.None; } }