예제 #1
0
        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);
                }
            }
        }
예제 #2
0
        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);
                }
            }
        }
예제 #3
0
        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
        }