Exemple #1
0
        /// <summary>
        /// Writes the end of a BSON document to the writer.
        /// </summary>
        public override void WriteEndDocument()
        {
            if (Disposed)
            {
                throw new ObjectDisposedException("BsonBinaryWriter");
            }
            if (State != BsonWriterState.Name)
            {
                ThrowInvalidState("WriteEndDocument", BsonWriterState.Name);
            }
            if (_context.ContextType != ContextType.Document && _context.ContextType != ContextType.ScopeDocument)
            {
                ThrowInvalidContextType("WriteEndDocument", _context.ContextType, ContextType.Document, ContextType.ScopeDocument);
            }

            base.WriteEndDocument();
            _bsonStream.WriteByte(0);
            BackpatchSize(); // size of document

            _context = _context.ParentContext;
            if (_context == null)
            {
                State = BsonWriterState.Done;
            }
            else
            {
                if (_context.ContextType == ContextType.JavaScriptWithScope)
                {
                    BackpatchSize(); // size of the JavaScript with scope value
                    _context = _context.ParentContext;
                }
                State = GetNextState();
            }
        }
        /// <summary>
        /// Writes the end of a BSON document to the writer.
        /// </summary>
        public override void WriteEndDocument()
        {
            if (disposed)
            {
                throw new ObjectDisposedException("BsonBinaryWriter");
            }
            if (state != BsonWriterState.Name || (context.ContextType != ContextType.Document && context.ContextType != ContextType.ScopeDocument))
            {
                var message = string.Format("WriteEndDocument cannot be called when State is: {0}", state);
                throw new InvalidOperationException(message);
            }

            buffer.WriteByte(0);
            BackpatchSize(); // size of document

            context = context.ParentContext;
            if (context == null)
            {
                state = BsonWriterState.Done;
            }
            else
            {
                if (context.ContextType == ContextType.JavaScriptWithScope)
                {
                    BackpatchSize(); // size of the JavaScript with scope value
                    context = context.ParentContext;
                }
                state = GetNextState();
            }
        }
Exemple #3
0
        /// <summary>
        /// Writes a raw BSON document.
        /// </summary>
        /// <param name="slice">The byte buffer containing the raw BSON document.</param>
        public override void WriteRawBsonDocument(IByteBuffer slice)
        {
            if (Disposed)
            {
                throw new ObjectDisposedException("BsonBinaryWriter");
            }
            if (State != BsonWriterState.Initial && State != BsonWriterState.Value && State != BsonWriterState.ScopeDocument && State != BsonWriterState.Done)
            {
                ThrowInvalidState("WriteRawBsonDocument", BsonWriterState.Initial, BsonWriterState.Value, BsonWriterState.ScopeDocument, BsonWriterState.Done);
            }

            if (State == BsonWriterState.Value)
            {
                _bsonStream.WriteBsonType(BsonType.Document);
                WriteNameHelper();
            }
            _bsonStream.WriteSlice(slice); // assumes byteBuffer is a valid raw BSON document

            if (_context == null)
            {
                State = BsonWriterState.Done;
            }
            else
            {
                if (_context.ContextType == ContextType.JavaScriptWithScope)
                {
                    BackpatchSize(); // size of the JavaScript with scope value
                    _context = _context.ParentContext;
                }
                State = GetNextState();
            }
        }
        private int _index; // used when contextType is Array

        // constructors
        internal BsonBinaryWriterContext(
            BsonBinaryWriterContext parentContext,
            ContextType contextType,
            int startPosition)
        {
            _parentContext = parentContext;
            _contextType   = contextType;
            _startPosition = startPosition;
        }
 // constructors
 internal BsonBinaryWriterContext(
     BsonBinaryWriterContext parentContext,
     ContextType contextType,
     int startPosition)
 {
     _parentContext = parentContext;
     _contextType = contextType;
     _startPosition = startPosition;
 }
 internal BsonBinaryWriterContext(
     BsonBinaryWriterContext parentContext,
     ContextType contextType,
     int startPosition
 )
 {
     this.parentContext = parentContext;
     this.contextType = contextType;
     this.startPosition = startPosition;
 }
