internal BsonBinaryWriterContext(
     BsonBinaryWriterContext parentContext,
     BsonWriteState writeState
 )
 {
     this.parentContext = parentContext;
     this.writeState = writeState;
 }
 internal BsonJsonWriterContext(
     BsonJsonWriterContext parentContext,
     BsonWriteState writeState,
     string indentation
 )
 {
     this.parentContext = parentContext;
     this.writeState = writeState;
     this.indentation = indentation;
 }
 public BsonJsonWriter(
     TextWriter writer,
     BsonJsonWriterSettings settings
 )
 {
     this.textWriter = writer;
     this.settings = settings;
     context = new BsonJsonWriterContext(null, ContextType.TopLevel, "");
     state = BsonWriteState.Initial;
 }
 public BsonJsonWriter(
     TextWriter writer,
     BsonJsonWriterSettings settings
 )
 {
     this.textWriter = writer;
     this.settings = settings;
     context = null;
     state = BsonWriteState.Initial;
 }
 public override void Close()
 {
     // Close can be called on Disposed objects
     if (state != BsonWriteState.Closed) {
         Flush();
         if (settings.CloseOutput) {
             textWriter.Close();
         }
         context = null;
         state = BsonWriteState.Closed;
     }
 }
 public override void Close() {
     // Close can be called on Disposed objects
     if (state != BsonWriteState.Closed) {
         if (state == BsonWriteState.Done) {
             Flush();
         }
         if (stream != null && settings.CloseOutput) {
             stream.Close();
         }
         context = null;
         state = BsonWriteState.Closed;
     }
 }
        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;

            context = null;
            state = BsonWriteState.Initial;
        }
        public override void WriteObjectId(
            int timestamp,
            int machine,
            short pid,
            int increment
        )
        {
            if (disposed) { throw new ObjectDisposedException("BsonJsonWriter"); }
            if (state != BsonWriteState.Value && state != BsonWriteState.Initial) {
                var message = string.Format("WriteObjectId cannot be called when WriterState is: {0}", state);
                throw new InvalidOperationException(message);
            }

            var bytes = ObjectId.Pack(timestamp, machine, pid, increment);
            switch (settings.OutputMode) {
                case BsonJsonOutputMode.Strict:
                case BsonJsonOutputMode.JavaScript:
                    WriteStartDocument();
                    WriteString("$oid", BsonUtils.ToHexString(bytes));
                    WriteEndDocument();
                    break;
                case BsonJsonOutputMode.TenGen:
                    WriteNameHelper(name);
                    textWriter.Write(string.Format("ObjectId(\"{0}\")", BsonUtils.ToHexString(bytes)));
                    break;
            }

            state = GetNextState();
        }
        public override void WriteName(
            string name
        )
        {
            if (disposed) { throw new ObjectDisposedException("BsonJsonWriter"); }
            if (state != BsonWriteState.Name) {
                var message = string.Format("WriteMinKey cannot be called when WriterState is: {0}", state);
                throw new InvalidOperationException(message);
            }

            this.name = name;
            state = BsonWriteState.Value;
        }
        public override void WriteJavaScriptWithScope(
            string code
        )
        {
            if (disposed) { throw new ObjectDisposedException("BsonJsonWriter"); }
            if (state != BsonWriteState.Value && state != BsonWriteState.Initial) {
                var message = string.Format("WriteJavaScriptWithScope cannot be called when WriterState is: {0}", state);
                throw new InvalidOperationException(message);
            }

            WriteStartDocument();
            WriteString("$code", code);
            WriteName("$scope");

            state = BsonWriteState.ScopeDocument;
        }
        public override void WriteEndDocument()
        {
            if (disposed) { throw new ObjectDisposedException("BsonJsonWriter"); }
            if (state != BsonWriteState.Name) {
                var message = string.Format("WriteDateTime cannot be called when WriterState is: {0}", state);
                throw new InvalidOperationException(message);
            }

            if (settings.Indent && context.HasElements) {
                textWriter.Write(settings.NewLineChars);
                if (context.ParentContext != null) {
                    textWriter.Write(context.ParentContext.Indentation);
                }
                textWriter.Write("}");
            } else {
                textWriter.Write(" }");
            }

            if (context.ContextType == ContextType.ScopeDocument) {
                context = context.ParentContext;
                WriteEndDocument();
            } else {
                context = context.ParentContext;
            }

            if (context == null) {
                state = BsonWriteState.Done;
            } else {
                state = GetNextState();
            }
        }
        public override void WriteEndArray()
        {
            if (disposed) { throw new ObjectDisposedException("BsonJsonWriter"); }
            if (state != BsonWriteState.Value) {
                var message = string.Format("WriteEndArray cannot be called when WriterState is: {0}", state);
                throw new InvalidOperationException(message);
            }

            textWriter.Write("]");

            context = context.ParentContext;
            state = GetNextState();
        }
        public override void WriteEndDocument() {
            if (disposed) { throw new ObjectDisposedException("BsonBinaryWriter"); }
            if (state != BsonWriteState.Name || (context.ContextType != ContextType.Document && context.ContextType != ContextType.ScopeDocument)) {
                var message = string.Format("WriteEndDocument cannot be called when WriterState is: {0}", state);
                throw new InvalidOperationException(message);
            }

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

            context = context.ParentContext;
            if (context == null) {
                state = BsonWriteState.Done;
            } else {
                if (context.ContextType == ContextType.JavaScriptWithScope) {
                    BackpatchSize(); // size of the JavaScript with scope value
                    context = context.ParentContext;
                }
                state = GetNextState();
            }
        }
        public override void WriteJavaScript(
            string code
        ) {
            if (disposed) { throw new ObjectDisposedException("BsonBinaryWriter"); }
            if (state != BsonWriteState.Value) {
                var message = string.Format("WriteJavaScript cannot be called when WriterState is: {0}", state);
                throw new InvalidOperationException(message);
            }

            buffer.WriteByte((byte) BsonType.JavaScript);
            WriteNameHelper();
            buffer.WriteString(code);

            state = GetNextState();
        }
        public override void WriteString(
            string value
        )
        {
            if (disposed) { throw new ObjectDisposedException("BsonJsonWriter"); }
            if (state != BsonWriteState.Value && state != BsonWriteState.Initial) {
                var message = string.Format("WriteString cannot be called when WriterState is: {0}", state);
                throw new InvalidOperationException(message);
            }

            WriteNameHelper(name);
            WriteStringHelper(value);

            state = GetNextState();
        }
        public override void WriteJavaScriptWithScope(
            string code
        ) {
            if (disposed) { throw new ObjectDisposedException("BsonBinaryWriter"); }
            if (state != BsonWriteState.Value) {
                var message = string.Format("WriteJavaScriptWithScope cannot be called when WriterState 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 = BsonWriteState.ScopeDocument;
        }
        public override void WriteRegularExpression(
            string pattern,
            string options
        )
        {
            if (disposed) { throw new ObjectDisposedException("BsonJsonWriter"); }
            if (state != BsonWriteState.Value && state != BsonWriteState.Initial) {
                var message = string.Format("WriteRegularExpression cannot be called when WriterState is: {0}", state);
                throw new InvalidOperationException(message);
            }

            switch (settings.OutputMode) {
                case BsonJsonOutputMode.Strict:
                    WriteStartDocument();
                    WriteString("$regex", pattern);
                    WriteString("$options", options);
                    WriteEndDocument();
                    break;
                case BsonJsonOutputMode.JavaScript:
                case BsonJsonOutputMode.TenGen:
                    WriteNameHelper(name);
                    textWriter.Write("/");
                    textWriter.Write(pattern.Replace(@"\", @"\\"));
                    textWriter.Write("/");
                    foreach (char c in options.ToLower()) {
                        switch (c) {
                            case 'g':
                            case 'i':
                            case 'm':
                                textWriter.Write(c);
                                break;
                        }
                    }
                    break;
            }

            state = GetNextState();
        }
        public override void WriteTimestamp(
            long value
        ) {
            if (disposed) { throw new ObjectDisposedException("BsonBinaryWriter"); }
            if (state != BsonWriteState.Value) {
                var message = string.Format("WriteSymbol cannot be called when WriterState is: {0}", state);
                throw new InvalidOperationException(message);
            }

            buffer.WriteByte((byte) BsonType.Timestamp);
            WriteNameHelper();
            buffer.WriteInt64(value);

            state = GetNextState();
        }
        public override void WriteStartDocument() {
            if (disposed) { throw new ObjectDisposedException("BsonBinaryWriter"); }
            if (state != BsonWriteState.Initial && state != BsonWriteState.Value && state != BsonWriteState.ScopeDocument && state != BsonWriteState.Done) {
                var message = string.Format("WriteStartDocument cannot be called when WriterState is: {0}", state);
                throw new InvalidOperationException(message);
            }

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

            state = BsonWriteState.Name;
        }
        public override void WriteStartArray() {
            if (disposed) { throw new ObjectDisposedException("BsonBinaryWriter"); }
            if (state != BsonWriteState.Value) {
                var message = string.Format("WriteStartArray cannot be called when WriterState 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 = BsonWriteState.Value;
        }
        public override void WriteRegularExpression(
            string pattern,
            string options
        ) {
            if (disposed) { throw new ObjectDisposedException("BsonBinaryWriter"); }
            if (state != BsonWriteState.Value) {
                var message = string.Format("WriteRegularExpression cannot be called when WriterState is: {0}", state);
                throw new InvalidOperationException(message);
            }

            buffer.WriteByte((byte) BsonType.RegularExpression);
            WriteNameHelper();
            buffer.WriteCString(pattern);
            buffer.WriteCString(options);

            state = GetNextState();
        }
        public override void WriteObjectId(
            int timestamp,
            int machine,
            short pid,
            int increment
        ) {
            if (disposed) { throw new ObjectDisposedException("BsonBinaryWriter"); }
            if (state != BsonWriteState.Value) {
                var message = string.Format("WriteObjectId cannot be called when WriterState is: {0}", state);
                throw new InvalidOperationException(message);
            }

            buffer.WriteByte((byte) BsonType.ObjectId);
            WriteNameHelper();
            buffer.WriteObjectId(timestamp, machine, pid, increment);

            state = GetNextState();
        }
        public override void WriteStartArray()
        {
            if (disposed) { throw new ObjectDisposedException("BsonJsonWriter"); }
            if (state != BsonWriteState.Value && state != BsonWriteState.Initial) {
                var message = string.Format("WriteStartArray cannot be called when WriterState is: {0}", state);
                throw new InvalidOperationException(message);
            }

            WriteNameHelper(name);
            textWriter.Write("[");

            context = new BsonJsonWriterContext(context, ContextType.Array, settings.IndentChars);
            state = BsonWriteState.Value;
        }
        #pragma warning disable 618 // about obsolete BsonBinarySubType.OldBinary
        public override void WriteBinaryData(
            byte[] bytes,
            BsonBinarySubType subType
        ) {
            if (disposed) { throw new ObjectDisposedException("BsonBinaryWriter"); }
            if (state != BsonWriteState.Value) {
                var message = string.Format("WriteBinaryData cannot be called when WriterState is: {0}", state);
                throw new InvalidOperationException(message);
            }

            buffer.WriteByte((byte) BsonType.Binary);
            WriteNameHelper();
            if (subType == BsonBinarySubType.OldBinary && settings.FixOldBinarySubTypeOnOutput) {
                subType = BsonBinarySubType.Binary; // replace obsolete OldBinary with new Binary sub type
            }
            if (subType == BsonBinarySubType.OldBinary) {
                // sub type OldBinary has two sizes (for historical reasons)
                buffer.WriteInt32(bytes.Length + 4);
                buffer.WriteByte((byte) subType);
                buffer.WriteInt32(bytes.Length);
            } else {
                buffer.WriteInt32(bytes.Length);
                buffer.WriteByte((byte) subType);
            }
            buffer.WriteBytes(bytes);

            state = GetNextState();
        }
        public override void WriteStartDocument()
        {
            if (disposed) { throw new ObjectDisposedException("BsonJsonWriter"); }
            if (state != BsonWriteState.Value && state != BsonWriteState.Initial && state != BsonWriteState.ScopeDocument) {
                var message = string.Format("WriteStartDocument cannot be called when WriterState is: {0}", state);
                throw new InvalidOperationException(message);
            }

            if (state == BsonWriteState.Value || state == BsonWriteState.ScopeDocument) {
                WriteNameHelper(name);
            }
            textWriter.Write("{");

            var contextType = (state == BsonWriteState.ScopeDocument) ? ContextType.ScopeDocument : ContextType.Document;
            context = new BsonJsonWriterContext(context, contextType, settings.IndentChars);
            state = BsonWriteState.Name;
        }
 private void WriteDocumentName(
     string name,
     BsonWriteState documentType
 )
 {
     WriteName(name);
     context = new BsonJsonWriterContext(context, documentType, context.Indentation + settings.IndentChars);
     context = new BsonJsonWriterContext(context, BsonWriteState.StartDocument, null);
 }
        public override void WriteTimestamp(
            long value
        )
        {
            if (disposed) { throw new ObjectDisposedException("BsonJsonWriter"); }
            if (state != BsonWriteState.Value && state != BsonWriteState.Initial) {
                var message = string.Format("WriteTimestamp cannot be called when WriterState is: {0}", state);
                throw new InvalidOperationException(message);
            }

            WriteStartDocument();
            WriteInt64("$timestamp", value);
            WriteEndDocument();

            state = GetNextState();
        }
        public override void WriteDateTime(
            DateTime value
        )
        {
            if (disposed) { throw new ObjectDisposedException("BsonJsonWriter"); }
            if (state != BsonWriteState.Value && state != BsonWriteState.Initial) {
                var message = string.Format("WriteDateTime cannot be called when WriterState is: {0}", state);
                throw new InvalidOperationException(message);
            }

            if (value.Kind != DateTimeKind.Utc) {
                throw new ArgumentException("DateTime value must be in UTC");
            }

            long milliseconds = (long) Math.Floor((value.ToUniversalTime() - BsonConstants.UnixEpoch).TotalMilliseconds);
            switch (settings.OutputMode) {
                case BsonJsonOutputMode.Strict:
                    WriteStartDocument();
                    WriteInt64("$date", milliseconds);
                    WriteEndDocument();
                    break;
                case BsonJsonOutputMode.JavaScript:
                case BsonJsonOutputMode.TenGen:
                    WriteNameHelper(name);
                    textWriter.Write("Date({0})", milliseconds);
                    break;
                default:
                    throw new BsonInternalException("Unexpected BsonJsonOutputMode");
            }

            state = GetNextState();
        }
        public override void WriteBinaryData(
            byte[] bytes,
            BsonBinarySubType subType
        )
        {
            if (disposed) { throw new ObjectDisposedException("BsonJsonWriter"); }
            if (state != BsonWriteState.Value && state != BsonWriteState.Initial) {
                var message = string.Format("WriteBinaryData cannot be called when WriterState is: {0}", state);
                throw new InvalidOperationException(message);
            }

            WriteStartDocument();
            WriteString("$binary", Convert.ToBase64String(bytes));
            WriteString("$type", ((int) subType).ToString("x2"));
            WriteEndDocument();

            state = GetNextState();
        }
        public override void WriteEndArray() {
            if (disposed) { throw new ObjectDisposedException("BsonBinaryWriter"); }
            if (state != BsonWriteState.Value || context.ContextType != ContextType.Array) {
                var message = string.Format("WriteEndArray cannot be called when WriterState is: {0}", state);
                throw new InvalidOperationException(message);
            }

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

            context = context.ParentContext;
            state = GetNextState();
        }