| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855 |
- /* Copyright 2010-2014 MongoDB Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- using System;
- using System.Globalization;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Text.RegularExpressions;
- namespace MongoDB.Bson.IO
- {
- /// <summary>
- /// Represents a BSON writer to a TextWriter (in JSON format).
- /// </summary>
- public class JsonWriter : BsonWriter
- {
- // private fields
- private TextWriter _textWriter;
- private JsonWriterSettings _jsonWriterSettings; // same value as in base class just declared as derived class
- private JsonWriterContext _context;
- // constructors
- /// <summary>
- /// Initializes a new instance of the JsonWriter class.
- /// </summary>
- /// <param name="writer">A TextWriter.</param>
- /// <param name="settings">Optional JsonWriter settings.</param>
- public JsonWriter(TextWriter writer, JsonWriterSettings settings)
- : base(settings)
- {
- if (writer == null)
- {
- throw new ArgumentNullException("writer");
- }
- _textWriter = writer;
- _jsonWriterSettings = settings; // already frozen by base class
- _context = new JsonWriterContext(null, ContextType.TopLevel, "");
- State = BsonWriterState.Initial;
- }
- // public methods
- /// <summary>
- /// Closes the writer.
- /// </summary>
- public override void Close()
- {
- // Close can be called on Disposed objects
- if (State != BsonWriterState.Closed)
- {
- Flush();
- if (_jsonWriterSettings.CloseOutput)
- {
- _textWriter.Close();
- }
- _context = null;
- State = BsonWriterState.Closed;
- }
- }
- /// <summary>
- /// Flushes any pending data to the output destination.
- /// </summary>
- public override void Flush()
- {
- if (Disposed) { throw new ObjectDisposedException("JsonWriter"); }
- _textWriter.Flush();
- }
- /// <summary>
- /// Writes BSON binary data to the writer.
- /// </summary>
- /// <param name="binaryData">The binary data.</param>
- public override void WriteBinaryData(BsonBinaryData binaryData)
- {
- if (Disposed) { throw new ObjectDisposedException("JsonWriter"); }
- if (State != BsonWriterState.Value && State != BsonWriterState.Initial)
- {
- ThrowInvalidState("WriteBinaryData", BsonWriterState.Value, BsonWriterState.Initial);
- }
- var subType = binaryData.SubType;
- var bytes = binaryData.Bytes;
- var guidRepresentation = binaryData.GuidRepresentation;
- WriteNameHelper(Name);
- switch (_jsonWriterSettings.OutputMode)
- {
- case JsonOutputMode.Strict:
- _textWriter.Write("{{ \"$binary\" : \"{0}\", \"$type\" : \"{1}\" }}", Convert.ToBase64String(bytes), ((int)subType).ToString("x2"));
- break;
- case JsonOutputMode.Shell:
- default:
- switch (subType)
- {
- case BsonBinarySubType.UuidLegacy:
- case BsonBinarySubType.UuidStandard:
- _textWriter.Write(GuidToString(subType, bytes, guidRepresentation));
- break;
- default:
- _textWriter.Write("new BinData({0}, \"{1}\")", (int)subType, Convert.ToBase64String(bytes));
- break;
- }
- break;
- }
- State = GetNextState();
- }
- /// <summary>
- /// Writes a BSON Boolean to the writer.
- /// </summary>
- /// <param name="value">The Boolean value.</param>
- public override void WriteBoolean(bool value)
- {
- if (Disposed) { throw new ObjectDisposedException("JsonWriter"); }
- if (State != BsonWriterState.Value && State != BsonWriterState.Initial)
- {
- ThrowInvalidState("WriteBoolean", BsonWriterState.Value, BsonWriterState.Initial);
- }
- WriteNameHelper(Name);
- _textWriter.Write(value ? "true" : "false");
- State = GetNextState();
- }
- /// <summary>
- /// Writes BSON binary data to the writer.
- /// </summary>
- /// <param name="bytes">The bytes.</param>
- public override void WriteBytes(byte[] bytes)
- {
- WriteBinaryData(new BsonBinaryData(bytes, BsonBinarySubType.Binary));
- }
- /// <summary>
- /// Writes a BSON DateTime to the writer.
- /// </summary>
- /// <param name="value">The number of milliseconds since the Unix epoch.</param>
- public override void WriteDateTime(long value)
- {
- if (Disposed) { throw new ObjectDisposedException("JsonWriter"); }
- if (State != BsonWriterState.Value && State != BsonWriterState.Initial)
- {
- ThrowInvalidState("WriteDateTime", BsonWriterState.Value, BsonWriterState.Initial);
- }
- WriteNameHelper(Name);
- switch (_jsonWriterSettings.OutputMode)
- {
- case JsonOutputMode.Strict:
- _textWriter.Write("{{ \"$date\" : {0} }}", value);
- break;
- case JsonOutputMode.Shell:
- default:
- // use ISODate for values that fall within .NET's DateTime range, and "new Date" for all others
- if (value >= BsonConstants.DateTimeMinValueMillisecondsSinceEpoch &&
- value <= BsonConstants.DateTimeMaxValueMillisecondsSinceEpoch)
- {
- var utcDateTime = BsonUtils.ToDateTimeFromMillisecondsSinceEpoch(value);
- _textWriter.Write("ISODate(\"{0}\")", utcDateTime.ToString("yyyy-MM-ddTHH:mm:ss.FFFZ"));
- }
- else
- {
- _textWriter.Write("new Date({0})", value);
- }
- break;
- }
- State = GetNextState();
- }
- /// <summary>
- /// Writes a BSON Double to the writer.
- /// </summary>
- /// <param name="value">The Double value.</param>
- public override void WriteDouble(double value)
- {
- if (Disposed) { throw new ObjectDisposedException("JsonWriter"); }
- if (State != BsonWriterState.Value && State != BsonWriterState.Initial)
- {
- ThrowInvalidState("WriteDouble", BsonWriterState.Value, BsonWriterState.Initial);
- }
- // if string representation looks like an integer add ".0" so that it looks like a double
- var stringRepresentation = value.ToString("R", NumberFormatInfo.InvariantInfo);
- if (Regex.IsMatch(stringRepresentation, @"^[+-]?\d+$"))
- {
- stringRepresentation += ".0";
- }
- WriteNameHelper(Name);
- _textWriter.Write(stringRepresentation);
- State = GetNextState();
- }
- /// <summary>
- /// Writes the end of a BSON array to the writer.
- /// </summary>
- public override void WriteEndArray()
- {
- if (Disposed) { throw new ObjectDisposedException("JsonWriter"); }
- if (State != BsonWriterState.Value)
- {
- ThrowInvalidState("WriteEndArray", BsonWriterState.Value);
- }
- base.WriteEndArray();
- _textWriter.Write("]");
- _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("JsonWriter"); }
- if (State != BsonWriterState.Name)
- {
- ThrowInvalidState("WriteEndDocument", BsonWriterState.Name);
- }
- base.WriteEndDocument();
- if (_jsonWriterSettings.Indent && _context.HasElements)
- {
- _textWriter.Write(_jsonWriterSettings.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 = BsonWriterState.Done;
- }
- else
- {
- State = GetNextState();
- }
- }
- /// <summary>
- /// Writes a BSON Int32 to the writer.
- /// </summary>
- /// <param name="value">The Int32 value.</param>
- public override void WriteInt32(int value)
- {
- if (Disposed) { throw new ObjectDisposedException("JsonWriter"); }
- if (State != BsonWriterState.Value && State != BsonWriterState.Initial)
- {
- ThrowInvalidState("WriteInt32", BsonWriterState.Value, BsonWriterState.Initial);
- }
- WriteNameHelper(Name);
- _textWriter.Write(value);
- State = GetNextState();
- }
- /// <summary>
- /// Writes a BSON Int64 to the writer.
- /// </summary>
- /// <param name="value">The Int64 value.</param>
- public override void WriteInt64(long value)
- {
- if (Disposed) { throw new ObjectDisposedException("JsonWriter"); }
- if (State != BsonWriterState.Value && State != BsonWriterState.Initial)
- {
- ThrowInvalidState("WriteInt64", BsonWriterState.Value, BsonWriterState.Initial);
- }
- WriteNameHelper(Name);
- switch (_jsonWriterSettings.OutputMode)
- {
- case JsonOutputMode.Strict:
- _textWriter.Write(value);
- break;
- case JsonOutputMode.Shell:
- default:
- if (value >= int.MinValue && value <= int.MaxValue)
- {
- _textWriter.Write("NumberLong({0})", value);
- }
- else
- {
- _textWriter.Write("NumberLong(\"{0}\")", value);
- }
- break;
- }
- State = GetNextState();
- }
- /// <summary>
- /// Writes a BSON JavaScript to the writer.
- /// </summary>
- /// <param name="code">The JavaScript code.</param>
- public override void WriteJavaScript(string code)
- {
- if (Disposed) { throw new ObjectDisposedException("JsonWriter"); }
- if (State != BsonWriterState.Value && State != BsonWriterState.Initial)
- {
- ThrowInvalidState("WriteJavaScript", BsonWriterState.Value, BsonWriterState.Initial);
- }
- WriteNameHelper(Name);
- _textWriter.Write("{{ \"$code\" : \"{0}\" }}", EscapedString(code));
- 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("JsonWriter"); }
- if (State != BsonWriterState.Value && State != BsonWriterState.Initial)
- {
- ThrowInvalidState("WriteJavaScriptWithScope", BsonWriterState.Value, BsonWriterState.Initial);
- }
- WriteStartDocument();
- WriteString("$code", code);
- WriteName("$scope");
- State = BsonWriterState.ScopeDocument;
- }
- /// <summary>
- /// Writes a BSON MaxKey to the writer.
- /// </summary>
- public override void WriteMaxKey()
- {
- if (Disposed) { throw new ObjectDisposedException("JsonWriter"); }
- if (State != BsonWriterState.Value && State != BsonWriterState.Initial)
- {
- ThrowInvalidState("WriteMaxKey", BsonWriterState.Value, BsonWriterState.Initial);
- }
- WriteNameHelper(Name);
- switch (_jsonWriterSettings.OutputMode)
- {
- case JsonOutputMode.Strict:
- _textWriter.Write("{ \"$maxKey\" : 1 }");
- break;
- case JsonOutputMode.Shell:
- default:
- _textWriter.Write("MaxKey");
- break;
- }
- State = GetNextState();
- }
- /// <summary>
- /// Writes a BSON MinKey to the writer.
- /// </summary>
- public override void WriteMinKey()
- {
- if (Disposed) { throw new ObjectDisposedException("JsonWriter"); }
- if (State != BsonWriterState.Value && State != BsonWriterState.Initial)
- {
- ThrowInvalidState("WriteMinKey", BsonWriterState.Value, BsonWriterState.Initial);
- }
- WriteNameHelper(Name);
- switch (_jsonWriterSettings.OutputMode)
- {
- case JsonOutputMode.Strict:
- _textWriter.Write("{ \"$minKey\" : 1 }");
- break;
- case JsonOutputMode.Shell:
- default:
- _textWriter.Write("MinKey");
- break;
- }
- State = GetNextState();
- }
- /// <summary>
- /// Writes a BSON null to the writer.
- /// </summary>
- public override void WriteNull()
- {
- if (Disposed) { throw new ObjectDisposedException("JsonWriter"); }
- if (State != BsonWriterState.Value && State != BsonWriterState.Initial)
- {
- ThrowInvalidState("WriteNull", BsonWriterState.Value, BsonWriterState.Initial);
- }
- WriteNameHelper(Name);
- _textWriter.Write("null");
- State = GetNextState();
- }
- /// <summary>
- /// Writes a BSON ObjectId to the writer.
- /// </summary>
- /// <param name="objectId">The ObjectId.</param>
- public override void WriteObjectId(ObjectId objectId)
- {
- if (Disposed) { throw new ObjectDisposedException("JsonWriter"); }
- if (State != BsonWriterState.Value && State != BsonWriterState.Initial)
- {
- ThrowInvalidState("WriteObjectId", BsonWriterState.Value, BsonWriterState.Initial);
- }
- var bytes = ObjectId.Pack(objectId.Timestamp, objectId.Machine, objectId.Pid, objectId.Increment);
- WriteNameHelper(Name);
- switch (_jsonWriterSettings.OutputMode)
- {
- case JsonOutputMode.Strict:
- _textWriter.Write("{{ \"$oid\" : \"{0}\" }}", BsonUtils.ToHexString(bytes));
- break;
- case JsonOutputMode.Shell:
- default:
- _textWriter.Write("ObjectId(\"{0}\")", BsonUtils.ToHexString(bytes));
- break;
- }
- State = GetNextState();
- }
- /// <summary>
- /// Writes a BSON regular expression to the writer.
- /// </summary>
- /// <param name="regex">A BsonRegularExpression.</param>
- public override void WriteRegularExpression(BsonRegularExpression regex)
- {
- if (Disposed) { throw new ObjectDisposedException("JsonWriter"); }
- if (State != BsonWriterState.Value && State != BsonWriterState.Initial)
- {
- ThrowInvalidState("WriteRegularExpression", BsonWriterState.Value, BsonWriterState.Initial);
- }
- var pattern = regex.Pattern;
- var options = regex.Options;
- WriteNameHelper(Name);
- switch (_jsonWriterSettings.OutputMode)
- {
- case JsonOutputMode.Strict:
- _textWriter.Write("{{ \"$regex\" : \"{0}\", \"$options\" : \"{1}\" }}", EscapedString(pattern), EscapedString(options));
- break;
- case JsonOutputMode.Shell:
- default:
- var escapedPattern = (pattern == "") ? "(?:)" : pattern.Replace("/", @"\/");
- _textWriter.Write("/{0}/{1}", escapedPattern, options);
- break;
- }
- State = GetNextState();
- }
- /// <summary>
- /// Writes the start of a BSON array to the writer.
- /// </summary>
- public override void WriteStartArray()
- {
- if (Disposed) { throw new ObjectDisposedException("JsonWriter"); }
- if (State != BsonWriterState.Value && State != BsonWriterState.Initial)
- {
- ThrowInvalidState("WriteStartArray", BsonWriterState.Value, BsonWriterState.Initial);
- }
- base.WriteStartArray();
- WriteNameHelper(Name);
- _textWriter.Write("[");
- _context = new JsonWriterContext(_context, ContextType.Array, _jsonWriterSettings.IndentChars);
- State = BsonWriterState.Value;
- }
- /// <summary>
- /// Writes the start of a BSON document to the writer.
- /// </summary>
- public override void WriteStartDocument()
- {
- if (Disposed) { throw new ObjectDisposedException("JsonWriter"); }
- if (State != BsonWriterState.Value && State != BsonWriterState.Initial && State != BsonWriterState.ScopeDocument)
- {
- ThrowInvalidState("WriteStartDocument", BsonWriterState.Value, BsonWriterState.Initial, BsonWriterState.ScopeDocument);
- }
- base.WriteStartDocument();
- if (State == BsonWriterState.Value || State == BsonWriterState.ScopeDocument)
- {
- WriteNameHelper(Name);
- }
- _textWriter.Write("{");
- var contextType = (State == BsonWriterState.ScopeDocument) ? ContextType.ScopeDocument : ContextType.Document;
- _context = new JsonWriterContext(_context, contextType, _jsonWriterSettings.IndentChars);
- State = BsonWriterState.Name;
- }
- /// <summary>
- /// Writes a BSON String to the writer.
- /// </summary>
- /// <param name="value">The String value.</param>
- public override void WriteString(string value)
- {
- if (Disposed) { throw new ObjectDisposedException("JsonWriter"); }
- if (State != BsonWriterState.Value && State != BsonWriterState.Initial)
- {
- ThrowInvalidState("WriteString", BsonWriterState.Value, BsonWriterState.Initial);
- }
- WriteNameHelper(Name);
- WriteQuotedString(value);
- State = GetNextState();
- }
- /// <summary>
- /// Writes a BSON Symbol to the writer.
- /// </summary>
- /// <param name="value">The symbol.</param>
- public override void WriteSymbol(string value)
- {
- if (Disposed) { throw new ObjectDisposedException("JsonWriter"); }
- if (State != BsonWriterState.Value && State != BsonWriterState.Initial)
- {
- ThrowInvalidState("WriteSymbol", BsonWriterState.Value, BsonWriterState.Initial);
- }
- WriteNameHelper(Name);
- _textWriter.Write("{{ \"$symbol\" : \"{0}\" }}", EscapedString(value));
- State = GetNextState();
- }
- /// <summary>
- /// Writes a BSON timestamp to the writer.
- /// </summary>
- /// <param name="value">The combined timestamp/increment value.</param>
- public override void WriteTimestamp(long value)
- {
- if (Disposed) { throw new ObjectDisposedException("JsonWriter"); }
- if (State != BsonWriterState.Value && State != BsonWriterState.Initial)
- {
- ThrowInvalidState("WriteTimestamp", BsonWriterState.Value, BsonWriterState.Initial);
- }
- var secondsSinceEpoch = (int)((value >> 32) & 0xffffffff);
- var increment = (int)(value & 0xffffffff);
- WriteNameHelper(Name);
- switch (_jsonWriterSettings.OutputMode)
- {
- case JsonOutputMode.Strict:
- _textWriter.Write("{{ \"$timestamp\" : {{ \"t\" : {0}, \"i\" : {1} }} }}", secondsSinceEpoch, increment);
- break;
- case JsonOutputMode.Shell:
- default:
- _textWriter.Write("Timestamp({0}, {1})", secondsSinceEpoch, increment);
- break;
- }
- State = GetNextState();
- }
- /// <summary>
- /// Writes a BSON undefined to the writer.
- /// </summary>
- public override void WriteUndefined()
- {
- if (Disposed) { throw new ObjectDisposedException("JsonWriter"); }
- if (State != BsonWriterState.Value && State != BsonWriterState.Initial)
- {
- ThrowInvalidState("WriteUndefined", BsonWriterState.Value, BsonWriterState.Initial);
- }
- WriteNameHelper(Name);
- switch (_jsonWriterSettings.OutputMode)
- {
- case JsonOutputMode.Strict:
- _textWriter.Write("{ \"$undefined\" : true }");
- break;
- case JsonOutputMode.Shell:
- default:
- _textWriter.Write("undefined");
- break;
- }
- State = GetNextState();
- }
- // protected methods
- /// <summary>
- /// Disposes of any resources used by the writer.
- /// </summary>
- /// <param name="disposing">True if called from Dispose.</param>
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- Close();
- _textWriter.Dispose();
- }
- base.Dispose(disposing);
- }
- // private methods
- private string EscapedString(string value)
- {
- if (value.All(c => !NeedsEscaping(c)))
- {
- return value;
- }
- var sb = new StringBuilder(value.Length);
- foreach (char c in value)
- {
- switch (c)
- {
- case '"': sb.Append("\\\""); break;
- case '\\': sb.Append("\\\\"); break;
- case '\b': sb.Append("\\b"); break;
- case '\f': sb.Append("\\f"); break;
- case '\n': sb.Append("\\n"); break;
- case '\r': sb.Append("\\r"); break;
- case '\t': sb.Append("\\t"); break;
- default:
- switch (char.GetUnicodeCategory(c))
- {
- case UnicodeCategory.UppercaseLetter:
- case UnicodeCategory.LowercaseLetter:
- case UnicodeCategory.TitlecaseLetter:
- case UnicodeCategory.OtherLetter:
- case UnicodeCategory.DecimalDigitNumber:
- case UnicodeCategory.LetterNumber:
- case UnicodeCategory.OtherNumber:
- case UnicodeCategory.SpaceSeparator:
- case UnicodeCategory.ConnectorPunctuation:
- case UnicodeCategory.DashPunctuation:
- case UnicodeCategory.OpenPunctuation:
- case UnicodeCategory.ClosePunctuation:
- case UnicodeCategory.InitialQuotePunctuation:
- case UnicodeCategory.FinalQuotePunctuation:
- case UnicodeCategory.OtherPunctuation:
- case UnicodeCategory.MathSymbol:
- case UnicodeCategory.CurrencySymbol:
- case UnicodeCategory.ModifierSymbol:
- case UnicodeCategory.OtherSymbol:
- sb.Append(c);
- break;
- default:
- sb.AppendFormat("\\u{0:x4}", (int)c);
- break;
- }
- break;
- }
- }
- return sb.ToString();
- }
- private BsonWriterState GetNextState()
- {
- if (_context.ContextType == ContextType.Array)
- {
- return BsonWriterState.Value;
- }
- else
- {
- return BsonWriterState.Name;
- }
- }
- private string GuidToString(BsonBinarySubType subType, byte[] bytes, GuidRepresentation guidRepresentation)
- {
- if (bytes.Length != 16)
- {
- var message = string.Format("Length of binary subtype {0} must be 16, not {1}.", subType, bytes.Length);
- throw new ArgumentException(message);
- }
- if (subType == BsonBinarySubType.UuidLegacy && guidRepresentation == GuidRepresentation.Standard)
- {
- throw new ArgumentException("GuidRepresentation for binary subtype UuidLegacy must not be Standard.");
- }
- if (subType == BsonBinarySubType.UuidStandard && guidRepresentation != GuidRepresentation.Standard)
- {
- var message = string.Format("GuidRepresentation for binary subtype UuidStandard must be Standard, not {0}.", guidRepresentation);
- throw new ArgumentException(message);
- }
- if (guidRepresentation == GuidRepresentation.Unspecified)
- {
- var s = BsonUtils.ToHexString(bytes);
- var parts = new string[]
- {
- s.Substring(0, 8),
- s.Substring(8, 4),
- s.Substring(12, 4),
- s.Substring(16, 4),
- s.Substring(20, 12)
- };
- return string.Format("HexData({0}, \"{1}\")", (int)subType, string.Join("-", parts));
- }
- else
- {
- string uuidConstructorName;
- switch (guidRepresentation)
- {
- case GuidRepresentation.CSharpLegacy: uuidConstructorName = "CSUUID"; break;
- case GuidRepresentation.JavaLegacy: uuidConstructorName = "JUUID"; break;
- case GuidRepresentation.PythonLegacy: uuidConstructorName = "PYUUID"; break;
- case GuidRepresentation.Standard: uuidConstructorName = "UUID"; break;
- default: throw new BsonInternalException("Unexpected GuidRepresentation");
- }
- var guid = GuidConverter.FromBytes(bytes, guidRepresentation);
- return string.Format("{0}(\"{1}\")", uuidConstructorName, guid.ToString());
- }
- }
- private bool NeedsEscaping(char c)
- {
- switch (c)
- {
- case '"':
- case '\\':
- case '\b':
- case '\f':
- case '\n':
- case '\r':
- case '\t':
- return true;
- default:
- switch (char.GetUnicodeCategory(c))
- {
- case UnicodeCategory.UppercaseLetter:
- case UnicodeCategory.LowercaseLetter:
- case UnicodeCategory.TitlecaseLetter:
- case UnicodeCategory.OtherLetter:
- case UnicodeCategory.DecimalDigitNumber:
- case UnicodeCategory.LetterNumber:
- case UnicodeCategory.OtherNumber:
- case UnicodeCategory.SpaceSeparator:
- case UnicodeCategory.ConnectorPunctuation:
- case UnicodeCategory.DashPunctuation:
- case UnicodeCategory.OpenPunctuation:
- case UnicodeCategory.ClosePunctuation:
- case UnicodeCategory.InitialQuotePunctuation:
- case UnicodeCategory.FinalQuotePunctuation:
- case UnicodeCategory.OtherPunctuation:
- case UnicodeCategory.MathSymbol:
- case UnicodeCategory.CurrencySymbol:
- case UnicodeCategory.ModifierSymbol:
- case UnicodeCategory.OtherSymbol:
- return false;
- default:
- return true;
- }
- }
- }
- private void WriteNameHelper(string name)
- {
- switch (_context.ContextType)
- {
- case ContextType.Array:
- // don't write Array element names in Json
- if (_context.HasElements)
- {
- _textWriter.Write(", ");
- }
- break;
- case ContextType.Document:
- case ContextType.ScopeDocument:
- if (_context.HasElements)
- {
- _textWriter.Write(",");
- }
- if (_jsonWriterSettings.Indent)
- {
- _textWriter.Write(_jsonWriterSettings.NewLineChars);
- _textWriter.Write(_context.Indentation);
- }
- else
- {
- _textWriter.Write(" ");
- }
- WriteQuotedString(name);
- _textWriter.Write(" : ");
- break;
- case ContextType.TopLevel:
- break;
- default:
- throw new BsonInternalException("Invalid ContextType.");
- }
- _context.HasElements = true;
- }
- private void WriteQuotedString(string value)
- {
- _textWriter.Write("\"");
- _textWriter.Write(EscapedString(value));
- _textWriter.Write("\"");
- }
- }
- }
|