Exemple #7
0
        private int index; // used when contextType is Array
        #endregion

        #region constructors
        internal BsonBinaryWriterContext(
            BsonBinaryWriterContext parentContext,
            ContextType contextType,
            int startPosition
            )
        {
            this.parentContext = parentContext;
            this.contextType   = contextType;
            this.startPosition = startPosition;
        }
Exemple #8
0
 // public methods
 /// <summary>
 /// Closes the writer. Also closes the base stream.
 /// </summary>
 public override void Close()
 {
     // Close can be called on Disposed objects
     if (State != BsonWriterState.Closed)
     {
         if (State == BsonWriterState.Done)
         {
             Flush();
         }
         _context = null;
         State    = BsonWriterState.Closed;
     }
 }
 /// <summary>
 /// Closes the writer.
 /// </summary>
 public override void Close() {
     // Close can be called on Disposed objects
     if (state != BsonWriterState.Closed) {
         if (state == BsonWriterState.Done) {
             Flush();
         }
         if (stream != null && settings.CloseOutput) {
             stream.Close();
         }
         context = null;
         state = BsonWriterState.Closed;
     }
 }
        /// <summary>
        /// Initializes a new instance of the BsonBinaryWriter class.
        /// </summary>
        /// <param name="buffer">A BsonBuffer.</param>
        /// <param name="disposeBuffer">if set to <c>true</c> this BsonBinaryReader will own the buffer and when Dispose is called the buffer will be Disposed also.</param>
        /// <param name="settings">Optional BsonBinaryWriter settings.</param>
        /// <exception cref="System.ArgumentNullException">
        /// encoder
        /// or
        /// settings
        /// </exception>
        public BsonBinaryWriter(BsonBuffer buffer, bool disposeBuffer, BsonBinaryWriterSettings settings)
            : base(settings)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException("encoder");
            }

            _buffer = buffer;
            _disposeBuffer = disposeBuffer;
            _binaryWriterSettings = settings; // already frozen by base class

            _context = null;
            State = BsonWriterState.Initial;
        }
        /// <summary>
        /// Initializes a new instance of the BsonBinaryWriter class.
        /// </summary>
        /// <param name="buffer">A BsonBuffer.</param>
        /// <param name="disposeBuffer">if set to <c>true</c> this BsonBinaryReader will own the buffer and when Dispose is called the buffer will be Disposed also.</param>
        /// <param name="settings">Optional BsonBinaryWriter settings.</param>
        /// <exception cref="System.ArgumentNullException">
        /// encoder
        /// or
        /// settings
        /// </exception>
        public BsonBinaryWriter(BsonBuffer buffer, bool disposeBuffer, BsonBinaryWriterSettings settings)
            : base(settings)
        {
            if (buffer == null)
            {
                throw new ArgumentNullException("encoder");
            }

            _buffer               = buffer;
            _disposeBuffer        = disposeBuffer;
            _binaryWriterSettings = settings; // already frozen by base class

            _context = null;
            State    = BsonWriterState.Initial;
        }
Exemple #12
0
 /// <summary>
 /// Closes the writer.
 /// </summary>
 public override void Close()
 {
     // Close can be called on Disposed objects
     if (state != BsonWriterState.Closed)
     {
         if (state == BsonWriterState.Done)
         {
             Flush();
         }
         if (stream != null && settings.CloseOutput)
         {
             stream.Close();
         }
         context = null;
         state   = BsonWriterState.Closed;
     }
 }
        /// <summary>
        /// Initializes a new instance of the BsonBinaryWriter class.
        /// </summary>
        /// <param name="stream">A stream.</param>
        /// <param name="buffer">A BsonBuffer.</param>
        /// <param name="settings">Optional BsonBinaryWriter settings.</param>
        public BsonBinaryWriter(
            Stream stream,
            BsonBuffer buffer,
            BsonBinaryWriterSettings settings
        ) {
            this.stream = stream;
            if (buffer == null) {
                this.buffer = new BsonBuffer();
                this.disposeBuffer = true; // only call Dispose if we allocated the buffer
            } else {
                this.buffer = buffer;
                this.disposeBuffer = false;
            }
            this.settings = settings.Freeze();

            context = null;
            state = BsonWriterState.Initial;
        }
