コード例 #1
0
            private void WriteArrayOrObjectEnd(bool isArray)
            {
                this.JsonObjectState.RegisterToken(isArray ? JsonTokenType.EndArray : JsonTokenType.EndObject);
                BeginOffsetAndCount nestedContext = this.bufferedContexts.Pop();

                // Do some math
                int typeMarkerIndex = (int)nestedContext.Offset;
                int payloadIndex    = typeMarkerIndex + this.reservationSize;
                int originalCursor  = (int)this.CurrentLength;
                int payloadLength   = originalCursor - payloadIndex;
                int count           = (int)nestedContext.Count;

                // Figure out what the typemarker and length should be and do any corrections needed
                if (count == 0)
                {
                    // Empty object

                    // Move the cursor back
                    this.binaryWriter.BaseStream.Seek(typeMarkerIndex, SeekOrigin.Begin);

                    // Write the type marker
                    this.binaryWriter.Write(
                        isArray ? JsonBinaryEncoding.TypeMarker.EmptyArray : JsonBinaryEncoding.TypeMarker.EmptyObject);
                }
                else if (count == 1)
                {
                    // Single-property object

                    // Move the buffer back 2 or 4 bytes since we don't need to encode a length
                    byte[] buffer = ((MemoryStream)this.binaryWriter.BaseStream).GetBuffer();
                    Array.Copy(buffer, payloadIndex, buffer, payloadIndex - (TwoByteLength + (this.serializeCount ? TwoByteCount : 0)), payloadLength);

                    // Move the cursor back
                    this.binaryWriter.BaseStream.Seek(typeMarkerIndex, SeekOrigin.Begin);

                    // Write the type marker
                    this.binaryWriter.Write(
                        isArray ? JsonBinaryEncoding.TypeMarker.SingleItemArray : JsonBinaryEncoding.TypeMarker.SinglePropertyObject);

                    // Move the cursor forward
                    this.binaryWriter.BaseStream.Seek(typeMarkerIndex + TypeMarker + payloadLength, SeekOrigin.Begin);
                }
                else
                {
                    // Need to figure out how many bytes to encode the length and the count
                    if (payloadLength <= byte.MaxValue)
                    {
                        // 1 byte length - move the buffer back
                        byte[] buffer = ((MemoryStream)this.binaryWriter.BaseStream).GetBuffer();
                        Array.Copy(buffer, payloadIndex, buffer, payloadIndex - (OneByteLength + (this.serializeCount ? OneByteCount : 0)), payloadLength);

                        // Move the cursor back
                        this.binaryWriter.BaseStream.Seek(typeMarkerIndex, SeekOrigin.Begin);

                        // Write the type marker
                        if (this.serializeCount)
                        {
                            this.binaryWriter.Write(
                                isArray ? JsonBinaryEncoding.TypeMarker.Array1ByteLengthAndCount : JsonBinaryEncoding.TypeMarker.Object1ByteLengthAndCount);
                            this.binaryWriter.Write((byte)payloadLength);
                            this.binaryWriter.Write((byte)count);
                        }
                        else
                        {
                            this.binaryWriter.Write(
                                isArray ? JsonBinaryEncoding.TypeMarker.Array1ByteLength : JsonBinaryEncoding.TypeMarker.Object1ByteLength);
                            this.binaryWriter.Write((byte)payloadLength);
                        }

                        // Move the cursor forward
                        this.binaryWriter.BaseStream.Seek(typeMarkerIndex + TypeMarker + OneByteLength + (this.serializeCount ? OneByteCount : 0) + payloadLength, SeekOrigin.Begin);
                    }
                    else if (payloadLength <= ushort.MaxValue)
                    {
                        // 2 byte length - don't need to move the buffer
                        // Move the cursor back
                        this.binaryWriter.BaseStream.Seek(typeMarkerIndex, SeekOrigin.Begin);

                        // Write the type marker
                        if (this.serializeCount)
                        {
                            this.binaryWriter.Write(
                                isArray ? JsonBinaryEncoding.TypeMarker.Array2ByteLengthAndCount : JsonBinaryEncoding.TypeMarker.Object2ByteLengthAndCount);
                            this.binaryWriter.Write((ushort)payloadLength);
                            this.binaryWriter.Write((ushort)count);
                        }
                        else
                        {
                            this.binaryWriter.Write(
                                isArray ? JsonBinaryEncoding.TypeMarker.Array2ByteLength : JsonBinaryEncoding.TypeMarker.Object2ByteLength);
                            this.binaryWriter.Write((ushort)payloadLength);
                        }

                        // Move the cursor forward
                        this.binaryWriter.BaseStream.Seek(typeMarkerIndex + TypeMarker + TwoByteLength + (this.serializeCount ? TwoByteCount : 0) + payloadLength, SeekOrigin.Begin);
                    }
                    else
                    {
                        // (payloadLength <= uint.MaxValue)

                        // 4 byte length - make space for an extra 2 byte length (and 2 byte count)
                        this.binaryWriter.Write((ushort)0);
                        if (this.serializeCount)
                        {
                            this.binaryWriter.Write((ushort)0);
                        }

                        // Move the buffer forward
                        byte[] buffer = ((MemoryStream)this.binaryWriter.BaseStream).GetBuffer();
                        Array.Copy(buffer, payloadIndex, buffer, payloadIndex + TwoByteLength + (this.serializeCount ? TwoByteCount : 0), payloadLength);

                        // Move the cursor back
                        this.binaryWriter.BaseStream.Seek(typeMarkerIndex, SeekOrigin.Begin);

                        // Write the type marker
                        if (this.serializeCount)
                        {
                            this.binaryWriter.Write(
                                isArray ? JsonBinaryEncoding.TypeMarker.Array4ByteLengthAndCount : JsonBinaryEncoding.TypeMarker.Object4ByteLengthAndCount);
                            this.binaryWriter.Write((uint)payloadLength);
                            this.binaryWriter.Write((uint)count);
                        }
                        else
                        {
                            this.binaryWriter.Write(
                                isArray ? JsonBinaryEncoding.TypeMarker.Array4ByteLength : JsonBinaryEncoding.TypeMarker.Object4ByteLength);
                            this.binaryWriter.Write((uint)payloadLength);
                        }

                        // Move the cursor forward
                        this.binaryWriter.BaseStream.Seek(typeMarkerIndex + TypeMarker + FourByteLength + (this.serializeCount ? FourByteCount : 0) + payloadLength, SeekOrigin.Begin);
                    }
                }

                this.bufferedContexts.Peek().Count++;
            }
