/// <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++;
        }
Пример #2
0
        /// <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++;
        }
Пример #3
0
        /// <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);
        }
Пример #4
0
        /// <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;
            }
        }