Exemple #14
0
        /// <summary>
        /// Initializes a new instance of the BsonBinaryWriter class.
        /// </summary>
        /// <param name="stream">A stream. The BsonBinaryWriter does not own the stream and will not Dispose it.</param>
        /// <param name="settings">The BsonBinaryWriter settings.</param>
        public BsonBinaryWriter(Stream stream, BsonBinaryWriterSettings settings)
            : base(settings)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            if (!stream.CanSeek)
            {
                throw new ArgumentException("The stream must be capable of seeking.", "stream");
            }

            _baseStream = stream;
            _bsonStream = (stream as BsonStream) ?? new BsonStreamAdapter(stream);

            _context = null;
            State    = BsonWriterState.Initial;
        }
Exemple #15
0
        /// <summary>
        /// Writes the start of a BSON array to the writer.
        /// </summary>
        public override void WriteStartArray()
        {
            if (disposed)
            {
                throw new ObjectDisposedException("BsonBinaryWriter");
            }
            if (state != BsonWriterState.Value)
            {
                ThrowInvalidState("WriteStartArray", BsonWriterState.Value);
            }

            buffer.WriteByte((byte)BsonType.Array);
            WriteNameHelper();
            context = new BsonBinaryWriterContext(context, ContextType.Array, buffer.Position);
            buffer.WriteInt32(0); // reserve space for size

            state = BsonWriterState.Value;
        }
        /// <summary>
        /// Writes the end of a BSON array to the writer.
        /// </summary>
        public override void WriteEndArray()
        {
            if (disposed)
            {
                throw new ObjectDisposedException("BsonBinaryWriter");
            }
            if (state != BsonWriterState.Value || context.ContextType != ContextType.Array)
            {
                var message = string.Format("WriteEndArray cannot be called when State is: {0}", state);
                throw new InvalidOperationException(message);
            }

            buffer.WriteByte(0);
            BackpatchSize(); // size of document

            context = context.ParentContext;
            state   = GetNextState();
        }
        // constructors
        /// <summary>
        /// Initializes a new instance of the BsonBinaryWriter class.
        /// </summary>
        /// <param name="stream">A stream.</param>
        /// <param name="buffer">A BsonBuffer.</param>
        /// <param name="settings">Optional BsonBinaryWriter settings.</param>
        public BsonBinaryWriter(Stream stream, BsonBuffer buffer, BsonBinaryWriterSettings settings)
            : base(settings)
        {
            _stream = stream;
            if (buffer == null)
            {
                _buffer        = new BsonBuffer();
                _disposeBuffer = true; // only call Dispose if we allocated the buffer
            }
            else
            {
                _buffer        = buffer;
                _disposeBuffer = false;
            }
            _binaryWriterSettings = settings; // already frozen by base class

            _context = null;
            State    = BsonWriterState.Initial;
        }
        /// <summary>
        /// Writes a BSON JavaScript to the writer (call WriteStartDocument to start writing the scope).
        /// </summary>
        /// <param name="code">The JavaScript code.</param>
        public override void WriteJavaScriptWithScope(string code)
        {
            if (disposed)
            {
                throw new ObjectDisposedException("BsonBinaryWriter");
            }
            if (state != BsonWriterState.Value)
            {
                ThrowInvalidState("WriteJavaScriptWithScope", BsonWriterState.Value);
            }

            buffer.WriteByte((byte)BsonType.JavaScriptWithScope);
            WriteNameHelper();
            context = new BsonBinaryWriterContext(context, ContextType.JavaScriptWithScope, buffer.Position);
            buffer.WriteInt32(0); // reserve space for size of JavaScript with scope value
            buffer.WriteString(code);

            state = BsonWriterState.ScopeDocument;
        }
        // constructors
        /// <summary>
        /// Initializes a new instance of the BsonBinaryWriter class.
        /// </summary>
        /// <param name="stream">A stream.</param>
        /// <param name="buffer">A BsonBuffer.</param>
        /// <param name="settings">Optional BsonBinaryWriter settings.</param>
        public BsonBinaryWriter(Stream stream, BsonBuffer buffer, BsonBinaryWriterSettings settings)
            : base(settings)
        {
            _stream = stream;
            if (buffer == null)
            {
                _buffer = new BsonBuffer();
                _disposeBuffer = true; // only call Dispose if we allocated the buffer
            }
            else
            {
                _buffer = buffer;
                _disposeBuffer = false;
            }
            _binaryWriterSettings = settings; // already frozen by base class

            _context = null;
            State = BsonWriterState.Initial;
        }