コード例 #2
0
            private void WriteArrayOrObjectEnd(bool isArray)
            {
                this.JsonObjectState.RegisterToken(isArray ? JsonTokenType.EndArray : JsonTokenType.EndObject);
                BeginOffsetAndCount nestedContext = this.bufferedContexts.Pop();

                // Do some math
                int typeMarkerIndex = (int)nestedContext.Offset;
                int payloadIndex    = typeMarkerIndex + this.reservationSize;
                int originalCursor  = (int)this.CurrentLength;
                int payloadLength   = originalCursor - payloadIndex;
                int count           = (int)nestedContext.Count;

                // Figure out what the typemarker and length should be and do any corrections needed
                if (count == 0)
                {
                    // Empty object

                    // Move the cursor back
                    this.binaryWriter.Position = typeMarkerIndex;

                    // Write the type marker
                    this.binaryWriter.Write(
                        isArray ? JsonBinaryEncoding.TypeMarker.EmptyArray : JsonBinaryEncoding.TypeMarker.EmptyObject);
                }
                else if (count == 1)
                {
                    // Single-property object

                    // Move the buffer back but leave one byte for the typemarker
                    Memory <byte> buffer = this.binaryWriter.Buffer;
                    buffer.Slice(payloadIndex).CopyTo(buffer.Slice(typeMarkerIndex + JsonBinaryEncoding.TypeMarkerLength));

                    // Move the cursor back
                    this.binaryWriter.Position = typeMarkerIndex;

                    // Write the type marker
                    this.binaryWriter.Write(
                        isArray ? JsonBinaryEncoding.TypeMarker.SingleItemArray : JsonBinaryEncoding.TypeMarker.SinglePropertyObject);

                    // Move the cursor forward
                    this.binaryWriter.Position = typeMarkerIndex + JsonBinaryEncoding.TypeMarkerLength + payloadLength;
                }
                else
                {
                    // Need to figure out how many bytes to encode the length and the count
                    if (payloadLength <= byte.MaxValue)
                    {
                        // 1 byte length - don't need to move the buffer
                        int bytesToWrite = JsonBinaryEncoding.TypeMarkerLength
                                           + JsonBinaryEncoding.OneByteLength
                                           + (this.serializeCount ? JsonBinaryEncoding.OneByteCount : 0);

                        // Move the cursor back
                        this.binaryWriter.Position = typeMarkerIndex;

                        // Write the type marker
                        if (this.serializeCount)
                        {
                            this.binaryWriter.Write(
                                isArray ? JsonBinaryEncoding.TypeMarker.Array1ByteLengthAndCount : JsonBinaryEncoding.TypeMarker.Object1ByteLengthAndCount);
                            this.binaryWriter.Write((byte)payloadLength);
                            this.binaryWriter.Write((byte)count);
                        }
                        else
                        {
                            this.binaryWriter.Write(
                                isArray ? JsonBinaryEncoding.TypeMarker.Array1ByteLength : JsonBinaryEncoding.TypeMarker.Object1ByteLength);
                            this.binaryWriter.Write((byte)payloadLength);
                        }

                        // Move the cursor forward
                        this.binaryWriter.Position = typeMarkerIndex + bytesToWrite + payloadLength;
                    }
                    else if (payloadLength <= ushort.MaxValue)
                    {
                        // 2 byte length - make space for the extra byte length (and extra byte count)
                        this.binaryWriter.Write((byte)0);
                        if (this.serializeCount)
                        {
                            this.binaryWriter.Write((byte)0);
                        }

                        // Move the buffer forward
                        Memory <byte> buffer       = this.binaryWriter.Buffer;
                        int           bytesToWrite = JsonBinaryEncoding.TypeMarkerLength
                                                     + JsonBinaryEncoding.TwoByteLength
                                                     + (this.serializeCount ? JsonBinaryEncoding.TwoByteCount : 0);
                        Memory <byte> payload         = buffer.Slice(payloadIndex, payloadLength);
                        Memory <byte> newPayloadStart = buffer.Slice(typeMarkerIndex + bytesToWrite);
                        payload.CopyTo(newPayloadStart);

                        // Move the cursor back
                        this.binaryWriter.Position = typeMarkerIndex;

                        // Write the type marker
                        if (this.serializeCount)
                        {
                            this.binaryWriter.Write(
                                isArray ? JsonBinaryEncoding.TypeMarker.Array2ByteLengthAndCount : JsonBinaryEncoding.TypeMarker.Object2ByteLengthAndCount);
                            this.binaryWriter.Write((ushort)payloadLength);
                            this.binaryWriter.Write((ushort)count);
                        }
                        else
                        {
                            this.binaryWriter.Write(
                                isArray ? JsonBinaryEncoding.TypeMarker.Array2ByteLength : JsonBinaryEncoding.TypeMarker.Object2ByteLength);
                            this.binaryWriter.Write((ushort)payloadLength);
                        }

                        // Move the cursor forward
                        this.binaryWriter.Position = typeMarkerIndex + bytesToWrite + payloadLength;
                    }
                    else
                    {
                        // (payloadLength <= uint.MaxValue)

                        // 4 byte length - make space for an extra 2 byte length (and 2 byte count)
                        this.binaryWriter.Write((ushort)0);
                        if (this.serializeCount)
                        {
                            this.binaryWriter.Write((ushort)0);
                        }

                        // Move the buffer forward
                        Memory <byte> buffer       = this.binaryWriter.Buffer;
                        int           bytesToWrite = JsonBinaryEncoding.TypeMarkerLength
                                                     + JsonBinaryEncoding.FourByteLength
                                                     + (this.serializeCount ? JsonBinaryEncoding.FourByteCount : 0);
                        Memory <byte> payload         = buffer.Slice(payloadIndex, payloadLength);
                        Memory <byte> newPayloadStart = buffer.Slice(typeMarkerIndex + bytesToWrite);
                        payload.CopyTo(newPayloadStart);

                        // Move the cursor back
                        this.binaryWriter.Position = typeMarkerIndex;

                        // Write the type marker
                        if (this.serializeCount)
                        {
                            this.binaryWriter.Write(
                                isArray ? JsonBinaryEncoding.TypeMarker.Array4ByteLengthAndCount : JsonBinaryEncoding.TypeMarker.Object4ByteLengthAndCount);
                            this.binaryWriter.Write((uint)payloadLength);
                            this.binaryWriter.Write((uint)count);
                        }
                        else
                        {
                            this.binaryWriter.Write(
                                isArray ? JsonBinaryEncoding.TypeMarker.Array4ByteLength : JsonBinaryEncoding.TypeMarker.Object4ByteLength);
                            this.binaryWriter.Write((uint)payloadLength);
                        }

                        // Move the cursor forward
                        this.binaryWriter.Position = typeMarkerIndex + bytesToWrite + payloadLength;
                    }
                }

                this.bufferedContexts.Peek().Count++;
            }