2
// Copyright (c) 2007 James Newton-King
4
// Permission is hereby granted, free of charge, to any person
5
// obtaining a copy of this software and associated documentation
6
// files (the "Software"), to deal in the Software without
7
// restriction, including without limitation the rights to use,
8
// copy, modify, merge, publish, distribute, sublicense, and/or sell
9
// copies of the Software, and to permit persons to whom the
10
// Software is furnished to do so, subject to the following
13
// The above copyright notice and this permission notice shall be
14
// included in all copies or substantial portions of the Software.
16
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
// OTHER DEALINGS IN THE SOFTWARE.
27
using System.Collections;
28
using System.Collections.Generic;
31
using Newtonsoft.Json.Utilities;
32
using Newtonsoft.Json.Linq;
33
using System.Globalization;
35
namespace Newtonsoft.Json.Bson
38
/// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data.
40
public class BsonWriter : JsonWriter
42
private readonly BsonBinaryWriter _writer;
44
private BsonToken _root;
45
private BsonToken _parent;
46
private string _propertyName;
49
/// Gets or sets the <see cref="DateTimeKind" /> used when writing <see cref="DateTime"/> values to BSON.
50
/// When set to <see cref="DateTimeKind.Unspecified" /> no conversion will occur.
52
/// <value>The <see cref="DateTimeKind" /> used when writing <see cref="DateTime"/> values to BSON.</value>
53
public DateTimeKind DateTimeKindHandling
55
get { return _writer.DateTimeKindHandling; }
56
set { _writer.DateTimeKindHandling = value; }
60
/// Initializes a new instance of the <see cref="BsonWriter"/> class.
62
/// <param name="stream">The stream.</param>
63
public BsonWriter(Stream stream)
65
ValidationUtils.ArgumentNotNull(stream, "stream");
66
_writer = new BsonBinaryWriter(stream);
70
/// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream.
72
public override void Flush()
80
/// <param name="token">The token.</param>
81
protected override void WriteEnd(JsonToken token)
88
_writer.WriteToken(_root);
93
/// Writes out a comment <code>/*...*/</code> containing the specified text.
95
/// <param name="text">Text to place inside the comment.</param>
96
public override void WriteComment(string text)
98
throw new JsonWriterException("Cannot write JSON comment as BSON.");
102
/// Writes the start of a constructor with the given name.
104
/// <param name="name">The name of the constructor.</param>
105
public override void WriteStartConstructor(string name)
107
throw new JsonWriterException("Cannot write JSON constructor as BSON.");
113
/// <param name="json">The raw JSON to write.</param>
114
public override void WriteRaw(string json)
116
throw new JsonWriterException("Cannot write raw JSON as BSON.");
120
/// Writes raw JSON where a value is expected and updates the writer's state.
122
/// <param name="json">The raw JSON to write.</param>
123
public override void WriteRawValue(string json)
125
throw new JsonWriterException("Cannot write raw JSON as BSON.");
129
/// Writes the beginning of a Json array.
131
public override void WriteStartArray()
133
base.WriteStartArray();
135
AddParent(new BsonArray());
139
/// Writes the beginning of a Json object.
141
public override void WriteStartObject()
143
base.WriteStartObject();
145
AddParent(new BsonObject());
149
/// Writes the property name of a name/value pair on a Json object.
151
/// <param name="name">The name of the property.</param>
152
public override void WritePropertyName(string name)
154
base.WritePropertyName(name);
156
_propertyName = name;
159
private void AddParent(BsonToken container)
165
private void RemoveParent()
167
_parent = _parent.Parent;
170
private void AddValue(object value, BsonType type)
172
AddToken(new BsonValue(value, type));
175
internal void AddToken(BsonToken token)
179
if (_parent is BsonObject)
181
((BsonObject)_parent).Add(_propertyName, token);
182
_propertyName = null;
186
((BsonArray)_parent).Add(token);
196
#region WriteValue methods
198
/// Writes a null value.
200
public override void WriteNull()
203
AddValue(null, BsonType.Null);
207
/// Writes an undefined value.
209
public override void WriteUndefined()
211
base.WriteUndefined();
212
AddValue(null, BsonType.Undefined);
216
/// Writes a <see cref="String"/> value.
218
/// <param name="value">The <see cref="String"/> value to write.</param>
219
public override void WriteValue(string value)
221
base.WriteValue(value);
223
AddValue(null, BsonType.Null);
225
AddToken(new BsonString(value, true));
229
/// Writes a <see cref="Int32"/> value.
231
/// <param name="value">The <see cref="Int32"/> value to write.</param>
232
public override void WriteValue(int value)
234
base.WriteValue(value);
235
AddValue(value, BsonType.Integer);
239
/// Writes a <see cref="UInt32"/> value.
241
/// <param name="value">The <see cref="UInt32"/> value to write.</param>
242
[CLSCompliant(false)]
243
public override void WriteValue(uint value)
245
if (value > int.MaxValue)
246
throw new JsonWriterException("Value is too large to fit in a signed 32 bit integer. BSON does not support unsigned values.");
248
base.WriteValue(value);
249
AddValue(value, BsonType.Integer);
253
/// Writes a <see cref="Int64"/> value.
255
/// <param name="value">The <see cref="Int64"/> value to write.</param>
256
public override void WriteValue(long value)
258
base.WriteValue(value);
259
AddValue(value, BsonType.Long);
263
/// Writes a <see cref="UInt64"/> value.
265
/// <param name="value">The <see cref="UInt64"/> value to write.</param>
266
[CLSCompliant(false)]
267
public override void WriteValue(ulong value)
269
if (value > long.MaxValue)
270
throw new JsonWriterException("Value is too large to fit in a signed 64 bit integer. BSON does not support unsigned values.");
272
base.WriteValue(value);
273
AddValue(value, BsonType.Long);
277
/// Writes a <see cref="Single"/> value.
279
/// <param name="value">The <see cref="Single"/> value to write.</param>
280
public override void WriteValue(float value)
282
base.WriteValue(value);
283
AddValue(value, BsonType.Number);
287
/// Writes a <see cref="Double"/> value.
289
/// <param name="value">The <see cref="Double"/> value to write.</param>
290
public override void WriteValue(double value)
292
base.WriteValue(value);
293
AddValue(value, BsonType.Number);
297
/// Writes a <see cref="Boolean"/> value.
299
/// <param name="value">The <see cref="Boolean"/> value to write.</param>
300
public override void WriteValue(bool value)
302
base.WriteValue(value);
303
AddValue(value, BsonType.Boolean);
307
/// Writes a <see cref="Int16"/> value.
309
/// <param name="value">The <see cref="Int16"/> value to write.</param>
310
public override void WriteValue(short value)
312
base.WriteValue(value);
313
AddValue(value, BsonType.Integer);
317
/// Writes a <see cref="UInt16"/> value.
319
/// <param name="value">The <see cref="UInt16"/> value to write.</param>
320
[CLSCompliant(false)]
321
public override void WriteValue(ushort value)
323
base.WriteValue(value);
324
AddValue(value, BsonType.Integer);
328
/// Writes a <see cref="Char"/> value.
330
/// <param name="value">The <see cref="Char"/> value to write.</param>
331
public override void WriteValue(char value)
333
base.WriteValue(value);
334
AddToken(new BsonString(value.ToString(), true));
338
/// Writes a <see cref="Byte"/> value.
340
/// <param name="value">The <see cref="Byte"/> value to write.</param>
341
public override void WriteValue(byte value)
343
base.WriteValue(value);
344
AddValue(value, BsonType.Integer);
348
/// Writes a <see cref="SByte"/> value.
350
/// <param name="value">The <see cref="SByte"/> value to write.</param>
351
[CLSCompliant(false)]
352
public override void WriteValue(sbyte value)
354
base.WriteValue(value);
355
AddValue(value, BsonType.Integer);
359
/// Writes a <see cref="Decimal"/> value.
361
/// <param name="value">The <see cref="Decimal"/> value to write.</param>
362
public override void WriteValue(decimal value)
364
base.WriteValue(value);
365
AddValue(value, BsonType.Number);
369
/// Writes a <see cref="DateTime"/> value.
371
/// <param name="value">The <see cref="DateTime"/> value to write.</param>
372
public override void WriteValue(DateTime value)
374
base.WriteValue(value);
375
AddValue(value, BsonType.Date);
378
#if !PocketPC && !NET20
380
/// Writes a <see cref="DateTimeOffset"/> value.
382
/// <param name="value">The <see cref="DateTimeOffset"/> value to write.</param>
383
public override void WriteValue(DateTimeOffset value)
385
base.WriteValue(value);
386
AddValue(value, BsonType.Date);
391
/// Writes a <see cref="T:Byte[]"/> value.
393
/// <param name="value">The <see cref="T:Byte[]"/> value to write.</param>
394
public override void WriteValue(byte[] value)
396
base.WriteValue(value);
397
AddValue(value, BsonType.Binary);
402
/// Writes a <see cref="T:Byte[]"/> value that represents a BSON object id.
404
/// <param name="value"></param>
405
public void WriteObjectId(byte[] value)
407
ValidationUtils.ArgumentNotNull(value, "value");
409
if (value.Length != 12)
410
throw new Exception("An object id must be 12 bytes");
412
// hack to update the writer state
413
AutoComplete(JsonToken.Undefined);
414
AddValue(value, BsonType.Oid);
418
/// Writes a BSON regex.
420
/// <param name="pattern">The regex pattern.</param>
421
/// <param name="options">The regex options.</param>
422
public void WriteRegex(string pattern, string options)
424
ValidationUtils.ArgumentNotNull(pattern, "pattern");
426
// hack to update the writer state
427
AutoComplete(JsonToken.Undefined);
428
AddToken(new BsonRegex(pattern, options));
2
// Copyright (c) 2007 James Newton-King
4
// Permission is hereby granted, free of charge, to any person
5
// obtaining a copy of this software and associated documentation
6
// files (the "Software"), to deal in the Software without
7
// restriction, including without limitation the rights to use,
8
// copy, modify, merge, publish, distribute, sublicense, and/or sell
9
// copies of the Software, and to permit persons to whom the
10
// Software is furnished to do so, subject to the following
13
// The above copyright notice and this permission notice shall be
14
// included in all copies or substantial portions of the Software.
16
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
18
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23
// OTHER DEALINGS IN THE SOFTWARE.
27
using System.Collections;
28
using System.Collections.Generic;
31
using Newtonsoft.Json.Utilities;
32
using Newtonsoft.Json.Linq;
33
using System.Globalization;
35
namespace Newtonsoft.Json.Bson
38
/// Represents a writer that provides a fast, non-cached, forward-only way of generating Json data.
40
public class BsonWriter : JsonWriter
42
private readonly BsonBinaryWriter _writer;
44
private BsonToken _root;
45
private BsonToken _parent;
46
private string _propertyName;
49
/// Gets or sets the <see cref="DateTimeKind" /> used when writing <see cref="DateTime"/> values to BSON.
50
/// When set to <see cref="DateTimeKind.Unspecified" /> no conversion will occur.
52
/// <value>The <see cref="DateTimeKind" /> used when writing <see cref="DateTime"/> values to BSON.</value>
53
public DateTimeKind DateTimeKindHandling
55
get { return _writer.DateTimeKindHandling; }
56
set { _writer.DateTimeKindHandling = value; }
60
/// Initializes a new instance of the <see cref="BsonWriter"/> class.
62
/// <param name="stream">The stream.</param>
63
public BsonWriter(Stream stream)
65
ValidationUtils.ArgumentNotNull(stream, "stream");
66
_writer = new BsonBinaryWriter(new BinaryWriter(stream));
70
/// Initializes a new instance of the <see cref="BsonWriter"/> class.
72
/// <param name="writer">The writer.</param>
73
public BsonWriter(BinaryWriter writer)
75
ValidationUtils.ArgumentNotNull(writer, "writer");
76
_writer = new BsonBinaryWriter(writer);
80
/// Flushes whatever is in the buffer to the underlying streams and also flushes the underlying stream.
82
public override void Flush()
90
/// <param name="token">The token.</param>
91
protected override void WriteEnd(JsonToken token)
98
_writer.WriteToken(_root);
103
/// Writes out a comment <code>/*...*/</code> containing the specified text.
105
/// <param name="text">Text to place inside the comment.</param>
106
public override void WriteComment(string text)
108
throw JsonWriterException.Create(this, "Cannot write JSON comment as BSON.", null);
112
/// Writes the start of a constructor with the given name.
114
/// <param name="name">The name of the constructor.</param>
115
public override void WriteStartConstructor(string name)
117
throw JsonWriterException.Create(this, "Cannot write JSON constructor as BSON.", null);
123
/// <param name="json">The raw JSON to write.</param>
124
public override void WriteRaw(string json)
126
throw JsonWriterException.Create(this, "Cannot write raw JSON as BSON.", null);
130
/// Writes raw JSON where a value is expected and updates the writer's state.
132
/// <param name="json">The raw JSON to write.</param>
133
public override void WriteRawValue(string json)
135
throw JsonWriterException.Create(this, "Cannot write raw JSON as BSON.", null);
139
/// Writes the beginning of a Json array.
141
public override void WriteStartArray()
143
base.WriteStartArray();
145
AddParent(new BsonArray());
149
/// Writes the beginning of a Json object.
151
public override void WriteStartObject()
153
base.WriteStartObject();
155
AddParent(new BsonObject());
159
/// Writes the property name of a name/value pair on a Json object.
161
/// <param name="name">The name of the property.</param>
162
public override void WritePropertyName(string name)
164
base.WritePropertyName(name);
166
_propertyName = name;
170
/// Closes this stream and the underlying stream.
172
public override void Close()
176
if (CloseOutput && _writer != null)
180
private void AddParent(BsonToken container)
186
private void RemoveParent()
188
_parent = _parent.Parent;
191
private void AddValue(object value, BsonType type)
193
AddToken(new BsonValue(value, type));
196
internal void AddToken(BsonToken token)
200
if (_parent is BsonObject)
202
((BsonObject) _parent).Add(_propertyName, token);
203
_propertyName = null;
207
((BsonArray) _parent).Add(token);
212
if (token.Type != BsonType.Object && token.Type != BsonType.Array)
213
throw JsonWriterException.Create(this, "Error writing {0} value. BSON must start with an Object or Array.".FormatWith(CultureInfo.InvariantCulture, token.Type), null);
220
#region WriteValue methods
223
/// Writes a null value.
225
public override void WriteNull()
228
AddValue(null, BsonType.Null);
232
/// Writes an undefined value.
234
public override void WriteUndefined()
236
base.WriteUndefined();
237
AddValue(null, BsonType.Undefined);
241
/// Writes a <see cref="String"/> value.
243
/// <param name="value">The <see cref="String"/> value to write.</param>
244
public override void WriteValue(string value)
246
base.WriteValue(value);
248
AddValue(null, BsonType.Null);
250
AddToken(new BsonString(value, true));
254
/// Writes a <see cref="Int32"/> value.
256
/// <param name="value">The <see cref="Int32"/> value to write.</param>
257
public override void WriteValue(int value)
259
base.WriteValue(value);
260
AddValue(value, BsonType.Integer);
264
/// Writes a <see cref="UInt32"/> value.
266
/// <param name="value">The <see cref="UInt32"/> value to write.</param>
267
[CLSCompliant(false)]
268
public override void WriteValue(uint value)
270
if (value > int.MaxValue)
271
throw JsonWriterException.Create(this, "Value is too large to fit in a signed 32 bit integer. BSON does not support unsigned values.", null);
273
base.WriteValue(value);
274
AddValue(value, BsonType.Integer);
278
/// Writes a <see cref="Int64"/> value.
280
/// <param name="value">The <see cref="Int64"/> value to write.</param>
281
public override void WriteValue(long value)
283
base.WriteValue(value);
284
AddValue(value, BsonType.Long);
288
/// Writes a <see cref="UInt64"/> value.
290
/// <param name="value">The <see cref="UInt64"/> value to write.</param>
291
[CLSCompliant(false)]
292
public override void WriteValue(ulong value)
294
if (value > long.MaxValue)
295
throw JsonWriterException.Create(this, "Value is too large to fit in a signed 64 bit integer. BSON does not support unsigned values.", null);
297
base.WriteValue(value);
298
AddValue(value, BsonType.Long);
302
/// Writes a <see cref="Single"/> value.
304
/// <param name="value">The <see cref="Single"/> value to write.</param>
305
public override void WriteValue(float value)
307
base.WriteValue(value);
308
AddValue(value, BsonType.Number);
312
/// Writes a <see cref="Double"/> value.
314
/// <param name="value">The <see cref="Double"/> value to write.</param>
315
public override void WriteValue(double value)
317
base.WriteValue(value);
318
AddValue(value, BsonType.Number);
322
/// Writes a <see cref="Boolean"/> value.
324
/// <param name="value">The <see cref="Boolean"/> value to write.</param>
325
public override void WriteValue(bool value)
327
base.WriteValue(value);
328
AddValue(value, BsonType.Boolean);
332
/// Writes a <see cref="Int16"/> value.
334
/// <param name="value">The <see cref="Int16"/> value to write.</param>
335
public override void WriteValue(short value)
337
base.WriteValue(value);
338
AddValue(value, BsonType.Integer);
342
/// Writes a <see cref="UInt16"/> value.
344
/// <param name="value">The <see cref="UInt16"/> value to write.</param>
345
[CLSCompliant(false)]
346
public override void WriteValue(ushort value)
348
base.WriteValue(value);
349
AddValue(value, BsonType.Integer);
353
/// Writes a <see cref="Char"/> value.
355
/// <param name="value">The <see cref="Char"/> value to write.</param>
356
public override void WriteValue(char value)
358
base.WriteValue(value);
360
#if !(NETFX_CORE || PORTABLE)
361
s = value.ToString(CultureInfo.InvariantCulture);
363
s = value.ToString();
365
AddToken(new BsonString(s, true));
369
/// Writes a <see cref="Byte"/> value.
371
/// <param name="value">The <see cref="Byte"/> value to write.</param>
372
public override void WriteValue(byte value)
374
base.WriteValue(value);
375
AddValue(value, BsonType.Integer);
379
/// Writes a <see cref="SByte"/> value.
381
/// <param name="value">The <see cref="SByte"/> value to write.</param>
382
[CLSCompliant(false)]
383
public override void WriteValue(sbyte value)
385
base.WriteValue(value);
386
AddValue(value, BsonType.Integer);
390
/// Writes a <see cref="Decimal"/> value.
392
/// <param name="value">The <see cref="Decimal"/> value to write.</param>
393
public override void WriteValue(decimal value)
395
base.WriteValue(value);
396
AddValue(value, BsonType.Number);
400
/// Writes a <see cref="DateTime"/> value.
402
/// <param name="value">The <see cref="DateTime"/> value to write.</param>
403
public override void WriteValue(DateTime value)
405
base.WriteValue(value);
406
value = JsonConvert.EnsureDateTime(value, DateTimeZoneHandling);
407
AddValue(value, BsonType.Date);
410
#if !PocketPC && !NET20
412
/// Writes a <see cref="DateTimeOffset"/> value.
414
/// <param name="value">The <see cref="DateTimeOffset"/> value to write.</param>
415
public override void WriteValue(DateTimeOffset value)
417
base.WriteValue(value);
418
AddValue(value, BsonType.Date);
423
/// Writes a <see cref="T:Byte[]"/> value.
425
/// <param name="value">The <see cref="T:Byte[]"/> value to write.</param>
426
public override void WriteValue(byte[] value)
428
base.WriteValue(value);
429
AddValue(value, BsonType.Binary);
433
/// Writes a <see cref="Guid"/> value.
435
/// <param name="value">The <see cref="Guid"/> value to write.</param>
436
public override void WriteValue(Guid value)
438
base.WriteValue(value);
439
AddToken(new BsonString(value.ToString(), true));
443
/// Writes a <see cref="TimeSpan"/> value.
445
/// <param name="value">The <see cref="TimeSpan"/> value to write.</param>
446
public override void WriteValue(TimeSpan value)
448
base.WriteValue(value);
449
AddToken(new BsonString(value.ToString(), true));
453
/// Writes a <see cref="Uri"/> value.
455
/// <param name="value">The <see cref="Uri"/> value to write.</param>
456
public override void WriteValue(Uri value)
458
base.WriteValue(value);
459
AddToken(new BsonString(value.ToString(), true));
465
/// Writes a <see cref="T:Byte[]"/> value that represents a BSON object id.
467
/// <param name="value">The Object ID value to write.</param>
468
public void WriteObjectId(byte[] value)
470
ValidationUtils.ArgumentNotNull(value, "value");
472
if (value.Length != 12)
473
throw JsonWriterException.Create(this, "An object id must be 12 bytes", null);
475
// hack to update the writer state
476
AutoComplete(JsonToken.Undefined);
477
AddValue(value, BsonType.Oid);
481
/// Writes a BSON regex.
483
/// <param name="pattern">The regex pattern.</param>
484
/// <param name="options">The regex options.</param>
485
public void WriteRegex(string pattern, string options)
487
ValidationUtils.ArgumentNotNull(pattern, "pattern");
489
// hack to update the writer state
490
AutoComplete(JsonToken.Undefined);
491
AddToken(new BsonRegex(pattern, options));
b'\\ No newline at end of file'