Exemple #20
0
        /// <summary>
        /// Writes a BSON JavaScript to the writer (call WriteStartDocument to start writing the scope).
        /// </summary>
        /// <param name="code">The JavaScript code.</param>
        public override void WriteJavaScriptWithScope(string code)
        {
            if (Disposed)
            {
                throw new ObjectDisposedException("BsonBinaryWriter");
            }
            if (State != BsonWriterState.Value)
            {
                ThrowInvalidState("WriteJavaScriptWithScope", BsonWriterState.Value);
            }

            _bsonStream.WriteBsonType(BsonType.JavaScriptWithScope);
            WriteNameHelper();
            _context = new BsonBinaryWriterContext(_context, ContextType.JavaScriptWithScope, _bsonStream.Position);
            _bsonStream.WriteInt32(0); // reserve space for size of JavaScript with scope value
            _bsonStream.WriteString(code, _settings.Encoding);

            State = BsonWriterState.ScopeDocument;
        }
        /// <summary>
        /// Writes the start of a BSON array to the writer.
        /// </summary>
        public override void WriteStartArray()
        {
            if (disposed)
            {
                throw new ObjectDisposedException("BsonBinaryWriter");
            }
            if (state != BsonWriterState.Value)
            {
                var message = string.Format("WriteStartArray cannot be called when State is: {0}", state);
                throw new InvalidOperationException(message);
            }

            buffer.WriteByte((byte)BsonType.Array);
            WriteNameHelper();
            context = new BsonBinaryWriterContext(context, ContextType.Array, buffer.Position);
            buffer.WriteInt32(0); // reserve space for size

            state = BsonWriterState.Value;
        }
Exemple #22
0
        /// <summary>
        /// Writes the start of a BSON array to the writer.
        /// </summary>
        public override void WriteStartArray()
        {
            if (Disposed)
            {
                throw new ObjectDisposedException("BsonBinaryWriter");
            }
            if (State != BsonWriterState.Value)
            {
                ThrowInvalidState("WriteStartArray", BsonWriterState.Value);
            }

            base.WriteStartArray();
            _bsonStream.WriteBsonType(BsonType.Array);
            WriteNameHelper();
            _context = new BsonBinaryWriterContext(_context, ContextType.Array, _bsonStream.Position);
            _bsonStream.WriteInt32(0); // reserve space for size

            State = BsonWriterState.Value;
        }
        /// <summary>
        /// Initializes a new instance of the BsonBinaryWriter class.
        /// </summary>
        /// <param name="stream">A stream. The BsonBinaryWriter does not own the stream and will not Dispose it.</param>
        /// <param name="settings">The BsonBinaryWriter settings.</param>
        public BsonBinaryWriter(Stream stream, BsonBinaryWriterSettings settings)
            : base(settings)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            if (!stream.CanSeek)
            {
                throw new ArgumentException("The stream must be capable of seeking.", "stream");
            }

            _baseStream = stream;
            _bsonStream = (stream as BsonStream) ?? new BsonStreamAdapter(stream);
            _settings = settings; // already frozen by base class
            _maxDocumentSizeStack.Push(_settings.MaxDocumentSize);

            _context = null;
            State = BsonWriterState.Initial;
        }
Exemple #24
0
        /// <summary>
        /// Initializes a new instance of the BsonBinaryWriter class.
        /// </summary>
        /// <param name="stream">A stream. The BsonBinaryWriter does not own the stream and will not Dispose it.</param>
        /// <param name="settings">The BsonBinaryWriter settings.</param>
        public BsonBinaryWriter(Stream stream, BsonBinaryWriterSettings settings)
            : base(settings)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }
            if (!stream.CanSeek)
            {
                throw new ArgumentException("The stream must be capable of seeking.", "stream");
            }

            _baseStream = stream;
            _bsonStream = (stream as BsonStream) ?? new BsonStreamAdapter(stream);
            _settings   = settings; // already frozen by base class
            _maxDocumentSizeStack.Push(_settings.MaxDocumentSize);

            _context = null;
            State    = BsonWriterState.Initial;
        }
Exemple #25
0
        /// <summary>
        /// Writes the end of a BSON array to the writer.
        /// </summary>
        public override void WriteEndArray()
        {
            if (disposed)
            {
                throw new ObjectDisposedException("BsonBinaryWriter");
            }
            if (state != BsonWriterState.Value)
            {
                ThrowInvalidState("WriteEndArray", BsonWriterState.Value);
            }
            if (context.ContextType != ContextType.Array)
            {
                ThrowInvalidContextType("WriteEndArray", context.ContextType, ContextType.Array);
            }

            buffer.WriteByte(0);
            BackpatchSize(); // size of document

            context = context.ParentContext;
            state   = GetNextState();
        }
        /// <summary>
        /// Writes a BSON JavaScript to the writer (call WriteStartDocument to start writing the scope).
        /// </summary>
        /// <param name="code">The JavaScript code.</param>
        public override void WriteJavaScriptWithScope(
            string code
            )
        {
            if (disposed)
            {
                throw new ObjectDisposedException("BsonBinaryWriter");
            }
            if (state != BsonWriterState.Value)
            {
                var message = string.Format("WriteJavaScriptWithScope cannot be called when State is: {0}", state);
                throw new InvalidOperationException(message);
            }

            buffer.WriteByte((byte)BsonType.JavaScriptWithScope);
            WriteNameHelper();
            context = new BsonBinaryWriterContext(context, ContextType.JavaScriptWithScope, buffer.Position);
            buffer.WriteInt32(0); // reserve space for size of JavaScript with scope value
            buffer.WriteString(code);

            state = BsonWriterState.ScopeDocument;
        }
Exemple #27
0
        /// <summary>
        /// Initializes a new instance of the BsonBinaryWriter class.
        /// </summary>
        /// <param name="stream">A stream.</param>
        /// <param name="buffer">A BsonBuffer.</param>
        /// <param name="settings">Optional BsonBinaryWriter settings.</param>
        public BsonBinaryWriter(
            Stream stream,
            BsonBuffer buffer,
            BsonBinaryWriterSettings settings
            )
        {
            this.stream = stream;
            if (buffer == null)
            {
                this.buffer        = new BsonBuffer();
                this.disposeBuffer = true; // only call Dispose if we allocated the buffer
            }
            else
            {
                this.buffer        = buffer;
                this.disposeBuffer = false;
            }
            this.settings = settings.Freeze();

            context = null;
            state   = BsonWriterState.Initial;
        }
Exemple #28
0
        /// <summary>
        /// Writes the end of a BSON array to the writer.
        /// </summary>
        public override void WriteEndArray()
        {
            if (Disposed)
            {
                throw new ObjectDisposedException("BsonBinaryWriter");
            }
            if (State != BsonWriterState.Value)
            {
                ThrowInvalidState("WriteEndArray", BsonWriterState.Value);
            }
            if (_context.ContextType != ContextType.Array)
            {
                ThrowInvalidContextType("WriteEndArray", _context.ContextType, ContextType.Array);
            }

            base.WriteEndArray();
            _bsonStream.WriteByte(0);
            BackpatchSize(); // size of document

            _context = _context.ParentContext;
            State    = GetNextState();
        }
Exemple #29
0
        /// <summary>
        /// Writes the start of a BSON document to the writer.
        /// </summary>
        public override void WriteStartDocument()
        {
            if (Disposed)
            {
                throw new ObjectDisposedException("BsonBinaryWriter");
            }
            if (State != BsonWriterState.Initial && State != BsonWriterState.Value && State != BsonWriterState.ScopeDocument && State != BsonWriterState.Done)
            {
                ThrowInvalidState("WriteStartDocument", BsonWriterState.Initial, BsonWriterState.Value, BsonWriterState.ScopeDocument, BsonWriterState.Done);
            }

            base.WriteStartDocument();
            if (State == BsonWriterState.Value)
            {
                _buffer.WriteByte((byte)BsonType.Document);
                WriteNameHelper();
            }
            _context = new BsonBinaryWriterContext(_context, ContextType.Document, _buffer.Position);
            _buffer.WriteInt32(0); // reserve space for size

            State = BsonWriterState.Name;
        }
        /// <summary>
        /// Writes the start of a BSON document to the writer.
        /// </summary>
        public override void WriteStartDocument()
        {
            if (disposed)
            {
                throw new ObjectDisposedException("BsonBinaryWriter");
            }
            if (state != BsonWriterState.Initial && state != BsonWriterState.Value && state != BsonWriterState.ScopeDocument && state != BsonWriterState.Done)
            {
                var message = string.Format("WriteStartDocument cannot be called when State is: {0}", state);
                throw new InvalidOperationException(message);
            }

            if (state == BsonWriterState.Value)
            {
                buffer.WriteByte((byte)BsonType.Document);
                WriteNameHelper();
            }
            var contextType = (state == BsonWriterState.ScopeDocument) ? ContextType.ScopeDocument : ContextType.Document;

            context = new BsonBinaryWriterContext(context, ContextType.Document, buffer.Position);
            buffer.WriteInt32(0); // reserve space for size

            state = BsonWriterState.Name;
        }
        /// <summary>
        /// Writes the end of a BSON array to the writer.
        /// </summary>
        public override void WriteEndArray()
        {
            if (Disposed) { throw new ObjectDisposedException("BsonBinaryWriter"); }
            if (State != BsonWriterState.Value)
            {
                ThrowInvalidState("WriteEndArray", BsonWriterState.Value);
            }
            if (_context.ContextType != ContextType.Array)
            {
                ThrowInvalidContextType("WriteEndArray", _context.ContextType, ContextType.Array);
            }

            _buffer.WriteByte(0);
            BackpatchSize(); // size of document

            _context = _context.ParentContext;
            State = GetNextState();
        }
        /// <summary>
        /// Writes the start of a BSON document to the writer.
        /// </summary>
        public override void WriteStartDocument() {
            if (disposed) { throw new ObjectDisposedException("BsonBinaryWriter"); }
            if (state != BsonWriterState.Initial && state != BsonWriterState.Value && state != BsonWriterState.ScopeDocument && state != BsonWriterState.Done) {
                var message = string.Format("WriteStartDocument cannot be called when State is: {0}", state);
                throw new InvalidOperationException(message);
            }

            if (state == BsonWriterState.Value) {
                buffer.WriteByte((byte) BsonType.Document);
                WriteNameHelper();
            }
            var contextType = (state == BsonWriterState.ScopeDocument) ? ContextType.ScopeDocument : ContextType.Document;
            context = new BsonBinaryWriterContext(context, ContextType.Document, buffer.Position);
            buffer.WriteInt32(0); // reserve space for size

            state = BsonWriterState.Name;
        }
 // public methods
 /// <summary>
 /// Closes the writer. Also closes the base stream.
 /// </summary>
 public override void Close()
 {
     // Close can be called on Disposed objects
     if (State != BsonWriterState.Closed)
     {
         if (State == BsonWriterState.Done)
         {
             Flush();
         }
         _context = null;
         State = BsonWriterState.Closed;
     }
 }
        /// <summary>
        /// Writes the start of a BSON array to the writer.
        /// </summary>
        public override void WriteStartArray() {
            if (disposed) { throw new ObjectDisposedException("BsonBinaryWriter"); }
            if (state != BsonWriterState.Value) {
                var message = string.Format("WriteStartArray cannot be called when State is: {0}", state);
                throw new InvalidOperationException(message);
            }

            buffer.WriteByte((byte) BsonType.Array);
            WriteNameHelper();
            context = new BsonBinaryWriterContext(context, ContextType.Array, buffer.Position);
            buffer.WriteInt32(0); // reserve space for size

            state = BsonWriterState.Value;
        }
        /// <summary>
        /// Writes the end of a BSON array to the writer.
        /// </summary>
        public override void WriteEndArray() {
            if (disposed) { throw new ObjectDisposedException("BsonBinaryWriter"); }
            if (state != BsonWriterState.Value || context.ContextType != ContextType.Array) {
                var message = string.Format("WriteEndArray cannot be called when State is: {0}", state);
                throw new InvalidOperationException(message);
            }

            buffer.WriteByte(0);
            BackpatchSize(); // size of document

            context = context.ParentContext;
            state = GetNextState();
        }
        /// <summary>
        /// Writes the start of a BSON document to the writer.
        /// </summary>
        public override void WriteStartDocument()
        {
            if (Disposed) { throw new ObjectDisposedException("BsonBinaryWriter"); }
            if (State != BsonWriterState.Initial && State != BsonWriterState.Value && State != BsonWriterState.ScopeDocument && State != BsonWriterState.Done)
            {
                ThrowInvalidState("WriteStartDocument", BsonWriterState.Initial, BsonWriterState.Value, BsonWriterState.ScopeDocument, BsonWriterState.Done);
            }

            if (State == BsonWriterState.Value)
            {
                _buffer.WriteByte((byte)BsonType.Document);
                WriteNameHelper();
            }
            var contextType = (State == BsonWriterState.ScopeDocument) ? ContextType.ScopeDocument : ContextType.Document;
            _context = new BsonBinaryWriterContext(_context, ContextType.Document, _buffer.Position);
            _buffer.WriteInt32(0); // reserve space for size

            State = BsonWriterState.Name;
        }
        /// <summary>
        /// Writes the start of a BSON array to the writer.
        /// </summary>
        public override void WriteStartArray()
        {
            if (Disposed) { throw new ObjectDisposedException("BsonBinaryWriter"); }
            if (State != BsonWriterState.Value)
            {
                ThrowInvalidState("WriteStartArray", BsonWriterState.Value);
            }

            _buffer.WriteByte((byte)BsonType.Array);
            WriteNameHelper();
            _context = new BsonBinaryWriterContext(_context, ContextType.Array, _buffer.Position);
            _buffer.WriteInt32(0); // reserve space for size

            State = BsonWriterState.Value;
        }
        /// <summary>
        /// Writes a BSON JavaScript to the writer (call WriteStartDocument to start writing the scope).
        /// </summary>
        /// <param name="code">The JavaScript code.</param>
        public override void WriteJavaScriptWithScope(
            string code
        ) {
            if (disposed) { throw new ObjectDisposedException("BsonBinaryWriter"); }
            if (state != BsonWriterState.Value) {
                var message = string.Format("WriteJavaScriptWithScope cannot be called when State is: {0}", state);
                throw new InvalidOperationException(message);
            }

            buffer.WriteByte((byte) BsonType.JavaScriptWithScope);
            WriteNameHelper();
            context = new BsonBinaryWriterContext(context, ContextType.JavaScriptWithScope, buffer.Position);
            buffer.WriteInt32(0); // reserve space for size of JavaScript with scope value
            buffer.WriteString(code);

            state = BsonWriterState.ScopeDocument;
        }
        /// <summary>
        /// Writes a BSON JavaScript to the writer (call WriteStartDocument to start writing the scope).
        /// </summary>
        /// <param name="code">The JavaScript code.</param>
        public override void WriteJavaScriptWithScope(string code)
        {
            if (Disposed) { throw new ObjectDisposedException("BsonBinaryWriter"); }
            if (State != BsonWriterState.Value)
            {
                ThrowInvalidState("WriteJavaScriptWithScope", BsonWriterState.Value);
            }

            _buffer.WriteByte((byte)BsonType.JavaScriptWithScope);
            WriteNameHelper();
            _context = new BsonBinaryWriterContext(_context, ContextType.JavaScriptWithScope, _buffer.Position);
            _buffer.WriteInt32(0); // reserve space for size of JavaScript with scope value
            _buffer.WriteString(code);

            State = BsonWriterState.ScopeDocument;
        }
        /// <summary>
        /// Writes the end of a BSON document to the writer.
        /// </summary>
        public override void WriteEndDocument() {
            if (disposed) { throw new ObjectDisposedException("BsonBinaryWriter"); }
            if (state != BsonWriterState.Name || (context.ContextType != ContextType.Document && context.ContextType != ContextType.ScopeDocument)) {
                var message = string.Format("WriteEndDocument cannot be called when State is: {0}", state);
                throw new InvalidOperationException(message);
            }

            buffer.WriteByte(0);
            BackpatchSize(); // size of document

            context = context.ParentContext;
            if (context == null) {
                state = BsonWriterState.Done;
            } else {
                if (context.ContextType == ContextType.JavaScriptWithScope) {
                    BackpatchSize(); // size of the JavaScript with scope value
                    context = context.ParentContext;
                }
                state = GetNextState();
            }
        }
        /// <summary>
        /// Writes the end of a BSON document to the writer.
        /// </summary>
        public override void WriteEndDocument()
        {
            if (Disposed) { throw new ObjectDisposedException("BsonBinaryWriter"); }
            if (State != BsonWriterState.Name)
            {
                ThrowInvalidState("WriteEndDocument", BsonWriterState.Name);
            }
            if (_context.ContextType != ContextType.Document && _context.ContextType != ContextType.ScopeDocument)
            {
                ThrowInvalidContextType("WriteEndDocument", _context.ContextType, ContextType.Document, ContextType.ScopeDocument);
            }

            _buffer.WriteByte(0);
            BackpatchSize(); // size of document

            _context = _context.ParentContext;
            if (_context == null)
            {
                State = BsonWriterState.Done;
            }
            else
            {
                if (_context.ContextType == ContextType.JavaScriptWithScope)
                {
                    BackpatchSize(); // size of the JavaScript with scope value
                    _context = _context.ParentContext;
                }
                State = GetNextState();
            }
        }
        /// <summary>
        /// Writes a raw BSON document.
        /// </summary>
        /// <param name="slice">The byte buffer containing the raw BSON document.</param>
        public override void WriteRawBsonDocument(IByteBuffer slice)
        {
            if (Disposed) { throw new ObjectDisposedException("BsonBinaryWriter"); }
            if (State != BsonWriterState.Initial && State != BsonWriterState.Value && State != BsonWriterState.ScopeDocument && State != BsonWriterState.Done)
            {
                ThrowInvalidState("WriteRawBsonDocument", BsonWriterState.Initial, BsonWriterState.Value, BsonWriterState.ScopeDocument, BsonWriterState.Done);
            }

            if (State == BsonWriterState.Value)
            {
                _buffer.WriteByte((byte)BsonType.Document);
                WriteNameHelper();
            }
            _buffer.ByteBuffer.WriteBytes(slice); // assumes byteBuffer is a valid raw BSON document

            if (_context == null)
            {
                State = BsonWriterState.Done;
            }
            else
            {
                if (_context.ContextType == ContextType.JavaScriptWithScope)
                {
                    BackpatchSize(); // size of the JavaScript with scope value
                    _context = _context.ParentContext;
                }
                State = GetNextState();
            }
        }