Преглед изворни кода

更新mongodb驱动到2.4版本

tanghai пре 8 година
родитељ
комит
009d24c4b3
100 измењених фајлова са 5081 додато и 3241 уклоњено
  1. 1 1
      Server/Model/Component/ActorProxyComponent.cs
  2. 1 1
      Server/Model/Message/OuterMessageDispatcher.cs
  3. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson.meta
  4. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/BsonConstants.cs.meta
  5. 47 0
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/BsonDefaults.cs
  6. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/BsonDefaults.cs.meta
  7. 138 214
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/BsonExtensionMethods.cs
  8. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/BsonExtensionMethods.cs.meta
  9. 5 3
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/BsonUtils.cs
  10. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/BsonUtils.cs.meta
  11. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/Exceptions.meta
  12. 7 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/Exceptions/BsonException.cs
  13. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/Exceptions/BsonException.cs.meta
  14. 7 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/Exceptions/BsonInternalException.cs
  15. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/Exceptions/BsonInternalException.cs.meta
  16. 7 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/Exceptions/BsonSerializationException.cs
  17. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/Exceptions/BsonSerializationException.cs.meta
  18. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/Exceptions/DuplicateBsonMemberMapAttributeException.cs
  19. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/Exceptions/DuplicateBsonMemberMapAttributeException.cs.meta
  20. 7 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/Exceptions/TruncationException.cs
  21. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/Exceptions/TruncationException.cs.meta
  22. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO.meta
  23. 125 0
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/ArrayElementNameAccelerator.cs
  24. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/ArrayElementNameAccelerator.cs.meta
  25. 222 104
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryReader.cs
  26. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryReader.cs.meta
  27. 3 3
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryReaderBookmark.cs
  28. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryReaderBookmark.cs.meta
  29. 31 13
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryReaderContext.cs
  30. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryReaderContext.cs.meta
  31. 4 40
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryReaderSettings.cs
  32. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryReaderSettings.cs.meta
  33. 131 120
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryWriter.cs
  34. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryWriter.cs.meta
  35. 3 3
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryWriterContext.cs
  36. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryWriterContext.cs.meta
  37. 4 37
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryWriterSettings.cs
  38. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryWriterSettings.cs.meta
  39. 0 804
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBuffer.cs
  40. 0 105
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonChunk.cs
  41. 179 48
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonChunkPool.cs
  42. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonChunkPool.cs.meta
  43. 67 23
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonDocumentReader.cs
  44. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonDocumentReader.cs.meta
  45. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonDocumentReaderBookmark.cs.meta
  46. 10 6
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonDocumentReaderContext.cs
  47. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonDocumentReaderContext.cs.meta
  48. 3 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonDocumentReaderSettings.cs
  49. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonDocumentReaderSettings.cs.meta
  50. 42 19
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonDocumentWriter.cs
  51. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonDocumentWriter.cs.meta
  52. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonDocumentWriterContext.cs.meta
  53. 3 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonDocumentWriterSettings.cs
  54. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonDocumentWriterSettings.cs.meta
  55. 47 566
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonReader.cs
  56. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonReader.cs.meta
  57. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonReaderBookmark.cs.meta
  58. 3 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonReaderSettings.cs
  59. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonReaderSettings.cs.meta
  60. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonReaderState.cs.meta
  61. 140 0
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonStream.cs
  62. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonStream.cs.meta
  63. 567 0
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonStreamAdapter.cs
  64. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonStreamAdapter.cs.meta
  65. 315 0
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonStreamExtensions.cs
  66. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonStreamExtensions.cs.meta
  67. 73 26
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonTrie.cs
  68. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonTrie.cs.meta
  69. 72 529
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonWriter.cs
  70. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonWriter.cs.meta
  71. 3 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonWriterSettings.cs
  72. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonWriterSettings.cs.meta
  73. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonWriterState.cs.meta
  74. 131 375
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/ByteArrayBuffer.cs
  75. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/ByteArrayBuffer.cs.meta
  76. 111 0
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/ByteArrayChunk.cs
  77. 12 0
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/ByteArrayChunk.cs.meta
  78. 30 53
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/ByteBufferFactory.cs
  79. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/ByteBufferFactory.cs.meta
  80. 235 0
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/ByteBufferSlice.cs
  81. 12 0
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/ByteBufferSlice.cs.meta
  82. 727 0
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/ByteBufferStream.cs
  83. 12 0
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/ByteBufferStream.cs.meta
  84. 76 0
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/CStringUtf8Encoding.cs
  85. 12 0
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/CStringUtf8Encoding.cs.meta
  86. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/ContextType.cs.meta
  87. 16 10
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IBsonChunk.cs
  88. 12 0
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IBsonChunk.cs.meta
  89. 10 10
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IBsonChunkSource.cs
  90. 12 0
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IBsonChunkSource.cs.meta
  91. 235 0
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IBsonReader.cs
  92. 12 0
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IBsonReader.cs.meta
  93. 361 0
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IBsonReaderExtensions.cs
  94. 12 0
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IBsonReaderExtensions.cs.meta
  95. 213 0
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IBsonWriter.cs
  96. 12 0
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IBsonWriter.cs.meta
  97. 293 0
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IBsonWriterExtensions.cs
  98. 12 0
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IBsonWriterExtensions.cs.meta
  99. 36 76
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IByteBuffer.cs
  100. 5 1
      Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IByteBuffer.cs.meta

+ 1 - 1
Server/Model/Component/ActorProxyComponent.cs

@@ -12,7 +12,7 @@ namespace Model
 			{
 				return actorProxy;
 			}
-
+			
 			actorProxy = ObjectFactory.CreateWithId<ActorProxy>(id);
 			this.dictionary[id] = actorProxy;
 			return actorProxy;

+ 1 - 1
Server/Model/Message/OuterMessageDispatcher.cs

@@ -9,9 +9,9 @@ namespace Model
 			// gate session收到actor消息直接转发给actor自己去处理
 			if (message is AActorMessage aActorMessage)
 			{
-				ActorProxy actorProxy = Game.Scene.GetComponent<ActorProxyComponent>().Get(aActorMessage.Id);
 				long unitId = session.GetComponent<SessionPlayerComponent>().Player.UnitId;
 				aActorMessage.Id = unitId;
+				ActorProxy actorProxy = Game.Scene.GetComponent<ActorProxyComponent>().Get(aActorMessage.Id);
 				actorProxy.Send(aActorMessage);
 				return;
 			}

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson.meta

@@ -1,5 +1,9 @@
 fileFormatVersion: 2
-guid: 39cbf921dcbc4bc4a93b693b5d822fff
+guid: d75a18497377f7941830d538edead694
 folderAsset: yes
+timeCreated: 1503738732
+licenseType: Free
 DefaultImporter:
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/BsonConstants.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: fd4be2b8d034a5747b0e38e2931f9c53
+guid: 629392d3729a3ba4998e1b005c39141d
+timeCreated: 1503738734
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 47 - 0
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/BsonDefaults.cs

@@ -13,6 +13,9 @@
 * limitations under the License.
 */
 
+using System.Collections.Generic;
+using System.Dynamic;
+using MongoDB.Bson.Serialization;
 namespace MongoDB.Bson
 {
     /// <summary>
@@ -21,11 +24,55 @@ namespace MongoDB.Bson
     public static class BsonDefaults
     {
         // private static fields
+        private static bool __dynamicArraySerializerWasSet;
+        private static IBsonSerializer __dynamicArraySerializer;
+        private static bool __dynamicDocumentSerializerWasSet;
+        private static IBsonSerializer __dynamicDocumentSerializer; 
         private static GuidRepresentation __guidRepresentation = GuidRepresentation.CSharpLegacy;
         private static int __maxDocumentSize = int.MaxValue;
         private static int __maxSerializationDepth = 100;
 
         // public static properties
+        /// <summary>
+        /// Gets or sets the dynamic array serializer.
+        /// </summary>
+        public static IBsonSerializer DynamicArraySerializer
+        {
+            get
+            {
+                if (!__dynamicArraySerializerWasSet)
+                {
+                    __dynamicArraySerializer = BsonSerializer.LookupSerializer<List<object>>();
+                }
+                return __dynamicArraySerializer;
+            }
+            set 
+            {
+                __dynamicArraySerializerWasSet = true;
+                __dynamicArraySerializer = value; 
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the dynamic document serializer.
+        /// </summary>
+        public static IBsonSerializer DynamicDocumentSerializer
+        {
+            get 
+            {
+                if (!__dynamicDocumentSerializerWasSet)
+                {
+                    __dynamicDocumentSerializer = BsonSerializer.LookupSerializer<ExpandoObject>();
+                }
+                return __dynamicDocumentSerializer; 
+            }
+            set 
+            {
+                __dynamicDocumentSerializerWasSet = true;
+                __dynamicDocumentSerializer = value; 
+            }
+        }
+
         /// <summary>
         /// Gets or sets the default representation to be used in serialization of 
         /// Guids to the database. 

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/BsonDefaults.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: 5939639edb3f9534694cbd0a2af84dfc
+guid: 16d3fa887e1ec644ab177503a42fbae5
+timeCreated: 1503738732
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 138 - 214
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/BsonExtensionMethods.cs

@@ -26,297 +26,221 @@ namespace MongoDB.Bson
     public static class BsonExtensionMethods
     {
         /// <summary>
-        /// Converts an object to a BSON document byte array.
+        /// Serializes an object to a BSON byte array.
         /// </summary>
         /// <typeparam name="TNominalType">The nominal type of the object.</typeparam>
         /// <param name="obj">The object.</param>
-        /// <returns>A byte array.</returns>
-        public static byte[] ToBson<TNominalType>(this TNominalType obj)
-        {
-            return ToBson(obj, typeof(TNominalType));
-        }
-
-        /// <summary>
-        /// Converts an object to a BSON document byte array.
-        /// </summary>
-        /// <typeparam name="TNominalType">The nominal type of the object.</typeparam>
-        /// <param name="obj">The object.</param>
-        /// <param name="options">The serialization options.</param>
-        /// <returns>A byte array.</returns>
-        public static byte[] ToBson<TNominalType>(this TNominalType obj, IBsonSerializationOptions options)
-        {
-            return ToBson(obj, typeof(TNominalType), options);
-        }
-
-        /// <summary>
-        /// Converts an object to a BSON document byte array.
-        /// </summary>
-        /// <typeparam name="TNominalType">The nominal type of the object.</typeparam>
-        /// <param name="obj">The object.</param>
-        /// <param name="options">The serialization options.</param>
-        /// <param name="settings">The BsonBinaryWriter settings.</param>
-        /// <returns>A byte array.</returns>
+        /// <param name="serializer">The serializer.</param>
+        /// <param name="writerSettings">The writer settings.</param>
+        /// <param name="configurator">The serialization context configurator.</param>
+        /// <param name="args">The serialization args.</param>
+        /// <returns>A BSON byte array.</returns>
         public static byte[] ToBson<TNominalType>(
             this TNominalType obj,
-            IBsonSerializationOptions options,
-            BsonBinaryWriterSettings settings)
+            IBsonSerializer<TNominalType> serializer = null,
+            BsonBinaryWriterSettings writerSettings = null,
+            Action<BsonSerializationContext.Builder> configurator = null,
+            BsonSerializationArgs args = default(BsonSerializationArgs)
+            )
         {
-            return ToBson(obj, typeof(TNominalType), options, settings);
+            return ToBson(obj, typeof(TNominalType), writerSettings, serializer, configurator, args);
         }
 
         /// <summary>
-        /// Converts an object to a BSON document byte array.
+        /// Serializes an object to a BSON byte array.
         /// </summary>
-        /// <typeparam name="TNominalType">The nominal type of the object.</typeparam>
         /// <param name="obj">The object.</param>
-        /// <param name="settings">The BsonBinaryWriter settings.</param>
-        /// <returns>A byte array.</returns>
-        public static byte[] ToBson<TNominalType>(this TNominalType obj, BsonBinaryWriterSettings settings)
-        {
-            return ToBson(obj, typeof(TNominalType), settings);
-        }
-
-        /// <summary>
-        /// Converts an object to a BSON document byte array.
-        /// </summary>
-        /// <param name="obj">The object.</param>
-        /// <param name="nominalType">The nominal type of the object.</param>
-        /// <returns>A byte array.</returns>
-        public static byte[] ToBson(this object obj, Type nominalType)
-        {
-            return ToBson(obj, nominalType, BsonBinaryWriterSettings.Defaults);
-        }
-
-        /// <summary>
-        /// Converts an object to a BSON document byte array.
-        /// </summary>
-        /// <param name="obj">The object.</param>
-        /// <param name="nominalType">The nominal type of the object.</param>
-        /// <param name="options">The serialization options.</param>
-        /// <returns>A byte array.</returns>
-        public static byte[] ToBson(this object obj, Type nominalType, IBsonSerializationOptions options)
-        {
-            return ToBson(obj, nominalType, options, BsonBinaryWriterSettings.Defaults);
-        }
-
-        /// <summary>
-        /// Converts an object to a BSON document byte array.
-        /// </summary>
-        /// <param name="obj">The object.</param>
-        /// <param name="nominalType">The nominal type of the object.</param>
-        /// <param name="options">The serialization options.</param>
-        /// <param name="settings">The BsonBinaryWriter settings.</param>
-        /// <returns>A byte array.</returns>
+        /// <param name="nominalType">The nominal type of the object..</param>
+        /// <param name="writerSettings">The writer settings.</param>
+        /// <param name="serializer">The serializer.</param>
+        /// <param name="configurator">The serialization context configurator.</param>
+        /// <param name="args">The serialization args.</param>
+        /// <returns>A BSON byte array.</returns>
+        /// <exception cref="System.ArgumentNullException">nominalType</exception>
+        /// <exception cref="System.ArgumentException">serializer</exception>
         public static byte[] ToBson(
             this object obj,
             Type nominalType,
-            IBsonSerializationOptions options,
-            BsonBinaryWriterSettings settings)
+            BsonBinaryWriterSettings writerSettings = null,
+            IBsonSerializer serializer = null,
+            Action<BsonSerializationContext.Builder> configurator = null,
+            BsonSerializationArgs args = default(BsonSerializationArgs))
         {
-            using (var buffer = new BsonBuffer())
+            if (nominalType == null)
             {
-                using (var bsonWriter = BsonWriter.Create(buffer, settings))
-                {
-                    BsonSerializer.Serialize(bsonWriter, nominalType, obj, options);
-                }
-                return buffer.ToByteArray();
+                throw new ArgumentNullException("nominalType");
             }
-        }
 
-        /// <summary>
-        /// Converts an object to a BSON document byte array.
-        /// </summary>
-        /// <param name="obj">The object.</param>
-        /// <param name="nominalType">The nominal type of the object.</param>
-        /// <param name="settings">The BsonBinaryWriter settings.</param>
-        /// <returns>A byte array.</returns>
-        public static byte[] ToBson(this object obj, Type nominalType, BsonBinaryWriterSettings settings)
-        {
-            return ToBson(obj, nominalType, null, settings);
-        }
+            if (serializer == null)
+            {
+                serializer = BsonSerializer.LookupSerializer(nominalType);
+            }
+            if (serializer.ValueType != nominalType)
+            {
+                var message = string.Format("Serializer type {0} value type does not match document types {1}.", serializer.GetType().FullName, nominalType.FullName);
+                throw new ArgumentException(message, "serializer");
+            }
 
-        /// <summary>
-        /// Converts an object to a BsonDocument.
-        /// </summary>
-        /// <typeparam name="TNominalType">The nominal type of the object.</typeparam>
-        /// <param name="obj">The object.</param>
-        /// <returns>A BsonDocument.</returns>
-        public static BsonDocument ToBsonDocument<TNominalType>(this TNominalType obj)
-        {
-            return ToBsonDocument(obj, typeof(TNominalType));
+            using (var memoryStream = new MemoryStream())
+            {
+                using (var bsonWriter = new BsonBinaryWriter(memoryStream, writerSettings ?? BsonBinaryWriterSettings.Defaults))
+                {
+                    var context = BsonSerializationContext.CreateRoot(bsonWriter, configurator);
+                    args.NominalType = nominalType;
+                    serializer.Serialize(context, args, obj);
+                }
+                return memoryStream.ToArray();
+            }
         }
 
         /// <summary>
-        /// Converts an object to a BsonDocument.
+        /// Serializes an object to a BsonDocument.
         /// </summary>
         /// <typeparam name="TNominalType">The nominal type of the object.</typeparam>
         /// <param name="obj">The object.</param>
-        /// <param name="options">The serialization options.</param>
+        /// <param name="serializer">The serializer.</param>
+        /// <param name="configurator">The serialization context configurator.</param>
+        /// <param name="args">The serialization args.</param>
         /// <returns>A BsonDocument.</returns>
         public static BsonDocument ToBsonDocument<TNominalType>(
-            this TNominalType obj,
-            IBsonSerializationOptions options)
-        {
-            return ToBsonDocument(obj, typeof(TNominalType), options);
-        }
-
-        /// <summary>
-        /// Converts an object to a BsonDocument.
-        /// </summary>
-        /// <param name="obj">The object.</param>
-        /// <param name="nominalType">The nominal type of the object.</param>
-        /// <returns>A BsonDocument.</returns>
-        public static BsonDocument ToBsonDocument(this object obj, Type nominalType)
+            this TNominalType obj, 
+            IBsonSerializer<TNominalType> serializer = null,
+            Action<BsonSerializationContext.Builder> configurator = null,
+            BsonSerializationArgs args = default(BsonSerializationArgs))
         {
-            return ToBsonDocument(obj, nominalType, null);
+            return ToBsonDocument(obj, typeof(TNominalType), serializer, configurator, args);
         }
 
         /// <summary>
-        /// Converts an object to a BsonDocument.
+        /// Serializes an object to a BsonDocument.
         /// </summary>
         /// <param name="obj">The object.</param>
         /// <param name="nominalType">The nominal type of the object.</param>
-        /// <param name="options">The serialization options.</param>
+        /// <param name="serializer">The serializer.</param>
+        /// <param name="configurator">The serialization context configurator.</param>
+        /// <param name="args">The serialization args.</param>
         /// <returns>A BsonDocument.</returns>
+        /// <exception cref="System.ArgumentNullException">nominalType</exception>
+        /// <exception cref="System.ArgumentException">serializer</exception>
         public static BsonDocument ToBsonDocument(
             this object obj,
             Type nominalType,
-            IBsonSerializationOptions options)
+            IBsonSerializer serializer = null,
+            Action<BsonSerializationContext.Builder> configurator = null,
+            BsonSerializationArgs args = default(BsonSerializationArgs))
         {
+            if (nominalType == null)
+            {
+                throw new ArgumentNullException("nominalType");
+            }
+
             if (obj == null)
             {
                 return null;
             }
 
-            var bsonDocument = obj as BsonDocument;
-            if (bsonDocument != null)
+            if (serializer == null)
             {
-                return bsonDocument; // it's already a BsonDocument
-            }
+                var bsonDocument = obj as BsonDocument;
+                if (bsonDocument != null)
+                {
+                    return bsonDocument; // it's already a BsonDocument
+                }
 
-            var convertibleToBsonDocument = obj as IConvertibleToBsonDocument;
-            if (convertibleToBsonDocument != null)
+                var convertibleToBsonDocument = obj as IConvertibleToBsonDocument;
+                if (convertibleToBsonDocument != null)
+                {
+                    return convertibleToBsonDocument.ToBsonDocument(); // use the provided ToBsonDocument method
+                }
+
+                serializer = BsonSerializer.LookupSerializer(nominalType);
+            }
+            if (serializer.ValueType != nominalType)
             {
-                return convertibleToBsonDocument.ToBsonDocument(); // use the provided ToBsonDocument method
+                var message = string.Format("Serializer type {0} value type does not match document types {1}.", serializer.GetType().FullName, nominalType.FullName);
+                throw new ArgumentException(message, "serializer");
             }
 
             // otherwise serialize into a new BsonDocument
             var document = new BsonDocument();
-            using (var writer = BsonWriter.Create(document))
+            using (var bsonWriter = new BsonDocumentWriter(document))
             {
-                BsonSerializer.Serialize(writer, nominalType, obj, options);
+                var context = BsonSerializationContext.CreateRoot(bsonWriter, configurator);
+                args.NominalType = nominalType;
+                serializer.Serialize(context, args, obj);
             }
             return document;
         }
 
         /// <summary>
-        /// Converts an object to a JSON string.
+        /// Serializes an object to a JSON string.
         /// </summary>
         /// <typeparam name="TNominalType">The nominal type of the object.</typeparam>
         /// <param name="obj">The object.</param>
-        /// <returns>A JSON string.</returns>
-        public static string ToJson<TNominalType>(this TNominalType obj)
-        {
-            return ToJson(obj, typeof(TNominalType));
-        }
-
-        /// <summary>
-        /// Converts an object to a JSON string.
-        /// </summary>
-        /// <typeparam name="TNominalType">The nominal type of the object.</typeparam>
-        /// <param name="obj">The object.</param>
-        /// <param name="options">The serialization options.</param>
-        /// <returns>A JSON string.</returns>
-        public static string ToJson<TNominalType>(this TNominalType obj, IBsonSerializationOptions options)
-        {
-            return ToJson(obj, typeof(TNominalType), options);
-        }
-
-        /// <summary>
-        /// Converts an object to a JSON string.
-        /// </summary>
-        /// <typeparam name="TNominalType">The nominal type of the object.</typeparam>
-        /// <param name="obj">The object.</param>
-        /// <param name="options">The serialization options.</param>
-        /// <param name="settings">The JsonWriter settings.</param>
-        /// <returns>A JSON string.</returns>
+        /// <param name="writerSettings">The JsonWriter settings.</param>
+        /// <param name="serializer">The serializer.</param>
+        /// <param name="configurator">The serializastion context configurator.</param>
+        /// <param name="args">The serialization args.</param>
+        /// <returns>
+        /// A JSON string.
+        /// </returns>
         public static string ToJson<TNominalType>(
-            this TNominalType obj,
-            IBsonSerializationOptions options,
-            JsonWriterSettings settings)
+            this TNominalType obj, 
+            JsonWriterSettings writerSettings = null,
+            IBsonSerializer<TNominalType> serializer = null, 
+            Action<BsonSerializationContext.Builder> configurator = null,
+            BsonSerializationArgs args = default(BsonSerializationArgs))
         {
-            return ToJson(obj, typeof(TNominalType), options, settings);
+            return ToJson(obj, typeof(TNominalType), writerSettings, serializer, configurator, args);
         }
 
         /// <summary>
-        /// Converts an object to a JSON string.
+        /// Serializes an object to a JSON string.
         /// </summary>
-        /// <typeparam name="TNominalType">The nominal type of the object.</typeparam>
         /// <param name="obj">The object.</param>
-        /// <param name="settings">The JsonWriter settings.</param>
-        /// <returns>A JSON string.</returns>
-        public static string ToJson<TNominalType>(this TNominalType obj, JsonWriterSettings settings)
-        {
-            return ToJson(obj, typeof(TNominalType), settings);
-        }
-
-        /// <summary>
-        /// Converts an object to a JSON string.
-        /// </summary>
-        /// <param name="obj">The object.</param>
-        /// <param name="nominalType">The nominal type of the object.</param>
-        /// <returns>A JSON string.</returns>
-        public static string ToJson(this object obj, Type nominalType)
-        {
-            return ToJson(obj, nominalType, JsonWriterSettings.Defaults);
-        }
-
-        /// <summary>
-        /// Converts an object to a JSON string.
-        /// </summary>
-        /// <param name="obj">The object.</param>
-        /// <param name="nominalType">The nominal type of the object.</param>
-        /// <param name="options">The serialization options.</param>
-        /// <returns>A JSON string.</returns>
-        public static string ToJson(this object obj, Type nominalType, IBsonSerializationOptions options)
-        {
-            return ToJson(obj, nominalType, options, JsonWriterSettings.Defaults);
-        }
-
-        /// <summary>
-        /// Converts an object to a JSON string.
-        /// </summary>
-        /// <param name="obj">The object.</param>
-        /// <param name="nominalType">The nominal type of the object.</param>
-        /// <param name="options">The serialization options.</param>
-        /// <param name="settings">The JsonWriter settings.</param>
-        /// <returns>A JSON string.</returns>
+        /// <param name="nominalType">The nominal type of the objectt.</param>
+        /// <param name="writerSettings">The JsonWriter settings.</param>
+        /// <param name="serializer">The serializer.</param>
+        /// <param name="configurator">The serialization context configurator.</param>
+        /// <param name="args">The serialization args.</param>
+        /// <returns>
+        /// A JSON string.
+        /// </returns>
+        /// <exception cref="System.ArgumentNullException">nominalType</exception>
+        /// <exception cref="System.ArgumentException">serializer</exception>
         public static string ToJson(
             this object obj,
             Type nominalType,
-            IBsonSerializationOptions options,
-            JsonWriterSettings settings)
+            JsonWriterSettings writerSettings = null,
+            IBsonSerializer serializer = null,
+            Action<BsonSerializationContext.Builder> configurator = null,
+            BsonSerializationArgs args = default(BsonSerializationArgs))
         {
+            if (nominalType == null)
+            {
+                throw new ArgumentNullException("nominalType");
+            }
+
+            if (serializer == null)
+            {
+                serializer = BsonSerializer.LookupSerializer(nominalType);
+            }
+            if (serializer.ValueType != nominalType)
+            {
+                var message = string.Format("Serializer type {0} value type does not match document types {1}.", serializer.GetType().FullName, nominalType.FullName);
+                throw new ArgumentException(message, "serializer");
+            }
+
             using (var stringWriter = new StringWriter())
             {
-                using (var bsonWriter = BsonWriter.Create(stringWriter, settings))
+                using (var bsonWriter = new JsonWriter(stringWriter, writerSettings ?? JsonWriterSettings.Defaults))
                 {
-                    BsonSerializer.Serialize(bsonWriter, nominalType, obj, options);
+                    var context = BsonSerializationContext.CreateRoot(bsonWriter, configurator);
+                    args.NominalType = nominalType;
+                    serializer.Serialize(context, args, obj);
                 }
                 return stringWriter.ToString();
             }
         }
-
-        /// <summary>
-        /// Converts an object to a JSON string.
-        /// </summary>
-        /// <param name="obj">The object.</param>
-        /// <param name="nominalType">The nominal type of the object.</param>
-        /// <param name="settings">The JsonWriter settings.</param>
-        /// <returns>A JSON string.</returns>
-        public static string ToJson(this object obj, Type nominalType, JsonWriterSettings settings)
-        {
-            return ToJson(obj, nominalType, null, settings);
-        }
     }
 }

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/BsonExtensionMethods.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: 9e5d3e4779adbd44fb162e4bc24e64ef
+guid: d2609b6466cfb9149a418aad81e2d9bf
+timeCreated: 1503738735
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 5 - 3
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/BsonUtils.cs

@@ -1,4 +1,4 @@
-/* Copyright 2010-2014 MongoDB Inc.
+/* Copyright 2010-2016 MongoDB Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -14,6 +14,7 @@
 */
 
 using System;
+using System.Reflection;
 using System.Text;
 using System.Text.RegularExpressions;
 
@@ -34,14 +35,15 @@ namespace MongoDB.Bson
         /// <returns>A friendly class name.</returns>
         public static string GetFriendlyTypeName(Type type)
         {
-            if (!type.IsGenericType)
+            var typeInfo = type.GetTypeInfo();
+            if (!typeInfo.IsGenericType)
             {
                 return type.Name;
             }
 
             var sb = new StringBuilder();
             sb.AppendFormat("{0}<", Regex.Replace(type.Name, @"\`\d+$", ""));
-            foreach (var typeParameter in type.GetGenericArguments())
+            foreach (var typeParameter in type.GetTypeInfo().GetGenericArguments())
             {
                 sb.AppendFormat("{0}, ", GetFriendlyTypeName(typeParameter));
             }

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/BsonUtils.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: 530321501c2b5504c9193c1bb8627794
+guid: 973c81f4320114544ab96b04d0e68ca3
+timeCreated: 1503738734
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/Exceptions.meta

@@ -1,5 +1,9 @@
 fileFormatVersion: 2
-guid: a372566b919124f4d91bdb8e3c9c2221
+guid: 535f74689d20ae3468a1bbdd74d1d2d6
 folderAsset: yes
+timeCreated: 1503738732
+licenseType: Free
 DefaultImporter:
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 7 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/Exceptions/BsonException.cs

@@ -1,4 +1,4 @@
-/* Copyright 2010-2014 MongoDB Inc.
+/* Copyright 2010-2016 MongoDB Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -14,14 +14,18 @@
 */
 
 using System;
+#if NET45
 using System.Runtime.Serialization;
+#endif
 
 namespace MongoDB.Bson
 {
     /// <summary>
     /// Represents a BSON exception.
     /// </summary>
+#if NET45
     [Serializable]
+#endif
     public class BsonException : Exception
     {
         // constructors
@@ -62,6 +66,7 @@ namespace MongoDB.Bson
         {
         }
 
+#if NET45
         /// <summary>
         /// Initializes a new instance of the BsonException class (this overload used by deserialization).
         /// </summary>
@@ -71,5 +76,6 @@ namespace MongoDB.Bson
             : base(info, context)
         {
         }
+#endif
     }
 }

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/Exceptions/BsonException.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: 7c4e01c6066b7be4b87a0b683389dd5c
+guid: b33d01c3c728ef448b641fc699a822e6
+timeCreated: 1503738735
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 7 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/Exceptions/BsonInternalException.cs

@@ -1,4 +1,4 @@
-/* Copyright 2010-2014 MongoDB Inc.
+/* Copyright 2010-2016 MongoDB Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -14,14 +14,18 @@
 */
 
 using System;
+#if NET45
 using System.Runtime.Serialization;
+#endif
 
 namespace MongoDB.Bson
 {
     /// <summary>
     /// Represents a BSON internal exception (almost surely the result of a bug).
     /// </summary>
+#if NET45
     [Serializable]
+#endif
     public class BsonInternalException : BsonException
     {
         // constructors
@@ -52,6 +56,7 @@ namespace MongoDB.Bson
         {
         }
 
+#if NET45
         /// <summary>
         /// Initializes a new instance of the BsonInternalException class (this overload used by deserialization).
         /// </summary>
@@ -61,5 +66,6 @@ namespace MongoDB.Bson
             : base(info, context)
         {
         }
+#endif
     }
 }

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/Exceptions/BsonInternalException.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: c03f560ff6e57574c8cbbbe73346a0b9
+guid: 666bd0648d9dd854db79401bf5df3cb9
+timeCreated: 1503738734
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 7 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/Exceptions/BsonSerializationException.cs

@@ -1,4 +1,4 @@
-/* Copyright 2010-2014 MongoDB Inc.
+/* Copyright 2010-2016 MongoDB Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -14,14 +14,18 @@
 */
 
 using System;
+#if NET45
 using System.Runtime.Serialization;
+#endif
 
 namespace MongoDB.Bson
 {
     /// <summary>
     /// Represents a BSON serialization exception.
     /// </summary>
+#if NET45
     [Serializable]
+#endif
     public class BsonSerializationException : BsonException
     {
         // constructors
@@ -52,6 +56,7 @@ namespace MongoDB.Bson
         {
         }
 
+#if NET45
         /// <summary>
         /// Initializes a new instance of the BsonSerializationException class (this overload used by deserialization).
         /// </summary>
@@ -61,5 +66,6 @@ namespace MongoDB.Bson
             : base(info, context)
         {
         }
+#endif
     }
 }

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/Exceptions/BsonSerializationException.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: 7ef7520c011708245850c5e7bd79d0f7
+guid: e33251635c1d97e4581ee2e7e3eafd3d
+timeCreated: 1503738736
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/Exceptions/DuplicateBsonMemberMapAttributeException.cs

@@ -1,4 +1,4 @@
-/* Copyright 2010-2014 MongoDB Inc.
+/* Copyright 2010-2016 MongoDB Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -20,7 +20,9 @@ namespace MongoDB.Bson
     /// <summary>
     /// Indicates that an attribute restricted to one member has been applied to multiple members.
     /// </summary>
+#if NET45
     [Serializable]
+#endif
     public class DuplicateBsonMemberMapAttributeException : BsonException
     {
         // constructors 
@@ -43,6 +45,7 @@ namespace MongoDB.Bson
         {
         }
 
+#if NET45
         /// <summary>
         /// Initializes a new instance of the <see cref="DuplicateBsonMemberMapAttributeException" /> class.
         /// </summary>
@@ -54,5 +57,6 @@ namespace MongoDB.Bson
             : base(info, context)
         {
         }
+#endif
     }
 }

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/Exceptions/DuplicateBsonMemberMapAttributeException.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: 3f6b60d31c63c924ab75234b4e23421f
+guid: 9ef6004bfc431a1499bc2cb0cb0ee26c
+timeCreated: 1503738735
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 7 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/Exceptions/TruncationException.cs

@@ -1,4 +1,4 @@
-/* Copyright 2010-2014 MongoDB Inc.
+/* Copyright 2010-2016 MongoDB Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -14,14 +14,18 @@
 */
 
 using System;
+#if NET45
 using System.Runtime.Serialization;
+#endif
 
 namespace MongoDB.Bson
 {
     /// <summary>
     /// Represents a truncation exception.
     /// </summary>
+#if NET45
     [Serializable]
+#endif
     public class TruncationException : BsonException
     {
         // constructors
@@ -52,6 +56,7 @@ namespace MongoDB.Bson
         {
         }
 
+#if NET45
         /// <summary>
         /// Initializes a new instance of the TruncationException class (this overload used by deserialization).
         /// </summary>
@@ -61,5 +66,6 @@ namespace MongoDB.Bson
             : base(info, context)
         {
         }
+#endif
     }
 }

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/Exceptions/TruncationException.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: 22e7ec2e14fb871438082dcfa7b9b32b
+guid: cc15768bf330d534ea5aa8126eee729f
+timeCreated: 1503738735
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO.meta

@@ -1,5 +1,9 @@
 fileFormatVersion: 2
-guid: 22d7dc519ad0d8d4fa3b81817f18edc5
+guid: 6b13bee276f97a1408d9686387bb83bd
 folderAsset: yes
+timeCreated: 1503738732
+licenseType: Free
 DefaultImporter:
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 125 - 0
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/ArrayElementNameAccelerator.cs

@@ -0,0 +1,125 @@
+/* Copyright 2010-2016 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;
+
+namespace MongoDB.Bson.IO
+{
+    /// <summary>
+    /// Represents a fast converter from integer indexes to UTF8 BSON array element names.
+    /// </summary>
+    internal interface IArrayElementNameAccelerator
+    {
+        /// <summary>
+        /// Gets the element name bytes.
+        /// </summary>
+        /// <param name="index">The index.</param>
+        /// <returns>The element name bytes.</returns>
+        byte[] GetElementNameBytes(int index);
+    }
+
+    /// <summary>
+    /// Represents a fast converter from integer indexes to UTF8 BSON array element names.
+    /// </summary>
+    internal class ArrayElementNameAccelerator : IArrayElementNameAccelerator
+    {
+        #region static
+        // static fields
+        private static IArrayElementNameAccelerator __default = new ArrayElementNameAccelerator(1000);
+
+        // static properties
+        /// <summary>
+        /// Gets or sets the default array element name accelerator.
+        /// </summary>
+        public static IArrayElementNameAccelerator Default
+        {
+            get { return __default; }
+            set { __default = value; }
+        }
+        #endregion
+
+        // fields
+        private readonly byte[][] _cachedElementNames;
+
+        // constructors
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ArrayElementNameAccelerator"/> class.
+        /// </summary>
+        /// <param name="numberOfCachedElementNames">The number of cached element names.</param>
+        public ArrayElementNameAccelerator(int numberOfCachedElementNames)
+        {
+            _cachedElementNames = new byte[numberOfCachedElementNames][];
+            for (int index = 0; index < numberOfCachedElementNames; index++)
+            {
+                _cachedElementNames[index] = CreateElementNameBytes(index);
+            }
+        }
+
+        // methods
+        private byte[] CreateElementNameBytes(int index)
+        {
+            // unrolled loop optimized for index values >= 1000 and < 10,000
+
+            const int asciiZero = 48;
+
+            var n = index;
+            var a = (byte)(asciiZero + n % 10);
+            n = n / 10;
+            var b = (byte)(asciiZero + n % 10);
+            n = n / 10;
+            var c = (byte)(asciiZero + n % 10);
+            n = n / 10;
+            var d = (byte)(asciiZero + n % 10);
+            n = n / 10;
+
+            if (n == 0)
+            {
+                if (d != (byte)asciiZero) { return new[] { d, c, b, a }; }
+                if (c != (byte)asciiZero) { return new[] { c, b, a }; }
+                if (b != (byte)asciiZero) { return new[] { b, a }; }
+                return new[] { a };
+            }
+
+            var e = (byte)(asciiZero + n % 10);
+            n = n / 10;
+            if (n == 0) { return new[] { e, d, c, b, a }; }
+
+            // really large indexes should be extremely rare and not worth optimizing further
+            return Utf8Encodings.Strict.GetBytes(index.ToString());
+        }
+
+        /// <summary>
+        /// Gets the element name bytes.
+        /// </summary>
+        /// <param name="index">The index.</param>
+        /// <returns>
+        /// The element name bytes.
+        /// </returns>
+        public byte[] GetElementNameBytes(int index)
+        {
+            if (index < 0)
+            {
+                throw new ArgumentOutOfRangeException("index", "index is negative.");
+            }
+
+            if (index < _cachedElementNames.Length)
+            {
+                return  _cachedElementNames[index];
+            }
+
+            return CreateElementNameBytes(index);
+        }
+    }
+}

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/Serialization/Attributes/IBsonClassMapModifier.cs.meta → Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/ArrayElementNameAccelerator.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: 663da8e7cb0a8734491393746403fcdf
+guid: 755fdba7a44e17f478c63b1de3d3f4ef
+timeCreated: 1503738734
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 222 - 104
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryReader.cs

@@ -1,4 +1,4 @@
-/* Copyright 2010-2014 MongoDB Inc.
+/* Copyright 2010-2016 MongoDB Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -14,6 +14,7 @@
 */
 
 using System;
+using System.Globalization;
 using System.IO;
 
 namespace MongoDB.Bson.IO
@@ -24,55 +25,66 @@ namespace MongoDB.Bson.IO
     public class BsonBinaryReader : BsonReader
     {
         // private fields
-        private BsonBuffer _buffer; // if reading from a stream Create will have loaded the buffer
-        private bool _disposeBuffer;
-        private BsonBinaryReaderSettings _binaryReaderSettings; // same value as in base class just declared as derived class
+        private readonly Stream _baseStream;
+        private readonly BsonStream _bsonStream;
+        private readonly BsonBinaryReaderSettings _settings; // same value as in base class just declared as derived class
         private BsonBinaryReaderContext _context;
 
         // constructors
         /// <summary>
         /// Initializes a new instance of the BsonBinaryReader class.
         /// </summary>
-        /// <param name="buffer">A BsonBuffer.</param>
-        /// <param name="settings">A BsonBinaryReaderSettings.</param>
-        public BsonBinaryReader(BsonBuffer buffer, BsonBinaryReaderSettings settings)
-            : this(buffer ?? new BsonBuffer(), buffer == null, settings)
+        /// <param name="stream">A stream (BsonBinary does not own the stream and will not Dispose it).</param>
+        public BsonBinaryReader(Stream stream)
+            : this(stream, BsonBinaryReaderSettings.Defaults)
         {
         }
 
         /// <summary>
         /// Initializes a new instance of the BsonBinaryReader 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="stream">A stream (BsonBinary does not own the stream and will not Dispose it).</param>
         /// <param name="settings">A BsonBinaryReaderSettings.</param>
-        /// <exception cref="System.ArgumentNullException">
-        /// buffer
-        /// or
-        /// settings
-        /// </exception>
-        public BsonBinaryReader(BsonBuffer buffer, bool disposeBuffer, BsonBinaryReaderSettings settings)
+        public BsonBinaryReader(Stream stream, BsonBinaryReaderSettings settings)
             : base(settings)
         {
-            if (buffer == null)
+            if (stream == null)
+            {
+                throw new ArgumentNullException("stream");
+            }
+            if (!stream.CanSeek)
             {
-                throw new ArgumentNullException("buffer");
+                throw new ArgumentException("The stream must be capable of seeking.", "stream");
             }
 
-            _buffer = buffer;
-            _disposeBuffer = disposeBuffer;
-            _binaryReaderSettings = settings; // already frozen by base class
+            _baseStream = stream;
+            _bsonStream = (stream as BsonStream) ?? new BsonStreamAdapter(stream);
+            _settings = settings; // already frozen by base class
 
             _context = new BsonBinaryReaderContext(null, ContextType.TopLevel, 0, 0);
         }
 
         // public properties
         /// <summary>
-        /// Gets the reader's buffer.
+        /// Gets the base stream.
         /// </summary>
-        public BsonBuffer Buffer
+        /// <value>
+        /// The base stream.
+        /// </value>
+        public Stream BaseStream
         {
-            get { return _buffer; }
+            get { return _baseStream; }
+        }
+
+        /// <summary>
+        /// Gets the BSON stream.
+        /// </summary>
+        /// <value>
+        /// The BSON stream.
+        /// </value>
+        public BsonStream BsonStream
+        {
+            get { return _bsonStream; }
         }
 
         // public methods
@@ -82,10 +94,7 @@ namespace MongoDB.Bson.IO
         public override void Close()
         {
             // Close can be called on Disposed objects
-            if (State != BsonReaderState.Closed)
-            {
-                State = BsonReaderState.Closed;
-            }
+            State = BsonReaderState.Closed;
         }
 
         /// <summary>
@@ -94,7 +103,18 @@ namespace MongoDB.Bson.IO
         /// <returns>A bookmark.</returns>
         public override BsonReaderBookmark GetBookmark()
         {
-            return new BsonBinaryReaderBookmark(State, CurrentBsonType, CurrentName, _context, _buffer.Position);
+            return new BsonBinaryReaderBookmark(State, CurrentBsonType, CurrentName, _context, _bsonStream.Position);
+        }
+
+        /// <summary>
+        /// Determines whether this reader is at end of file.
+        /// </summary>
+        /// <returns>
+        /// Whether this reader is at end of file.
+        /// </returns>
+        public override bool IsAtEndOfFile()
+        {
+            return _bsonStream.Position >= _bsonStream.Length;
         }
 
         /// <summary>
@@ -109,40 +129,40 @@ namespace MongoDB.Bson.IO
 
             int size = ReadSize();
 
-            var subType = (BsonBinarySubType)_buffer.ReadByte();
+            var subType = _bsonStream.ReadBinarySubType();
             if (subType == BsonBinarySubType.OldBinary)
             {
                 // sub type OldBinary has two sizes (for historical reasons)
                 int size2 = ReadSize();
                 if (size2 != size - 4)
                 {
-                    throw new Exception("Binary sub type OldBinary has inconsistent sizes");
+                    throw new FormatException("Binary sub type OldBinary has inconsistent sizes");
                 }
                 size = size2;
 
-                if (_binaryReaderSettings.FixOldBinarySubTypeOnInput)
+                if (_settings.FixOldBinarySubTypeOnInput)
                 {
                     subType = BsonBinarySubType.Binary; // replace obsolete OldBinary with new Binary sub type
                 }
             }
 
-            var bytes = _buffer.ReadBytes(size);
+            var bytes = _bsonStream.ReadBytes(size);
 
             var guidRepresentation = GuidRepresentation.Unspecified;
             if (subType == BsonBinarySubType.UuidLegacy || subType == BsonBinarySubType.UuidStandard)
             {
-                if (_binaryReaderSettings.GuidRepresentation != GuidRepresentation.Unspecified)
+                if (_settings.GuidRepresentation != GuidRepresentation.Unspecified)
                 {
-                    var expectedSubType = (_binaryReaderSettings.GuidRepresentation == GuidRepresentation.Standard) ? BsonBinarySubType.UuidStandard : BsonBinarySubType.UuidLegacy;
+                    var expectedSubType = (_settings.GuidRepresentation == GuidRepresentation.Standard) ? BsonBinarySubType.UuidStandard : BsonBinarySubType.UuidLegacy;
                     if (subType != expectedSubType)
                     {
                         var message = string.Format(
                             "The GuidRepresentation for the reader is {0}, which requires the binary sub type to be {1}, not {2}.",
-                            _binaryReaderSettings.GuidRepresentation, expectedSubType, subType);
-                        throw new Exception(message);
+                            _settings.GuidRepresentation, expectedSubType, subType);
+                        throw new FormatException(message);
                     }
                 }
-                guidRepresentation = (subType == BsonBinarySubType.UuidStandard) ? GuidRepresentation.Standard : _binaryReaderSettings.GuidRepresentation;
+                guidRepresentation = (subType == BsonBinarySubType.UuidStandard) ? GuidRepresentation.Standard : _settings.GuidRepresentation;
             }
 
             State = GetNextState();
@@ -159,23 +179,17 @@ namespace MongoDB.Bson.IO
             if (Disposed) { ThrowObjectDisposedException(); }
             VerifyBsonType("ReadBoolean", BsonType.Boolean);
             State = GetNextState();
-            return _buffer.ReadBoolean();
+            return _bsonStream.ReadBoolean();
         }
 
         /// <summary>
         /// Reads a BsonType from the reader.
         /// </summary>
-        /// <typeparam name="TValue">The type of the BsonTrie values.</typeparam>
-        /// <param name="bsonTrie">An optional trie to search for a value that matches the next element name.</param>
-        /// <param name="found">Set to true if a matching value was found in the trie.</param>
-        /// <param name="value">Set to the matching value found in the trie or null if no matching value was found.</param>
         /// <returns>A BsonType.</returns>
-        public override BsonType ReadBsonType<TValue>(BsonTrie<TValue> bsonTrie, out bool found, out TValue value)
+        public override BsonType ReadBsonType()
         {
             if (Disposed) { ThrowObjectDisposedException(); }
-            found = false;
-            value = default(TValue);
-            if (State == BsonReaderState.Initial || State == BsonReaderState.Done || State == BsonReaderState.ScopeDocument)
+            if (State == BsonReaderState.Initial || State == BsonReaderState.ScopeDocument)
             {
                 // there is an implied type of Document for the top level and for scope documents
                 CurrentBsonType = BsonType.Document;
@@ -187,7 +201,28 @@ namespace MongoDB.Bson.IO
                 ThrowInvalidState("ReadBsonType", BsonReaderState.Type);
             }
 
-            CurrentBsonType = _buffer.ReadBsonType();
+            if (_context.ContextType == ContextType.Array)
+            {
+                _context.CurrentArrayIndex++;
+            }
+
+            try
+            {
+
+                CurrentBsonType = _bsonStream.ReadBsonType();
+            }
+            catch (FormatException ex)
+            {
+                if (ex.Message.StartsWith("Detected unknown BSON type"))
+                {
+                    // insert the element name into the error message
+                    var periodIndex = ex.Message.IndexOf('.');
+                    var dottedElementName = GenerateDottedElementName();
+                    var message = ex.Message.Substring(0, periodIndex) + $" for fieldname \"{dottedElementName}\"" + ex.Message.Substring(periodIndex);
+                    throw new FormatException(message);
+                }
+                throw;
+            }
 
             if (CurrentBsonType == BsonType.EndOfDocument)
             {
@@ -202,7 +237,7 @@ namespace MongoDB.Bson.IO
                         return BsonType.EndOfDocument;
                     default:
                         var message = string.Format("BsonType EndOfDocument is not valid when ContextType is {0}.", _context.ContextType);
-                        throw new Exception(message);
+                        throw new FormatException(message);
                 }
             }
             else
@@ -210,12 +245,11 @@ namespace MongoDB.Bson.IO
                 switch (_context.ContextType)
                 {
                     case ContextType.Array:
-                        _buffer.SkipCString(); // ignore array element names
+                        _bsonStream.SkipCString(); // ignore array element names
                         State = BsonReaderState.Value;
                         break;
                     case ContextType.Document:
                     case ContextType.ScopeDocument:
-                        CurrentName = _buffer.ReadName(bsonTrie, out found, out value);
                         State = BsonReaderState.Name;
                         break;
                     default:
@@ -238,15 +272,15 @@ namespace MongoDB.Bson.IO
 
             int size = ReadSize();
 
-            var subType = (BsonBinarySubType)_buffer.ReadByte();
+            var subType = _bsonStream.ReadBinarySubType();
             if (subType != BsonBinarySubType.Binary && subType != BsonBinarySubType.OldBinary)
             {
-                var message = string.Format("ReadBytes requires the binary sub type to be Binary, not {2}.", subType);
-                throw new Exception(message);
+                var message = string.Format("ReadBytes requires the binary sub type to be Binary, not {0}.", subType);
+                throw new FormatException(message);
             }
 
             State = GetNextState();
-            return _buffer.ReadBytes(size);
+            return _bsonStream.ReadBytes(size);
         }
 #pragma warning restore 618
 
@@ -259,10 +293,10 @@ namespace MongoDB.Bson.IO
             if (Disposed) { ThrowObjectDisposedException(); }
             VerifyBsonType("ReadDateTime", BsonType.DateTime);
             State = GetNextState();
-            var value = _buffer.ReadInt64();
+            var value = _bsonStream.ReadInt64();
             if (value == BsonConstants.DateTimeMaxValueMillisecondsSinceEpoch + 1)
             {
-                if (_binaryReaderSettings.FixOldDateTimeMaxValueOnInput)
+                if (_settings.FixOldDateTimeMaxValueOnInput)
                 {
                     value = BsonConstants.DateTimeMaxValueMillisecondsSinceEpoch;
                 }
@@ -270,6 +304,15 @@ namespace MongoDB.Bson.IO
             return value;
         }
 
+        /// <inheritdoc />
+        public override Decimal128 ReadDecimal128()
+        {
+            if (Disposed) { ThrowObjectDisposedException(); }
+            VerifyBsonType(nameof(ReadDecimal128), BsonType.Decimal128);
+            State = GetNextState();
+            return _bsonStream.ReadDecimal128();
+        }
+
         /// <summary>
         /// Reads a BSON Double from the reader.
         /// </summary>
@@ -279,7 +322,7 @@ namespace MongoDB.Bson.IO
             if (Disposed) { ThrowObjectDisposedException(); }
             VerifyBsonType("ReadDouble", BsonType.Double);
             State = GetNextState();
-            return _buffer.ReadDouble();
+            return _bsonStream.ReadDouble();
         }
 
         /// <summary>
@@ -301,12 +344,12 @@ namespace MongoDB.Bson.IO
                 ThrowInvalidState("ReadEndArray", BsonReaderState.EndOfArray);
             }
 
-            _context = _context.PopContext(_buffer.Position);
+            _context = _context.PopContext(_bsonStream.Position);
             switch (_context.ContextType)
             {
                 case ContextType.Array: State = BsonReaderState.Type; break;
                 case ContextType.Document: State = BsonReaderState.Type; break;
-                case ContextType.TopLevel: State = BsonReaderState.Done; break;
+                case ContextType.TopLevel: State = BsonReaderState.Initial; break;
                 default: throw new BsonInternalException("Unexpected ContextType.");
             }
         }
@@ -330,16 +373,16 @@ namespace MongoDB.Bson.IO
                 ThrowInvalidState("ReadEndDocument", BsonReaderState.EndOfDocument);
             }
 
-            _context = _context.PopContext(_buffer.Position);
+            _context = _context.PopContext(_bsonStream.Position);
             if (_context.ContextType == ContextType.JavaScriptWithScope)
             {
-                _context = _context.PopContext(_buffer.Position); // JavaScriptWithScope
+                _context = _context.PopContext(_bsonStream.Position); // JavaScriptWithScope
             }
             switch (_context.ContextType)
             {
                 case ContextType.Array: State = BsonReaderState.Type; break;
                 case ContextType.Document: State = BsonReaderState.Type; break;
-                case ContextType.TopLevel: State = BsonReaderState.Done; break;
+                case ContextType.TopLevel: State = BsonReaderState.Initial; break;
                 default: throw new BsonInternalException("Unexpected ContextType.");
             }
         }
@@ -353,7 +396,7 @@ namespace MongoDB.Bson.IO
             if (Disposed) { ThrowObjectDisposedException(); }
             VerifyBsonType("ReadInt32", BsonType.Int32);
             State = GetNextState();
-            return _buffer.ReadInt32();
+            return _bsonStream.ReadInt32();
         }
 
         /// <summary>
@@ -365,7 +408,7 @@ namespace MongoDB.Bson.IO
             if (Disposed) { ThrowObjectDisposedException(); }
             VerifyBsonType("ReadInt64", BsonType.Int64);
             State = GetNextState();
-            return _buffer.ReadInt64();
+            return _bsonStream.ReadInt64();
         }
 
         /// <summary>
@@ -377,7 +420,7 @@ namespace MongoDB.Bson.IO
             if (Disposed) { ThrowObjectDisposedException(); }
             VerifyBsonType("ReadJavaScript", BsonType.JavaScript);
             State = GetNextState();
-            return _buffer.ReadString(_binaryReaderSettings.Encoding);
+            return _bsonStream.ReadString(_settings.Encoding);
         }
 
         /// <summary>
@@ -389,10 +432,10 @@ namespace MongoDB.Bson.IO
             if (Disposed) { ThrowObjectDisposedException(); }
             VerifyBsonType("ReadJavaScriptWithScope", BsonType.JavaScriptWithScope);
 
-            var startPosition = _buffer.Position; // position of size field
+            var startPosition = _bsonStream.Position; // position of size field
             var size = ReadSize();
             _context = new BsonBinaryReaderContext(_context, ContextType.JavaScriptWithScope, startPosition, size);
-            var code = _buffer.ReadString(_binaryReaderSettings.Encoding);
+            var code = _bsonStream.ReadString(_settings.Encoding);
 
             State = BsonReaderState.ScopeDocument;
             return code;
@@ -418,6 +461,39 @@ namespace MongoDB.Bson.IO
             State = GetNextState();
         }
 
+        /// <summary>
+        /// Reads the name of an element from the reader.
+        /// </summary>
+        /// <param name="nameDecoder">The name decoder.</param>
+        /// <returns>The name of the element.</returns>
+        public override string ReadName(INameDecoder nameDecoder)
+        {
+            if (nameDecoder == null)
+            {
+                throw new ArgumentNullException("nameDecoder");
+            }
+
+            if (Disposed) { ThrowObjectDisposedException(); }
+            if (State == BsonReaderState.Type)
+            {
+                ReadBsonType();
+            }
+            if (State != BsonReaderState.Name)
+            {
+                ThrowInvalidState("ReadName", BsonReaderState.Name);
+            }
+
+            CurrentName = nameDecoder.Decode(_bsonStream, _settings.Encoding);
+            State = BsonReaderState.Value;
+
+            if (_context.ContextType == ContextType.Document)
+            {
+                _context.CurrentElementName = CurrentName;
+            }
+
+            return CurrentName;
+        }
+
         /// <summary>
         /// Reads a BSON null from the reader.
         /// </summary>
@@ -437,7 +513,7 @@ namespace MongoDB.Bson.IO
             if (Disposed) { ThrowObjectDisposedException(); }
             VerifyBsonType("ReadObjectId", BsonType.ObjectId);
             State = GetNextState();
-            return _buffer.ReadObjectId();
+            return _bsonStream.ReadObjectId();
         }
 
         /// <summary>
@@ -451,16 +527,13 @@ namespace MongoDB.Bson.IO
             if (Disposed) { ThrowObjectDisposedException(); }
             VerifyBsonType("ReadRawBsonArray", BsonType.Array);
 
-            var position = _buffer.Position;
-            var length = _buffer.ReadInt32();
-            var slice = _buffer.ByteBuffer.GetSlice(position, length);
-            _buffer.Position = position + length;
+            var slice = _bsonStream.ReadSlice();
 
             switch (_context.ContextType)
             {
                 case ContextType.Array: State = BsonReaderState.Type; break;
                 case ContextType.Document: State = BsonReaderState.Type; break;
-                case ContextType.TopLevel: State = BsonReaderState.Done; break;
+                case ContextType.TopLevel: State = BsonReaderState.Initial; break;
                 default: throw new BsonInternalException("Unexpected ContextType.");
             }
 
@@ -478,20 +551,17 @@ namespace MongoDB.Bson.IO
             if (Disposed) { ThrowObjectDisposedException(); }
             VerifyBsonType("ReadRawBsonDocument", BsonType.Document);
 
-            var position = _buffer.Position;
-            var length = _buffer.ReadInt32();
-            var slice = _buffer.ByteBuffer.GetSlice(position, length);
-            _buffer.Position = position + length;
+            var slice = _bsonStream.ReadSlice();
 
             if (_context.ContextType == ContextType.JavaScriptWithScope)
             {
-                _context = _context.PopContext(_buffer.Position); // JavaScriptWithScope
+                _context = _context.PopContext(_bsonStream.Position); // JavaScriptWithScope
             }
             switch (_context.ContextType)
             {
                 case ContextType.Array: State = BsonReaderState.Type; break;
                 case ContextType.Document: State = BsonReaderState.Type; break;
-                case ContextType.TopLevel: State = BsonReaderState.Done; break;
+                case ContextType.TopLevel: State = BsonReaderState.Initial; break;
                 default: throw new BsonInternalException("Unexpected ContextType.");
             }
 
@@ -507,8 +577,8 @@ namespace MongoDB.Bson.IO
             if (Disposed) { ThrowObjectDisposedException(); }
             VerifyBsonType("ReadRegularExpression", BsonType.RegularExpression);
             State = GetNextState();
-            var pattern = _buffer.ReadCString(_binaryReaderSettings.Encoding);
-            var options = _buffer.ReadCString(_binaryReaderSettings.Encoding);
+            var pattern = _bsonStream.ReadCString(_settings.Encoding);
+            var options = _bsonStream.ReadCString(_settings.Encoding);
             return new BsonRegularExpression(pattern, options);
         }
 
@@ -520,7 +590,7 @@ namespace MongoDB.Bson.IO
             if (Disposed) { ThrowObjectDisposedException(); }
             VerifyBsonType("ReadStartArray", BsonType.Array);
 
-            var startPosition = _buffer.Position; // position of size field
+            var startPosition = _bsonStream.Position; // position of size field
             var size = ReadSize();
             _context = new BsonBinaryReaderContext(_context, ContextType.Array, startPosition, size);
             State = BsonReaderState.Type;
@@ -535,7 +605,7 @@ namespace MongoDB.Bson.IO
             VerifyBsonType("ReadStartDocument", BsonType.Document);
 
             var contextType = (State == BsonReaderState.ScopeDocument) ? ContextType.ScopeDocument : ContextType.Document;
-            var startPosition = _buffer.Position; // position of size field
+            var startPosition = _bsonStream.Position; // position of size field
             var size = ReadSize();
             _context = new BsonBinaryReaderContext(_context, contextType, startPosition, size);
             State = BsonReaderState.Type;
@@ -550,7 +620,7 @@ namespace MongoDB.Bson.IO
             if (Disposed) { ThrowObjectDisposedException(); }
             VerifyBsonType("ReadString", BsonType.String);
             State = GetNextState();
-            return _buffer.ReadString(_binaryReaderSettings.Encoding);
+            return _bsonStream.ReadString(_settings.Encoding);
         }
 
         /// <summary>
@@ -562,7 +632,7 @@ namespace MongoDB.Bson.IO
             if (Disposed) { ThrowObjectDisposedException(); }
             VerifyBsonType("ReadSymbol", BsonType.Symbol);
             State = GetNextState();
-            return _buffer.ReadString(_binaryReaderSettings.Encoding);
+            return _bsonStream.ReadString(_settings.Encoding);
         }
 
         /// <summary>
@@ -574,7 +644,7 @@ namespace MongoDB.Bson.IO
             if (Disposed) { ThrowObjectDisposedException(); }
             VerifyBsonType("ReadTimestamp", BsonType.Timestamp);
             State = GetNextState();
-            return _buffer.ReadInt64();
+            return _bsonStream.ReadInt64();
         }
 
         /// <summary>
@@ -598,7 +668,7 @@ namespace MongoDB.Bson.IO
             CurrentBsonType = binaryReaderBookmark.CurrentBsonType;
             CurrentName = binaryReaderBookmark.CurrentName;
             _context = binaryReaderBookmark.CloneContext();
-            _buffer.Position = binaryReaderBookmark.Position;
+            _bsonStream.Position = binaryReaderBookmark.Position;
         }
 
         /// <summary>
@@ -612,7 +682,14 @@ namespace MongoDB.Bson.IO
                 ThrowInvalidState("SkipName", BsonReaderState.Name);
             }
 
+            _bsonStream.SkipCString();
+            CurrentName = null;
             State = BsonReaderState.Value;
+
+            if (_context.ContextType == ContextType.Document)
+            {
+                _context.CurrentElementName = CurrentName;
+            }
         }
 
         /// <summary>
@@ -634,6 +711,7 @@ namespace MongoDB.Bson.IO
                 case BsonType.Boolean: skip = 1; break;
                 case BsonType.DateTime: skip = 8; break;
                 case BsonType.Document: skip = ReadSize() - 4; break;
+                case BsonType.Decimal128: skip = 16; break;
                 case BsonType.Double: skip = 8; break;
                 case BsonType.Int32: skip = 4; break;
                 case BsonType.Int64: skip = 8; break;
@@ -643,14 +721,14 @@ namespace MongoDB.Bson.IO
                 case BsonType.MinKey: skip = 0; break;
                 case BsonType.Null: skip = 0; break;
                 case BsonType.ObjectId: skip = 12; break;
-                case BsonType.RegularExpression: _buffer.SkipCString(); _buffer.SkipCString(); skip = 0; break;
+                case BsonType.RegularExpression: _bsonStream.SkipCString(); _bsonStream.SkipCString(); skip = 0; break;
                 case BsonType.String: skip = ReadSize(); break;
                 case BsonType.Symbol: skip = ReadSize(); break;
                 case BsonType.Timestamp: skip = 8; break;
                 case BsonType.Undefined: skip = 0; break;
                 default: throw new BsonInternalException("Unexpected BsonType.");
             }
-            _buffer.Skip(skip);
+            _bsonStream.Seek(skip, SeekOrigin.Current);
 
             State = BsonReaderState.Type;
         }
@@ -662,19 +740,12 @@ namespace MongoDB.Bson.IO
         /// <param name="disposing">True if called from Dispose.</param>
         protected override void Dispose(bool disposing)
         {
+            // don't Dispose the _stream because we don't own it
             if (disposing)
             {
                 try
                 {
                     Close();
-                    if (_buffer != null)
-                    {
-                        if (_disposeBuffer)
-                        {
-                            _buffer.Dispose();
-                        }
-                        _buffer = null;
-                    }
                 }
                 catch { } // ignore exceptions
             }
@@ -682,6 +753,53 @@ namespace MongoDB.Bson.IO
         }
 
         // private methods
+        private string GenerateDottedElementName()
+        {
+            string elementName;
+            if (_context.ContextType == ContextType.Document)
+            {
+                try
+                {
+                    elementName = _bsonStream.ReadCString(Utf8Encodings.Lenient);
+                }
+                catch
+                {
+                    elementName = "?"; // ignore exception
+                }
+            }
+            else if (_context.ContextType == ContextType.Array)
+            {
+                elementName = _context.CurrentArrayIndex.ToString(NumberFormatInfo.InvariantInfo);
+            }
+            else
+            {
+                elementName = "?";
+            }
+
+            return GenerateDottedElementName(_context.ParentContext, elementName);
+        }
+
+        private string GenerateDottedElementName(BsonBinaryReaderContext context, string elementName)
+        {
+            if (context.ContextType == ContextType.Document)
+            {
+                return GenerateDottedElementName(context.ParentContext, (context.CurrentElementName ?? "?") + "." + elementName);
+            }
+            else if (context.ContextType == ContextType.Array)
+            {
+                var indexElementName = context.CurrentArrayIndex.ToString(NumberFormatInfo.InvariantInfo);
+                return GenerateDottedElementName(context.ParentContext, indexElementName + "." + elementName);
+            }
+            else if (context.ParentContext != null)
+            {
+                return GenerateDottedElementName(context.ParentContext, "?." + elementName);
+            }
+            else
+            {
+                return elementName;
+            }
+        }
+
         private BsonReaderState GetNextState()
         {
             switch (_context.ContextType)
@@ -691,7 +809,7 @@ namespace MongoDB.Bson.IO
                 case ContextType.ScopeDocument:
                     return BsonReaderState.Type;
                 case ContextType.TopLevel:
-                    return BsonReaderState.Done;
+                    return BsonReaderState.Initial;
                 default:
                     throw new BsonInternalException("Unexpected ContextType.");
             }
@@ -699,16 +817,16 @@ namespace MongoDB.Bson.IO
 
         private int ReadSize()
         {
-            int size = _buffer.ReadInt32();
+            int size = _bsonStream.ReadInt32();
             if (size < 0)
             {
                 var message = string.Format("Size {0} is not valid because it is negative.", size);
-                throw new Exception(message);
+                throw new FormatException(message);
             }
-            if (size > _binaryReaderSettings.MaxDocumentSize)
+            if (size > _settings.MaxDocumentSize)
             {
-                var message = string.Format("Size {0} is not valid because it is larger than MaxDocumentSize {1}.", size, _binaryReaderSettings.MaxDocumentSize);
-                throw new Exception(message);
+                var message = string.Format("Size {0} is not valid because it is larger than MaxDocumentSize {1}.", size, _settings.MaxDocumentSize);
+                throw new FormatException(message);
             }
             return size;
         }

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryReader.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: a80ff80615d759e49aac45acd751a312
+guid: 8a5b3e52e7d803d4baf3097168468f07
+timeCreated: 1503738734
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 3 - 3
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryReaderBookmark.cs

@@ -22,7 +22,7 @@ namespace MongoDB.Bson.IO
     {
         // private fields
         private BsonBinaryReaderContext _context;
-        private int _position;
+        private long _position;
 
         // constructors
         internal BsonBinaryReaderBookmark(
@@ -30,7 +30,7 @@ namespace MongoDB.Bson.IO
             BsonType currentBsonType,
             string currentName,
             BsonBinaryReaderContext context,
-            int position)
+            long position)
             : base(state, currentBsonType, currentName)
         {
             _context = context.Clone();
@@ -38,7 +38,7 @@ namespace MongoDB.Bson.IO
         }
 
         // internal properties
-        internal int Position
+        internal long Position
         {
             get { return _position; }
         }

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryReaderBookmark.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: 4380bba3214c8a94c8fae471f9abfd7a
+guid: 8c7395972bc4a6549ae77026af563002
+timeCreated: 1503738734
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 31 - 13
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryReaderContext.cs

@@ -1,4 +1,4 @@
-/* Copyright 2010-2014 MongoDB Inc.
+/* Copyright 2010-2016 MongoDB Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -14,24 +14,25 @@
 */
 
 using System;
-using System.IO;
 
 namespace MongoDB.Bson.IO
 {
     internal class BsonBinaryReaderContext
     {
         // private fields
-        private BsonBinaryReaderContext _parentContext;
-        private ContextType _contextType;
-        private int _startPosition;
-        private int _size;
+        private readonly BsonBinaryReaderContext _parentContext;
+        private readonly ContextType _contextType;
+        private readonly long _startPosition;
+        private readonly long _size;
+        private string _currentElementName;
+        private int _currentArrayIndex = -1;
 
         // constructors
         internal BsonBinaryReaderContext(
             BsonBinaryReaderContext parentContext,
             ContextType contextType,
-            int startPosition, 
-            int size)
+            long startPosition,
+            long size)
         {
             _parentContext = parentContext;
             _contextType = contextType;
@@ -39,12 +40,29 @@ namespace MongoDB.Bson.IO
             _size = size;
         }
 
-        // internal properties
-        internal ContextType ContextType
+        // public properties
+        public ContextType ContextType
         {
             get { return _contextType; }
         }
 
+        public int CurrentArrayIndex
+        {
+            get { return _currentArrayIndex; }
+            set { _currentArrayIndex = value; }
+        }
+
+        public string CurrentElementName
+        {
+            get { return _currentElementName; }
+            set { _currentElementName = value; }
+        }
+
+        public BsonBinaryReaderContext ParentContext
+        {
+            get { return _parentContext; }
+        }
+
         // public methods
         /// <summary>
         /// Creates a clone of the context.
@@ -55,13 +73,13 @@ namespace MongoDB.Bson.IO
             return new BsonBinaryReaderContext(_parentContext, _contextType, _startPosition, _size);
         }
 
-        public BsonBinaryReaderContext PopContext(int position)
+        public BsonBinaryReaderContext PopContext(long position)
         {
-            int actualSize = position - _startPosition;
+            var actualSize = position - _startPosition;
             if (actualSize != _size)
             {
                 var message = string.Format("Expected size to be {0}, not {1}.", _size, actualSize);
-                throw new Exception(message);
+                throw new FormatException(message);
             }
             return _parentContext;
         }

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryReaderContext.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: bf041ffe9fe989841a3cd574309b991d
+guid: 83d2e15e2de1f734ea170b31e955f6e5
+timeCreated: 1503738734
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 4 - 40
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryReaderSettings.cs

@@ -1,4 +1,4 @@
-/* Copyright 2010-2014 MongoDB Inc.
+/* Copyright 2010-2016 MongoDB Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -21,15 +21,16 @@ namespace MongoDB.Bson.IO
     /// <summary>
     /// Represents settings for a BsonBinaryReader.
     /// </summary>
+#if NET45
     [Serializable]
+#endif
     public class BsonBinaryReaderSettings : BsonReaderSettings
     {
         // private static fields
         private static BsonBinaryReaderSettings __defaults = null; // delay creation to pick up the latest default values
 
         // private fields
-        private bool _closeInput = false;
-        private UTF8Encoding _encoding = new UTF8Encoding(false, true);
+        private UTF8Encoding _encoding = Utf8Encodings.Strict;
         private bool _fixOldBinarySubTypeOnInput = true;
         private bool _fixOldDateTimeMaxValueOnInput = true;
         private int _maxDocumentSize = BsonDefaults.MaxDocumentSize;
@@ -42,29 +43,6 @@ namespace MongoDB.Bson.IO
         {
         }
 
-        /// <summary>
-        /// Initializes a new instance of the BsonBinaryReaderSettings class.
-        /// </summary>
-        /// <param name="closeInput">Whether to close the input stream when the reader is closed.</param>
-        /// <param name="fixOldBinarySubTypeOnInput">Whether to fix occurrences of the old binary subtype on input.</param>
-        /// <param name="fixOldDateTimeMaxValueOnInput">Whether to fix occurrences of the old representation of DateTime.MaxValue on input.</param>
-        /// <param name="guidRepresentation">The representation for Guids.</param>
-        /// <param name="maxDocumentSize">The max document size.</param>
-        [Obsolete("Use the no-argument constructor instead and set the properties.")]
-        public BsonBinaryReaderSettings(
-            bool closeInput,
-            bool fixOldBinarySubTypeOnInput,
-            bool fixOldDateTimeMaxValueOnInput,
-            GuidRepresentation guidRepresentation,
-            int maxDocumentSize)
-            : base(guidRepresentation)
-        {
-            _closeInput = closeInput;
-            _fixOldBinarySubTypeOnInput = fixOldBinarySubTypeOnInput;
-            _fixOldDateTimeMaxValueOnInput = fixOldDateTimeMaxValueOnInput;
-            _maxDocumentSize = maxDocumentSize;
-        }
-
         // public static properties
         /// <summary>
         /// Gets or sets the default settings for a BsonBinaryReader.
@@ -83,19 +61,6 @@ namespace MongoDB.Bson.IO
         }
 
         // public properties
-        /// <summary>
-        /// Gets or sets whether to close the input stream when the reader is closed.
-        /// </summary>
-        public bool CloseInput
-        {
-            get { return _closeInput; }
-            set
-            {
-                if (IsFrozen) { throw new InvalidOperationException("BsonBinaryReaderSettings is frozen."); }
-                _closeInput = value;
-            }
-        }
-
         /// <summary>
         /// Gets or sets the Encoding.
         /// </summary>
@@ -171,7 +136,6 @@ namespace MongoDB.Bson.IO
         {
             var clone = new BsonBinaryReaderSettings
             {
-                CloseInput = _closeInput,
                 Encoding = _encoding,
                 FixOldBinarySubTypeOnInput = _fixOldBinarySubTypeOnInput,
                 FixOldDateTimeMaxValueOnInput = _fixOldDateTimeMaxValueOnInput,

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryReaderSettings.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: 0c4a0a11e2696554080efde23051bed1
+guid: 1103fe9431ab80e41b542fde3a67b124
+timeCreated: 1503738732
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 131 - 120
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryWriter.cs

@@ -1,4 +1,4 @@
-/* Copyright 2010-2014 MongoDB Inc.
+/* Copyright 2010-2016 MongoDB Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
 using System;
 using System.Collections.Generic;
 using System.IO;
-using System.Text;
 
 namespace MongoDB.Bson.IO
 {
@@ -25,53 +24,44 @@ namespace MongoDB.Bson.IO
     /// </summary>
     public class BsonBinaryWriter : BsonWriter
     {
-        // private static fields
-        private static readonly UTF8Encoding __strictUtf8Encoding = new UTF8Encoding(false, true);
-
         // private fields
-        private Stream _stream; // can be null if we're only writing to the buffer
-        private BsonBuffer _buffer;
-        private bool _disposeBuffer;
-        private BsonBinaryWriterSettings _binaryWriterSettings; // same value as in base class just declared as derived class
-        private Stack<int> _maxDocumentSizeStack = new Stack<int>();
+        private readonly Stream _baseStream;
+        private readonly BsonStream _bsonStream;
+        private readonly BsonBinaryWriterSettings _settings; // same value as in base class just declared as derived class
+        private readonly Stack<int> _maxDocumentSizeStack = new Stack<int>();
         private BsonBinaryWriterContext _context;
 
         // 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)
-            : this(buffer ?? new BsonBuffer(), buffer == null, settings)
+        /// <param name="stream">A stream. The BsonBinaryWriter does not own the stream and will not Dispose it.</param>
+        public BsonBinaryWriter(Stream stream)
+            : this(stream, BsonBinaryWriterSettings.Defaults)
         {
-            _stream = stream;
         }
 
         /// <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)
+        /// <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 (buffer == null)
+            if (stream == null)
+            {
+                throw new ArgumentNullException("stream");
+            }
+            if (!stream.CanSeek)
             {
-                throw new ArgumentNullException("encoder");
+                throw new ArgumentException("The stream must be capable of seeking.", "stream");
             }
 
-            _buffer = buffer;
-            _disposeBuffer = disposeBuffer;
-            _binaryWriterSettings = settings; // already frozen by base class
-            _maxDocumentSizeStack.Push(_binaryWriterSettings.MaxDocumentSize);
+            _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;
@@ -79,16 +69,30 @@ namespace MongoDB.Bson.IO
 
         // public properties
         /// <summary>
-        /// Gets the writer's BsonBuffer.
+        /// Gets the base stream.
+        /// </summary>
+        /// <value>
+        /// The base stream.
+        /// </value>
+        public Stream BaseStream
+        {
+            get { return _baseStream; }
+        }
+
+        /// <summary>
+        /// Gets the BSON stream.
         /// </summary>
-        public BsonBuffer Buffer
+        /// <value>
+        /// The BSON stream.
+        /// </value>
+        public BsonStream BsonStream
         {
-            get { return _buffer; }
+            get { return _bsonStream; }
         }
 
         // public methods
         /// <summary>
-        /// Closes the writer.
+        /// Closes the writer. Also closes the base stream.
         /// </summary>
         public override void Close()
         {
@@ -99,10 +103,6 @@ namespace MongoDB.Bson.IO
                 {
                     Flush();
                 }
-                if (_stream != null && _binaryWriterSettings.CloseOutput)
-                {
-                    _stream.Close();
-                }
                 _context = null;
                 State = BsonWriterState.Closed;
             }
@@ -122,12 +122,7 @@ namespace MongoDB.Bson.IO
             {
                 throw new InvalidOperationException("Flush called before BsonBinaryWriter was finished writing to buffer.");
             }
-            if (_stream != null)
-            {
-                _buffer.WriteTo(_stream);
-                _stream.Flush();
-                _buffer.Clear(); // only clear the buffer if we have written it to a stream
-            }
+            _bsonStream.Flush();
         }
 
         /// <summary>
@@ -166,49 +161,49 @@ namespace MongoDB.Bson.IO
             switch (subType)
             {
                 case BsonBinarySubType.OldBinary:
-                    if (_binaryWriterSettings.FixOldBinarySubTypeOnOutput)
+                    if (_settings.FixOldBinarySubTypeOnOutput)
                     {
                         subType = BsonBinarySubType.Binary; // replace obsolete OldBinary with new Binary sub type
                     }
                     break;
                 case BsonBinarySubType.UuidLegacy:
                 case BsonBinarySubType.UuidStandard:
-                    if (_binaryWriterSettings.GuidRepresentation != GuidRepresentation.Unspecified)
+                    if (_settings.GuidRepresentation != GuidRepresentation.Unspecified)
                     {
-                        var expectedSubType = (_binaryWriterSettings.GuidRepresentation == GuidRepresentation.Standard) ? BsonBinarySubType.UuidStandard : BsonBinarySubType.UuidLegacy;
+                        var expectedSubType = (_settings.GuidRepresentation == GuidRepresentation.Standard) ? BsonBinarySubType.UuidStandard : BsonBinarySubType.UuidLegacy;
                         if (subType != expectedSubType)
                         {
                             var message = string.Format(
                                 "The GuidRepresentation for the writer is {0}, which requires the subType argument to be {1}, not {2}.",
-                                _binaryWriterSettings.GuidRepresentation, expectedSubType, subType);
+                                _settings.GuidRepresentation, expectedSubType, subType);
                             throw new BsonSerializationException(message);
                         }
-                        if (guidRepresentation != _binaryWriterSettings.GuidRepresentation)
+                        if (guidRepresentation != _settings.GuidRepresentation)
                         {
                             var message = string.Format(
                                 "The GuidRepresentation for the writer is {0}, which requires the the guidRepresentation argument to also be {0}, not {1}.",
-                                _binaryWriterSettings.GuidRepresentation, guidRepresentation);
+                                _settings.GuidRepresentation, guidRepresentation);
                             throw new BsonSerializationException(message);
                         }
                     }
                     break;
             }
 
-            _buffer.WriteByte((byte)BsonType.Binary);
+            _bsonStream.WriteBsonType(BsonType.Binary);
             WriteNameHelper();
             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);
+                _bsonStream.WriteInt32(bytes.Length + 4);
+                _bsonStream.WriteBinarySubType(subType);
+                _bsonStream.WriteInt32(bytes.Length);
             }
             else
             {
-                _buffer.WriteInt32(bytes.Length);
-                _buffer.WriteByte((byte)subType);
+                _bsonStream.WriteInt32(bytes.Length);
+                _bsonStream.WriteBinarySubType(subType);
             }
-            _buffer.WriteBytes(bytes);
+            _bsonStream.WriteBytes(bytes, 0, bytes.Length);
 
             State = GetNextState();
         }
@@ -226,9 +221,9 @@ namespace MongoDB.Bson.IO
                 ThrowInvalidState("WriteBoolean", BsonWriterState.Value);
             }
 
-            _buffer.WriteByte((byte)BsonType.Boolean);
+            _bsonStream.WriteBsonType(BsonType.Boolean);
             WriteNameHelper();
-            _buffer.WriteBoolean(value);
+            _bsonStream.WriteBoolean(value);
 
             State = GetNextState();
         }
@@ -245,11 +240,11 @@ namespace MongoDB.Bson.IO
                 ThrowInvalidState("WriteBytes", BsonWriterState.Value);
             }
 
-            _buffer.WriteByte((byte)BsonType.Binary);
+            _bsonStream.WriteBsonType(BsonType.Binary);
             WriteNameHelper();
-            _buffer.WriteInt32(bytes.Length);
-            _buffer.WriteByte((byte)BsonBinarySubType.Binary);
-            _buffer.WriteBytes(bytes);
+            _bsonStream.WriteInt32(bytes.Length);
+            _bsonStream.WriteBinarySubType(BsonBinarySubType.Binary);
+            _bsonStream.WriteBytes(bytes, 0, bytes.Length);
 
             State = GetNextState();
         }
@@ -266,9 +261,25 @@ namespace MongoDB.Bson.IO
                 ThrowInvalidState("WriteDateTime", BsonWriterState.Value);
             }
 
-            _buffer.WriteByte((byte)BsonType.DateTime);
+            _bsonStream.WriteBsonType(BsonType.DateTime);
             WriteNameHelper();
-            _buffer.WriteInt64(value);
+            _bsonStream.WriteInt64(value);
+
+            State = GetNextState();
+        }
+
+        /// <inheritdoc />
+        public override void WriteDecimal128(Decimal128 value)
+        {
+            if (Disposed) { throw new ObjectDisposedException("BsonBinaryWriter"); }
+            if (State != BsonWriterState.Value)
+            {
+                ThrowInvalidState(nameof(WriteDecimal128), BsonWriterState.Value);
+            }
+
+            _bsonStream.WriteBsonType(BsonType.Decimal128);
+            WriteNameHelper();
+            _bsonStream.WriteDecimal128(value);
 
             State = GetNextState();
         }
@@ -285,9 +296,9 @@ namespace MongoDB.Bson.IO
                 ThrowInvalidState("WriteDouble", BsonWriterState.Value);
             }
 
-            _buffer.WriteByte((byte)BsonType.Double);
+            _bsonStream.WriteBsonType(BsonType.Double);
             WriteNameHelper();
-            _buffer.WriteDouble(value);
+            _bsonStream.WriteDouble(value);
 
             State = GetNextState();
         }
@@ -308,7 +319,7 @@ namespace MongoDB.Bson.IO
             }
 
             base.WriteEndArray();
-            _buffer.WriteByte(0);
+            _bsonStream.WriteByte(0);
             BackpatchSize(); // size of document
 
             _context = _context.ParentContext;
@@ -331,7 +342,7 @@ namespace MongoDB.Bson.IO
             }
 
             base.WriteEndDocument();
-            _buffer.WriteByte(0);
+            _bsonStream.WriteByte(0);
             BackpatchSize(); // size of document
 
             _context = _context.ParentContext;
@@ -362,9 +373,9 @@ namespace MongoDB.Bson.IO
                 ThrowInvalidState("WriteInt32", BsonWriterState.Value);
             }
 
-            _buffer.WriteByte((byte)BsonType.Int32);
+            _bsonStream.WriteBsonType(BsonType.Int32);
             WriteNameHelper();
-            _buffer.WriteInt32(value);
+            _bsonStream.WriteInt32(value);
 
             State = GetNextState();
         }
@@ -381,9 +392,9 @@ namespace MongoDB.Bson.IO
                 ThrowInvalidState("WriteInt64", BsonWriterState.Value);
             }
 
-            _buffer.WriteByte((byte)BsonType.Int64);
+            _bsonStream.WriteBsonType(BsonType.Int64);
             WriteNameHelper();
-            _buffer.WriteInt64(value);
+            _bsonStream.WriteInt64(value);
 
             State = GetNextState();
         }
@@ -400,9 +411,9 @@ namespace MongoDB.Bson.IO
                 ThrowInvalidState("WriteJavaScript", BsonWriterState.Value);
             }
 
-            _buffer.WriteByte((byte)BsonType.JavaScript);
+            _bsonStream.WriteBsonType(BsonType.JavaScript);
             WriteNameHelper();
-            _buffer.WriteString(_binaryWriterSettings.Encoding, code);
+            _bsonStream.WriteString(code, _settings.Encoding);
 
             State = GetNextState();
         }
@@ -419,11 +430,11 @@ namespace MongoDB.Bson.IO
                 ThrowInvalidState("WriteJavaScriptWithScope", BsonWriterState.Value);
             }
 
-            _buffer.WriteByte((byte)BsonType.JavaScriptWithScope);
+            _bsonStream.WriteBsonType(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(_binaryWriterSettings.Encoding, code);
+            _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;
         }
@@ -439,7 +450,7 @@ namespace MongoDB.Bson.IO
                 ThrowInvalidState("WriteMaxKey", BsonWriterState.Value);
             }
 
-            _buffer.WriteByte((byte)BsonType.MaxKey);
+            _bsonStream.WriteBsonType(BsonType.MaxKey);
             WriteNameHelper();
 
             State = GetNextState();
@@ -456,7 +467,7 @@ namespace MongoDB.Bson.IO
                 ThrowInvalidState("WriteMinKey", BsonWriterState.Value);
             }
 
-            _buffer.WriteByte((byte)BsonType.MinKey);
+            _bsonStream.WriteBsonType(BsonType.MinKey);
             WriteNameHelper();
 
             State = GetNextState();
@@ -473,7 +484,7 @@ namespace MongoDB.Bson.IO
                 ThrowInvalidState("WriteNull", BsonWriterState.Value);
             }
 
-            _buffer.WriteByte((byte)BsonType.Null);
+            _bsonStream.WriteBsonType(BsonType.Null);
             WriteNameHelper();
 
             State = GetNextState();
@@ -491,9 +502,9 @@ namespace MongoDB.Bson.IO
                 ThrowInvalidState("WriteObjectId", BsonWriterState.Value);
             }
 
-            _buffer.WriteByte((byte)BsonType.ObjectId);
+            _bsonStream.WriteBsonType(BsonType.ObjectId);
             WriteNameHelper();
-            _buffer.WriteObjectId(objectId);
+            _bsonStream.WriteObjectId(objectId);
 
             State = GetNextState();
         }
@@ -510,9 +521,9 @@ namespace MongoDB.Bson.IO
                 ThrowInvalidState("WriteRawBsonArray", BsonWriterState.Value);
             }
 
-            _buffer.WriteByte((byte)BsonType.Array);
+            _bsonStream.WriteBsonType(BsonType.Array);
             WriteNameHelper();
-            _buffer.ByteBuffer.WriteBytes(slice); // assumes byteBuffer is a valid raw BSON array
+            _bsonStream.WriteSlice(slice); // assumes slice is a valid raw BSON array
 
             State = GetNextState();
         }
@@ -531,10 +542,10 @@ namespace MongoDB.Bson.IO
 
             if (State == BsonWriterState.Value)
             {
-                _buffer.WriteByte((byte)BsonType.Document);
+                _bsonStream.WriteBsonType(BsonType.Document);
                 WriteNameHelper();
             }
-            _buffer.ByteBuffer.WriteBytes(slice); // assumes byteBuffer is a valid raw BSON document
+            _bsonStream.WriteSlice(slice); // assumes byteBuffer is a valid raw BSON document
 
             if (_context == null)
             {
@@ -563,10 +574,10 @@ namespace MongoDB.Bson.IO
                 ThrowInvalidState("WriteRegularExpression", BsonWriterState.Value);
             }
 
-            _buffer.WriteByte((byte)BsonType.RegularExpression);
+            _bsonStream.WriteBsonType(BsonType.RegularExpression);
             WriteNameHelper();
-            _buffer.WriteCString(_binaryWriterSettings.Encoding, regex.Pattern);
-            _buffer.WriteCString(_binaryWriterSettings.Encoding, regex.Options);
+            _bsonStream.WriteCString(regex.Pattern);
+            _bsonStream.WriteCString(regex.Options);
 
             State = GetNextState();
         }
@@ -583,10 +594,10 @@ namespace MongoDB.Bson.IO
             }
 
             base.WriteStartArray();
-            _buffer.WriteByte((byte)BsonType.Array);
+            _bsonStream.WriteBsonType(BsonType.Array);
             WriteNameHelper();
-            _context = new BsonBinaryWriterContext(_context, ContextType.Array, _buffer.Position);
-            _buffer.WriteInt32(0); // reserve space for size
+            _context = new BsonBinaryWriterContext(_context, ContextType.Array, _bsonStream.Position);
+            _bsonStream.WriteInt32(0); // reserve space for size
 
             State = BsonWriterState.Value;
         }
@@ -605,11 +616,12 @@ namespace MongoDB.Bson.IO
             base.WriteStartDocument();
             if (State == BsonWriterState.Value)
             {
-                _buffer.WriteByte((byte)BsonType.Document);
+                _bsonStream.WriteBsonType(BsonType.Document);
                 WriteNameHelper();
             }
-	        _context = new BsonBinaryWriterContext(_context, ContextType.Document, _buffer.Position);
-            _buffer.WriteInt32(0); // reserve space for size
+            var contextType = (State == BsonWriterState.ScopeDocument) ? ContextType.ScopeDocument : ContextType.Document;
+            _context = new BsonBinaryWriterContext(_context, contextType, _bsonStream.Position);
+            _bsonStream.WriteInt32(0); // reserve space for size
 
             State = BsonWriterState.Name;
         }
@@ -626,9 +638,9 @@ namespace MongoDB.Bson.IO
                 ThrowInvalidState("WriteString", BsonWriterState.Value);
             }
 
-            _buffer.WriteByte((byte)BsonType.String);
+            _bsonStream.WriteBsonType(BsonType.String);
             WriteNameHelper();
-            _buffer.WriteString(_binaryWriterSettings.Encoding, value);
+            _bsonStream.WriteString(value, _settings.Encoding);
 
             State = GetNextState();
         }
@@ -645,9 +657,9 @@ namespace MongoDB.Bson.IO
                 ThrowInvalidState("WriteSymbol", BsonWriterState.Value);
             }
 
-            _buffer.WriteByte((byte)BsonType.Symbol);
+            _bsonStream.WriteBsonType(BsonType.Symbol);
             WriteNameHelper();
-            _buffer.WriteString(_binaryWriterSettings.Encoding, value);
+            _bsonStream.WriteString(value, _settings.Encoding);
 
             State = GetNextState();
         }
@@ -664,9 +676,9 @@ namespace MongoDB.Bson.IO
                 ThrowInvalidState("WriteTimestamp", BsonWriterState.Value);
             }
 
-            _buffer.WriteByte((byte)BsonType.Timestamp);
+            _bsonStream.WriteBsonType(BsonType.Timestamp);
             WriteNameHelper();
-            _buffer.WriteInt64(value);
+            _bsonStream.WriteInt64(value);
 
             State = GetNextState();
         }
@@ -682,7 +694,7 @@ namespace MongoDB.Bson.IO
                 ThrowInvalidState("WriteUndefined", BsonWriterState.Value);
             }
 
-            _buffer.WriteByte((byte)BsonType.Undefined);
+            _bsonStream.WriteBsonType(BsonType.Undefined);
             WriteNameHelper();
 
             State = GetNextState();
@@ -697,15 +709,11 @@ namespace MongoDB.Bson.IO
         {
             if (disposing)
             {
-                Close();
-                if (_buffer != null)
+                try
                 {
-                    if (_disposeBuffer)
-                    {
-                        _buffer.Dispose();
-                    }
-                    _buffer = null;
+                    Close();
                 }
+                catch { } // ignore exceptions
             }
             base.Dispose(disposing);
         }
@@ -713,13 +721,17 @@ namespace MongoDB.Bson.IO
         // private methods
         private void BackpatchSize()
         {
-            int size = _buffer.Position - _context.StartPosition;
+            var size = _bsonStream.Position - _context.StartPosition;
             if (size > _maxDocumentSizeStack.Peek())
             {
                 var message = string.Format("Size {0} is larger than MaxDocumentSize {1}.", size, _maxDocumentSizeStack.Peek());
-                throw new Exception(message);
+                throw new FormatException(message);
             }
-            _buffer.Backpatch(_context.StartPosition, size);
+
+            var currentPosition = _bsonStream.Position;
+            _bsonStream.Position = _context.StartPosition;
+            _bsonStream.WriteInt32((int)size);
+            _bsonStream.Position = currentPosition;
         }
 
         private BsonWriterState GetNextState()
@@ -736,17 +748,16 @@ namespace MongoDB.Bson.IO
 
         private void WriteNameHelper()
         {
-            string name;
             if (_context.ContextType == ContextType.Array)
             {
-                name = (_context.Index++).ToString();
+                var index = _context.Index++;
+                var nameBytes = ArrayElementNameAccelerator.Default.GetElementNameBytes(index);
+                _bsonStream.WriteCStringBytes(nameBytes);
             }
             else
             {
-                name = Name;
+                _bsonStream.WriteCString(Name);
             }
-
-            _buffer.WriteCString(__strictUtf8Encoding, name);
         }
     }
 }

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryWriter.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: 37f28baa6aba24042a448612e74b725a
+guid: 437116959b2710b45aea155f8369810c
+timeCreated: 1503738733
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 3 - 3
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryWriterContext.cs

@@ -20,14 +20,14 @@ namespace MongoDB.Bson.IO
         // private fields
         private BsonBinaryWriterContext _parentContext;
         private ContextType _contextType;
-        private int _startPosition;
+        private long _startPosition;
         private int _index; // used when contextType is Array
 
         // constructors
         internal BsonBinaryWriterContext(
             BsonBinaryWriterContext parentContext,
             ContextType contextType,
-            int startPosition)
+            long startPosition)
         {
             _parentContext = parentContext;
             _contextType = contextType;
@@ -45,7 +45,7 @@ namespace MongoDB.Bson.IO
             get { return _contextType; }
         }
 
-        internal int StartPosition
+        internal long StartPosition
         {
             get { return _startPosition; }
         }

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryWriterContext.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: 3b35a234249f7854381552ff7c0324fc
+guid: 4d911b59059dd154ab025285bf6c7b5f
+timeCreated: 1503738733
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 4 - 37
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryWriterSettings.cs

@@ -1,4 +1,4 @@
-/* Copyright 2010-2014 MongoDB Inc.
+/* Copyright 2010-2016 MongoDB Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -21,15 +21,16 @@ namespace MongoDB.Bson.IO
     /// <summary>
     /// Represents settings for a BsonBinaryWriter.
     /// </summary>
+#if NET45
     [Serializable]
+#endif
     public class BsonBinaryWriterSettings : BsonWriterSettings
     {
         // private static fields
         private static BsonBinaryWriterSettings __defaults = null; // delay creation to pick up the latest default values
 
         // private fields
-        private bool _closeOutput = false;
-        private UTF8Encoding _encoding = new UTF8Encoding(false, true);
+        private UTF8Encoding _encoding = Utf8Encodings.Strict;
         private bool _fixOldBinarySubTypeOnOutput = true;
         private int _maxDocumentSize = BsonDefaults.MaxDocumentSize;
 
@@ -41,26 +42,6 @@ namespace MongoDB.Bson.IO
         {
         }
 
-        /// <summary>
-        /// Initializes a new instance of the BsonBinaryWriterSettings class.
-        /// </summary>
-        /// <param name="closeOutput">Whether to close the output stream when the writer is closed.</param>
-        /// <param name="fixOldBinarySubTypeOnOutput">Whether to fix old binary data subtype on output.</param>
-        /// <param name="guidRepresentation">The representation for Guids.</param>
-        /// <param name="maxDocumentSize">The max document size.</param>
-        [Obsolete("Use the no-argument constructor instead and set the properties.")]
-        public BsonBinaryWriterSettings(
-            bool closeOutput,
-            bool fixOldBinarySubTypeOnOutput,
-            GuidRepresentation guidRepresentation,
-            int maxDocumentSize)
-            : base(guidRepresentation)
-        {
-            _closeOutput = closeOutput;
-            _fixOldBinarySubTypeOnOutput = fixOldBinarySubTypeOnOutput;
-            _maxDocumentSize = maxDocumentSize;
-        }
-
         // public static properties
         /// <summary>
         /// Gets or sets the default BsonBinaryWriter settings.
@@ -79,19 +60,6 @@ namespace MongoDB.Bson.IO
         }
 
         // public properties
-        /// <summary>
-        /// Gets or sets whether to close the output when the writer is closed.
-        /// </summary>
-        public bool CloseOutput
-        {
-            get { return _closeOutput; }
-            set
-            {
-                if (IsFrozen) { throw new InvalidOperationException("BsonBinaryWriterSettings is frozen."); }
-                _closeOutput = value;
-            }
-        }
-
         /// <summary>
         /// Gets or sets the Encoding.
         /// </summary>
@@ -154,7 +122,6 @@ namespace MongoDB.Bson.IO
         {
             var clone = new BsonBinaryWriterSettings
             {
-                CloseOutput = _closeOutput,
                 Encoding = _encoding,
                 FixOldBinarySubTypeOnOutput = _fixOldBinarySubTypeOnOutput,
                 GuidRepresentation = GuidRepresentation,

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBinaryWriterSettings.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: d1f3818c03a5bdd4cb27717e8f268f73
+guid: f06cf8e15ac8e5e408030eacb8b9cfd5
+timeCreated: 1503738736
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 0 - 804
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBuffer.cs

@@ -1,804 +0,0 @@
-/* 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.IO;
-using System.Text;
-
-namespace MongoDB.Bson.IO
-{
-    /// <summary>
-    /// Represents a buffer for BSON encoded bytes.
-    /// </summary>
-    public class BsonBuffer : IDisposable
-    {
-        // private static fields
-        private static readonly string[] __asciiStringTable = BuildAsciiStringTable();
-        private static readonly bool[] __validBsonTypes = new bool[256];
-
-        // private fields
-        private bool _disposed = false;
-        private IByteBuffer _byteBuffer;
-        private bool _disposeByteBuffer;
-
-        // static constructor
-        static BsonBuffer()
-        {
-            foreach (BsonType bsonType in Enum.GetValues(typeof(BsonType)))
-            {
-                __validBsonTypes[(byte)bsonType] = true;
-            }
-        }
-
-        // constructors
-        /// <summary>
-        /// Initializes a new instance of the BsonBuffer class.
-        /// </summary>
-        public BsonBuffer()
-            : this(new MultiChunkBuffer(BsonChunkPool.Default), true)
-        {
-        }
-
-        /// <summary>
-        /// Initializes a new instance of the <see cref="BsonBuffer" /> class.
-        /// </summary>
-        /// <param name="byteBuffer">The buffer.</param>
-        /// <param name="disposeByteBuffer">if set to <c>true</c> this BsonBuffer will own the byte buffer and when Dispose is called the byte buffer will be Disposed also.</param>
-        public BsonBuffer(IByteBuffer byteBuffer, bool disposeByteBuffer)
-        {
-            _byteBuffer = byteBuffer;
-            _disposeByteBuffer = disposeByteBuffer;
-        }
-
-        // public properties
-        /// <summary>
-        /// Gets the byte buffer.
-        /// </summary>
-        /// <value>
-        /// The byte buffer.
-        /// </value>
-        public IByteBuffer ByteBuffer
-        {
-            get { return _byteBuffer; }
-        }
-
-        /// <summary>
-        /// Gets or sets the length of the data in the buffer.
-        /// </summary>
-        public int Length
-        {
-            get
-            {
-                ThrowIfDisposed();
-                return _byteBuffer.Length;
-            }
-            set
-            {
-                ThrowIfDisposed();
-                _byteBuffer.Length = value;
-            }
-        }
-
-        /// <summary>
-        /// Gets or sets the current position in the buffer.
-        /// </summary>
-        public int Position
-        {
-            get
-            {
-                ThrowIfDisposed();
-                return _byteBuffer.Position;
-            }
-            set
-            {
-                ThrowIfDisposed();
-                _byteBuffer.Position = value;
-            }
-        }
-
-        // private static methods
-        private static string[] BuildAsciiStringTable()
-        {
-            var asciiStringTable = new string[128];
-
-            for (int i = 0; i < 128; ++i)
-            {
-                asciiStringTable[i] = new string((char)i, 1);
-            }
-
-            return asciiStringTable;
-        }
-
-        // public methods
-        /// <summary>
-        /// Backpatches the length of an object.
-        /// </summary>
-        /// <param name="position">The start position of the object.</param>
-        /// <param name="length">The length of the object.</param>
-        public void Backpatch(int position, int length)
-        {
-            ThrowIfDisposed();
-            var savedPosition = _byteBuffer.Position;
-            _byteBuffer.Position = position;
-            WriteInt32(length);
-            _byteBuffer.Position = savedPosition;
-        }
-
-        /// <summary>
-        /// Clears the data in the buffer.
-        /// </summary>
-        public void Clear()
-        {
-            ThrowIfDisposed();
-            _byteBuffer.Clear();
-        }
-
-        /// <summary>
-        /// Copies data from the buffer to a byte array.
-        /// </summary>
-        /// <param name="sourceOffset">The source offset in the buffer.</param>
-        /// <param name="destination">The destination byte array.</param>
-        /// <param name="destinationOffset">The destination offset in the byte array.</param>
-        /// <param name="count">The number of bytes to copy.</param>
-        [Obsolete("Use ReadBytes instead.")]
-        public void CopyTo(int sourceOffset, byte[] destination, int destinationOffset, int count)
-        {
-            ThrowIfDisposed();
-            var savedPosition = _byteBuffer.Position;
-            _byteBuffer.Position = sourceOffset;
-            _byteBuffer.ReadBytes(destination, destinationOffset, count);
-            _byteBuffer.Position = savedPosition;
-        }
-
-        /// <summary>
-        /// Disposes of any resources held by the buffer.
-        /// </summary>
-        public void Dispose()
-        {
-            Dispose(true);
-            GC.SuppressFinalize(this);
-        }
-
-        /// <summary>
-        /// Loads the buffer from a Stream (the Stream must be positioned at a 4 byte length field).
-        /// </summary>
-        /// <param name="stream">The Stream.</param>
-        public void LoadFrom(Stream stream)
-        {
-            LoadFrom(stream, 4); // does not advance position
-            int length = ReadInt32(); // advances position 4 bytes
-            LoadFrom(stream, length - 4); // does not advance position
-            Position -= 4; // move back to just before the length field
-        }
-
-        /// <summary>
-        /// Loads the buffer from a Stream (leaving the position in the buffer unchanged).
-        /// </summary>
-        /// <param name="stream">The stream.</param>
-        /// <param name="count">The number of bytes to load.</param>
-        public void LoadFrom(Stream stream, int count)
-        {
-            ThrowIfDisposed();
-            _byteBuffer.LoadFrom(stream, count); // does not advance position
-        }
-
-        /// <summary>
-        /// Peeks at the next byte in the buffer and returns it as a BsonType.
-        /// </summary>
-        /// <returns>A BsonType.</returns>
-        [Obsolete("Use ReadBsonType instead.")]
-        public BsonType PeekBsonType()
-        {
-            ThrowIfDisposed();
-            var value = ReadBsonType();
-            Position -= 1;
-            return value;
-        }
-
-        /// <summary>
-        /// Peeks at the next byte in the buffer.
-        /// </summary>
-        /// <returns>A Byte.</returns>
-        [Obsolete("Use ReadByte instead.")]
-        public byte PeekByte()
-        {
-            ThrowIfDisposed();
-            var value = ReadByte();
-            Position -= 1;
-            return value;
-        }
-
-        /// <summary>
-        /// Reads a BSON Boolean from the buffer.
-        /// </summary>
-        /// <returns>A Boolean.</returns>
-        public bool ReadBoolean()
-        {
-            ThrowIfDisposed();
-            return _byteBuffer.ReadByte() != 0;
-        }
-
-        /// <summary>
-        /// Reads a BSON type from the buffer.
-        /// </summary>
-        /// <returns>A BsonType.</returns>
-        public BsonType ReadBsonType()
-        {
-            ThrowIfDisposed();
-            var bsonType = (int)_byteBuffer.ReadByte();
-            if (!__validBsonTypes[bsonType])
-            {
-                string message = string.Format("Invalid BsonType {0}.", bsonType);
-                throw new Exception(message);
-            }
-            return (BsonType)bsonType;
-        }
-
-        /// <summary>
-        /// Reads a byte from the buffer.
-        /// </summary>
-        /// <returns>A Byte.</returns>
-        public byte ReadByte()
-        {
-            ThrowIfDisposed();
-            return _byteBuffer.ReadByte();
-        }
-
-        /// <summary>
-        /// Reads bytes from the buffer.
-        /// </summary>
-        /// <param name="count">The number of bytes to read.</param>
-        /// <returns>A byte array.</returns>
-        public byte[] ReadBytes(int count)
-        {
-            ThrowIfDisposed();
-            return _byteBuffer.ReadBytes(count);
-        }
-
-        /// <summary>
-        /// Reads a BSON Double from the buffer.
-        /// </summary>
-        /// <returns>A Double.</returns>
-        public double ReadDouble()
-        {
-            ThrowIfDisposed();
-
-            var segment = _byteBuffer.ReadBackingBytes(8);
-            if (segment.Count >= 8)
-            {
-                return BitConverter.ToDouble(segment.Array, segment.Offset);
-            }
-            else
-            {
-                var bytes = _byteBuffer.ReadBytes(8);
-                return BitConverter.ToDouble(bytes, 0);
-            }
-        }
-
-        /// <summary>
-        /// Reads a BSON Int32 from the reader.
-        /// </summary>
-        /// <returns>An Int32.</returns>
-        public int ReadInt32()
-        {
-            ThrowIfDisposed();
-
-            var segment = _byteBuffer.ReadBackingBytes(4);
-            if (segment.Count >= 4)
-            {
-                // for int only we come out ahead with this code vs using BitConverter
-                return
-                    ((int)segment.Array[segment.Offset + 0]) +
-                    ((int)segment.Array[segment.Offset + 1] << 8) +
-                    ((int)segment.Array[segment.Offset + 2] << 16) +
-                    ((int)segment.Array[segment.Offset + 3] << 24);
-            }
-            else
-            {
-                var bytes = _byteBuffer.ReadBytes(4);
-                return BitConverter.ToInt32(bytes, 0);
-            }
-        }
-
-        /// <summary>
-        /// Reads a BSON Int64 from the reader.
-        /// </summary>
-        /// <returns>An Int64.</returns>
-        public long ReadInt64()
-        {
-            ThrowIfDisposed();
-
-            var segment = _byteBuffer.ReadBackingBytes(8);
-            if (segment.Count >= 8)
-            {
-                return BitConverter.ToInt64(segment.Array, segment.Offset);
-            }
-            else
-            {
-                var bytes = _byteBuffer.ReadBytes(8);
-                return BitConverter.ToInt64(bytes, 0);
-            }
-        }
-
-        /// <summary>
-        /// Reads a BSON ObjectId from the reader.
-        /// </summary>
-        /// <returns>An ObjectId.</returns>
-        public ObjectId ReadObjectId()
-        {
-            ThrowIfDisposed();
-
-            var segment = _byteBuffer.ReadBackingBytes(12);
-            if (segment.Count >= 12)
-            {
-                var bytes = segment.Array;
-                var offset = segment.Offset;
-                var timestamp = (bytes[offset + 0] << 24) + (bytes[offset + 1] << 16) + (bytes[offset + 2] << 8) + bytes[offset + 3];
-                var machine = (bytes[offset + 4] << 16) + (bytes[offset + 5] << 8) + bytes[offset + 6];
-                var pid = (short)((bytes[offset + 7] << 8) + bytes[offset + 8]);
-                var increment = (bytes[offset + 9] << 16) + (bytes[offset + 10] << 8) + bytes[offset + 11];
-                return new ObjectId(timestamp, machine, pid, increment);
-            }
-            else
-            {
-                var bytes = _byteBuffer.ReadBytes(12);
-                return new ObjectId(bytes);
-            }
-        }
-
-        /// <summary>
-        /// Reads a BSON ObjectId from the reader.
-        /// </summary>
-        /// <param name="timestamp">The timestamp.</param>
-        /// <param name="machine">The machine hash.</param>
-        /// <param name="pid">The PID.</param>
-        /// <param name="increment">The increment.</param>
-        [Obsolete("Use ReadObjectId() instead.")]
-        public void ReadObjectId(out int timestamp, out int machine, out short pid, out int increment)
-        {
-            var objectId = ReadObjectId();
-            timestamp = objectId.Timestamp;
-            machine = objectId.Machine;
-            pid = objectId.Pid;
-            increment = objectId.Increment;
-        }
-
-        /// <summary>
-        /// Reads a BSON string from the reader.
-        /// </summary>
-        /// <returns>A String.</returns>
-        public string ReadString(UTF8Encoding encoding)
-        {
-            ThrowIfDisposed();
-            var length = ReadInt32(); // length including the null terminator
-            if (length <= 0)
-            {
-                var message = string.Format("Invalid string length: {0} (the length includes the null terminator so it must be greater than or equal to 1).", length);
-                throw new Exception(message);
-            }
-
-            string value;
-            byte finalByte;
-
-            var segment = _byteBuffer.ReadBackingBytes(length);
-            if (segment.Count >= length)
-            {
-                value = DecodeUtf8String(encoding, segment.Array, segment.Offset, length - 1);
-                finalByte = segment.Array[segment.Offset + length - 1];
-            }
-            else
-            {
-                var bytes = _byteBuffer.ReadBytes(length);
-                value = DecodeUtf8String(encoding, bytes, 0, length - 1);
-                finalByte = bytes[length - 1];
-            }
-
-            if (finalByte != 0)
-            {
-                throw new Exception("String is missing null terminator.");
-            }
-
-            return value;
-        }
-
-        /// <summary>
-        /// Reads a BSON CString from the reader (a null terminated string).
-        /// </summary>
-        /// <returns>A string.</returns>
-        public string ReadCString(UTF8Encoding encoding)
-        {
-            ThrowIfDisposed();
-
-            var nullPosition = _byteBuffer.FindNullByte();
-            if (nullPosition == -1)
-            {
-                throw new BsonSerializationException("Missing null terminator.");
-            }
-
-            return ReadCString(encoding, nullPosition);
-        }
-
-        /// <summary>
-        /// Reads an element name.
-        /// </summary>
-        /// <typeparam name="TValue">The type of the BsonTrie values.</typeparam>
-        /// <param name="bsonTrie">An optional BsonTrie to use during decoding.</param>
-        /// <param name="found">Set to true if the string was found in the trie.</param>
-        /// <param name="value">Set to the value found in the trie; otherwise, null.</param>
-        /// <returns>A string.</returns>
-        public string ReadName<TValue>(BsonTrie<TValue> bsonTrie, out bool found, out TValue value)
-        {
-            ThrowIfDisposed();
-            found = false;
-            value = default(TValue);
-
-            if (bsonTrie == null)
-            {
-                return ReadCString(new UTF8Encoding(false, true)); // always use strict encoding for names
-            }
-
-            var savedPosition = _byteBuffer.Position;
-            var bsonTrieNode = bsonTrie.Root;
-            while (true)
-            {
-                var keyByte = _byteBuffer.ReadByte();
-                if (keyByte == 0)
-                {
-                    if (bsonTrieNode.HasValue)
-                    {
-                        found = true;
-                        value = bsonTrieNode.Value;
-                        return bsonTrieNode.ElementName;
-                    }
-                    else
-                    {
-                        var nullPosition = _byteBuffer.Position - 1;
-                        _byteBuffer.Position = savedPosition;
-                        return ReadCString(new UTF8Encoding(false, true), nullPosition); // always use strict encoding for names
-                    }
-                }
-
-                bsonTrieNode = bsonTrieNode.GetChild(keyByte);
-                if (bsonTrieNode == null)
-                {
-                    var nullPosition = _byteBuffer.FindNullByte(); // starting from where we got so far
-                    _byteBuffer.Position = savedPosition;
-                    return ReadCString(new UTF8Encoding(false, true), nullPosition); // always use strict encoding for names
-                }
-            }
-        }
-
-        /// <summary>
-        /// Skips over bytes in the buffer (advances the position).
-        /// </summary>
-        /// <param name="count">The number of bytes to skip.</param>
-        public void Skip(int count)
-        {
-            _byteBuffer.Position += count;
-        }
-
-        /// <summary>
-        /// Skips over a CString in the buffer (advances the position).
-        /// </summary>
-        public void SkipCString()
-        {
-            ThrowIfDisposed();
-            var nullPosition = _byteBuffer.FindNullByte();
-            if (nullPosition == -1)
-            {
-                throw new Exception("String is missing null terminator");
-            }
-            _byteBuffer.Position = nullPosition + 1;
-        }
-
-        /// <summary>
-        /// Converts the buffer to a byte array.
-        /// </summary>
-        /// <returns>A byte array.</returns>
-        public byte[] ToByteArray()
-        {
-            ThrowIfDisposed();
-            var savedPosition = _byteBuffer.Position;
-            _byteBuffer.Position = 0;
-            var byteArray = _byteBuffer.ReadBytes(_byteBuffer.Length);
-            _byteBuffer.Position = savedPosition;
-            return byteArray;
-        }
-
-        /// <summary>
-        /// Writes a BSON Boolean to the buffer.
-        /// </summary>
-        /// <param name="value">The Boolean value.</param>
-        public void WriteBoolean(bool value)
-        {
-            ThrowIfDisposed();
-            _byteBuffer.WriteByte(value ? (byte)1 : (byte)0);
-        }
-
-        /// <summary>
-        /// Writes a byte to the buffer.
-        /// </summary>
-        /// <param name="value">A byte.</param>
-        public void WriteByte(byte value)
-        {
-            ThrowIfDisposed();
-            _byteBuffer.WriteByte(value);
-        }
-
-        /// <summary>
-        /// Writes bytes to the buffer.
-        /// </summary>
-        /// <param name="value">A byte array.</param>
-        public void WriteBytes(byte[] value)
-        {
-            ThrowIfDisposed();
-            _byteBuffer.WriteBytes(value);
-        }
-
-        /// <summary>
-        /// Writes a CString to the buffer.
-        /// </summary>
-        /// <param name="encoding">A UTF8 encoding.</param>
-        /// <param name="value">A string.</param>
-        public void WriteCString(UTF8Encoding encoding, string value)
-        {
-            if (value == null)
-            {
-                throw new ArgumentNullException("value");
-            }
-            if (value.IndexOf('\0') != -1)
-            {
-                throw new ArgumentException("CStrings cannot contain nulls.", "value");
-            }
-            ThrowIfDisposed();
-
-            var maxLength = encoding.GetMaxByteCount(value.Length) + 1;
-            var segment = _byteBuffer.WriteBackingBytes(maxLength);
-            if (segment.Count >= maxLength)
-            {
-                var length = encoding.GetBytes(value, 0, value.Length, segment.Array, segment.Offset);
-                segment.Array[segment.Offset + length] = 0;
-                _byteBuffer.Position += length + 1;
-            }
-            else
-            {
-                _byteBuffer.WriteBytes(encoding.GetBytes(value));
-                _byteBuffer.WriteByte(0);
-            }
-        }
-
-        /// <summary>
-        /// Writes a BSON Double to the buffer.
-        /// </summary>
-        /// <param name="value">The Double value.</param>
-        public void WriteDouble(double value)
-        {
-            ThrowIfDisposed();
-            _byteBuffer.WriteBytes(BitConverter.GetBytes(value));
-        }
-
-        /// <summary>
-        /// Writes a BSON Int32 to the buffer.
-        /// </summary>
-        /// <param name="value">The Int32 value.</param>
-        public void WriteInt32(int value)
-        {
-            ThrowIfDisposed();
-
-            var segment = _byteBuffer.WriteBackingBytes(4);
-            if (segment.Count >= 4)
-            {
-                segment.Array[segment.Offset + 0] = (byte)(value);
-                segment.Array[segment.Offset + 1] = (byte)(value >> 8);
-                segment.Array[segment.Offset + 2] = (byte)(value >> 16);
-                segment.Array[segment.Offset + 3] = (byte)(value >> 24);
-                _byteBuffer.Position += 4;
-            }
-            else
-            {
-                _byteBuffer.WriteBytes(BitConverter.GetBytes(value));
-            }
-        }
-
-        /// <summary>
-        /// Writes a BSON Int64 to the buffer.
-        /// </summary>
-        /// <param name="value">The Int64 value.</param>
-        public void WriteInt64(long value)
-        {
-            ThrowIfDisposed();
-            _byteBuffer.WriteBytes(BitConverter.GetBytes(value));
-        }
-
-        /// <summary>
-        /// Writes a BSON ObjectId to the buffer.
-        /// </summary>
-        /// <param name="timestamp">The timestamp.</param>
-        /// <param name="machine">The machine hash.</param>
-        /// <param name="pid">The PID.</param>
-        /// <param name="increment">The increment.</param>
-        [Obsolete("Use WriteObjectId(ObjectId objectId) instead.")]
-        public void WriteObjectId(int timestamp, int machine, short pid, int increment)
-        {
-            var objectId = new ObjectId(timestamp, machine, pid, increment);
-            WriteObjectId(objectId);
-        }
-
-        /// <summary>
-        /// Writes a BSON ObjectId to the buffer.
-        /// </summary>
-        /// <param name="objectId">The ObjectId.</param>
-        public void WriteObjectId(ObjectId objectId)
-        {
-            ThrowIfDisposed();
-
-            var segment = _byteBuffer.WriteBackingBytes(12);
-            if (segment.Count >= 12)
-            {
-                var timestamp = objectId.Timestamp;
-                var machine = objectId.Machine;
-                var pid = objectId.Pid;
-                var increment = objectId.Increment;
-                segment.Array[segment.Offset + 0] = (byte)(timestamp >> 24);
-                segment.Array[segment.Offset + 1] = (byte)(timestamp >> 16);
-                segment.Array[segment.Offset + 2] = (byte)(timestamp >> 8);
-                segment.Array[segment.Offset + 3] = (byte)(timestamp);
-                segment.Array[segment.Offset + 4] = (byte)(machine >> 16);
-                segment.Array[segment.Offset + 5] = (byte)(machine >> 8);
-                segment.Array[segment.Offset + 6] = (byte)(machine);
-                segment.Array[segment.Offset + 7] = (byte)(pid >> 8);
-                segment.Array[segment.Offset + 8] = (byte)(pid);
-                segment.Array[segment.Offset + 9] = (byte)(increment >> 16);
-                segment.Array[segment.Offset + 10] = (byte)(increment >> 8);
-                segment.Array[segment.Offset + 11] = (byte)(increment);
-                _byteBuffer.Position += 12;
-            }
-            else
-            {
-                _byteBuffer.WriteBytes(objectId.ToByteArray());
-            }
-        }
-
-        /// <summary>
-        /// Writes a BSON String to the buffer.
-        /// </summary>
-        /// <param name="encoding">A UTF8 encoding.</param>
-        /// <param name="value">The String value.</param>
-        public void WriteString(UTF8Encoding encoding, string value)
-        {
-            ThrowIfDisposed();
-
-            var maxLength = encoding.GetMaxByteCount(value.Length) + 5;
-            var segment = _byteBuffer.WriteBackingBytes(maxLength);
-            if (segment.Count >= maxLength)
-            {
-                var length = encoding.GetBytes(value, 0, value.Length, segment.Array, segment.Offset + 4);
-                var lengthPlusOne = length + 1;
-                segment.Array[segment.Offset + 0] = (byte)(lengthPlusOne); // now we know the length
-                segment.Array[segment.Offset + 1] = (byte)(lengthPlusOne >> 8);
-                segment.Array[segment.Offset + 2] = (byte)(lengthPlusOne >> 16);
-                segment.Array[segment.Offset + 3] = (byte)(lengthPlusOne >> 24);
-                segment.Array[segment.Offset + 4 + length] = 0;
-                _byteBuffer.Position += length + 5;
-            }
-            else
-            {
-                var bytes = encoding.GetBytes(value);
-                WriteInt32(bytes.Length + 1);
-                _byteBuffer.WriteBytes(bytes);
-                _byteBuffer.WriteByte(0);
-            }
-        }
-
-        /// <summary>
-        /// Writes all the data in the buffer to a Stream.
-        /// </summary>
-        /// <param name="stream">The Stream.</param>
-        public void WriteTo(Stream stream)
-        {
-            ThrowIfDisposed();
-            _byteBuffer.WriteTo(stream);
-        }
-
-        /// <summary>
-        /// Writes a 32-bit zero the the buffer.
-        /// </summary>
-        [Obsolete("Use WriteByte or WriteInt32 instead.")]
-        public void WriteZero()
-        {
-            ThrowIfDisposed();
-            WriteInt32(0);
-        }
-
-        // private static methods
-        private static string DecodeUtf8String(UTF8Encoding encoding, byte[] buffer, int index, int count)
-        {
-            switch (count)
-            {
-                // special case empty strings
-                case 0:
-                    return string.Empty;
-
-                // special case single character strings
-                case 1:
-                    var byte1 = (int)buffer[index];
-                    if (byte1 < __asciiStringTable.Length)
-                    {
-                        return __asciiStringTable[byte1];
-                    }
-                    break;
-            }
-
-            return encoding.GetString(buffer, index, count);
-        }
-
-        // protected methods
-        /// <summary>
-        /// Releases unmanaged and - optionally - managed resources.
-        /// </summary>
-        /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
-        protected virtual void Dispose(bool disposing)
-        {
-            if (!_disposed)
-            {
-                if (disposing)
-                {
-                    if (_byteBuffer != null)
-                    {
-                        if (_disposeByteBuffer)
-                        {
-                            _byteBuffer.Dispose();
-                        }
-                        _byteBuffer = null;
-                    }
-                }
-                _disposed = true;
-            }
-        }
-
-        /// <summary>
-        /// Throws if disposed.
-        /// </summary>
-        /// <exception cref="System.ObjectDisposedException"></exception>
-        protected void ThrowIfDisposed()
-        {
-            if (_disposed)
-            {
-                throw new ObjectDisposedException(GetType().Name);
-            }
-        }
-        
-        // private methods
-        private string ReadCString(UTF8Encoding encoding, int nullPosition)
-        {
-            if (nullPosition == -1)
-            {
-                throw new BsonSerializationException("Missing null terminator.");
-            }
-
-            var length = nullPosition - _byteBuffer.Position + 1;
-            var segment = _byteBuffer.ReadBackingBytes(length);
-            if (segment.Count >= length)
-            {
-                return DecodeUtf8String(encoding, segment.Array, segment.Offset, length - 1);
-            }
-            else
-            {
-                var bytes = _byteBuffer.ReadBytes(length);
-                return DecodeUtf8String(encoding, bytes, 0, length - 1);
-            }
-        }
-    }
-}

+ 0 - 105
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonChunk.cs

@@ -1,105 +0,0 @@
-/* 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;
-
-namespace MongoDB.Bson.IO
-{
-    /// <summary>
-    /// Represents a BSON buffer chunk.
-    /// </summary>
-    public class BsonChunk
-    {
-        // private fields
-        private readonly byte[] _bytes;
-        private readonly BsonChunkPool _chunkPool;
-        private int _referenceCount;
-
-        // constructors
-        /// <summary>
-        /// Initializes a new instance of the <see cref="BsonChunk"/> class.
-        /// </summary>
-        /// <param name="bytes">The bytes.</param>
-        /// <param name="chunkPool">The chunk pool.</param>
-        /// <exception cref="System.ArgumentNullException">
-        /// bytes
-        /// or
-        /// pool
-        /// </exception>
-        public BsonChunk(byte[] bytes, BsonChunkPool chunkPool)
-        {
-            if (bytes == null)
-            {
-                throw new ArgumentNullException("bytes");
-            }
-            if (chunkPool == null)
-            {
-                throw new ArgumentNullException("chunkPool");
-            }
-
-            _bytes = bytes;
-            _chunkPool = chunkPool;
-        }
-
-        // public properties
-        /// <summary>
-        /// Gets the bytes.
-        /// </summary>
-        /// <value>
-        /// The bytes.
-        /// </value>
-        public byte[] Bytes
-        {
-            get { return _bytes; }
-        }
-
-        /// <summary>
-        /// Gets the reference count.
-        /// </summary>
-        /// <value>
-        /// The reference count.
-        /// </value>
-        public int ReferenceCount
-        {
-            get { return _referenceCount; }
-        }
-
-        // public methods
-        /// <summary>
-        /// Decrements the reference count.
-        /// </summary>
-        /// <exception cref="BsonInternalException">Reference count is less than or equal to zero.</exception>
-        public void DecrementReferenceCount()
-        {
-            if (_referenceCount <= 0)
-            {
-                throw new BsonInternalException("Reference count is less than or equal to zero.");
-            }
-
-            if (--_referenceCount == 0 && _chunkPool != null)
-            {
-                _chunkPool.ReleaseChunk(this);
-            }
-        }
-
-        /// <summary>
-        /// Increments the reference count.
-        /// </summary>
-        public void IncrementReferenceCount()
-        {
-            _referenceCount++;
-        }
-    }
-}

+ 179 - 48
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonChunkPool.cs

@@ -1,4 +1,4 @@
-/* Copyright 2010-2014 MongoDB Inc.
+/* Copyright 2010-2015 MongoDB Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -15,38 +15,22 @@
 
 using System;
 using System.Collections.Generic;
+using System.Threading;
 
 namespace MongoDB.Bson.IO
 {
     /// <summary>
-    /// Represents a pool of chunks used by BsonBuffer.
+    /// Represents a pool of chunks.
     /// </summary>
-    public class BsonChunkPool
+    public sealed class BsonChunkPool : IBsonChunkSource
     {
-        // private static fields
-        private static BsonChunkPool __default = new BsonChunkPool(2048, 16 * 1024); // 32MiB of 16KiB chunks
+        #region static
+        // static fields
+        private static BsonChunkPool __default = new BsonChunkPool(8192, 64 * 1024); // 512MiB of 64KiB chunks
 
-        // private fields
-        private readonly object _lock = new object();
-        private readonly Stack<BsonChunk> _chunks = new Stack<BsonChunk>();
-        private readonly int _maxPoolSize;
-        private readonly int _chunkSize;
-
-        // constructors
-        /// <summary>
-        /// Initializes a new instance of the <see cref="BsonChunkPool"/> class.
-        /// </summary>
-        /// <param name="maxPoolSize">The maximum number of chunks to keep in the pool.</param>
-        /// <param name="chunkSize">The size of each chunk.</param>
-        public BsonChunkPool(int maxPoolSize, int chunkSize)
-        {
-            _maxPoolSize = maxPoolSize;
-            _chunkSize = chunkSize;
-        }
-
-        // public static properties
+        // static properties
         /// <summary>
-        /// Gets the default chunk pool.
+        /// Gets or sets the default chunk pool.
         /// </summary>
         /// <value>
         /// The default chunk pool.
@@ -58,11 +42,40 @@ namespace MongoDB.Bson.IO
             {
                 if (value == null)
                 {
-                    throw new ArgumentNullException("Default");
+                    throw new ArgumentNullException("value");
                 }
                 __default = value;
             }
         }
+        #endregion
+
+        // private fields
+        private Stack<ReferenceCountedChunk> _chunks = new Stack<ReferenceCountedChunk>();
+        private readonly int _chunkSize;
+        private bool _disposed;
+        private readonly object _lock = new object();
+        private readonly int _maxChunkCount;
+
+        // constructors
+        /// <summary>
+        /// Initializes a new instance of the <see cref="BsonChunkPool"/> class.
+        /// </summary>
+        /// <param name="maxChunkCount">The maximum number of chunks to keep in the pool.</param>
+        /// <param name="chunkSize">The size of each chunk.</param>
+        public BsonChunkPool(int maxChunkCount, int chunkSize)
+        {
+            if (maxChunkCount < 0)
+            {
+                throw new ArgumentOutOfRangeException("maxChunkCount");
+            }
+            if (chunkSize <= 0)
+            {
+                throw new ArgumentOutOfRangeException("chunkSize");
+            }
+
+            _maxChunkCount = maxChunkCount;
+            _chunkSize = chunkSize;
+        }
 
         // public properties
         /// <summary>
@@ -77,51 +90,169 @@ namespace MongoDB.Bson.IO
         }
 
         /// <summary>
-        /// Gets or sets the max pool size.
+        /// Gets the maximum size of the pool.
         /// </summary>
-        public int MaxPoolSize
+        /// <value>
+        /// The maximum size of the pool.
+        /// </value>
+        public int MaxChunkCount
         {
-            get { return _maxPoolSize; }
+            get { return _maxChunkCount; }
         }
 
-        // internal methods
         /// <summary>
-        /// Acquires a chunk.
+        /// Gets the size of the pool.
         /// </summary>
-        /// <returns></returns>
-        internal  BsonChunk AcquireChunk()
+        /// <value>
+        /// The size of the pool.
+        /// </value>
+        public int ChunkCount
+        {
+            get
+            {
+                lock (_lock)
+                {
+                    return _chunks.Count;
+                }
+            }
+        }
+
+        // public methods
+        /// <inheritdoc/>
+        public void Dispose()
+        {
+            if (!_disposed)
+            {
+                _disposed = true;
+                _chunks = null;
+            }
+        }
+
+        /// <inheritdoc/>
+        public IBsonChunk GetChunk(int requestedSize)
         {
+            ThrowIfDisposed();
+
+            ReferenceCountedChunk referenceCountedChunk = null;
             lock (_lock)
             {
                 if (_chunks.Count > 0)
                 {
-                    return _chunks.Pop();
+                    referenceCountedChunk = _chunks.Pop();
                 }
             }
 
-            // release the lock before allocating memory
-            var bytes = new byte[_chunkSize];
-            return new BsonChunk(bytes, this);
+            if (referenceCountedChunk == null)
+            {
+                var chunk = new byte[_chunkSize];
+                referenceCountedChunk = new ReferenceCountedChunk(chunk, this);
+            }
+
+            return new DisposableChunk(referenceCountedChunk);
         }
 
-        /// <summary>
-        /// Releases a chunk.
-        /// </summary>
-        /// <param name="chunk">The chunk.</param>
-        internal void ReleaseChunk(BsonChunk chunk)
+        // private methods
+        private void ReleaseChunk(ReferenceCountedChunk chunk)
         {
-            if (chunk.ReferenceCount != 0)
+            if (!_disposed)
             {
-                new BsonInternalException("A chunk is being returned to the pool and the reference count is not zero.");
+                lock (_lock)
+                {
+                    if (_chunks.Count < _maxChunkCount)
+                    {
+                        _chunks.Push(chunk);
+                    }
+                    // otherwise just let it get garbage collected
+                }
             }
+        }
 
-            lock (_lock)
+        private void ThrowIfDisposed()
+        {
+            if (_disposed)
+            {
+                throw new ObjectDisposedException(GetType().Name);
+            }
+        }
+
+        // nested types
+        private sealed class DisposableChunk : IBsonChunk
+        {
+            // fields
+            private bool _disposed;
+            private readonly ReferenceCountedChunk _referenceCountedChunk;
+
+            // constructors
+            public DisposableChunk(ReferenceCountedChunk referenceCountedChunk)
+            {
+                _referenceCountedChunk = referenceCountedChunk;
+                _referenceCountedChunk.IncrementReferenceCount();
+            }
+
+            // properties
+            public ArraySegment<byte> Bytes
+            {
+                get
+                {
+                    ThrowIfDisposed();
+                    return new ArraySegment<byte>(_referenceCountedChunk.Chunk);
+                }
+            }
+
+            // methods
+            public void Dispose()
+            {
+                if (!_disposed)
+                {
+                    _disposed = true;
+                    _referenceCountedChunk.DecrementReferenceCount();
+                }
+            }
+
+            public IBsonChunk Fork()
+            {
+                ThrowIfDisposed();
+                return new DisposableChunk(_referenceCountedChunk);
+            }
+
+            // private methods
+            private void ThrowIfDisposed()
+            {
+                if (_disposed)
+                {
+                    throw new ObjectDisposedException(GetType().Name);
+                }
+            }
+        }
+
+        private sealed class ReferenceCountedChunk
+        {
+            private byte[] _chunk;
+            private BsonChunkPool _pool;
+            private int _referenceCount;
+
+            public ReferenceCountedChunk(byte[] chunk, BsonChunkPool pool)
+            {
+                _chunk = chunk;
+                _pool = pool;
+            }
+
+            public byte[] Chunk
             {
-                if (_chunks.Count < _maxPoolSize)
+                get { return _chunk; }
+            }
+
+            public void DecrementReferenceCount()
+            {
+                if (Interlocked.Decrement(ref _referenceCount) == 0)
                 {
-                    _chunks.Push(chunk);
+                    _pool.ReleaseChunk(this);
                 }
-                // otherwise just let it get garbage collected
+            }
+
+            public void IncrementReferenceCount()
+            {
+                Interlocked.Increment(ref _referenceCount);
             }
         }
     }

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonChunkPool.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: 17dc04b25ed780d4f891c812fe7f0cf5
+guid: 2a83147c11652194c858c913c9d8b7ee
+timeCreated: 1503738733
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 67 - 23
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonDocumentReader.cs

@@ -1,4 +1,4 @@
-/* Copyright 2010-2014 MongoDB Inc.
+/* Copyright 2010-2016 MongoDB Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -24,10 +24,19 @@ namespace MongoDB.Bson.IO
     public class BsonDocumentReader : BsonReader
     {
         // private fields
-	    private BsonDocumentReaderContext _context;
+        private BsonDocumentReaderContext _context;
         private BsonValue _currentValue;
 
         // constructors
+        /// <summary>
+        /// Initializes a new instance of the BsonDocumentReader class.
+        /// </summary>
+        /// <param name="document">A BsonDocument.</param>
+        public BsonDocumentReader(BsonDocument document)
+            : this(document, BsonDocumentReaderSettings.Defaults)
+        {
+        }
+
         /// <summary>
         /// Initializes a new instance of the BsonDocumentReader class.
         /// </summary>
@@ -52,10 +61,7 @@ namespace MongoDB.Bson.IO
         public override void Close()
         {
             // Close can be called on Disposed objects
-            if (State != BsonReaderState.Closed)
-            {
-                State = BsonReaderState.Closed;
-            }
+            State = BsonReaderState.Closed;
         }
 
         /// <summary>
@@ -67,6 +73,17 @@ namespace MongoDB.Bson.IO
             return new BsonDocumentReaderBookmark(State, CurrentBsonType, CurrentName, _context, _currentValue);
         }
 
+        /// <summary>
+        /// Determines whether this reader is at end of file.
+        /// </summary>
+        /// <returns>
+        /// Whether this reader is at end of file.
+        /// </returns>
+        public override bool IsAtEndOfFile()
+        {
+            return State == BsonReaderState.Done;
+        }
+
         /// <summary>
         /// Reads BSON binary data from the reader.
         /// </summary>
@@ -95,16 +112,10 @@ namespace MongoDB.Bson.IO
         /// <summary>
         /// Reads a BsonType from the reader.
         /// </summary>
-        /// <typeparam name="TValue">The type of the BsonTrie values.</typeparam>
-        /// <param name="bsonTrie">An optional trie to search for a value that matches the next element name.</param>
-        /// <param name="found">Set to true if a matching value was found in the trie.</param>
-        /// <param name="value">Set to the matching value found in the trie or null if no matching value was found.</param>
         /// <returns>A BsonType.</returns>
-        public override BsonType ReadBsonType<TValue>(BsonTrie<TValue> bsonTrie, out bool found, out TValue value)
+        public override BsonType ReadBsonType()
         {
             if (Disposed) { ThrowObjectDisposedException(); }
-            found = false;
-            value = default(TValue);
             if (State == BsonReaderState.Initial || State == BsonReaderState.ScopeDocument)
             {
                 // there is an implied type of Document for the top level and for scope documents
@@ -120,8 +131,7 @@ namespace MongoDB.Bson.IO
             switch (_context.ContextType)
             {
                 case ContextType.Array:
-                    _currentValue = _context.GetNextValue();
-                    if (_currentValue == null)
+                    if (!_context.TryGetNextValue(out _currentValue))
                     {
                         State = BsonReaderState.EndOfArray;
                         return BsonType.EndOfDocument;
@@ -129,16 +139,12 @@ namespace MongoDB.Bson.IO
                     State = BsonReaderState.Value;
                     break;
                 case ContextType.Document:
-                    var currentElement = _context.GetNextElement();
-                    if (currentElement == null)
+                    BsonElement currentElement;
+                    if (!_context.TryGetNextElement(out currentElement))
                     {
                         State = BsonReaderState.EndOfDocument;
                         return BsonType.EndOfDocument;
                     }
-                    if (bsonTrie != null)
-                    {
-                        found = bsonTrie.TryGetValue(currentElement.Name, out value);
-                    }
                     CurrentName = currentElement.Name;
                     _currentValue = currentElement.Value;
                     State = BsonReaderState.Name;
@@ -167,8 +173,8 @@ namespace MongoDB.Bson.IO
             var subType = binaryData.SubType;
             if (subType != BsonBinarySubType.Binary && subType != BsonBinarySubType.OldBinary)
             {
-                var message = string.Format("ReadBytes requires the binary sub type to be Binary, not {2}.", subType);
-                throw new Exception(message);
+                var message = string.Format("ReadBytes requires the binary sub type to be Binary, not {0}.", subType);
+                throw new FormatException(message);
             }
 
             return binaryData.Bytes;
@@ -187,6 +193,15 @@ namespace MongoDB.Bson.IO
             return _currentValue.AsBsonDateTime.MillisecondsSinceEpoch;
         }
 
+        /// <inheritdoc />
+        public override Decimal128 ReadDecimal128()
+        {
+            if (Disposed) { ThrowObjectDisposedException(); }
+            VerifyBsonType(nameof(ReadDecimal128), BsonType.Decimal128);
+            State = GetNextState();
+            return _currentValue.AsDecimal128;
+        }
+
         /// <summary>
         /// Reads a BSON Double from the reader.
         /// </summary>
@@ -326,6 +341,35 @@ namespace MongoDB.Bson.IO
             State = GetNextState();
         }
 
+        /// <summary>
+        /// Reads the name of an element from the reader.
+        /// </summary>
+        /// <param name="nameDecoder">The name decoder.</param>
+        /// <returns>
+        /// The name of the element.
+        /// </returns>
+        public override string ReadName(INameDecoder nameDecoder)
+        {
+            if (nameDecoder == null)
+            {
+                throw new ArgumentNullException("nameDecoder");
+            }
+
+            if (Disposed) { ThrowObjectDisposedException(); }
+            if (State == BsonReaderState.Type)
+            {
+                ReadBsonType();
+            }
+            if (State != BsonReaderState.Name)
+            {
+                ThrowInvalidState("ReadName", BsonReaderState.Name);
+            }
+
+            nameDecoder.Inform(CurrentName);
+            State = BsonReaderState.Value;
+            return CurrentName;
+        }
+
         /// <summary>
         /// Reads a BSON null from the reader.
         /// </summary>

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonDocumentReader.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: c9065310af78ac6488437a7a791fb0a0
+guid: b35eb8aca3d61224c90cd8e7e187278f
+timeCreated: 1503738735
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonDocumentReaderBookmark.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: 0c4d1b9effbf1534d862573e264ed1a0
+guid: daabae31bc59cef4dac47efee71e50a1
+timeCreated: 1503738736
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 10 - 6
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonDocumentReaderContext.cs

@@ -92,27 +92,31 @@ namespace MongoDB.Bson.IO
             return new BsonDocumentReaderContext(_parentContext, _contextType, _document, _array, _index);
         }
 
-        public BsonElement GetNextElement()
+        public bool TryGetNextElement(out BsonElement element)
         {
             if (_index < _document.ElementCount)
             {
-                return _document.GetElement(_index++);
+                element = _document.GetElement(_index++);
+                return true;
             }
             else
             {
-                return null;
+                element = default(BsonElement);
+                return false;
             }
         }
 
-        public BsonValue GetNextValue()
+        public bool TryGetNextValue(out BsonValue value)
         {
             if (_index < _array.Count)
             {
-                return _array[_index++];
+                value = _array[_index++];
+                return true;
             }
             else
             {
-                return null;
+                value = null;
+                return false;
             }
         }
 

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonDocumentReaderContext.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: df22228a4352c004a88ce6f07b73bf38
+guid: 592dc2959c673514e8ad9c0274331495
+timeCreated: 1503738733
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 3 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonDocumentReaderSettings.cs

@@ -1,4 +1,4 @@
-/* Copyright 2010-2014 MongoDB Inc.
+/* Copyright 2010-2016 MongoDB Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -20,7 +20,9 @@ namespace MongoDB.Bson.IO
     /// <summary>
     /// Represents settings for a BsonDocumentReader.
     /// </summary>
+#if NET45
     [Serializable]
+#endif
     public class BsonDocumentReaderSettings : BsonReaderSettings
     {
         // private static fields

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonDocumentReaderSettings.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: 5f07677cfabfe5543810159d42cd14c1
+guid: 64af3629138e0f145971de2b05034c25
+timeCreated: 1503738734
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 42 - 19
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonDocumentWriter.cs

@@ -1,4 +1,4 @@
-/* Copyright 2010-2014 MongoDB Inc.
+/* Copyright 2010-2016 MongoDB Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -23,35 +23,44 @@ namespace MongoDB.Bson.IO
     public class BsonDocumentWriter : BsonWriter
     {
         // private fields
-        private BsonDocument _topLevelDocument;
-	    private BsonDocumentWriterContext _context;
+        private BsonDocument _document;
+        private BsonDocumentWriterContext _context;
 
         // constructors
         /// <summary>
         /// Initializes a new instance of the BsonDocumentWriter class.
         /// </summary>
-        /// <param name="topLevelDocument">The document to write to (normally starts out as an empty document).</param>
+        /// <param name="document">The document to write to (normally starts out as an empty document).</param>
+        public BsonDocumentWriter(BsonDocument document)
+            : this(document, BsonDocumentWriterSettings.Defaults)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the BsonDocumentWriter class.
+        /// </summary>
+        /// <param name="document">The document to write to (normally starts out as an empty document).</param>
         /// <param name="settings">The settings.</param>
-        public BsonDocumentWriter(BsonDocument topLevelDocument, BsonDocumentWriterSettings settings)
+        public BsonDocumentWriter(BsonDocument document, BsonDocumentWriterSettings settings)
             : base(settings)
         {
-            if (topLevelDocument == null)
+            if (document == null)
             {
-                throw new ArgumentNullException("topLevelDocument");
+                throw new ArgumentNullException("document");
             }
 
-            _topLevelDocument = topLevelDocument;
-	        _context = null;
+            _document = document;
+            _context = null;
             State = BsonWriterState.Initial;
         }
 
         // public properties
         /// <summary>
-        /// Gets the top level BsonDocument.
+        /// Gets the BsonDocument being written to.
         /// </summary>
-        public BsonDocument TopLevelDocument
+        public BsonDocument Document
         {
-            get { return _topLevelDocument; }
+            get { return _document; }
         }
 
         // public methods
@@ -61,11 +70,8 @@ namespace MongoDB.Bson.IO
         public override void Close()
         {
             // Close can be called on Disposed objects
-            if (State != BsonWriterState.Closed)
-            {
-                _context = null;
-                State = BsonWriterState.Closed;
-            }
+            _context = null;
+            State = BsonWriterState.Closed;
         }
 
         /// <summary>
@@ -140,6 +146,19 @@ namespace MongoDB.Bson.IO
             State = GetNextState();
         }
 
+        /// <inheritdoc />
+        public override void WriteDecimal128(Decimal128 value)
+        {
+            if (Disposed) { throw new ObjectDisposedException("BsonDocumentWriter"); }
+            if (State != BsonWriterState.Value)
+            {
+                ThrowInvalidState(nameof(WriteDecimal128), BsonWriterState.Value);
+            }
+
+            WriteValue(new BsonDecimal128(value));
+            State = GetNextState();
+        }
+
         /// <summary>
         /// Writes a BSON Double to the writer.
         /// </summary>
@@ -405,7 +424,7 @@ namespace MongoDB.Bson.IO
             {
                 case BsonWriterState.Initial:
                 case BsonWriterState.Done:
-                    _context = new BsonDocumentWriterContext(null, ContextType.Document, _topLevelDocument);
+                    _context = new BsonDocumentWriterContext(null, ContextType.Document, _document);
                     break;
                 case BsonWriterState.Value:
                     _context = new BsonDocumentWriterContext(_context, ContextType.Document, new BsonDocument());
@@ -492,7 +511,11 @@ namespace MongoDB.Bson.IO
         {
             if (disposing)
             {
-                Close();
+                try
+                {
+                    Close();
+                }
+                catch { } // ignore exceptions
             }
             base.Dispose(disposing);
         }

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonDocumentWriter.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: f2ccaac556b49254ab977d71aeca4158
+guid: 3c598f258b2631142880a3f134376fed
+timeCreated: 1503738733
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonDocumentWriterContext.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: 37b8623ed8ebfe9439c0e24b9268e1ab
+guid: c5363ecbd657042449e0419815019835
+timeCreated: 1503738735
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 3 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonDocumentWriterSettings.cs

@@ -1,4 +1,4 @@
-/* Copyright 2010-2014 MongoDB Inc.
+/* Copyright 2010-2016 MongoDB Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -20,7 +20,9 @@ namespace MongoDB.Bson.IO
     /// <summary>
     /// Represents settings for a BsonDocumentWriter.
     /// </summary>
+#if NET45
     [Serializable]
+#endif
     public class BsonDocumentWriterSettings : BsonWriterSettings
     {
         // private static fields

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonDocumentWriterSettings.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: 3d0f2ed6022d7bd4d92d5551195afc62
+guid: e48702e7b1594db43a8d7154d1aa90ab
+timeCreated: 1503738736
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 47 - 566
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonReader.cs

@@ -1,4 +1,4 @@
-/* Copyright 2010-2014 MongoDB Inc.
+/* Copyright 2010-2016 MongoDB Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
 using System;
 using System.IO;
 using System.Linq;
+using MongoDB.Bson.Serialization;
 using MongoDB.Bson.Serialization.Serializers;
 
 namespace MongoDB.Bson.IO
@@ -23,7 +24,7 @@ namespace MongoDB.Bson.IO
     /// <summary>
     /// Represents a BSON reader for some external format (see subclasses).
     /// </summary>
-    public abstract class BsonReader : IDisposable
+    public abstract class BsonReader : IBsonReader
     {
         // private fields
         private bool _disposed = false;
@@ -93,115 +94,6 @@ namespace MongoDB.Bson.IO
             get { return _disposed; }
         }
 
-        // public static methods
-        /// <summary>
-        /// Creates a BsonReader for a BsonBuffer.
-        /// </summary>
-        /// <param name="buffer">The BsonBuffer.</param>
-        /// <returns>A BsonReader.</returns>
-        public static BsonReader Create(BsonBuffer buffer)
-        {
-            return Create(buffer, BsonBinaryReaderSettings.Defaults);
-        }
-
-        /// <summary>
-        /// Creates a BsonReader for a BsonBuffer.
-        /// </summary>
-        /// <param name="buffer">The BsonBuffer.</param>
-        /// <param name="settings">Optional reader settings.</param>
-        /// <returns>A BsonReader.</returns>
-        public static BsonReader Create(BsonBuffer buffer, BsonBinaryReaderSettings settings)
-        {
-            return new BsonBinaryReader(buffer, false, settings);
-        }
-
-        /// <summary>
-        /// Creates a BsonReader for a BsonDocument.
-        /// </summary>
-        /// <param name="document">The BsonDocument.</param>
-        /// <returns>A BsonReader.</returns>
-        public static BsonReader Create(BsonDocument document)
-        {
-            return Create(document, BsonDocumentReaderSettings.Defaults);
-        }
-
-        /// <summary>
-        /// Creates a BsonReader for a BsonDocument.
-        /// </summary>
-        /// <param name="document">The BsonDocument.</param>
-        /// <param name="settings">The settings.</param>
-        /// <returns>A BsonReader.</returns>
-        public static BsonReader Create(BsonDocument document, BsonDocumentReaderSettings settings)
-        {
-            return new BsonDocumentReader(document, settings);
-        }
-
-        /// <summary>
-        /// Creates a BsonReader for a JsonBuffer.
-        /// </summary>
-        /// <param name="buffer">The buffer.</param>
-        /// <returns>A BsonReader.</returns>
-        public static BsonReader Create(JsonBuffer buffer)
-        {
-            return Create(buffer, JsonReaderSettings.Defaults);
-        }
-
-        /// <summary>
-        /// Creates a BsonReader for a JsonBuffer.
-        /// </summary>
-        /// <param name="buffer">The buffer.</param>
-        /// <param name="settings">The settings.</param>
-        /// <returns>A BsonReader.</returns>
-        public static BsonReader Create(JsonBuffer buffer, JsonReaderSettings settings)
-        {
-            return new JsonReader(buffer, settings);
-        }
-
-        /// <summary>
-        /// Creates a BsonReader for a BSON Stream.
-        /// </summary>
-        /// <param name="stream">The BSON Stream.</param>
-        /// <returns>A BsonReader.</returns>
-        public static BsonReader Create(Stream stream)
-        {
-            return Create(stream, BsonBinaryReaderSettings.Defaults);
-        }
-
-        /// <summary>
-        /// Creates a BsonReader for a BSON Stream.
-        /// </summary>
-        /// <param name="stream">The BSON Stream.</param>
-        /// <param name="settings">Optional reader settings.</param>
-        /// <returns>A BsonReader.</returns>
-        public static BsonReader Create(Stream stream, BsonBinaryReaderSettings settings)
-        {
-            var byteBuffer = ByteBufferFactory.LoadFrom(stream);
-            byteBuffer.MakeReadOnly();
-            return new BsonBinaryReader(new BsonBuffer(byteBuffer, true), true, settings);
-        }
-
-        /// <summary>
-        /// Creates a BsonReader for a JSON string.
-        /// </summary>
-        /// <param name="json">The JSON string.</param>
-        /// <returns>A BsonReader.</returns>
-        public static BsonReader Create(string json)
-        {
-            var buffer = new JsonBuffer(json);
-            return Create(buffer);
-        }
-
-        /// <summary>
-        /// Creates a BsonReader for a JSON TextReader.
-        /// </summary>
-        /// <param name="textReader">The JSON TextReader.</param>
-        /// <returns>A BsonReader.</returns>
-        public static BsonReader Create(TextReader textReader)
-        {
-            var json = textReader.ReadToEnd();
-            return Create(json);
-        }
-
         // public methods
         /// <summary>
         /// Closes the reader.
@@ -220,62 +112,6 @@ namespace MongoDB.Bson.IO
             }
         }
 
-        /// <summary>
-        /// Positions the reader to an element by name.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <returns>True if the element was found.</returns>
-        public bool FindElement(string name)
-        {
-            if (_disposed) { ThrowObjectDisposedException(); }
-            if (_state != BsonReaderState.Type)
-            {
-                ThrowInvalidState("FindElement", BsonReaderState.Type);
-            }
-
-	        while ((ReadBsonType()) != BsonType.EndOfDocument)
-            {
-                var elementName = ReadName();
-                if (elementName == name)
-                {
-                    return true;
-                }
-                SkipValue();
-            }
-
-            return false;
-        }
-
-        /// <summary>
-        /// Positions the reader to a string element by name.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <returns>True if the element was found.</returns>
-        public string FindStringElement(string name)
-        {
-            if (_disposed) { ThrowObjectDisposedException(); }
-            if (_state != BsonReaderState.Type)
-            {
-                ThrowInvalidState("FindStringElement", BsonReaderState.Type);
-            }
-
-            BsonType bsonType;
-            while ((bsonType = ReadBsonType()) != BsonType.EndOfDocument)
-            {
-                var elementName = ReadName();
-                if (bsonType == BsonType.String && elementName == name)
-                {
-                    return ReadString();
-                }
-                else
-                {
-                    SkipValue();
-                }
-            }
-
-            return null;
-        }
-
         /// <summary>
         /// Gets a bookmark to the reader's current position and state.
         /// </summary>
@@ -288,7 +124,7 @@ namespace MongoDB.Bson.IO
         /// <returns>The current BsonType.</returns>
         public BsonType GetCurrentBsonType()
         {
-            if (_state == BsonReaderState.Initial || _state == BsonReaderState.Done || _state == BsonReaderState.ScopeDocument || _state == BsonReaderState.Type)
+            if (_state == BsonReaderState.Initial || _state == BsonReaderState.ScopeDocument || _state == BsonReaderState.Type)
             {
                 ReadBsonType();
             }
@@ -300,82 +136,18 @@ namespace MongoDB.Bson.IO
         }
 
         /// <summary>
-        /// Reads BSON binary data from the reader.
+        /// Determines whether this reader is at end of file.
         /// </summary>
-        /// <returns>A BsonBinaryData.</returns>
-        public abstract BsonBinaryData ReadBinaryData();
-
-        /// <summary>
-        /// Reads BSON binary data from the reader.
-        /// </summary>
-        /// <param name="bytes">The binary data.</param>
-        /// <param name="subType">The binary data subtype.</param>
-        [Obsolete("Use ReadBinaryData() instead.")]
-        public void ReadBinaryData(out byte[] bytes, out BsonBinarySubType subType)
-        {
-            GuidRepresentation guidRepresentation;
-            ReadBinaryData(out bytes, out subType, out guidRepresentation);
-        }
+        /// <returns>
+        /// Whether this reader is at end of file.
+        /// </returns>
+        public abstract bool IsAtEndOfFile();
 
         /// <summary>
         /// Reads BSON binary data from the reader.
         /// </summary>
-        /// <param name="bytes">The binary data.</param>
-        /// <param name="subType">The binary data subtype.</param>
-        /// <param name="guidRepresentation">The representation for Guids.</param>
-        [Obsolete("Use ReadBinaryData() instead.")]
-        public void ReadBinaryData(
-            out byte[] bytes,
-            out BsonBinarySubType subType,
-            out GuidRepresentation guidRepresentation)
-        {
-            var binaryData = ReadBinaryData();
-            bytes = binaryData.Bytes;
-            subType = binaryData.SubType;
-            guidRepresentation = binaryData.GuidRepresentation;
-        }
-
-        /// <summary>
-        /// Reads a BSON binary data element from the reader.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
         /// <returns>A BsonBinaryData.</returns>
-        public BsonBinaryData ReadBinaryData(string name)
-        {
-            VerifyName(name);
-            return ReadBinaryData();
-        }
-
-        /// <summary>
-        /// Reads a BSON binary data element from the reader.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <param name="bytes">The binary data.</param>
-        /// <param name="subType">The binary data subtype.</param>
-        [Obsolete("Use ReadBinaryData(string name) instead.")]
-        public void ReadBinaryData(string name, out byte[] bytes, out BsonBinarySubType subType)
-        {
-            GuidRepresentation guidRepresentation;
-            ReadBinaryData(name, out bytes, out subType, out guidRepresentation);
-        }
-
-        /// <summary>
-        /// Reads a BSON binary data element from the reader.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <param name="bytes">The binary data.</param>
-        /// <param name="subType">The binary data subtype.</param>
-        /// <param name="guidRepresentation">The representation for Guids.</param>
-        [Obsolete("Use ReadBinaryData(string name) instead.")]
-        public void ReadBinaryData(
-            string name,
-            out byte[] bytes,
-            out BsonBinarySubType subType,
-            out GuidRepresentation guidRepresentation)
-        {
-            VerifyName(name);
-            ReadBinaryData(out bytes, out subType, out guidRepresentation);
-        }
+        public abstract BsonBinaryData ReadBinaryData();
 
         /// <summary>
         /// Reads a BSON boolean from the reader.
@@ -383,37 +155,11 @@ namespace MongoDB.Bson.IO
         /// <returns>A Boolean.</returns>
         public abstract bool ReadBoolean();
 
-        /// <summary>
-        /// Reads a BSON boolean element from the reader.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <returns>A Boolean.</returns>
-        public bool ReadBoolean(string name)
-        {
-            VerifyName(name);
-            return ReadBoolean();
-        }
-
         /// <summary>
         /// Reads a BsonType from the reader.
         /// </summary>
         /// <returns>A BsonType.</returns>
-        public BsonType ReadBsonType()
-        {
-            bool found;
-            object value;
-            return ReadBsonType(null, out found, out value);
-        }
-
-        /// <summary>
-        /// Reads a BsonType from the reader.
-        /// </summary>
-        /// <typeparam name="TValue">The type of the BsonTrie values.</typeparam>
-        /// <param name="bsonTrie">An optional trie to search for a value that matches the next element name.</param>
-        /// <param name="found">Set to true if a matching value was found in the trie.</param>
-        /// <param name="value">Set to the matching value found in the trie or null if no matching value was found.</param>
-        /// <returns>A BsonType.</returns>
-        public abstract BsonType ReadBsonType<TValue>(BsonTrie<TValue> bsonTrie, out bool found, out TValue value);
+        public abstract BsonType ReadBsonType();
 
         /// <summary>
         /// Reads BSON binary data from the reader.
@@ -421,33 +167,14 @@ namespace MongoDB.Bson.IO
         /// <returns>A byte array.</returns>
         public abstract byte[] ReadBytes();
 
-        /// <summary>
-        /// Reads a BSON binary data element from the reader.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <returns>A byte array.</returns>
-        public byte[] ReadBytes(string name)
-        {
-            VerifyName(name);
-            return ReadBytes();
-        }
-
         /// <summary>
         /// Reads a BSON DateTime from the reader.
         /// </summary>
         /// <returns>The number of milliseconds since the Unix epoch.</returns>
         public abstract long ReadDateTime();
 
-        /// <summary>
-        /// Reads a BSON DateTime element from the reader.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <returns>The number of milliseconds since the Unix epoch.</returns>
-        public long ReadDateTime(string name)
-        {
-            VerifyName(name);
-            return ReadDateTime();
-        }
+        /// <inheritdoc />
+        public abstract Decimal128 ReadDecimal128();
 
         /// <summary>
         /// Reads a BSON Double from the reader.
@@ -455,17 +182,6 @@ namespace MongoDB.Bson.IO
         /// <returns>A Double.</returns>
         public abstract double ReadDouble();
 
-        /// <summary>
-        /// Reads a BSON Double element from the reader.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <returns>A Double.</returns>
-        public double ReadDouble(string name)
-        {
-            VerifyName(name);
-            return ReadDouble();
-        }
-
         /// <summary>
         /// Reads the end of a BSON array from the reader.
         /// </summary>
@@ -482,249 +198,110 @@ namespace MongoDB.Bson.IO
         /// <returns>An Int32.</returns>
         public abstract int ReadInt32();
 
-        /// <summary>
-        /// Reads a BSON Int32 element from the reader.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <returns>An Int32.</returns>
-        public int ReadInt32(string name)
-        {
-            VerifyName(name);
-            return ReadInt32();
-        }
-
         /// <summary>
         /// Reads a BSON Int64 from the reader.
         /// </summary>
         /// <returns>An Int64.</returns>
         public abstract long ReadInt64();
 
-        /// <summary>
-        /// Reads a BSON Int64 element from the reader.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <returns>An Int64.</returns>
-        public long ReadInt64(string name)
-        {
-            VerifyName(name);
-            return ReadInt64();
-        }
-
         /// <summary>
         /// Reads a BSON JavaScript from the reader.
         /// </summary>
         /// <returns>A string.</returns>
         public abstract string ReadJavaScript();
 
-        /// <summary>
-        /// Reads a BSON JavaScript element from the reader.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <returns>A string.</returns>
-        public string ReadJavaScript(string name)
-        {
-            VerifyName(name);
-            return ReadJavaScript();
-        }
-
         /// <summary>
         /// Reads a BSON JavaScript with scope from the reader (call ReadStartDocument next to read the scope).
         /// </summary>
         /// <returns>A string.</returns>
         public abstract string ReadJavaScriptWithScope();
 
-        /// <summary>
-        /// Reads a BSON JavaScript with scope element from the reader (call ReadStartDocument next to read the scope).
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <returns>A string.</returns>
-        public string ReadJavaScriptWithScope(string name)
-        {
-            VerifyName(name);
-            return ReadJavaScriptWithScope();
-        }
-
         /// <summary>
         /// Reads a BSON MaxKey from the reader.
         /// </summary>
         public abstract void ReadMaxKey();
 
-        /// <summary>
-        /// Reads a BSON MaxKey element from the reader.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        public void ReadMaxKey(string name)
-        {
-            VerifyName(name);
-            ReadMaxKey();
-        }
-
         /// <summary>
         /// Reads a BSON MinKey from the reader.
         /// </summary>
         public abstract void ReadMinKey();
 
-        /// <summary>
-        /// Reads a BSON MinKey element from the reader.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        public void ReadMinKey(string name)
-        {
-            VerifyName(name);
-            ReadMinKey();
-        }
-
         /// <summary>
         /// Reads the name of an element from the reader.
         /// </summary>
         /// <returns>The name of the element.</returns>
-        public string ReadName()
+        public virtual string ReadName()
         {
-            if (_disposed) { ThrowObjectDisposedException(); }
-            if (_state == BsonReaderState.Type)
-            {
-                ReadBsonType();
-            }
-            if (_state != BsonReaderState.Name)
-            {
-                ThrowInvalidState("ReadName", BsonReaderState.Name);
-            }
-
-            _state = BsonReaderState.Value;
-            return _currentName;
+            return ReadName(Utf8NameDecoder.Instance);
         }
 
         /// <summary>
-        /// Reads the name of an element from the reader.
+        /// Reads the name of an element from the reader (using the provided name decoder).
         /// </summary>
-        /// <param name="name">The name of the element.</param>
-        public void ReadName(string name)
-        {
-            VerifyName(name);
-        }
+        /// <param name="nameDecoder">The name decoder.</param>
+        /// <returns>
+        /// The name of the element.
+        /// </returns>
+        public abstract string ReadName(INameDecoder nameDecoder);
 
         /// <summary>
         /// Reads a BSON null from the reader.
         /// </summary>
         public abstract void ReadNull();
 
-        /// <summary>
-        /// Reads a BSON null element from the reader.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        public void ReadNull(string name)
-        {
-            VerifyName(name);
-            ReadNull();
-        }
-
         /// <summary>
         /// Reads a BSON ObjectId from the reader.
         /// </summary>
         /// <returns>An ObjectId.</returns>
         public abstract ObjectId ReadObjectId();
 
-        /// <summary>
-        /// Reads a BSON ObjectId from the reader.
-        /// </summary>
-        /// <param name="timestamp">The timestamp.</param>
-        /// <param name="machine">The machine hash.</param>
-        /// <param name="pid">The PID.</param>
-        /// <param name="increment">The increment.</param>
-        [Obsolete("Use ReadObjectId() instead.")]
-        public void ReadObjectId(out int timestamp, out int machine, out short pid, out int increment)
-        {
-            var objectId = ReadObjectId();
-            timestamp = objectId.Timestamp;
-            machine = objectId.Machine;
-            pid = objectId.Pid;
-            increment = objectId.Increment;
-        }
-
-        /// <summary>
-        /// Reads a BSON ObjectId element from the reader.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <returns>An ObjectId.</returns>
-        public ObjectId ReadObjectId(string name)
-        {
-            VerifyName(name);
-            return ReadObjectId();
-        }
-
-        /// <summary>
-        /// Reads a BSON ObjectId element from the reader.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <param name="timestamp">The timestamp.</param>
-        /// <param name="machine">The machine hash.</param>
-        /// <param name="pid">The PID.</param>
-        /// <param name="increment">The increment.</param>
-        [Obsolete("Use ReadObjectId(string name) instead.")]
-        public void ReadObjectId(string name, out int timestamp, out int machine, out short pid, out int increment)
-        {
-            VerifyName(name);
-            ReadObjectId(out timestamp, out machine, out pid, out increment);
-        }
-
         /// <summary>
         /// Reads a raw BSON array.
         /// </summary>
         /// <returns>The raw BSON array.</returns>
         public virtual IByteBuffer ReadRawBsonArray()
         {
-            // overridden in BsonBinaryReader
-            var array = BsonArraySerializer.Instance.Deserialize(this, typeof(BsonArray), null);
-            using (var bsonWriter = new BsonBinaryWriter(new BsonBuffer(), true, BsonBinaryWriterSettings.Defaults))
+            // overridden in BsonBinaryReader to read the raw bytes from the stream
+            // for all other streams, deserialize the array and reserialize it using a BsonBinaryWriter to get the raw bytes
+
+            var deserializationContext = BsonDeserializationContext.CreateRoot(this);
+            var array = BsonArraySerializer.Instance.Deserialize(deserializationContext);
+
+            using (var memoryStream = new MemoryStream())
+            using (var bsonWriter = new BsonBinaryWriter(memoryStream, BsonBinaryWriterSettings.Defaults))
             {
+                var serializationContext = BsonSerializationContext.CreateRoot(bsonWriter);
                 bsonWriter.WriteStartDocument();
-                var startPosition = bsonWriter.Buffer.Position + 3; // just past BsonType, "x" and null byte
+                var startPosition = memoryStream.Position + 3; // just past BsonType, "x" and null byte
                 bsonWriter.WriteName("x");
-                BsonArraySerializer.Instance.Serialize(bsonWriter, typeof(BsonArray), array, null);
-                var endPosition = bsonWriter.Buffer.Position;
+                BsonArraySerializer.Instance.Serialize(serializationContext, array);
+                var endPosition = memoryStream.Position;
                 bsonWriter.WriteEndDocument();
 
-                var length = (int)(endPosition - startPosition);
-                bsonWriter.Buffer.Position = startPosition;
-                var bytes = bsonWriter.Buffer.ReadBytes(length);
-                return new ByteArrayBuffer(bytes, 0, length, true);
+                byte[] memoryStreamBuffer;
+#if NETSTANDARD1_5 || NETSTANDARD1_6
+                memoryStreamBuffer = memoryStream.ToArray();
+#else
+                memoryStreamBuffer = memoryStream.GetBuffer();
+#endif
+                var buffer = new ByteArrayBuffer(memoryStreamBuffer, (int)memoryStream.Length, isReadOnly: true);
+                return new ByteBufferSlice(buffer, (int)startPosition, (int)(endPosition - startPosition));
             }
         }
 
-        /// <summary>
-        /// Reads a raw BSON array.
-        /// </summary>
-        /// <param name="name">The name.</param>
-        /// <returns>
-        /// The raw BSON array.
-        /// </returns>
-        public IByteBuffer ReadRawBsonArray(string name)
-        {
-            VerifyName(name);
-            return ReadRawBsonArray();
-        }
-
         /// <summary>
         /// Reads a raw BSON document.
         /// </summary>
         /// <returns>The raw BSON document.</returns>
         public virtual IByteBuffer ReadRawBsonDocument()
         {
-            // overridden in BsonBinaryReader
-            var document = BsonDocumentSerializer.Instance.Deserialize(this, typeof(BsonDocument), null);
-            var bytes = document.ToBson();
-            return new ByteArrayBuffer(bytes, 0, bytes.Length, true);
-        }
+            // overridden in BsonBinaryReader to read the raw bytes from the stream
+            // for all other streams, deserialize the document and use ToBson to get the raw bytes
 
-        /// <summary>
-        /// Reads a raw BSON document.
-        /// </summary>
-        /// <param name="name">The name.</param>
-        /// <returns>The raw BSON document.</returns>
-        public IByteBuffer ReadRawBsonDocument(string name)
-        {
-            VerifyName(name);
-            return ReadRawBsonDocument();
+            var deserializationContext = BsonDeserializationContext.CreateRoot(this);
+            var document = BsonDocumentSerializer.Instance.Deserialize(deserializationContext);
+            var bytes = document.ToBson();
+            return new ByteArrayBuffer(bytes, isReadOnly: true);
         }
 
         /// <summary>
@@ -733,43 +310,6 @@ namespace MongoDB.Bson.IO
         /// <returns>A BsonRegularExpression.</returns>
         public abstract BsonRegularExpression ReadRegularExpression();
 
-        /// <summary>
-        /// Reads a BSON regular expression from the reader.
-        /// </summary>
-        /// <param name="pattern">A regular expression pattern.</param>
-        /// <param name="options">A regular expression options.</param>
-        [Obsolete("Use ReadRegularExpression() instead.")]
-        public void ReadRegularExpression(out string pattern, out string options)
-        {
-            var regex = ReadRegularExpression();
-            pattern = regex.Pattern;
-            options = regex.Options;
-        }
-
-        /// <summary>
-        /// Reads a BSON regular expression element from the reader.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <returns>A BsonRegularExpression.</returns>
-        public BsonRegularExpression ReadRegularExpression(string name)
-        {
-            VerifyName(name);
-            return ReadRegularExpression();
-        }
-
-        /// <summary>
-        /// Reads a BSON regular expression element from the reader.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <param name="pattern">A regular expression pattern.</param>
-        /// <param name="options">A regular expression options.</param>
-        [Obsolete("Use ReadRegularExpression(string name) instead.")]
-        public void ReadRegularExpression(string name, out string pattern, out string options)
-        {
-            VerifyName(name);
-            ReadRegularExpression(out pattern, out options);
-        }
-
         /// <summary>
         /// Reads the start of a BSON array.
         /// </summary>
@@ -786,66 +326,23 @@ namespace MongoDB.Bson.IO
         /// <returns>A String.</returns>
         public abstract string ReadString();
 
-        /// <summary>
-        /// Reads a BSON string element from the reader.
-        /// </summary>
-        /// <returns>A String.</returns>
-        /// <param name="name">The name of the element.</param>
-        public string ReadString(string name)
-        {
-            VerifyName(name);
-            return ReadString();
-        }
-
         /// <summary>
         /// Reads a BSON symbol from the reader.
         /// </summary>
         /// <returns>A string.</returns>
         public abstract string ReadSymbol();
 
-        /// <summary>
-        /// Reads a BSON symbol element from the reader.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <returns>A string.</returns>
-        public string ReadSymbol(string name)
-        {
-            VerifyName(name);
-            return ReadSymbol();
-        }
-
         /// <summary>
         /// Reads a BSON timestamp from the reader.
         /// </summary>
         /// <returns>The combined timestamp/increment.</returns>
         public abstract long ReadTimestamp();
 
-        /// <summary>
-        /// Reads a BSON timestamp element from the reader.
-        /// </summary>
-        /// <returns>The combined timestamp/increment.</returns>
-        /// <param name="name">The name of the element.</param>
-        public long ReadTimestamp(string name)
-        {
-            VerifyName(name);
-            return ReadTimestamp();
-        }
-
         /// <summary>
         /// Reads a BSON undefined from the reader.
         /// </summary>
         public abstract void ReadUndefined();
 
-        /// <summary>
-        /// Reads a BSON undefined element from the reader.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        public void ReadUndefined(string name)
-        {
-            VerifyName(name);
-            ReadUndefined();
-        }
-
         /// <summary>
         /// Returns the reader to previously bookmarked position and state.
         /// </summary>
@@ -939,21 +436,5 @@ namespace MongoDB.Bson.IO
                 throw new InvalidOperationException(message);
             }
         }
-
-        /// <summary>
-        /// Verifies the name of the current element.
-        /// </summary>
-        /// <param name="expectedName">The expected name.</param>
-        protected void VerifyName(string expectedName)
-        {
-            var actualName = ReadName();
-            if (actualName != expectedName)
-            {
-                var message = string.Format(
-                    "Expected element name to be '{0}', not '{1}'.",
-                    expectedName, actualName);
-                throw new Exception(message);
-            }
-        }
     }
 }

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonReader.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: 662f0b2d97caefa43b6ad1930686d562
+guid: 9e16b4a12b208304caaacbbd92f4fc5d
+timeCreated: 1503738735
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonReaderBookmark.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: d97bd6cc4d7465f4abc15b61bfcda3f8
+guid: dad9ffec391312a4e912c92c0ec24e58
+timeCreated: 1503738736
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 3 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonReaderSettings.cs

@@ -1,4 +1,4 @@
-/* Copyright 2010-2014 MongoDB Inc.
+/* Copyright 2010-2016 MongoDB Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -20,7 +20,9 @@ namespace MongoDB.Bson.IO
     /// <summary>
     /// Represents settings for a BsonReader.
     /// </summary>
+#if NET45
     [Serializable]
+#endif
     public abstract class BsonReaderSettings
     {
         // private fields

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonReaderSettings.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: 8413e6dd4d4d0b34a9f4955c64a1b901
+guid: f0b56440f8d5c9c40823d04469cc33c0
+timeCreated: 1503738736
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonReaderState.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: 8cba4338cf3ac114a971525e5bdc8429
+guid: 4a502ad6d4fb45c42bc7480de40649a5
+timeCreated: 1503738733
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 140 - 0
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonStream.cs

@@ -0,0 +1,140 @@
+/* Copyright 2010-2016 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.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MongoDB.Bson.IO
+{
+    /// <summary>
+    /// Represents a Stream has additional methods to suport reading and writing BSON values.
+    /// </summary>
+    public abstract class BsonStream : Stream
+    {
+        /// <summary>
+        /// Reads a BSON CString from the stream.
+        /// </summary>
+        /// <param name="encoding">The encoding.</param>
+        /// <returns>A string.</returns>
+        public abstract string ReadCString(UTF8Encoding encoding);
+
+        /// <summary>
+        /// Reads a BSON CString from the stream.
+        /// </summary>
+        /// <returns>An ArraySegment containing the CString bytes (without the null byte).</returns>
+        public abstract ArraySegment<byte> ReadCStringBytes();
+
+        /// <summary>
+        /// Reads a BSON Decimal128 from the stream.
+        /// </summary>
+        /// <returns>A <see cref="Decimal128"/>.</returns>
+        public abstract Decimal128 ReadDecimal128();
+
+        /// <summary>
+        /// Reads a BSON double from the stream.
+        /// </summary>
+        /// <returns>A double.</returns>
+        public abstract double ReadDouble();
+
+        /// <summary>
+        /// Reads a 32-bit BSON integer from the stream.
+        /// </summary>
+        /// <returns>An int.</returns>
+        public abstract int ReadInt32();
+
+        /// <summary>
+        /// Reads a 64-bit BSON integer from the stream.
+        /// </summary>
+        /// <returns>A long.</returns>
+        public abstract long ReadInt64();
+
+        /// <summary>
+        /// Reads a BSON ObjectId from the stream.
+        /// </summary>
+        /// <returns>An ObjectId.</returns>
+        public abstract ObjectId ReadObjectId();
+
+        /// <summary>
+        /// Reads a raw length prefixed slice from the stream.
+        /// </summary>
+        /// <returns>A slice.</returns>
+        public abstract IByteBuffer ReadSlice();
+
+        /// <summary>
+        /// Reads a BSON string from the stream.
+        /// </summary>
+        /// <param name="encoding">The encoding.</param>
+        /// <returns>A string.</returns>
+        public abstract string ReadString(UTF8Encoding encoding);
+
+        /// <summary>
+        /// Skips over a BSON CString leaving the stream positioned just after the terminating null byte.
+        /// </summary>
+        public abstract void SkipCString();
+
+        /// <summary>
+        /// Writes a BSON CString to the stream.
+        /// </summary>
+        /// <param name="value">The value.</param>
+        public abstract void WriteCString(string value);
+
+        /// <summary>
+        /// Writes the CString bytes to the stream.
+        /// </summary>
+        /// <param name="value">The value.</param>
+        public abstract void WriteCStringBytes(byte[] value);
+
+        /// <summary>
+        /// Writes a BSON Decimal128 to the stream.
+        /// </summary>
+        /// <param name="value">The value.</param>
+        public abstract void WriteDecimal128(Decimal128 value);
+
+        /// <summary>
+        /// Writes a BSON double to the stream.
+        /// </summary>
+        /// <param name="value">The value.</param>
+        public abstract void WriteDouble(double value);
+
+        /// <summary>
+        /// Writes a 32-bit BSON integer to the stream.
+        /// </summary>
+        /// <param name="value">The value.</param>
+        public abstract void WriteInt32(int value);
+
+        /// <summary>
+        /// Writes a 64-bit BSON integer to the stream.
+        /// </summary>
+        /// <param name="value">The value.</param>
+        public abstract void WriteInt64(long value);
+
+        /// <summary>
+        /// Writes a BSON ObjectId to the stream.
+        /// </summary>
+        /// <param name="value">The value.</param>
+        public abstract void WriteObjectId(ObjectId value);
+
+        /// <summary>
+        /// Writes a BSON string to the stream.
+        /// </summary>
+        /// <param name="value">The value.</param>
+        /// <param name="encoding">The encoding.</param>
+        public abstract void WriteString(string value, UTF8Encoding encoding);
+    }
+}

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonBuffer.cs.meta → Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonStream.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: 76a15caaa01dd164d881f9f477bd9e85
+guid: 62f94aa39e52a5f4893a7ad84ddefcc9
+timeCreated: 1503738734
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 567 - 0
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonStreamAdapter.cs

@@ -0,0 +1,567 @@
+/* Copyright 2010-2016 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.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MongoDB.Bson.IO
+{
+    /// <summary>
+    /// A Stream that wraps another Stream while implementing the BsonStream abstract methods.
+    /// </summary>
+    public sealed class BsonStreamAdapter : BsonStream
+    {
+        // fields
+        private bool _disposed;
+        private bool _ownsStream;
+        private readonly Stream _stream;
+        private readonly byte[] _temp = new byte[12];
+        private readonly byte[] _tempUtf8 = new byte[128];
+
+        // constructors
+        /// <summary>
+        /// Initializes a new instance of the <see cref="BsonStreamAdapter"/> class.
+        /// </summary>
+        /// <param name="stream">The stream.</param>
+        /// <param name="ownsStream">if set to <c>true</c> [owns stream].</param>
+        /// <exception cref="System.ArgumentNullException">stream</exception>
+        public BsonStreamAdapter(Stream stream, bool ownsStream = false)
+        {
+            if (stream == null)
+            {
+                throw new ArgumentNullException("stream");
+            }
+
+            _stream = stream;
+            _ownsStream = ownsStream;
+        }
+
+        // properties        
+        /// <summary>
+        /// Gets the base stream.
+        /// </summary>
+        /// <value>
+        /// The base stream.
+        /// </value>
+        public Stream BaseStream
+        {
+            get
+            {
+                ThrowIfDisposed();
+                return _stream;
+            }
+        }
+
+        /// <inheritdoc/>
+        public override bool CanRead
+        {
+            get
+            {
+                ThrowIfDisposed();
+                return _stream.CanRead;
+            }
+        }
+
+        /// <inheritdoc/>
+        public override bool CanSeek
+        {
+            get
+            {
+                ThrowIfDisposed();
+                return _stream.CanSeek;
+            }
+        }
+
+        /// <inheritdoc/>
+        public override bool CanTimeout
+        {
+            get
+            {
+                ThrowIfDisposed();
+                return _stream.CanTimeout;
+            }
+        }
+
+        /// <inheritdoc/>
+        public override bool CanWrite
+        {
+            get
+            {
+                ThrowIfDisposed();
+                return _stream.CanWrite;
+            }
+        }
+
+        /// <inheritdoc/>
+        public override long Length
+        {
+            get
+            {
+                ThrowIfDisposed();
+                return _stream.Length;
+            }
+        }
+
+        /// <inheritdoc/>
+        public override long Position
+        {
+            get
+            {
+                ThrowIfDisposed();
+                return _stream.Position;
+            }
+            set
+            {
+                ThrowIfDisposed();
+                _stream.Position = value;
+            }
+        }
+
+        /// <inheritdoc/>
+        public override int ReadTimeout
+        {
+            get
+            {
+                ThrowIfDisposed();
+                return _stream.ReadTimeout;
+            }
+            set
+            {
+                ThrowIfDisposed();
+                _stream.ReadTimeout = value;
+            }
+        }
+
+        /// <inheritdoc/>
+        public override int WriteTimeout
+        {
+            get
+            {
+                ThrowIfDisposed();
+                return _stream.WriteTimeout;
+            }
+            set
+            {
+                ThrowIfDisposed();
+                _stream.WriteTimeout = value;
+            }
+        }
+
+        // methods
+#if NET45
+        /// <inheritdoc/>
+        public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
+        {
+            ThrowIfDisposed();
+            return _stream.BeginRead(buffer, offset, count, callback, state);
+        }
+#endif
+
+#if NET45
+        /// <inheritdoc/>
+        public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
+        {
+            ThrowIfDisposed();
+            return _stream.BeginWrite(buffer, offset, count, callback, state);
+        }
+#endif
+
+#if NET45
+        /// <inheritdoc/>
+        public override void Close()
+        {
+            base.Close(); // base class will call Dispose
+        }
+#endif
+
+        /// <inheritdoc/>
+        public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken)
+        {
+            ThrowIfDisposed();
+            return _stream.CopyToAsync(destination, bufferSize, cancellationToken);
+        }
+
+        /// <inheritdoc/>
+        protected override void Dispose(bool disposing)
+        {
+            if (!_disposed)
+            {
+                if (disposing)
+                {
+                    if (_ownsStream)
+                    {
+                        _stream.Dispose();
+                    }
+                }
+                _disposed = true;
+            }
+            base.Dispose(disposing);
+        }
+
+#if NET45
+        /// <inheritdoc/>
+        public override int EndRead(IAsyncResult asyncResult)
+        {
+            ThrowIfDisposed();
+            return _stream.EndRead(asyncResult);
+        }
+#endif
+
+#if NET45
+        /// <inheritdoc/>
+        public override void EndWrite(IAsyncResult asyncResult)
+        {
+            ThrowIfDisposed();
+            _stream.EndWrite(asyncResult);
+        }
+#endif
+
+        /// <inheritdoc/>
+        public override void Flush()
+        {
+            ThrowIfDisposed();
+            _stream.Flush();
+        }
+
+        /// <inheritdoc/>
+        public override Task FlushAsync(CancellationToken cancellationToken)
+        {
+            ThrowIfDisposed();
+            return _stream.FlushAsync(cancellationToken);
+        }
+
+        /// <inheritdoc/>
+        public override int Read(byte[] buffer, int offset, int count)
+        {
+            ThrowIfDisposed();
+            return _stream.Read(buffer, offset, count);
+        }
+
+        /// <inheritdoc/>
+        public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
+        {
+            ThrowIfDisposed();
+            return _stream.ReadAsync(buffer, offset, count, cancellationToken);
+        }
+
+        /// <inheritdoc/>
+        public override int ReadByte()
+        {
+            ThrowIfDisposed();
+            return _stream.ReadByte();
+        }
+
+        /// <inheritdoc/>
+        public override string ReadCString(UTF8Encoding encoding)
+        {
+            if (encoding == null)
+            {
+                throw new ArgumentNullException("encoding");
+            }
+            ThrowIfDisposed();
+
+            var bytes = ReadCStringBytes();
+            return Utf8Helper.DecodeUtf8String(bytes.Array, 0, bytes.Count, encoding);
+        }
+
+        /// <inheritdoc/>
+        public override ArraySegment<byte> ReadCStringBytes()
+        {
+            ThrowIfDisposed();
+
+            var memoryStream = new MemoryStream(32);
+
+            while (true)
+            {
+                var b = _stream.ReadByte();
+                if (b == -1)
+                {
+                    throw new EndOfStreamException();
+                }
+                if (b == 0)
+                {
+                    byte[] memoryStreamBuffer;
+#if NETSTANDARD1_5 || NETSTANDARD1_6
+                    memoryStreamBuffer = memoryStream.ToArray();
+#else
+                    memoryStreamBuffer = memoryStream.GetBuffer();
+#endif
+                    return new ArraySegment<byte>(memoryStreamBuffer, 0, (int)memoryStream.Length);
+                }
+
+                memoryStream.WriteByte((byte)b);
+            }
+        }
+
+        /// <inheritdoc/>
+        public override Decimal128 ReadDecimal128()
+        {
+            ThrowIfDisposed();
+            var lowBits = (ulong)ReadInt64();
+            var highBits = (ulong)ReadInt64();
+            return Decimal128.FromIEEEBits(highBits, lowBits);
+        }
+
+        /// <inheritdoc/>
+        public override double ReadDouble()
+        {
+            ThrowIfDisposed();
+            this.ReadBytes(_temp, 0, 8);
+            return BitConverter.ToDouble(_temp, 0);
+        }
+
+        /// <inheritdoc/>
+        public override int ReadInt32()
+        {
+            ThrowIfDisposed();
+            this.ReadBytes(_temp, 0, 4);
+            return _temp[0] | (_temp[1] << 8) | (_temp[2] << 16) | (_temp[3] << 24);
+        }
+
+        /// <inheritdoc/>
+        public override long ReadInt64()
+        {
+            ThrowIfDisposed();
+            this.ReadBytes(_temp, 0, 8);
+            return BitConverter.ToInt64(_temp, 0);
+        }
+
+        /// <inheritdoc/>
+        public override ObjectId ReadObjectId()
+        {
+            ThrowIfDisposed();
+            this.ReadBytes(_temp, 0, 12);
+            return new ObjectId(_temp, 0);
+        }
+
+        /// <inheritdoc/>
+        public override IByteBuffer ReadSlice()
+        {
+            ThrowIfDisposed();
+            var position = _stream.Position;
+            var length = ReadInt32();
+            var bytes = new byte[length];
+            _stream.Position = position;
+            this.ReadBytes(bytes, 0, length);
+            return new ByteArrayBuffer(bytes, isReadOnly: true);
+        }
+
+        /// <inheritdoc/>
+        public override string ReadString(UTF8Encoding encoding)
+        {
+            if (encoding == null)
+            {
+                throw new ArgumentNullException("encoding");
+            }
+            ThrowIfDisposed();
+
+            var length = ReadInt32();
+            var bytes = length <= _tempUtf8.Length ? _tempUtf8 : new byte[length];
+            this.ReadBytes(bytes, 0, length);
+            if (bytes[length - 1] != 0)
+            {
+                throw new FormatException("String is missing terminating null byte.");
+            }
+
+            return encoding.GetString(bytes, 0, length - 1);
+        }
+
+        /// <inheritdoc/>
+        public override long Seek(long offset, SeekOrigin origin)
+        {
+            ThrowIfDisposed();
+            return _stream.Seek(offset, origin);
+        }
+
+        /// <inheritdoc/>
+        public override void SetLength(long value)
+        {
+            ThrowIfDisposed();
+            _stream.SetLength(value);
+        }
+
+        /// <inheritdoc/>
+        public override void SkipCString()
+        {
+            ThrowIfDisposed();
+
+            while (true)
+            {
+                var b = _stream.ReadByte();
+                if (b == -1)
+                {
+                    throw new EndOfStreamException();
+                }
+                if (b == 0)
+                {
+                    return;
+                }
+            }
+        }
+
+        /// <inheritdoc/>
+        private void ThrowIfDisposed()
+        {
+            if (_disposed)
+            {
+                throw new ObjectDisposedException(GetType().Name);
+            }
+        }
+
+        /// <inheritdoc/>
+        public override void Write(byte[] buffer, int offset, int count)
+        {
+            ThrowIfDisposed();
+            _stream.Write(buffer, offset, count);
+        }
+
+        /// <inheritdoc/>
+        public override Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
+        {
+            ThrowIfDisposed();
+            return _stream.WriteAsync(buffer, offset, count, cancellationToken);
+        }
+
+        /// <inheritdoc/>
+        public override void WriteByte(byte value)
+        {
+            ThrowIfDisposed();
+            _stream.WriteByte(value);
+        }
+
+        /// <inheritdoc/>
+        public override void WriteCString(string value)
+        {
+            if (value == null)
+            {
+                throw new ArgumentNullException("value");
+            }
+            ThrowIfDisposed();
+
+            byte[] bytes;
+            int length;
+
+            if (CStringUtf8Encoding.GetMaxByteCount(value.Length) <= _tempUtf8.Length)
+            {
+                bytes = _tempUtf8;
+                length = CStringUtf8Encoding.GetBytes(value, _tempUtf8, 0, Utf8Encodings.Strict);
+            }
+            else
+            {
+                bytes = Utf8Encodings.Strict.GetBytes(value);
+                if (Array.IndexOf<byte>(bytes, 0) != -1)
+                {
+                    throw new ArgumentException("A CString cannot contain null bytes.", "value");
+                }
+                length = bytes.Length;
+            }
+
+            _stream.Write(bytes, 0, length);
+            _stream.WriteByte(0);
+        }
+
+        /// <inheritdoc/>
+        public override void WriteCStringBytes(byte[] value)
+        {
+            if (value == null)
+            {
+                throw new ArgumentNullException("value");
+            }
+            ThrowIfDisposed();
+
+            this.WriteBytes(value, 0, value.Length);
+            WriteByte(0);
+        }
+
+        /// <inheritdoc/>
+        public override void WriteDecimal128(Decimal128 value)
+        {
+            ThrowIfDisposed();
+            WriteInt64((long)value.GetIEEELowBits());
+            WriteInt64((long)value.GetIEEEHighBits());
+        }
+
+        /// <inheritdoc/>
+        public override void WriteDouble(double value)
+        {
+            ThrowIfDisposed();
+            var bytes = BitConverter.GetBytes(value);
+            _stream.Write(bytes, 0, 8);
+        }
+
+        /// <inheritdoc/>
+        public override void WriteInt32(int value)
+        {
+            ThrowIfDisposed();
+            _temp[0] = (byte)(value);
+            _temp[1] = (byte)(value >> 8);
+            _temp[2] = (byte)(value >> 16);
+            _temp[3] = (byte)(value >> 24);
+            _stream.Write(_temp, 0, 4);
+        }
+
+        /// <inheritdoc/>
+        public override void WriteInt64(long value)
+        {
+            ThrowIfDisposed();
+            var bytes = BitConverter.GetBytes(value);
+            _stream.Write(bytes, 0, 8);
+        }
+
+        /// <inheritdoc/>
+        public override void WriteObjectId(ObjectId value)
+        {
+            ThrowIfDisposed();
+            value.ToByteArray(_temp, 0);
+            _stream.Write(_temp, 0, 12);
+        }
+
+        /// <inheritdoc/>
+        public override void WriteString(string value, UTF8Encoding encoding)
+        {
+            if (value == null)
+            {
+                throw new ArgumentNullException("value");
+            }
+            if (encoding == null)
+            {
+                throw new ArgumentNullException("encoding");
+            }
+            ThrowIfDisposed();
+
+            byte[] bytes;
+            int length;
+
+            if (encoding.GetMaxByteCount(value.Length) <= _tempUtf8.Length)
+            {
+                bytes = _tempUtf8;
+                length = encoding.GetBytes(value, 0, value.Length, _tempUtf8, 0);
+            }
+            else
+            {
+                bytes = encoding.GetBytes(value);
+                length = bytes.Length;
+            }
+
+            WriteInt32(length + 1);
+            _stream.Write(bytes, 0, length);
+            _stream.WriteByte(0);
+        }
+    }
+}

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/Serialization/Attributes/IBsonMemberMapModifier.cs.meta → Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonStreamAdapter.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: 0b11f92e7dce29b4d8cb52d223bff154
+guid: 31d3bcfad962ad24eae85782f416c4f7
+timeCreated: 1503738733
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 315 - 0
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonStreamExtensions.cs

@@ -0,0 +1,315 @@
+/* Copyright 2010-2016 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.IO;
+
+namespace MongoDB.Bson.IO
+{
+    /// <summary>
+    /// Represents extension methods on BsonStream.
+    /// </summary>
+    public static class BsonStreamExtensions
+    {
+        // static fields
+        private static readonly bool[] __validBsonTypes = new bool[256];
+
+        // static constructor
+        static BsonStreamExtensions()
+        {
+            foreach (BsonType bsonType in Enum.GetValues(typeof(BsonType)))
+            {
+                __validBsonTypes[(byte)bsonType] = true;
+            }
+        }
+
+        // static methods
+        /// <summary>
+        /// Backpatches the size.
+        /// </summary>
+        /// <param name="stream">The stream.</param>
+        /// <param name="startPosition">The start position.</param>
+        public static void BackpatchSize(this BsonStream stream, long startPosition)
+        {
+            if (stream == null)
+            {
+                throw new ArgumentNullException("stream");
+            }
+            if (startPosition < 0 || startPosition > stream.Length)
+            {
+                throw new ArgumentOutOfRangeException("startPosition");
+            }
+
+            var size = stream.Position - startPosition;
+            if (size > int.MaxValue)
+            {
+                var message = string.Format("Size {0} is larger than {1} (Int32.MaxValue).", size, int.MaxValue);
+                throw new FormatException(message);
+            }
+
+            var endPosition = stream.Position;
+            stream.Position = startPosition;
+            stream.WriteInt32((int)size);
+            stream.Position = endPosition;
+        }
+
+        /// <summary>
+        /// Reads the binary sub type.
+        /// </summary>
+        /// <param name="stream">The stream.</param>
+        /// <returns>The binary sub type.</returns>
+        public static BsonBinarySubType ReadBinarySubType(this BsonStream stream)
+        {
+            if (stream == null)
+            {
+                throw new ArgumentNullException("stream");
+            }
+            
+            var b = stream.ReadByte();
+            if (b == -1)
+            {
+                throw new EndOfStreamException();
+            }
+            return (BsonBinarySubType)b;
+        }
+
+        /// <summary>
+        /// Reads a boolean from the stream.
+        /// </summary>
+        /// <param name="stream">The stream.</param>
+        /// <returns>A boolean.</returns>
+        public static bool ReadBoolean(this BsonStream stream)
+        {
+            if (stream == null)
+            {
+                throw new ArgumentNullException("stream");
+            }
+            
+            var b = stream.ReadByte();
+            if (b == -1)
+            {
+                throw new EndOfStreamException();
+            }
+            return b != 0;
+        }
+
+        /// <summary>
+        /// Reads the BSON type.
+        /// </summary>
+        /// <param name="stream">The stream.</param>
+        /// <returns>The BSON type.</returns>
+        public static BsonType ReadBsonType(this BsonStream stream)
+        {
+            if (stream == null)
+            {
+                throw new ArgumentNullException("stream");
+            }
+
+            var b = stream.ReadByte();
+            if (b == -1)
+            {
+                throw new EndOfStreamException();
+            }
+            if (!__validBsonTypes[b])
+            {
+                var message = string.Format("Detected unknown BSON type \"\\x{0:x2}\". Are you using the latest driver version?", b);
+                throw new FormatException(message);
+            }
+            return (BsonType)b;
+        }
+
+        /// <summary>
+        /// Reads bytes from the stream.
+        /// </summary>
+        /// <param name="stream">The stream.</param>
+        /// <param name="buffer">The buffer.</param>
+        /// <param name="offset">The offset.</param>
+        /// <param name="count">The count.</param>
+        public static void ReadBytes(this BsonStream stream, byte[] buffer, int offset, int count)
+        {
+            if (stream == null)
+            {
+                throw new ArgumentNullException("stream");
+            }
+            if (buffer == null)
+            {
+                throw new ArgumentNullException("buffer");
+            }
+            if (offset < 0 || offset > buffer.Length)
+            {
+                throw new ArgumentOutOfRangeException("offset");
+            }
+            if (count < 0 || offset + count > buffer.Length)
+            {
+                throw new ArgumentOutOfRangeException("count");
+            }
+
+            if (count == 1)
+            {
+                var b = stream.ReadByte();
+                if (b == -1)
+                {
+                    throw new EndOfStreamException();
+                }
+                buffer[offset] = (byte)b;
+            }
+            else
+            {
+                while (count > 0)
+                {
+                    var bytesRead = stream.Read(buffer, offset, count);
+                    if (bytesRead == 0)
+                    {
+                        throw new EndOfStreamException();
+                    }
+                    offset += bytesRead;
+                    count -= bytesRead;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Reads bytes from the stream.
+        /// </summary>
+        /// <param name="stream">The stream.</param>
+        /// <param name="count">The count.</param>
+        /// <returns>The bytes.</returns>
+        public static byte[] ReadBytes(this BsonStream stream, int count)
+        {
+            if (stream == null)
+            {
+                throw new ArgumentNullException("stream");
+            }
+            if (count < 0)
+            {
+                throw new ArgumentOutOfRangeException("count");
+            }
+
+            var bytes = new byte[count];
+            stream.ReadBytes(bytes, 0, count);
+            return bytes;
+        }
+
+        /// <summary>
+        /// Writes a binary sub type to the stream.
+        /// </summary>
+        /// <param name="stream">The stream.</param>
+        /// <param name="value">The value.</param>
+        public static void WriteBinarySubType(this BsonStream stream, BsonBinarySubType value)
+        {
+            if (stream == null)
+            {
+                throw new ArgumentNullException("stream");
+            }
+            
+            stream.WriteByte((byte)value);
+        }
+
+        /// <summary>
+        /// Writes a boolean to the stream.
+        /// </summary>
+        /// <param name="stream">The stream.</param>
+        /// <param name="value">The value.</param>
+        public static void WriteBoolean(this BsonStream stream, bool value)
+        {
+            if (stream == null)
+            {
+                throw new ArgumentNullException("stream");
+            }
+            
+            stream.WriteByte(value ? (byte)1 : (byte)0);
+        }
+
+        /// <summary>
+        /// Writes a BsonType to the stream.
+        /// </summary>
+        /// <param name="stream">The stream.</param>
+        /// <param name="value">The value.</param>
+        public static void WriteBsonType(this BsonStream stream, BsonType value)
+        {
+            if (stream == null)
+            {
+                throw new ArgumentNullException("stream");
+            }
+            
+            stream.WriteByte((byte)value);
+        }
+
+        /// <summary>
+        /// Writes bytes to the stream.
+        /// </summary>
+        /// <param name="stream">The stream.</param>
+        /// <param name="buffer">The buffer.</param>
+        /// <param name="offset">The offset.</param>
+        /// <param name="count">The count.</param>
+        public static void WriteBytes(this BsonStream stream, byte[] buffer, int offset, int count)
+        {
+            if (stream == null)
+            {
+                throw new ArgumentNullException("stream");
+            }
+            if (buffer == null)
+            {
+                throw new ArgumentNullException("buffer");
+            }
+            if (offset < 0 || offset > buffer.Length)
+            {
+                throw new ArgumentOutOfRangeException("offset");
+            }
+            if (count < 0 || offset + count > buffer.Length)
+            {
+                throw new ArgumentOutOfRangeException("count");
+            }
+
+            if (count == 1)
+            {
+                stream.WriteByte(buffer[offset]);
+            }
+            else
+            {
+                stream.Write(buffer, offset, count);
+            }
+        }
+
+        /// <summary>
+        /// Writes a slice to the stream.
+        /// </summary>
+        /// <param name="stream">The stream.</param>
+        /// <param name="slice">The slice.</param>
+        public static void WriteSlice(this BsonStream stream, IByteBuffer slice)
+        {
+            if (stream == null)
+            {
+                throw new ArgumentNullException("stream");
+            }
+            if (slice == null)
+            {
+                throw new ArgumentNullException("slice");
+            }
+
+            var position = 0;
+            var count = slice.Length;
+
+            while (count > 0)
+            {
+                var segment = slice.AccessBackingBytes(position);
+                var partialCount = Math.Min(count, segment.Count);
+                stream.WriteBytes(segment.Array, segment.Offset, partialCount);
+                position += partialCount;
+                count -= partialCount;
+            }
+        }
+    }
+}

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonChunk.cs.meta → Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonStreamExtensions.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: eb1e3fb44f0abd34ab80a1d41d74fde4
+guid: 5af976712ce63d842aeb814ea2d40d8e
+timeCreated: 1503738734
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 73 - 26
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonTrie.cs

@@ -1,4 +1,4 @@
-/* Copyright 2010-2014 MongoDB Inc.
+/* Copyright 2010-2015 MongoDB Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -14,6 +14,7 @@
 */
 
 using System;
+using System.IO;
 using System.Text;
 
 namespace MongoDB.Bson.IO
@@ -24,9 +25,6 @@ namespace MongoDB.Bson.IO
     /// <typeparam name="TValue">The type of the BsonTrie values.</typeparam>
     public class BsonTrie<TValue>
     {
-        // private static fields
-        private static readonly UTF8Encoding __utf8Encoding = new UTF8Encoding(false, true); // throw on invalid bytes
-
         // private fields
         private readonly BsonTrieNode<TValue> _root;
 
@@ -59,10 +57,10 @@ namespace MongoDB.Bson.IO
         /// <param name="value">The value to add. The value can be null for reference types.</param>
         public void Add(string elementName, TValue value)
         {
-            var keyBytes = __utf8Encoding.GetBytes(elementName);
+            var utf8 = Utf8Encodings.Strict.GetBytes(elementName);
 
             var node = _root;
-            foreach (var keyByte in keyBytes)
+            foreach (var keyByte in utf8)
             {
                 var child = node.GetChild(keyByte);
                 if (child == null)
@@ -76,38 +74,87 @@ namespace MongoDB.Bson.IO
             node.SetValue(elementName, value);
         }
 
+        /// <summary>
+        /// Gets the node associated with the specified element name.
+        /// </summary>
+        /// <param name="utf8">The element name.</param>
+        /// <param name="node">
+        /// When this method returns, contains the node associated with the specified element name, if the key is found;
+        /// otherwise, null. This parameter is passed unitialized.
+        /// </param>
+        /// <returns>True if the node was found; otherwise, false.</returns>
+        public bool TryGetNode(ArraySegment<byte> utf8, out BsonTrieNode<TValue> node)
+        {
+            node = _root;
+            for (var i = 0; node != null && i < utf8.Count; i++)
+            {
+                var keyByte = utf8.Array[utf8.Offset + i];
+                node = node.GetChild(keyByte);
+            }
+
+            return node != null;
+        }
+
+        /// <summary>
+        /// Tries to get the node associated with a name read from a stream.
+        /// </summary>
+        /// <param name="stream">The stream.</param>
+        /// <param name="node">The node.</param>
+        /// <returns>
+        /// True if the node was found.
+        /// If the node was found the stream is advanced over the name, otherwise
+        /// the stream is repositioned to the beginning of the name.
+        /// </returns>
+        public bool TryGetNode(BsonStream stream, out BsonTrieNode<TValue> node)
+        {
+            var position = stream.Position;
+            var utf8 = stream.ReadCStringBytes();
+
+            if (TryGetNode(utf8, out node))
+            {
+                return true;
+            }
+
+            stream.Position = position;
+            return false;
+        }
+
         /// <summary>
         /// Gets the value associated with the specified element name.
         /// </summary>
-        /// <param name="elementName">The element name.</param>
+        /// <param name="utf8">The element name.</param>
         /// <param name="value">
         /// When this method returns, contains the value associated with the specified element name, if the key is found;
         /// otherwise, the default value for the type of the value parameter. This parameter is passed unitialized.
         /// </param>
         /// <returns>True if the value was found; otherwise, false.</returns>
-        public bool TryGetValue(string elementName, out TValue value)
+        public bool TryGetValue(ArraySegment<byte> utf8, out TValue value)
         {
-            var keyBytes = __utf8Encoding.GetBytes(elementName);
-
-            var node = _root;
-            for (var i = 0; i < keyBytes.Length; i++)
+            BsonTrieNode<TValue> node;
+            if (TryGetNode(utf8, out node) && node.HasValue)
             {
-                node = node.GetChild(keyBytes[i]);
-                if (node == null)
-                {
-                    value = default(TValue);
-                    return false;
-                }
+                value = node.Value;
+                return true;
             }
 
-            if (!node.HasValue)
-            {
-                value = default(TValue);
-                return false;
-            }
+            value = default(TValue);
+            return false;
+        }
 
-            value = node.Value;
-            return true;
+        /// <summary>
+        /// Gets the value associated with the specified element name.
+        /// </summary>
+        /// <param name="elementName">The element name.</param>
+        /// <param name="value">
+        /// When this method returns, contains the value associated with the specified element name, if the key is found;
+        /// otherwise, the default value for the type of the value parameter. This parameter is passed unitialized.
+        /// </param>
+        /// <returns>True if the value was found; otherwise, false.</returns>
+        public bool TryGetValue(string elementName, out TValue value)
+        {
+            var bytes = Utf8Encodings.Strict.GetBytes(elementName);
+            var utf8 = new ArraySegment<byte>(bytes, 0, bytes.Length);
+            return TryGetValue(utf8, out value);
         }
     }
 
@@ -243,7 +290,7 @@ namespace MongoDB.Bson.IO
                     // grow the indexes on the max side
                     maxChildKeyByte = child._keyByte;
                     childrenIndexes = new byte[maxChildKeyByte - minChildKeyByte + 1];
-	                Array.Copy(_childrenIndexes, 0, childrenIndexes, 0, _childrenIndexes.Length);
+                    Array.Copy(_childrenIndexes, 0, childrenIndexes, 0, _childrenIndexes.Length);
                     for (var i = _childrenIndexes.Length; i < childrenIndexes.Length; i++)
                     {
                         childrenIndexes[i] = 255;

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonTrie.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: a7f2044749d0ddc4c8b5263f565a867e
+guid: 50dfe0455dc654542a8a070465122981
+timeCreated: 1503738733
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 72 - 529
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonWriter.cs

@@ -1,4 +1,4 @@
-/* Copyright 2010-2014 MongoDB Inc.
+/* Copyright 2010-2016 MongoDB Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
 */
 
 using System;
-using System.IO;
+using System.Collections.Generic;
 using System.Linq;
 using MongoDB.Bson.Serialization;
 using MongoDB.Bson.Serialization.Serializers;
@@ -24,15 +24,16 @@ namespace MongoDB.Bson.IO
     /// <summary>
     /// Represents a BSON writer for some external format (see subclasses).
     /// </summary>
-    public abstract class BsonWriter : IDisposable
+    public abstract class BsonWriter : IBsonWriter
     {
         // private fields
+        private Func<IElementNameValidator> _childElementNameValidatorFactory = () => NoOpElementNameValidator.Instance;
         private bool _disposed = false;
+        private IElementNameValidator _elementNameValidator = NoOpElementNameValidator.Instance;
+        private Stack<IElementNameValidator> _elementNameValidatorStack = new Stack<IElementNameValidator>();
         private BsonWriterSettings _settings;
         private BsonWriterState _state;
         private string _name;
-        private bool _checkElementNames;
-        private bool _checkUpdateDocument;
         private int _serializationDepth;
 
         // constructors
@@ -52,24 +53,6 @@ namespace MongoDB.Bson.IO
         }
 
         // public properties
-        /// <summary>
-        /// Gets or sets whether to check element names (no periods or leading $).
-        /// </summary>
-        public bool CheckElementNames
-        {
-            get { return _checkElementNames; }
-            set { _checkElementNames = value; }
-        }
-
-        /// <summary>
-        /// Gets or sets whether to check an update document (turns CheckElementNames on if first element name does *not* start with $).
-        /// </summary>
-        public bool CheckUpdateDocument
-        {
-            get { return _checkUpdateDocument; }
-            set { _checkUpdateDocument = value; }
-        }
-
         /// <summary>
         /// Gets the current serialization depth.
         /// </summary>
@@ -114,100 +97,6 @@ namespace MongoDB.Bson.IO
         }
 
         // public static methods
-        /// <summary>
-        /// Creates a BsonWriter to a BsonBuffer.
-        /// </summary>
-        /// <param name="settings">Optional BsonBinaryWriterSettings.</param>
-        /// <returns>A BsonWriter.</returns>
-        public static BsonWriter Create(BsonBinaryWriterSettings settings)
-        {
-            return new BsonBinaryWriter(null, null, settings);
-        }
-
-        /// <summary>
-        /// Creates a BsonWriter to a BsonBuffer.
-        /// </summary>
-        /// <param name="buffer">A BsonBuffer.</param>
-        /// <returns>A BsonWriter.</returns>
-        public static BsonWriter Create(BsonBuffer buffer)
-        {
-            return new BsonBinaryWriter(null, buffer, BsonBinaryWriterSettings.Defaults);
-        }
-
-        /// <summary>
-        /// Creates a BsonWriter to a BsonBuffer.
-        /// </summary>
-        /// <param name="buffer">A BsonBuffer.</param>
-        /// <param name="settings">Optional BsonBinaryWriterSettings.</param>
-        /// <returns>A BsonWriter.</returns>
-        public static BsonWriter Create(BsonBuffer buffer, BsonBinaryWriterSettings settings)
-        {
-            return new BsonBinaryWriter(null, buffer, settings);
-        }
-
-        /// <summary>
-        /// Creates a BsonWriter to a BsonDocument.
-        /// </summary>
-        /// <param name="document">A BsonDocument.</param>
-        /// <returns>A BsonWriter.</returns>
-        public static BsonWriter Create(BsonDocument document)
-        {
-            return Create(document, BsonDocumentWriterSettings.Defaults);
-        }
-
-        /// <summary>
-        /// Creates a BsonWriter to a BsonDocument.
-        /// </summary>
-        /// <param name="document">A BsonDocument.</param>
-        /// <param name="settings">The settings.</param>
-        /// <returns>A BsonWriter.</returns>
-        public static BsonWriter Create(BsonDocument document, BsonDocumentWriterSettings settings)
-        {
-            return new BsonDocumentWriter(document, settings);
-        }
-
-        /// <summary>
-        /// Creates a BsonWriter to a BSON Stream.
-        /// </summary>
-        /// <param name="stream">A Stream.</param>
-        /// <returns>A BsonWriter.</returns>
-        public static BsonWriter Create(Stream stream)
-        {
-            return Create(stream, BsonBinaryWriterSettings.Defaults);
-        }
-
-        /// <summary>
-        /// Creates a BsonWriter to a BSON Stream.
-        /// </summary>
-        /// <param name="stream">A Stream.</param>
-        /// <param name="settings">Optional BsonBinaryWriterSettings.</param>
-        /// <returns>A BsonWriter.</returns>
-        public static BsonWriter Create(Stream stream, BsonBinaryWriterSettings settings)
-        {
-            return new BsonBinaryWriter(stream, null, settings);
-        }
-
-        /// <summary>
-        /// Creates a BsonWriter to a JSON TextWriter.
-        /// </summary>
-        /// <param name="writer">A TextWriter.</param>
-        /// <returns>A BsonWriter.</returns>
-        public static BsonWriter Create(TextWriter writer)
-        {
-            return new JsonWriter(writer, JsonWriterSettings.Defaults);
-        }
-
-        /// <summary>
-        /// Creates a BsonWriter to a JSON TextWriter.
-        /// </summary>
-        /// <param name="writer">A TextWriter.</param>
-        /// <param name="settings">Optional JsonWriterSettings.</param>
-        /// <returns>A BsonWriter.</returns>
-        public static BsonWriter Create(TextWriter writer, JsonWriterSettings settings)
-        {
-            return new JsonWriter(writer, settings);
-        }
-
         // public methods
         /// <summary>
         /// Closes the writer.
@@ -232,80 +121,36 @@ namespace MongoDB.Bson.IO
         public abstract void Flush();
 
         /// <summary>
-        /// Writes BSON binary data to the writer.
-        /// </summary>
-        /// <param name="binaryData">The binary data.</param>
-        public abstract void WriteBinaryData(BsonBinaryData binaryData);
-
-        /// <summary>
-        /// Writes a BSON binary data element to the writer.
+        /// Pops the element name validator.
         /// </summary>
-        /// <param name="bytes">The binary data.</param>
-        /// <param name="subType">The binary data subtype.</param>
-        [Obsolete("Use WriteBinaryData(BsonBinaryData binaryData) instead.")]
-        public void WriteBinaryData(byte[] bytes, BsonBinarySubType subType)
+        /// <returns>The popped element validator.</returns>
+        public void PopElementNameValidator()
         {
-            var guidRepresentation = (subType == BsonBinarySubType.UuidStandard) ? GuidRepresentation.Standard : GuidRepresentation.Unspecified;
-            WriteBinaryData(bytes, subType, guidRepresentation);
+            _elementNameValidator = _elementNameValidatorStack.Pop();
+            _childElementNameValidatorFactory = () => _elementNameValidator;
         }
 
         /// <summary>
-        /// Writes BSON binary data to the writer.
-        /// </summary>
-        /// <param name="bytes">The binary data.</param>
-        /// <param name="subType">The binary data subtype.</param>
-        /// <param name="guidRepresentation">The respresentation for Guids.</param>
-        [Obsolete("Use WriteBinaryData(BsonBinaryData binaryData) instead.")]
-        public void WriteBinaryData(
-            byte[] bytes,
-            BsonBinarySubType subType,
-            GuidRepresentation guidRepresentation)
-        {
-            var binaryData = new BsonBinaryData(bytes, subType, guidRepresentation);
-            WriteBinaryData(binaryData);
-        }
-
-        /// <summary>
-        /// Writes a BSON binary data element to the writer.
+        /// Pushes the element name validator.
         /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <param name="binaryData">The binary data.</param>
-        public void WriteBinaryData(string name, BsonBinaryData binaryData)
+        /// <param name="validator">The validator.</param>
+        public void PushElementNameValidator(IElementNameValidator validator)
         {
-            WriteName(name);
-            WriteBinaryData(binaryData);
-        }
+            if (validator == null)
+            {
+                throw new ArgumentNullException("validator");
+            }
 
-        /// <summary>
-        /// Writes a BSON binary data element to the writer.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <param name="bytes">The binary data.</param>
-        /// <param name="subType">The binary data subtype.</param>
-        [Obsolete("Use WriteBinaryData(string name, BsonBinaryData binaryData) instead.")]
-        public void WriteBinaryData(string name, byte[] bytes, BsonBinarySubType subType)
-        {
-            WriteName(name);
-            WriteBinaryData(bytes, subType);
+            _elementNameValidatorStack.Push(_elementNameValidator);
+            _elementNameValidator = validator;
+            _childElementNameValidatorFactory = () => _elementNameValidator;
         }
 
         /// <summary>
-        /// Writes a BSON binary data element to the writer.
+        /// Writes BSON binary data to the writer.
         /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <param name="bytes">The binary data.</param>
-        /// <param name="subType">The binary data subtype.</param>
-        /// <param name="guidRepresentation">The representation for Guids.</param>
-        [Obsolete("Use WriteBinaryData(string name, BsonBinaryData binaryData) instead.")]
-        public void WriteBinaryData(
-            string name,
-            byte[] bytes,
-            BsonBinarySubType subType,
-            GuidRepresentation guidRepresentation)
-        {
-            WriteName(name);
-            WriteBinaryData(bytes, subType, guidRepresentation);
-        }
+        /// <param name="binaryData">The binary data.</param>
+        public abstract void WriteBinaryData(BsonBinaryData binaryData);
 
         /// <summary>
         /// Writes a BSON Boolean to the writer.
@@ -313,50 +158,20 @@ namespace MongoDB.Bson.IO
         /// <param name="value">The Boolean value.</param>
         public abstract void WriteBoolean(bool value);
 
-        /// <summary>
-        /// Writes a BSON Boolean element to the writer.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <param name="value">The Boolean value.</param>
-        public void WriteBoolean(string name, bool value)
-        {
-            WriteName(name);
-            WriteBoolean(value);
-        }
-
         /// <summary>
         /// Writes BSON binary data to the writer.
         /// </summary>
         /// <param name="bytes">The bytes.</param>
         public abstract void WriteBytes(byte[] bytes);
 
-        /// <summary>
-        /// Writes a BSON binary data element to the writer.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <param name="bytes">The bytes.</param>
-        public void WriteBytes(string name, byte[] bytes)
-        {
-            WriteName(name);
-            WriteBytes(bytes);
-        }
-
         /// <summary>
         /// Writes a BSON DateTime to the writer.
         /// </summary>
         /// <param name="value">The number of milliseconds since the Unix epoch.</param>
         public abstract void WriteDateTime(long value);
 
-        /// <summary>
-        /// Writes a BSON DateTime element to the writer.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <param name="value">The number of milliseconds since the Unix epoch.</param>
-        public void WriteDateTime(string name, long value)
-        {
-            WriteName(name);
-            WriteDateTime(value);
-        }
+        /// <inheritdoc />
+        public abstract void WriteDecimal128(Decimal128 value);
 
         /// <summary>
         /// Writes a BSON Double to the writer.
@@ -364,17 +179,6 @@ namespace MongoDB.Bson.IO
         /// <param name="value">The Double value.</param>
         public abstract void WriteDouble(double value);
 
-        /// <summary>
-        /// Writes a BSON Double element to the writer.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <param name="value">The Double value.</param>
-        public void WriteDouble(string name, double value)
-        {
-            WriteName(name);
-            WriteDouble(value);
-        }
-
         /// <summary>
         /// Writes the end of a BSON array to the writer.
         /// </summary>
@@ -389,6 +193,8 @@ namespace MongoDB.Bson.IO
         public virtual void WriteEndDocument()
         {
             _serializationDepth--;
+
+            PopElementNameValidator();
         }
 
         /// <summary>
@@ -397,98 +203,34 @@ namespace MongoDB.Bson.IO
         /// <param name="value">The Int32 value.</param>
         public abstract void WriteInt32(int value);
 
-        /// <summary>
-        /// Writes a BSON Int32 element to the writer.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <param name="value">The Int32 value.</param>
-        public void WriteInt32(string name, int value)
-        {
-            WriteName(name);
-            WriteInt32(value);
-        }
-
         /// <summary>
         /// Writes a BSON Int64 to the writer.
         /// </summary>
         /// <param name="value">The Int64 value.</param>
         public abstract void WriteInt64(long value);
 
-        /// <summary>
-        /// Writes a BSON Int64 element to the writer.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <param name="value">The Int64 value.</param>
-        public void WriteInt64(string name, long value)
-        {
-            WriteName(name);
-            WriteInt64(value);
-        }
-
         /// <summary>
         /// Writes a BSON JavaScript to the writer.
         /// </summary>
         /// <param name="code">The JavaScript code.</param>
         public abstract void WriteJavaScript(string code);
 
-        /// <summary>
-        /// Writes a BSON JavaScript element to the writer.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <param name="code">The JavaScript code.</param>
-        public void WriteJavaScript(string name, string code)
-        {
-            WriteName(name);
-            WriteJavaScript(code);
-        }
-
         /// <summary>
         /// Writes a BSON JavaScript to the writer (call WriteStartDocument to start writing the scope).
         /// </summary>
         /// <param name="code">The JavaScript code.</param>
         public abstract void WriteJavaScriptWithScope(string code);
 
-        /// <summary>
-        /// Writes a BSON JavaScript element to the writer (call WriteStartDocument to start writing the scope).
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <param name="code">The JavaScript code.</param>
-        public void WriteJavaScriptWithScope(string name, string code)
-        {
-            WriteName(name);
-            WriteJavaScriptWithScope(code);
-        }
-
         /// <summary>
         /// Writes a BSON MaxKey to the writer.
         /// </summary>
         public abstract void WriteMaxKey();
 
-        /// <summary>
-        /// Writes a BSON MaxKey element to the writer.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        public void WriteMaxKey(string name)
-        {
-            WriteName(name);
-            WriteMaxKey();
-        }
-
         /// <summary>
         /// Writes a BSON MinKey to the writer.
         /// </summary>
         public abstract void WriteMinKey();
 
-        /// <summary>
-        /// Writes a BSON MinKey element to the writer.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        public void WriteMinKey(string name)
-        {
-            WriteName(name);
-            WriteMinKey();
-        }
-
         /// <summary>
         /// Writes the name of an element to the writer.
         /// </summary>
@@ -501,14 +243,20 @@ namespace MongoDB.Bson.IO
             }
             if (name.IndexOf('\0') != -1)
             {
-                throw new ArgumentException("Element names cannot contain nulls.", "name");
+                throw new BsonSerializationException("Element names cannot contain nulls.");
             }
             if (_disposed) { throw new ObjectDisposedException(this.GetType().Name); }
             if (_state != BsonWriterState.Name)
             {
                 ThrowInvalidState("WriteName", BsonWriterState.Name);
             }
-            CheckElementName(name);
+
+            if (!_elementNameValidator.IsValidElementName(name))
+            {
+                var message = string.Format("Element name '{0}' is not valid'.", name);
+                throw new BsonSerializationException(message);
+            }
+            _childElementNameValidatorFactory = () => _elementNameValidator.GetValidatorForChildContent(name);
 
             _name = name;
             _state = BsonWriterState.Value;
@@ -519,131 +267,69 @@ namespace MongoDB.Bson.IO
         /// </summary>
         public abstract void WriteNull();
 
-        /// <summary>
-        /// Writes a BSON null element to the writer.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        public void WriteNull(string name)
-        {
-            WriteName(name);
-            WriteNull();
-        }
-
         /// <summary>
         /// Writes a BSON ObjectId to the writer.
         /// </summary>
         /// <param name="objectId">The ObjectId.</param>
         public abstract void WriteObjectId(ObjectId objectId);
 
-        /// <summary>
-        /// Writes a BSON ObjectId to the writer.
-        /// </summary>
-        /// <param name="timestamp">The timestamp.</param>
-        /// <param name="machine">The machine hash.</param>
-        /// <param name="pid">The PID.</param>
-        /// <param name="increment">The increment.</param>
-        [Obsolete("Use WriteObjectId(ObjectId objectId) instead.")]
-        public void WriteObjectId(int timestamp, int machine, short pid, int increment)
-        {
-            var objectId = new ObjectId(timestamp, machine, pid, increment);
-            WriteObjectId(objectId);
-        }
-
-        /// <summary>
-        /// Writes a BSON ObjectId element to the writer.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <param name="objectId">The ObjectId.</param>
-        public void WriteObjectId(string name, ObjectId objectId)
-        {
-            WriteName(name);
-            WriteObjectId(objectId);
-        }
-
-        /// <summary>
-        /// Writes a BSON ObjectId element to the writer.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <param name="timestamp">The timestamp.</param>
-        /// <param name="machine">The machine hash.</param>
-        /// <param name="pid">The PID.</param>
-        /// <param name="increment">The increment.</param>
-        [Obsolete("Use WriteObjectId(string name, ObjectId objectId) instead.")]
-        public void WriteObjectId(string name, int timestamp, int machine, short pid, int increment)
-        {
-            WriteName(name);
-            WriteObjectId(timestamp, machine, pid, increment);
-        }
-
         /// <summary>
         /// Writes a raw BSON array.
         /// </summary>
         /// <param name="slice">The byte buffer containing the raw BSON array.</param>
         public virtual void WriteRawBsonArray(IByteBuffer slice)
         {
-            // overridden in BsonBinaryWriter
+            // overridden in BsonBinaryWriter to write the raw bytes to the stream
+            // for all other streams, deserialize the raw bytes and serialize the resulting array instead
 
-            using (var bsonBuffer = new BsonBuffer())
+            using (var chunkSource = new InputBufferChunkSource(BsonChunkPool.Default))
+            using (var buffer = new MultiChunkBuffer(chunkSource))
+            using (var stream = new ByteBufferStream(buffer))
             {
-                BsonArray array;
-
                 // wrap the array in a fake document so we can deserialize it
-                var arrayLength = slice.Length;
-                var documentLength = arrayLength + 8;
-                bsonBuffer.WriteInt32(documentLength);
-                bsonBuffer.WriteByte((byte)BsonType.Array);
-                bsonBuffer.WriteByte((byte)'x');
-                bsonBuffer.WriteByte((byte)0);
-                bsonBuffer.ByteBuffer.WriteBytes(slice);
-                bsonBuffer.WriteByte((byte)0);
-
-                bsonBuffer.Position = 0;
-                using (var bsonReader = new BsonBinaryReader(bsonBuffer, true, BsonBinaryReaderSettings.Defaults))
+                var documentLength = slice.Length + 8;
+                buffer.EnsureCapacity(documentLength);
+                stream.WriteInt32(documentLength);
+                stream.WriteBsonType(BsonType.Array);
+                stream.WriteByte((byte)'x');
+                stream.WriteByte(0);
+                stream.WriteSlice(slice);
+                stream.WriteByte(0);
+                buffer.MakeReadOnly();
+
+                stream.Position = 0;
+                using (var reader = new BsonBinaryReader(stream, BsonBinaryReaderSettings.Defaults))
                 {
-                    bsonReader.ReadStartDocument();
-                    bsonReader.ReadName("x");
-                    array = (BsonArray)BsonArraySerializer.Instance.Deserialize(bsonReader, typeof(BsonArray), null);
-                    bsonReader.ReadEndDocument();
+                    var deserializationContext = BsonDeserializationContext.CreateRoot(reader);
+                    reader.ReadStartDocument();
+                    reader.ReadName("x");
+                    var array = BsonArraySerializer.Instance.Deserialize(deserializationContext);
+                    reader.ReadEndDocument();
+
+                    var serializationContext = BsonSerializationContext.CreateRoot(this);
+                    BsonArraySerializer.Instance.Serialize(serializationContext, array);
                 }
-
-                BsonArraySerializer.Instance.Serialize(this, typeof(BsonArray), array, null);
             }
         }
 
-        /// <summary>
-        /// Writes a raw BSON array.
-        /// </summary>
-        /// <param name="name">The name.</param>
-        /// <param name="slice">The byte buffer containing the raw BSON array.</param>
-        public void WriteRawBsonArray(string name, IByteBuffer slice)
-        {
-            WriteName(name);
-            WriteRawBsonArray(slice);
-        }
-
         /// <summary>
         /// Writes a raw BSON document.
         /// </summary>
         /// <param name="slice">The byte buffer containing the raw BSON document.</param>
         public virtual void WriteRawBsonDocument(IByteBuffer slice)
         {
-            // overridden in BsonBinaryWriter
-            using (var bsonReader = new BsonBinaryReader(new BsonBuffer(slice, false), true, BsonBinaryReaderSettings.Defaults))
+            // overridden in BsonBinaryWriter to write the raw bytes to the stream
+            // for all other streams, deserialize the raw bytes and serialize the resulting document instead
+
+            using (var stream = new ByteBufferStream(slice, ownsBuffer: false))
+            using (var bsonReader = new BsonBinaryReader(stream, BsonBinaryReaderSettings.Defaults))
             {
-                var document = BsonSerializer.Deserialize<BsonDocument>(bsonReader);
-                BsonDocumentSerializer.Instance.Serialize(this, typeof(BsonDocument), document, null);
-            }
-        }
+                var deserializationContext = BsonDeserializationContext.CreateRoot(bsonReader);
+                var document = BsonDocumentSerializer.Instance.Deserialize(deserializationContext);
 
-        /// <summary>
-        /// Writes a raw BSON document.
-        /// </summary>
-        /// <param name="name">The name.</param>
-        /// <param name="slice">The byte buffer containing the raw BSON document.</param>
-        public void WriteRawBsonDocument(string name, IByteBuffer slice)
-        {
-            WriteName(name);
-            WriteRawBsonDocument(slice);
+                var serializationContext = BsonSerializationContext.CreateRoot(this);
+                BsonDocumentSerializer.Instance.Serialize(serializationContext, document);
+            }
         }
 
         /// <summary>
@@ -652,42 +338,6 @@ namespace MongoDB.Bson.IO
         /// <param name="regex">A BsonRegularExpression.</param>
         public abstract void WriteRegularExpression(BsonRegularExpression regex);
 
-        /// <summary>
-        /// Writes a BSON regular expression to the writer.
-        /// </summary>
-        /// <param name="pattern">A regular expression pattern.</param>
-        /// <param name="options">A regular expression options.</param>
-        [Obsolete("Use WriteRegularExpression(BsonRegularExpression regex) instead.")]
-        public void WriteRegularExpression(string pattern, string options)
-        {
-            var regex = new BsonRegularExpression(pattern, options);
-            WriteRegularExpression(regex);
-        }
-
-        /// <summary>
-        /// Writes a BSON regular expression element to the writer.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <param name="regex">A BsonRegularExpression.</param>
-        public void WriteRegularExpression(string name, BsonRegularExpression regex)
-        {
-            WriteName(name);
-            WriteRegularExpression(regex);
-        }
-
-        /// <summary>
-        /// Writes a BSON regular expression element to the writer.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <param name="pattern">A regular expression pattern.</param>
-        /// <param name="options">A regular expression options.</param>
-        [Obsolete("Use WriteRegularExpression(string name, BsonRegularExpression regex) instead.")]
-        public void WriteRegularExpression(string name, string pattern, string options)
-        {
-            WriteName(name);
-            WriteRegularExpression(pattern, options);
-        }
-
         /// <summary>
         /// Writes the start of a BSON array to the writer.
         /// </summary>
@@ -700,16 +350,6 @@ namespace MongoDB.Bson.IO
             }
         }
 
-        /// <summary>
-        /// Writes the start of a BSON array element to the writer.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        public void WriteStartArray(string name)
-        {
-            WriteName(name);
-            WriteStartArray();
-        }
-
         /// <summary>
         /// Writes the start of a BSON document to the writer.
         /// </summary>
@@ -720,16 +360,8 @@ namespace MongoDB.Bson.IO
             {
                 throw new BsonSerializationException("Maximum serialization depth exceeded (does the object being serialized have a circular reference?).");
             }
-        }
 
-        /// <summary>
-        /// Writes the start of a BSON document element to the writer.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        public void WriteStartDocument(string name)
-        {
-            WriteName(name);
-            WriteStartDocument();
+            PushElementNameValidator(_childElementNameValidatorFactory());
         }
 
         /// <summary>
@@ -738,113 +370,24 @@ namespace MongoDB.Bson.IO
         /// <param name="value">The String value.</param>
         public abstract void WriteString(string value);
 
-        /// <summary>
-        /// Writes a BSON String element to the writer.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <param name="value">The String value.</param>
-        public void WriteString(string name, string value)
-        {
-            WriteName(name);
-            WriteString(value);
-        }
-
         /// <summary>
         /// Writes a BSON Symbol to the writer.
         /// </summary>
         /// <param name="value">The symbol.</param>
         public abstract void WriteSymbol(string value);
 
-        /// <summary>
-        /// Writes a BSON Symbol element to the writer.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <param name="value">The symbol.</param>
-        public void WriteSymbol(string name, string value)
-        {
-            WriteName(name);
-            WriteSymbol(value);
-        }
-
         /// <summary>
         /// Writes a BSON timestamp to the writer.
         /// </summary>
         /// <param name="value">The combined timestamp/increment value.</param>
         public abstract void WriteTimestamp(long value);
 
-        /// <summary>
-        /// Writes a BSON timestamp element to the writer.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        /// <param name="value">The combined timestamp/increment value.</param>
-        public void WriteTimestamp(string name, long value)
-        {
-            WriteName(name);
-            WriteTimestamp(value);
-        }
-
         /// <summary>
         /// Writes a BSON undefined to the writer.
         /// </summary>
         public abstract void WriteUndefined();
 
-        /// <summary>
-        /// Writes a BSON undefined element to the writer.
-        /// </summary>
-        /// <param name="name">The name of the element.</param>
-        public void WriteUndefined(string name)
-        {
-            WriteName(name);
-            WriteUndefined();
-        }
-
         // protected methods
-        /// <summary>
-        /// Checks that the element name is valid.
-        /// </summary>
-        /// <param name="name">The element name to be checked.</param>
-        protected void CheckElementName(string name)
-        {
-            if (_checkUpdateDocument)
-            {
-                _checkElementNames = name == "" || name[0] != '$';
-                _checkUpdateDocument = false;
-                return;
-            }
-
-            if (_checkElementNames)
-            {
-                if (name == "")
-                {
-                    var message = "Element name '' is not valid because it is an empty string.";
-                    throw new BsonSerializationException(message);
-                }
-
-                if (name[0] == '$')
-                {
-                    // a few element names starting with $ have to be allowed for historical reasons
-                    switch (name)
-                    {
-                        case "$code":
-                        case "$db":
-                        case "$id":
-                        case "$ref":
-                        case "$scope":
-                            break;
-                        default:
-                            var message = string.Format("Element name '{0}' is not valid because it starts with a '$'.", name);
-                            throw new BsonSerializationException(message);
-                    }
-                }
-
-                if (name.IndexOf('.') != -1)
-                {
-                    var message = string.Format("Element name '{0}' is not valid because it contains a '.'.", name);
-                    throw new BsonSerializationException(message);
-                }
-            }
-        }
-
         /// <summary>
         /// Disposes of any resources used by the writer.
         /// </summary>

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonWriter.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: f48f8def7bac1224cb268bdaa9e7076b
+guid: 8da7789b839ed2949a7b3d58b2c25d51
+timeCreated: 1503738734
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 3 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonWriterSettings.cs

@@ -1,4 +1,4 @@
-/* Copyright 2010-2014 MongoDB Inc.
+/* Copyright 2010-2016 MongoDB Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -20,7 +20,9 @@ namespace MongoDB.Bson.IO
     /// <summary>
     /// Represents settings for a BsonWriter.
     /// </summary>
+#if NET45
     [Serializable]
+#endif
     public abstract class BsonWriterSettings
     {
         // private fields

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonWriterSettings.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: a1fa0352ac847874a85adab82910f1ce
+guid: 87316a42109234940b799779d0e23eed
+timeCreated: 1503738734
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/BsonWriterState.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: 799d36ab68c96c24190477a99a42cbdf
+guid: 53b5b135e597b4648a5a47dd941ff03a
+timeCreated: 1503738733
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 131 - 375
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/ByteArrayBuffer.cs

@@ -1,4 +1,4 @@
-/* Copyright 2010-2014 MongoDB Inc.
+/* Copyright 2010-2015 MongoDB Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -14,78 +14,65 @@
 */
 
 using System;
-using System.IO;
 
 namespace MongoDB.Bson.IO
 {
     /// <summary>
-    /// A BSON buffer that is backed by a byte array.
+    /// An IByteBuffer that is backed by a contiguous byte array.
     /// </summary>
-    public class ByteArrayBuffer : IByteBuffer
+    public sealed class ByteArrayBuffer : IByteBuffer
     {
         // private fields
-        private bool _disposed;
         private byte[] _bytes;
-        private int _sliceOffset;
-        private int _capacity;
-        private int _length;
-        private int _position;
+        private bool _disposed;
         private bool _isReadOnly;
+        private int _length;
 
         // constructors
         /// <summary>
         /// Initializes a new instance of the <see cref="ByteArrayBuffer"/> class.
         /// </summary>
-        /// <param name="bytes">The backing bytes.</param>
-        /// <param name="sliceOffset">The offset where the slice begins.</param>
-        /// <param name="length">The length of the slice.</param>
+        /// <param name="bytes">The bytes.</param>
+        /// <param name="isReadOnly">Whether the buffer is read only.</param>
+        public ByteArrayBuffer(byte[] bytes, bool isReadOnly = false)
+            : this(bytes, bytes == null ? 0 : bytes.Length, isReadOnly)
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ByteArrayBuffer"/> class.
+        /// </summary>
+        /// <param name="bytes">The bytes.</param>
+        /// <param name="length">The length.</param>
         /// <param name="isReadOnly">Whether the buffer is read only.</param>
-        /// <exception cref="System.ArgumentNullException">bytes</exception>
-        public ByteArrayBuffer(byte[] bytes, int sliceOffset, int length, bool isReadOnly)
+        public ByteArrayBuffer(byte[] bytes, int length, bool isReadOnly = false)
         {
             if (bytes == null)
             {
                 throw new ArgumentNullException("bytes");
             }
+            if (length < 0 || length > bytes.Length)
+            {
+                throw new ArgumentOutOfRangeException("length");
+            }
 
-            _bytes = bytes;
-            _sliceOffset = sliceOffset;
-            _capacity = isReadOnly ? length : bytes.Length - _sliceOffset;
             _length = length;
+            _bytes = bytes;
             _isReadOnly = isReadOnly;
-            _position = 0;
         }
 
         // public properties
-        /// <summary>
-        /// Gets or sets the capacity.
-        /// </summary>
-        /// <value>
-        /// The capacity.
-        /// </value>
-        /// <exception cref="System.ObjectDisposedException">ByteArrayBuffer</exception>
-        /// <exception cref="System.NotSupportedException">The capacity of a ByteArrayBuffer cannot be changed.</exception>
+        /// <inheritdoc/>
         public int Capacity
         {
             get
             {
                 ThrowIfDisposed();
-                return _capacity;
-            }
-            set
-            {
-                ThrowIfDisposed();
-                throw new NotSupportedException("The capacity of a ByteArrayBuffer cannot be changed.");
+                return _isReadOnly ? _length : _bytes.Length;
             }
         }
 
-        /// <summary>
-        /// Gets a value indicating whether this instance is read only.
-        /// </summary>
-        /// <value>
-        /// <c>true</c> if this instance is read only; otherwise, <c>false</c>.
-        /// </value>
-        /// <exception cref="System.ObjectDisposedException">ByteArrayBuffer</exception>
+        /// <inheritdoc/>
         public bool IsReadOnly
         {
             get
@@ -95,15 +82,7 @@ namespace MongoDB.Bson.IO
             }
         }
 
-        /// <summary>
-        /// Gets or sets the length.
-        /// </summary>
-        /// <value>
-        /// The length.
-        /// </value>
-        /// <exception cref="System.ObjectDisposedException">ByteArrayBuffer</exception>
-        /// <exception cref="System.InvalidOperationException">The length of a read only buffer cannot be changed.</exception>
-        /// <exception cref="System.ArgumentOutOfRangeException">Length</exception>
+        /// <inheritdoc/>
         public int Length
         {
             get
@@ -114,382 +93,171 @@ namespace MongoDB.Bson.IO
             set
             {
                 ThrowIfDisposed();
-                EnsureIsWritable();
-                if (value < 0 || value > _capacity)
+                if (value < 0 || value > _bytes.Length)
                 {
-                    throw new ArgumentOutOfRangeException("length");
+                    throw new ArgumentOutOfRangeException("value");
                 }
+                EnsureIsWritable();
+
                 _length = value;
-                if (_position > _length)
-                {
-                    _position = _length;
-                }
             }
         }
 
-        /// <summary>
-        /// Gets or sets the position.
-        /// </summary>
-        /// <value>
-        /// The position.
-        /// </value>
-        /// <exception cref="System.ObjectDisposedException">ByteArrayBuffer</exception>
-        /// <exception cref="System.ArgumentOutOfRangeException">Position</exception>
-        public int Position
+        // public methods
+        /// <inheritdoc/>
+        public ArraySegment<byte> AccessBackingBytes(int position)
         {
-            get
-            {
-                ThrowIfDisposed();
-                return _position;
-            }
-            set
+            ThrowIfDisposed();
+            if (position < 0 || position > _length)
             {
-                ThrowIfDisposed();
-                if (value < 0 || value > _capacity)
-                {
-                    throw new ArgumentOutOfRangeException("Position");
-                }
-                _position = value;
-                if (_length < _position)
-                {
-                    _length = _position;
-                }
+                throw new ArgumentOutOfRangeException("position");
             }
-        }
-
-        // protected properties
-        /// <summary>
-        /// Gets a value indicating whether this <see cref="ByteArrayBuffer"/> is disposed.
-        /// </summary>
-        /// <value>
-        ///   <c>true</c> if disposed; otherwise, <c>false</c>.
-        /// </value>
-        protected bool Disposed
-        {
-            get { return _disposed; }
-        }
 
-        /// <summary>
-        /// Gets the slice offset.
-        /// </summary>
-        /// <value>
-        /// The slice offset.
-        /// </value>
-        protected int SliceOffset
-        {
-            get { return _sliceOffset; }
+            return new ArraySegment<byte>(_bytes, position, _length - position);
         }
 
-        // public methods
-        /// <summary>
-        /// Clears this instance.
-        /// </summary>
-        /// <exception cref="System.ObjectDisposedException">ByteArrayBuffer</exception>
-        /// <exception cref="System.InvalidOperationException">Write operations are not allowed for read only buffers.</exception>
-        public virtual void Clear()
+        /// <inheritdoc/>
+        public void Clear(int position, int count)
         {
             ThrowIfDisposed();
+            if (position < 0 || position > _length)
+            {
+                throw new ArgumentOutOfRangeException("position");
+            }
+            if (count < 0 || position + count > _length)
+            {
+                throw new ArgumentOutOfRangeException("count");
+            }
             EnsureIsWritable();
-            _position = 0;
-            _length = 0;
+
+            Array.Clear(_bytes, position, count);
         }
 
-        /// <summary>
-        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
-        /// </summary>
+        /// <inheritdoc/>
         public void Dispose()
         {
-            Dispose(true);
+            _disposed = true;
             GC.SuppressFinalize(this);
         }
 
-        /// <summary>
-        /// Finds the next null byte.
-        /// </summary>
-        /// <returns>
-        /// The position of the next null byte.
-        /// </returns>
-        /// <exception cref="System.ObjectDisposedException">ByteArrayBuffer</exception>
-        public int FindNullByte()
+        /// <inheritdoc/>
+        public void EnsureCapacity(int minimumCapacity)
         {
+            if (minimumCapacity < 0)
+            {
+                throw new ArgumentOutOfRangeException("minimumCapacity");
+            }
             ThrowIfDisposed();
-            var index = Array.IndexOf<byte>(_bytes, 0, _sliceOffset + _position, _length - _position);
-            return (index == -1) ? -1 : index - _sliceOffset;
+            EnsureIsWritable();
+
+            if (minimumCapacity > _bytes.Length)
+            {
+                var powerOf2 = Math.Max(32, PowerOf2.RoundUpToPowerOf2(minimumCapacity));
+                SetCapacity(powerOf2);
+            }
         }
 
-        /// <summary>
-        /// Gets a slice of this buffer.
-        /// </summary>
-        /// <param name="position">The position of the start of the slice.</param>
-        /// <param name="length">The length of the slice.</param>
-        /// <returns>
-        /// A slice of this buffer.
-        /// </returns>
-        /// <exception cref="System.ObjectDisposedException">ByteArrayBuffer</exception>
-        /// <exception cref="System.InvalidOperationException">GetSlice can only be called for read only buffers.</exception>
-        /// <exception cref="System.ArgumentOutOfRangeException">
-        /// position
-        /// or
-        /// length
-        /// </exception>
-        public virtual IByteBuffer GetSlice(int position, int length)
+        /// <inheritdoc/>
+        public byte GetByte(int position)
         {
             ThrowIfDisposed();
-            EnsureIsReadOnly();
-            if (position < 0 || position >= _length)
+            if (position < 0 || position > _length)
             {
                 throw new ArgumentOutOfRangeException("position");
             }
-            if (length <= 0 || length > _length - position)
-            {
-                throw new ArgumentOutOfRangeException("length");
-            }
 
-            return new ByteArrayBuffer(_bytes, _sliceOffset + position, length, true);
+            return _bytes[position];
         }
 
-        /// <summary>
-        /// Loads the buffer from a stream.
-        /// </summary>
-        /// <param name="stream">The stream.</param>
-        /// <param name="count">The count.</param>
-        /// <exception cref="System.ObjectDisposedException">ByteArrayBuffer</exception>
-        /// <exception cref="System.InvalidOperationException">Write operations are not allowed for read only buffers.</exception>
-        /// <exception cref="System.ArgumentNullException">stream</exception>
-        /// <exception cref="System.ArgumentOutOfRangeException">count</exception>
-        public void LoadFrom(Stream stream, int count)
+        /// <inheritdoc/>
+        public void GetBytes(int position, byte[] destination, int offset, int count)
         {
             ThrowIfDisposed();
-            EnsureIsWritable();
-            if (stream == null)
+            if (position < 0 || position > _length)
             {
-                throw new ArgumentNullException("stream");
+                throw new ArgumentOutOfRangeException("position");
             }
-            if (count > _capacity - _position)
+            if (destination == null)
             {
-                throw new ArgumentOutOfRangeException("count");
+                throw new ArgumentNullException("destination");
             }
-
-            EnsureSpaceAvailable(count);
-            var position = _position; // don't advance position
-            while (count > 0)
+            if (offset < 0 || offset > destination.Length)
             {
-                var bytesRead = stream.Read(_bytes, _sliceOffset + position, count);
-                if (bytesRead == 0)
-                {
-                    throw new EndOfStreamException();
-                }
-                position += bytesRead;
-                count -= bytesRead;
+                throw new ArgumentOutOfRangeException("offset");
             }
-            if (_length < position)
+            if (count < 0 || position + count > _length || offset + count > destination.Length)
             {
-                _length = position;
+                throw new ArgumentOutOfRangeException("count");
             }
-        }
 
-        /// <summary>
-        /// Makes this buffer read only.
-        /// </summary>
-        /// <exception cref="System.ObjectDisposedException">ByteArrayBuffer</exception>
-        public void MakeReadOnly()
-        {
-            ThrowIfDisposed();
-            _isReadOnly = true;
+            Buffer.BlockCopy(_bytes, position, destination, offset, count);
         }
 
-        /// <summary>
-        /// Read directly from the backing bytes. The returned ArraySegment points directly to the backing bytes for
-        /// the current position and you can read the bytes directly from there. If the backing bytes happen to span
-        /// a chunk boundary shortly after the current position there might not be enough bytes left in the current
-        /// chunk in which case the returned ArraySegment will have a Count of zero and you should call ReadBytes instead.
-        /// 
-        /// When ReadBackingBytes returns the position will have been advanced by count bytes *if and only if* there
-        /// were count bytes left in the current chunk.
-        /// </summary>
-        /// <param name="count">The number of bytes you need to read.</param>
-        /// <returns>
-        /// An ArraySegment pointing directly to the backing bytes for the current position.
-        /// </returns>
-        /// <exception cref="System.ObjectDisposedException">ByteArrayBuffer</exception>
-        public ArraySegment<byte> ReadBackingBytes(int count)
+        /// <inheritdoc/>
+        public IByteBuffer GetSlice(int position, int length)
         {
             ThrowIfDisposed();
-            EnsureDataAvailable(count);
-            var offset = _sliceOffset + _position;
-            _position += count;
-            return new ArraySegment<byte>(_bytes, offset, count);
-        }
+            if (position < 0 || position > _length)
+            {
+                throw new ArgumentOutOfRangeException("position");
+            }
+            if (length < 0 || position + length > _length)
+            {
+                throw new ArgumentOutOfRangeException("length");
+            }
+            EnsureIsReadOnly();
 
-        /// <summary>
-        /// Reads a byte.
-        /// </summary>
-        /// <returns>
-        /// A byte.
-        /// </returns>
-        /// <exception cref="System.ObjectDisposedException">ByteArrayBuffer</exception>
-        public byte ReadByte()
-        {
-            ThrowIfDisposed();
-            EnsureDataAvailable(1);
-            return _bytes[_sliceOffset + _position++];
+            var forkedBuffer = new ByteArrayBuffer(_bytes, _length, isReadOnly: true);
+            return new ByteBufferSlice(forkedBuffer, position, length);
         }
 
-        /// <summary>
-        /// Reads bytes.
-        /// </summary>
-        /// <param name="destination">The destination.</param>
-        /// <param name="destinationOffset">The destination offset.</param>
-        /// <param name="count">The count.</param>
-        /// <exception cref="System.ObjectDisposedException">ByteArrayBuffer</exception>
-        public void ReadBytes(byte[] destination, int destinationOffset, int count)
+        /// <inheritdoc/>
+        public void MakeReadOnly()
         {
             ThrowIfDisposed();
-            EnsureDataAvailable(count);
-            Buffer.BlockCopy(_bytes, _sliceOffset + _position, destination, destinationOffset, count);
-            _position += count;
+            _isReadOnly = true;
         }
 
-        /// <summary>
-        /// Reads bytes.
-        /// </summary>
-        /// <param name="count">The count.</param>
-        /// <returns>
-        /// The bytes.
-        /// </returns>
-        /// <exception cref="System.ObjectDisposedException">ByteArrayBuffer</exception>
-        public byte[] ReadBytes(int count)
+        /// <inheritdoc/>
+        public void SetByte(int position, byte value)
         {
             ThrowIfDisposed();
+            if (position < 0 || position > _length)
+            {
+                throw new ArgumentOutOfRangeException("position");
+            }
+            EnsureIsWritable();
 
-            var destination = new byte[count];
-            ReadBytes(destination, 0, count);
-
-            return destination;
+            _bytes[position] = value;
         }
 
-        /// <summary>
-        /// Write directly to the backing bytes. The returned ArraySegment points directly to the backing bytes for
-        /// the current position and you can write the bytes directly to there. If the backing bytes happen to span
-        /// a chunk boundary shortly after the current position there might not be enough bytes left in the current
-        /// chunk in which case the returned ArraySegment will have a Count of zero and you should call WriteBytes instead.
-        /// 
-        /// When WriteBackingBytes returns the position has not been advanced. After you have written up to count
-        /// bytes directly to the backing bytes advance the position by the number of bytes actually written.
-        /// </summary>
-        /// <param name="count">The count.</param>
-        /// <returns>
-        /// An ArraySegment pointing directly to the backing bytes for the current position.
-        /// </returns>
-        public ArraySegment<byte> WriteBackingBytes(int count)
+        /// <inheritdoc/>
+        public void SetBytes(int position, byte[] source, int offset, int count)
         {
             ThrowIfDisposed();
-            EnsureSpaceAvailable(count);
-            var offset = _sliceOffset + _position;
-            return new ArraySegment<byte>(_bytes, offset, count);
-        }
-
-        /// <summary>
-        /// Writes a byte.
-        /// </summary>
-        /// <param name="source">The byte.</param>
-        /// <exception cref="System.ObjectDisposedException">ByteArrayBuffer</exception>
-        /// <exception cref="System.InvalidOperationException">Write operations are not allowed for read only buffers.</exception>
-        public void WriteByte(byte source)
-        {
-            ThrowIfDisposed();
-            EnsureIsWritable();
-            EnsureSpaceAvailable(1);
-            _bytes[_sliceOffset + _position++] = source;
-            if (_length < _position)
+            if (position < 0 || position > _length)
             {
-                _length = _position;
+                throw new ArgumentOutOfRangeException("position");
             }
-        }
-
-        /// <summary>
-        /// Writes bytes.
-        /// </summary>
-        /// <param name="bytes">The bytes.</param>
-        /// <exception cref="System.ObjectDisposedException">ByteArrayBuffer</exception>
-        /// <exception cref="System.InvalidOperationException">Write operations are not allowed for read only buffers.</exception>
-        public void WriteBytes(byte[] bytes)
-        {
-            ThrowIfDisposed();
-            EnsureIsWritable();
-            var count = bytes.Length;
-            EnsureSpaceAvailable(count);
-            Buffer.BlockCopy(bytes, 0, _bytes, _sliceOffset + _position, count);
-            _position += count;
-            if (_length < _position)
+            if (source == null)
             {
-                _length = _position;
+                throw new ArgumentNullException("source");
             }
-        }
-
-        /// <summary>
-        /// Writes bytes.
-        /// </summary>
-        /// <param name="source">The bytes (in the form of an IByteBuffer).</param>
-        /// <exception cref="System.ObjectDisposedException">ByteArrayBuffer</exception>
-        /// <exception cref="System.InvalidOperationException">Write operations are not allowed for read only buffers.</exception>
-        public void WriteBytes(IByteBuffer source)
-        {
-            ThrowIfDisposed();
-            EnsureIsWritable();
-            var count = source.Length;
-            EnsureSpaceAvailable(count);
-            var savedPosition = source.Position;
-            source.Position = 0;
-            source.ReadBytes(_bytes, _sliceOffset + _position, count);
-            _position += count;
-            if (_length < _position)
+            if (offset < 0 || offset > source.Length)
             {
-                _length = _position;
+                throw new ArgumentOutOfRangeException("offset");
             }
-            source.Position = savedPosition;
-        }
-
-        /// <summary>
-        /// Writes Length bytes from this buffer starting at Position 0 to a stream.
-        /// </summary>
-        /// <param name="stream">The stream.</param>
-        /// <exception cref="System.ObjectDisposedException">ByteArrayBuffer</exception>
-        public void WriteTo(Stream stream)
-        {
-            ThrowIfDisposed();
-            stream.Write(_bytes, _sliceOffset, _length);
-        }
-
-        // protected methods
-        /// <summary>
-        /// Releases unmanaged and - optionally - managed resources.
-        /// </summary>
-        /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
-        protected virtual void Dispose(bool disposing)
-        {
-            // subclasses override this method if they have anything to Dispose
-            _disposed = true;
-        }
-
-        /// <summary>
-        /// Ensures the buffer is writable.
-        /// </summary>
-        /// <exception cref="System.ObjectDisposedException">ByteArrayBuffer is not writable.</exception>
-        protected void EnsureIsWritable()
-        {
-            if (_isReadOnly)
+            if (count < 0 || position + count > _length || offset + count > source.Length)
             {
-                var message = string.Format("{0} is not writable.", GetType().Name);
-                throw new InvalidOperationException(message);
+                throw new ArgumentOutOfRangeException("count");
             }
+            EnsureIsWritable();
+
+            Buffer.BlockCopy(source, offset, _bytes, position, count);
         }
 
-        /// <summary>
-        /// Ensures the buffer is read only.
-        /// </summary>
-        /// <exception cref="System.ObjectDisposedException">ByteArrayBuffer is not read only.</exception>
-        protected void EnsureIsReadOnly()
+        // private methods
+        private void EnsureIsReadOnly()
         {
             if (!_isReadOnly)
             {
@@ -498,40 +266,28 @@ namespace MongoDB.Bson.IO
             }
         }
 
-        /// <summary>
-        /// Throws if disposed.
-        /// </summary>
-        /// <exception cref="System.ObjectDisposedException"></exception>
-        protected void ThrowIfDisposed()
+        private void EnsureIsWritable()
         {
-            if (_disposed)
+            if (_isReadOnly)
             {
-                throw new ObjectDisposedException(GetType().Name);
+                var message = string.Format("{0} is not writable.", GetType().Name);
+                throw new InvalidOperationException(message);
             }
         }
 
-        // private methods
-        private void EnsureDataAvailable(int needed)
+        private void SetCapacity(int capacity)
         {
-            if (needed > _length - _position)
-            {
-                var available = _length - _position;
-                var message = string.Format(
-                    "Not enough input bytes available. Needed {0}, but only {1} are available (at position {2}).",
-                    needed, available, _position);
-                throw new EndOfStreamException(message);
-            }
+            var oldBytes = _bytes;
+            _bytes = new byte[capacity];
+            var bytesToCopy = capacity < oldBytes.Length ? capacity : oldBytes.Length;
+            Buffer.BlockCopy(oldBytes, 0, _bytes, 0, bytesToCopy);
         }
 
-        private void EnsureSpaceAvailable(int needed)
+        private void ThrowIfDisposed()
         {
-            if (needed > _capacity - _length)
+            if (_disposed)
             {
-                var available = _capacity - _length;
-                var message = string.Format(
-                    "Not enough space available. Needed {0}, but only {1} are available (at position {2}).",
-                    needed, available, _position);
-                throw new EndOfStreamException(message);
+                throw new ObjectDisposedException(GetType().Name);
             }
         }
     }

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/ByteArrayBuffer.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: dbe492da2e91b8441a2083a7deb18747
+guid: c0160b03c1c24ee4baa68f42949b6289
+timeCreated: 1503738735
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 111 - 0
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/ByteArrayChunk.cs

@@ -0,0 +1,111 @@
+/* Copyright 2013-2015 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;
+
+namespace MongoDB.Bson.IO
+{
+    /// <summary>
+    /// Represents a chunk backed by a byte array.
+    /// </summary>
+    public class ByteArrayChunk : IBsonChunk
+    {
+        #region static
+        private static byte[] CreateByteArray(int size)
+        {
+            if (size < 0)
+            {
+                throw new ArgumentOutOfRangeException("size");
+            }
+            return new byte[size];
+        }
+        #endregion
+
+        // fields
+        private byte[] _bytes;
+        private bool _disposed;
+
+        // constructors
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ByteArrayChunk"/> class.
+        /// </summary>
+        /// <param name="size">The size.</param>
+        public ByteArrayChunk(int size)
+            : this(CreateByteArray(size))
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ByteArrayChunk"/> class.
+        /// </summary>
+        /// <param name="bytes">The bytes.</param>
+        /// <exception cref="System.ArgumentNullException">bytes</exception>
+        public ByteArrayChunk(byte[] bytes)
+        {
+            if (bytes == null)
+            {
+                throw new ArgumentNullException("bytes");
+            }
+            _bytes = bytes;
+        }
+
+        // properties
+        /// <inheritdoc/>
+        public ArraySegment<byte> Bytes
+        {
+            get
+            {
+                ThrowIfDisposed();
+                return new ArraySegment<byte>(_bytes);
+            }
+        }
+
+        // methods
+        /// <inheritdoc/>
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
+        /// <inheritdoc/>
+        public IBsonChunk Fork()
+        {
+            ThrowIfDisposed();
+            return new ByteArrayChunk(_bytes);
+        }
+
+        /// <summary>
+        /// Releases unmanaged and - optionally - managed resources.
+        /// </summary>
+        /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
+        protected virtual void Dispose(bool disposing)
+        {
+            if (disposing)
+            {
+                _bytes = null;
+            }
+            _disposed = true;
+        }
+
+        private void ThrowIfDisposed()
+        {
+            if (_disposed)
+            {
+                throw new ObjectDisposedException(GetType().Name);
+            }
+        }
+    }
+}

+ 12 - 0
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/ByteArrayChunk.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: b96869eac81e01548989523d91c70468
+timeCreated: 1503738735
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 30 - 53
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/ByteBufferFactory.cs

@@ -1,4 +1,4 @@
-/* Copyright 2010-2014 MongoDB Inc.
+/* Copyright 2010-2015 MongoDB Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -25,74 +25,51 @@ namespace MongoDB.Bson.IO
     public static class ByteBufferFactory
     {
         /// <summary>
-        /// Creates a buffer of the specified fixed capacity. Depending on the required capacity, either a SingleChunkBuffer or a MultiChunkBuffer will be created.
+        /// Creates a buffer of the specified length. Depending on the length, either a SingleChunkBuffer or a MultiChunkBuffer will be created.
         /// </summary>
-        /// <param name="chunkPool">The chunk pool.</param>
-        /// <param name="fixedCapacity">The required capacity.</param>
-        /// <returns>A buffer.</returns>
-        public static IByteBuffer Create(BsonChunkPool chunkPool, int fixedCapacity)
+        /// <param name="chunkSource">The chunk pool.</param>
+        /// <param name="minimumCapacity">The minimum capacity.</param>
+        /// <returns>A buffer with at least the minimum capacity.</returns>
+        public static IByteBuffer Create(IBsonChunkSource chunkSource, int minimumCapacity)
         {
-            if (chunkPool == null)
+            if (chunkSource == null)
             {
-                throw new ArgumentNullException("pool");
+                throw new ArgumentNullException("chunkSource");
             }
-            if (fixedCapacity <= 0)
+            if (minimumCapacity <= 0)
             {
-                throw new ArgumentOutOfRangeException("capacity");
+                throw new ArgumentOutOfRangeException("minimumCapacity");
             }
 
-            if (fixedCapacity < chunkPool.ChunkSize)
+            var capacity = 0;
+            var chunks = new List<IBsonChunk>();
+            while (capacity < minimumCapacity)
             {
-                var chunk = chunkPool.AcquireChunk();
-                return new SingleChunkBuffer(chunk, 0, 0, false);
+                var chunk = chunkSource.GetChunk(minimumCapacity - capacity);
+                chunks.Add(chunk);
+                capacity += chunk.Bytes.Count;
             }
-            else
+
+            if (chunks.Count == 1)
             {
-                var chunksNeeded = ((fixedCapacity - 1) / chunkPool.ChunkSize) + 1;
-                var chunks = new List<BsonChunk>(chunksNeeded);
-                for (int i = 0; i < chunksNeeded; i++)
+                var chunk = chunks[0];
+
+                ByteArrayChunk byteArrayChunk;
+                if ((byteArrayChunk = chunk as ByteArrayChunk) != null)
                 {
-                    chunks.Add(chunkPool.AcquireChunk());
+                    var segment = byteArrayChunk.Bytes;
+                    if (segment.Offset == 0)
+                    {
+                        return new ByteArrayBuffer(segment.Array, segment.Count, isReadOnly: false);
+                    }
                 }
-                return new MultiChunkBuffer(chunks, 0, 0, false);
-            }
-        }
 
-        /// <summary>
-        /// Loads a byte buffer from a stream (the first 4 bytes in the stream are the length of the data).
-        /// Depending on the required capacity, either a SingleChunkBuffer or a MultiChunkBuffer will be created.
-        /// </summary>
-        /// <param name="stream">The stream.</param>
-        /// <returns>A buffer.</returns>
-        /// <exception cref="System.ArgumentNullException">stream</exception>
-        public static IByteBuffer LoadFrom(Stream stream)
-        {
-            if (stream == null)
-            {
-                throw new ArgumentNullException("stream");
+                return new SingleChunkBuffer(chunk, 0, isReadOnly: false);
             }
-
-            var lengthBytes = new byte[4];
-            var offset = 0;
-            var count = 4;
-            while (count > 0)
+            else
             {
-                var bytesRead = stream.Read(lengthBytes, offset, count);
-                if (bytesRead == 0)
-                {
-                    throw new EndOfStreamException();
-                }
-                offset += bytesRead;
-                count -= bytesRead;
+                return new MultiChunkBuffer(chunks, 0, isReadOnly: false);
             }
-            var length = BitConverter.ToInt32(lengthBytes, 0);
-
-            var buffer = Create(BsonChunkPool.Default, length);
-            buffer.WriteBytes(lengthBytes);
-            buffer.LoadFrom(stream, length - 4);
-            buffer.Position = 0;
-
-            return buffer;
         }
     }
 }

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/ByteBufferFactory.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: 2996822bc562c40488506180d5e015fe
+guid: d0db760928313b3499134723d17cb9ea
+timeCreated: 1503738735
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 235 - 0
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/ByteBufferSlice.cs

@@ -0,0 +1,235 @@
+/* Copyright 2010-2015 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.IO;
+
+namespace MongoDB.Bson.IO
+{
+    /// <summary>
+    /// Represents a slice of a byte buffer.
+    /// </summary>
+    public class ByteBufferSlice : IByteBuffer
+    {
+        private readonly IByteBuffer _buffer;
+        private bool _disposed;
+        private readonly int _length;
+        private readonly int _offset;
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ByteBufferSlice"/> class.
+        /// </summary>
+        /// <param name="buffer">The byte buffer.</param>
+        /// <param name="offset">The offset of the slice.</param>
+        /// <param name="length">The length of the slice.</param>
+        public ByteBufferSlice(IByteBuffer buffer, int offset, int length)
+        {
+            if (buffer == null)
+            {
+                throw new ArgumentNullException("buffer");
+            }
+            if (!buffer.IsReadOnly)
+            {
+                throw new ArgumentException("The buffer is not read only.", "buffer");
+            }
+            if (offset < 0 || offset > buffer.Length)
+            {
+                throw new ArgumentOutOfRangeException("offset");
+            }
+            if (length < 0 || offset + length > buffer.Length)
+            {
+                throw new ArgumentOutOfRangeException("length");
+            }
+
+            _buffer = buffer;
+            _offset = offset;
+            _length = length;
+        }
+
+        /// <summary>
+        /// Gets the buffer.
+        /// </summary>
+        /// <value>
+        /// The buffer.
+        /// </value>
+        public IByteBuffer Buffer
+        {
+            get
+            {
+                ThrowIfDisposed();
+                return _buffer;
+            }
+        }
+
+        /// <inheritdoc/>
+        public int Capacity
+        {
+            get
+            {
+                ThrowIfDisposed();
+                return _length;
+            }
+        }
+
+        /// <inheritdoc/>
+        public bool IsReadOnly
+        {
+            get
+            {
+                ThrowIfDisposed();
+                return true;
+            }
+        }
+
+        /// <inheritdoc/>
+        public int Length
+        {
+            get
+            {
+                ThrowIfDisposed();
+                return _length;
+            }
+            set
+            {
+                throw new NotSupportedException();
+            }
+        }
+
+        /// <inheritdoc/>
+        public ArraySegment<byte> AccessBackingBytes(int position)
+        {
+            EnsureValidPosition(position);
+            ThrowIfDisposed();
+
+            var segment = _buffer.AccessBackingBytes(position + _offset);
+            var count = Math.Min(segment.Count, _length - position);
+            return new ArraySegment<byte>(segment.Array, segment.Offset, count);
+        }
+
+        /// <inheritdoc/>
+        public void Clear(int position, int count)
+        {
+            EnsureValidPositionAndCount(position, count);
+            ThrowIfDisposed();
+
+            _buffer.Clear(position + _offset, count);
+        }
+
+        /// <inheritdoc/>
+        public void Dispose()
+        {
+            Dispose(true);
+            GC.SuppressFinalize(this);
+        }
+
+        /// <inheritdoc/>
+        public void EnsureCapacity(int minimumCapacity)
+        {
+            throw new NotSupportedException();
+        }
+
+        /// <inheritdoc/>
+        public byte GetByte(int position)
+        {
+            EnsureValidPosition(position);
+            ThrowIfDisposed();
+
+            return _buffer.GetByte(position + _offset);
+        }
+
+        /// <inheritdoc/>
+        public void GetBytes(int position, byte[] destination, int offset, int count)
+        {
+            EnsureValidPositionAndCount(position, count);
+            ThrowIfDisposed();
+
+            _buffer.GetBytes(position + _offset, destination, offset, count);
+        }
+
+        /// <inheritdoc/>
+        public IByteBuffer GetSlice(int position, int length)
+        {
+            EnsureValidPositionAndLength(position, length);
+            ThrowIfDisposed();
+
+            return _buffer.GetSlice(position + _offset, length);
+        }
+
+        /// <inheritdoc/>
+        public void MakeReadOnly()
+        {
+            ThrowIfDisposed();
+        }
+
+        /// <inheritdoc/>
+        public void SetByte(int position, byte value)
+        {
+            throw new NotSupportedException();
+        }
+
+        /// <inheritdoc/>
+        public void SetBytes(int position, byte[] source, int offset, int count)
+        {
+            throw new NotSupportedException();
+        }
+
+        /// <summary>
+        /// Releases unmanaged and - optionally - managed resources.
+        /// </summary>
+        /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
+        protected virtual void Dispose(bool disposing)
+        {
+            if (disposing && !_disposed)
+            {
+                _buffer.Dispose();
+            }
+            _disposed = true;
+        }
+
+        private void EnsureValidPosition(int position)
+        {
+            if (position < 0 || position > _length)
+            {
+                throw new ArgumentOutOfRangeException("position");
+            }
+        }
+
+        private void EnsureValidPositionAndCount(int position, int count)
+        {
+            EnsureValidPosition(position);
+            if (count < 0 || position + count > _length)
+            {
+                throw new ArgumentOutOfRangeException("count");
+            }
+        }
+
+        private void EnsureValidPositionAndLength(int position, int length)
+        {
+            EnsureValidPosition(position);
+            if (length < 0 || position + length > _length)
+            {
+                throw new ArgumentOutOfRangeException("length");
+            }
+        }
+
+        private void ThrowIfDisposed()
+        {
+            if (_disposed)
+            {
+                throw new ObjectDisposedException(GetType().Name);
+            }
+        }
+    }
+}

+ 12 - 0
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/ByteBufferSlice.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 9eb3210208360f04ba2e06cd2e125bd7
+timeCreated: 1503738735
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 727 - 0
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/ByteBufferStream.cs

@@ -0,0 +1,727 @@
+/* Copyright 2010-2016 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.IO;
+using System.Text;
+
+namespace MongoDB.Bson.IO
+{
+    /// <summary>
+    /// Represents a Stream backed by an IByteBuffer. Similar to MemoryStream but backed by an IByteBuffer
+    /// instead of a byte array and also implements the BsonStream interface for higher performance BSON I/O.
+    /// </summary>
+    public class ByteBufferStream : BsonStream
+    {
+        // private fields
+        private IByteBuffer _buffer;
+        private bool _disposed;
+        private int _length;
+        private readonly bool _ownsBuffer;
+        private int _position;
+        private readonly byte[] _temp = new byte[12];
+        private readonly byte[] _tempUtf8 = new byte[128];
+
+        // constructors
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ByteBufferStream"/> class.
+        /// </summary>
+        /// <param name="buffer">The buffer.</param>
+        /// <param name="ownsBuffer">Whether the stream owns the buffer and should Dispose it when done.</param>
+        public ByteBufferStream(IByteBuffer buffer, bool ownsBuffer = false)
+        {
+            if (buffer == null)
+            {
+                throw new ArgumentNullException("buffer");
+            }
+
+            _buffer = buffer;
+            _ownsBuffer = ownsBuffer;
+            _length = buffer.Length;
+        }
+
+        // public properties
+        /// <summary>
+        /// Gets the buffer.
+        /// </summary>
+        /// <value>
+        /// The buffer.
+        /// </value>
+        public IByteBuffer Buffer
+        {
+            get
+            {
+                ThrowIfDisposed();
+                return _buffer;
+            }
+        }
+
+        /// <inheritdoc/>
+        public override bool CanRead
+        {
+            get { return !_disposed; }
+        }
+
+        /// <inheritdoc/>
+        public override bool CanSeek
+        {
+            get { return !_disposed; }
+        }
+
+        /// <inheritdoc/>
+        public override bool CanTimeout
+        {
+            get { return false; }
+        }
+
+        /// <inheritdoc/>
+        public override bool CanWrite
+        {
+            get { return !_disposed && !_buffer.IsReadOnly; }
+        }
+
+        /// <inheritdoc/>
+        public override long Length
+        {
+            get
+            {
+                ThrowIfDisposed();
+                return _length;
+            }
+        }
+
+        /// <inheritdoc/>
+        public override long Position
+        {
+            get
+            {
+                ThrowIfDisposed();
+                return _position;
+            }
+            set
+            {
+                if (value < 0 || value > int.MaxValue)
+                {
+                    throw new ArgumentOutOfRangeException("value");
+                }
+                ThrowIfDisposed();
+                _position = (int)value;
+            }
+        }
+
+        // public methods
+        /// <inheritdoc/>
+        public override void Flush()
+        {
+            ThrowIfDisposed();
+            // do nothing
+        }
+
+        /// <inheritdoc/>
+        public override int Read(byte[] buffer, int offset, int count)
+        {
+            if (buffer == null)
+            {
+                throw new ArgumentNullException("buffer");
+            }
+            if (offset < 0 || offset > buffer.Length)
+            {
+                throw new ArgumentOutOfRangeException("offset");
+            }
+            if (count < 0 || offset + count > buffer.Length)
+            {
+                throw new ArgumentOutOfRangeException("count");
+            }
+            ThrowIfDisposed();
+
+            if (_position >= _length)
+            {
+                return 0;
+            }
+
+            var available = _length - _position;
+            if (count > available)
+            {
+                count = available;
+            }
+
+            _buffer.GetBytes(_position, buffer, offset, count);
+            _position += count;
+
+            return count;
+        }
+
+        /// <inheritdoc/>
+        public override int ReadByte()
+        {
+            ThrowIfDisposed();
+            if (_position >= _length)
+            {
+                return -1;
+            }
+            return _buffer.GetByte(_position++);
+        }
+
+        /// <inheritdoc/>
+        public override long Seek(long offset, SeekOrigin origin)
+        {
+            ThrowIfDisposed();
+
+            long position;
+            switch (origin)
+            {
+                case SeekOrigin.Begin: position = offset; break;
+                case SeekOrigin.Current: position = _position + offset; break;
+                case SeekOrigin.End: position = _length + offset; break;
+                default: throw new ArgumentException("Invalid origin.", "origin");
+            }
+            if (position < 0)
+            {
+                throw new IOException("Attempted to seek before the beginning of the stream.");
+            }
+            if (position > int.MaxValue)
+            {
+                throw new IOException("Attempted to seek beyond the maximum value that can be represented using 32 bits.");
+            }
+
+            _position = (int)position;
+            return position;
+        }
+
+        /// <inheritdoc/>
+        public override void SetLength(long value)
+        {
+            if (value < 0 || value > int.MaxValue)
+            {
+                throw new ArgumentOutOfRangeException("value");
+            }
+            ThrowIfDisposed();
+            EnsureWriteable();
+
+            _buffer.EnsureCapacity((int)value);
+            _length = (int)value;
+            if (_position > _length)
+            {
+                _position = _length;
+            }
+        }
+
+        /// <inheritdoc/>
+        public override void Write(byte[] buffer, int offset, int count)
+        {
+            if (buffer == null)
+            {
+                throw new ArgumentNullException("buffer");
+            }
+            if (offset < 0 || offset > buffer.Length)
+            {
+                throw new ArgumentOutOfRangeException("offset");
+            }
+            if (count < 0 || offset + count > buffer.Length)
+            {
+                throw new ArgumentOutOfRangeException("count");
+            }
+            ThrowIfDisposed();
+            EnsureWriteable();
+
+            PrepareToWrite(count);
+            _buffer.SetBytes(_position, buffer, offset, count);
+            SetPositionAfterWrite(_position + count);
+        }
+
+        /// <inheritdoc/>
+        public override void WriteByte(byte value)
+        {
+            ThrowIfDisposed();
+            PrepareToWrite(1);
+            _buffer.SetByte(_position, value);
+            SetPositionAfterWrite(_position + 1);
+        }
+
+        // protected methods
+        /// <inheritdoc/>
+        protected override void Dispose(bool disposing)
+        {
+            if (!_disposed)
+            {
+                if (_ownsBuffer)
+                {
+                    _buffer.Dispose();
+                }
+                _disposed = true;
+            }
+            base.Dispose(disposing);
+        }
+
+        // private methods
+        private void EnsureWriteable()
+        {
+            if (!CanWrite)
+            {
+                throw new NotSupportedException("Stream is not writeable.");
+            }
+        }
+
+        private int FindNullByte()
+        {
+            var position = _position;
+            while (position < _length)
+            {
+                var segment = _buffer.AccessBackingBytes(position);
+                var endOfSegmentIndex = segment.Offset + segment.Count;
+                for (var index = segment.Offset; index < endOfSegmentIndex; index++)
+                {
+                    if (segment.Array[index] == 0)
+                    {
+                        return position + (index - segment.Offset);
+                    }
+                }
+                position += segment.Count;
+            }
+
+            throw new EndOfStreamException();
+        }
+
+        private void PrepareToWrite(int count)
+        {
+            var minimumCapacity = (long)_position + (long)count;
+            if (minimumCapacity > int.MaxValue)
+            {
+                throw new IOException("Stream was too long.");
+            }
+
+            _buffer.EnsureCapacity((int)minimumCapacity);
+            _buffer.Length = _buffer.Capacity;
+            if (_length < _position)
+            {
+                _buffer.Clear(_length, _position - _length);
+            }
+        }
+
+        private byte[] ReadBytes(int count)
+        {
+            ThrowIfEndOfStream(count);
+            var bytes = new byte[count];
+            _buffer.GetBytes(_position, bytes, 0, count);
+            _position += count;
+            return bytes;
+        }
+
+        private void SetPositionAfterWrite(int position)
+        {
+            _position = position;
+            if (_length < position)
+            {
+                _length = position;
+            }
+        }
+
+        private void ThrowIfDisposed()
+        {
+            if (_disposed)
+            {
+                throw new ObjectDisposedException("ByteBufferStream");
+            }
+        }
+
+        private void ThrowIfEndOfStream(int count)
+        {
+            var minimumLength = (long)_position + (long)count;
+            if (_length < minimumLength)
+            {
+                if (_position < _length)
+                {
+                    _position = _length;
+                }
+                throw new EndOfStreamException();
+            }
+        }
+
+        /// <inheritdoc/>
+        public override string ReadCString(UTF8Encoding encoding)
+        {
+            if (encoding == null)
+            {
+                throw new ArgumentNullException("encoding");
+            }
+            ThrowIfDisposed();
+
+            var bytes = ReadCStringBytes();
+            return Utf8Helper.DecodeUtf8String(bytes.Array, bytes.Offset, bytes.Count, encoding);
+        }
+
+        /// <inheritdoc/>
+        public override ArraySegment<byte> ReadCStringBytes()
+        {
+            ThrowIfDisposed();
+            ThrowIfEndOfStream(1);
+
+            var segment = _buffer.AccessBackingBytes(_position);
+            var index = Array.IndexOf<byte>(segment.Array, 0, segment.Offset, segment.Count);
+            if (index != -1)
+            {
+                var length = index - segment.Offset;
+                _position += length + 1; // advance over the null byte
+                return new ArraySegment<byte>(segment.Array, segment.Offset, length); // without the null byte
+            }
+            else
+            {
+                var nullPosition = FindNullByte();
+                var length = nullPosition - _position;
+                var cstring = ReadBytes(length + 1); // advance over the null byte
+                return new ArraySegment<byte>(cstring, 0, length); // without the null byte
+            }
+        }
+
+        /// <inheritdoc/>
+        public override Decimal128 ReadDecimal128()
+        {
+            ThrowIfDisposed();
+            ThrowIfEndOfStream(16);
+
+            var lowBits = (ulong)ReadInt64();
+            var highBits = (ulong)ReadInt64();
+            return Decimal128.FromIEEEBits(highBits, lowBits);
+        }
+
+        /// <inheritdoc/>
+        public override double ReadDouble()
+        {
+            ThrowIfDisposed();
+            ThrowIfEndOfStream(8);
+
+            var segment = _buffer.AccessBackingBytes(_position);
+            if (segment.Count >= 8)
+            {
+                _position += 8;
+                return BitConverter.ToDouble(segment.Array, segment.Offset);
+            }
+            else
+            {
+                this.ReadBytes(_temp, 0, 8);
+                return BitConverter.ToDouble(_temp, 0);
+            }
+        }
+
+        /// <inheritdoc/>
+        public override int ReadInt32()
+        {
+            ThrowIfDisposed();
+            ThrowIfEndOfStream(4);
+
+            var segment = _buffer.AccessBackingBytes(_position);
+            if (segment.Count >= 4)
+            {
+                _position += 4;
+                var bytes = segment.Array;
+                var offset = segment.Offset;
+                return bytes[offset] | (bytes[offset + 1] << 8) | (bytes[offset + 2] << 16) | (bytes[offset + 3] << 24);
+            }
+            else
+            {
+                this.ReadBytes(_temp, 0, 4);
+                return _temp[0] | (_temp[1] << 8) | (_temp[2] << 16) | (_temp[3] << 24);
+            }
+        }
+
+        /// <inheritdoc/>
+        public override long ReadInt64()
+        {
+            ThrowIfDisposed();
+            ThrowIfEndOfStream(8);
+
+            var segment = _buffer.AccessBackingBytes(_position);
+            if (segment.Count >= 8)
+            {
+                _position += 8;
+                return BitConverter.ToInt64(segment.Array, segment.Offset);
+            }
+            else
+            {
+                this.ReadBytes(_temp, 0, 8);
+                return BitConverter.ToInt64(_temp, 0);
+            }
+        }
+
+        /// <inheritdoc/>
+        public override ObjectId ReadObjectId()
+        {
+            ThrowIfDisposed();
+            ThrowIfEndOfStream(12);
+
+            var segment = _buffer.AccessBackingBytes(_position);
+            if (segment.Count >= 12)
+            {
+                _position += 12;
+                return new ObjectId(segment.Array, segment.Offset);
+            }
+            else
+            {
+                this.ReadBytes(_temp, 0, 12);
+                return new ObjectId(_temp, 0);
+            }
+        }
+
+        /// <inheritdoc/>
+        public override IByteBuffer ReadSlice()
+        {
+            ThrowIfDisposed();
+
+            var position = _position;
+            var length = ReadInt32();
+            ThrowIfEndOfStream(length - 4);
+            Position = position + length;
+
+            return _buffer.GetSlice(position, length);
+        }
+
+        /// <inheritdoc/>
+        public override string ReadString(UTF8Encoding encoding)
+        {
+            if (encoding == null)
+            {
+                throw new ArgumentNullException("encoding");
+            }
+            ThrowIfDisposed();
+
+            var length = ReadInt32();
+            if (length <= 0)
+            {
+                var message = string.Format("Invalid string length: {0}.", length);
+                throw new FormatException(message);
+            }
+
+            var segment = _buffer.AccessBackingBytes(_position);
+            if (segment.Count >= length)
+            {
+                ThrowIfEndOfStream(length);
+                if (segment.Array[segment.Offset + length - 1] != 0)
+                {
+                    throw new FormatException("String is missing terminating null byte.");
+                }
+                _position += length;
+                return Utf8Helper.DecodeUtf8String(segment.Array, segment.Offset, length - 1, encoding);
+            }
+            else
+            {
+                var bytes = length <= _tempUtf8.Length ? _tempUtf8 : new byte[length];
+                this.ReadBytes(bytes, 0, length);
+                if (bytes[length - 1] != 0)
+                {
+                    throw new FormatException("String is missing terminating null byte.");
+                }
+                return Utf8Helper.DecodeUtf8String(bytes, 0, length - 1, encoding);
+            }
+        }
+
+        /// <inheritdoc/>
+        public override void SkipCString()
+        {
+            ThrowIfDisposed();
+            var nullPosition = FindNullByte();
+            _position = nullPosition + 1;
+        }
+
+        /// <inheritdoc/>
+        public override void WriteCString(string value)
+        {
+            if (value == null)
+            {
+                throw new ArgumentNullException("value");
+            }
+            ThrowIfDisposed();
+
+            var maxLength = CStringUtf8Encoding.GetMaxByteCount(value.Length) + 1;
+            PrepareToWrite(maxLength);
+
+            int actualLength;
+            var segment = _buffer.AccessBackingBytes(_position);
+            if (segment.Count >= maxLength)
+            {
+                actualLength = CStringUtf8Encoding.GetBytes(value, segment.Array, segment.Offset, Utf8Encodings.Strict);
+                segment.Array[segment.Offset + actualLength] = 0;
+            }
+            else
+            {
+                byte[] bytes;
+                if (maxLength <= _tempUtf8.Length)
+                {
+                    bytes = _tempUtf8;
+                    actualLength = CStringUtf8Encoding.GetBytes(value, bytes, 0, Utf8Encodings.Strict);
+                }
+                else
+                {
+                    bytes = Utf8Encodings.Strict.GetBytes(value);
+                    if (Array.IndexOf<byte>(bytes, 0) != -1)
+                    {
+                        throw new ArgumentException("A CString cannot contain null bytes.", "value");
+                    }
+                    actualLength = bytes.Length;
+                }
+
+                _buffer.SetBytes(_position, bytes, 0, actualLength);
+                _buffer.SetByte(_position + actualLength, 0);
+            }
+
+            SetPositionAfterWrite(_position + actualLength + 1);
+        }
+
+        /// <inheritdoc/>
+        public override void WriteCStringBytes(byte[] value)
+        {
+            if (value == null)
+            {
+                throw new ArgumentNullException("value");
+            }
+            ThrowIfDisposed();
+
+            var length = value.Length;
+
+            PrepareToWrite(length + 1);
+
+            _buffer.SetBytes(_position, value, 0, length);
+            _buffer.SetByte(_position + length, 0);
+
+            SetPositionAfterWrite(_position + length + 1);
+        }
+
+        /// <inheritdoc/>
+        public override void WriteDecimal128(Decimal128 value)
+        {
+            ThrowIfDisposed();
+            WriteInt64((long)value.GetIEEELowBits());
+            WriteInt64((long)value.GetIEEEHighBits());
+        }
+
+        /// <inheritdoc/>
+        public override void WriteDouble(double value)
+        {
+            ThrowIfDisposed();
+
+            PrepareToWrite(8);
+
+            var bytes = BitConverter.GetBytes(value);
+            _buffer.SetBytes(_position, bytes, 0, 8);
+
+            SetPositionAfterWrite(_position + 8);
+        }
+
+        /// <inheritdoc/>
+        public override void WriteInt32(int value)
+        {
+            ThrowIfDisposed();
+
+            PrepareToWrite(4);
+
+            var segment = _buffer.AccessBackingBytes(_position);
+            if (segment.Count >= 4)
+            {
+                segment.Array[segment.Offset] = (byte)value;
+                segment.Array[segment.Offset + 1] = (byte)(value >> 8);
+                segment.Array[segment.Offset + 2] = (byte)(value >> 16);
+                segment.Array[segment.Offset + 3] = (byte)(value >> 24);
+            }
+            else
+            {
+                _temp[0] = (byte)(value);
+                _temp[1] = (byte)(value >> 8);
+                _temp[2] = (byte)(value >> 16);
+                _temp[3] = (byte)(value >> 24);
+                _buffer.SetBytes(_position, _temp, 0, 4);
+            }
+
+            SetPositionAfterWrite(_position + 4);
+        }
+
+        /// <inheritdoc/>
+        public override void WriteInt64(long value)
+        {
+            ThrowIfDisposed();
+
+            PrepareToWrite(8);
+
+            var bytes = BitConverter.GetBytes(value);
+            _buffer.SetBytes(_position, bytes, 0, 8);
+
+            SetPositionAfterWrite(_position + 8);
+        }
+
+        /// <inheritdoc/>
+        public override void WriteObjectId(ObjectId value)
+        {
+            ThrowIfDisposed();
+
+            PrepareToWrite(12);
+
+            var segment = _buffer.AccessBackingBytes(_position);
+            if (segment.Count >= 12)
+            {
+                value.ToByteArray(segment.Array, segment.Offset);
+            }
+            else
+            {
+                var bytes = value.ToByteArray();
+                _buffer.SetBytes(_position, bytes, 0, 12);
+            }
+
+            SetPositionAfterWrite(_position + 12);
+        }
+
+        /// <inheritdoc/>
+        public override void WriteString(string value, UTF8Encoding encoding)
+        {
+            ThrowIfDisposed();
+
+            var maxLength = encoding.GetMaxByteCount(value.Length) + 5;
+            PrepareToWrite(maxLength);
+
+            int actualLength;
+            var segment = _buffer.AccessBackingBytes(_position);
+            if (segment.Count >= maxLength)
+            {
+                actualLength = encoding.GetBytes(value, 0, value.Length, segment.Array, segment.Offset + 4);
+
+                var lengthPlusOne = actualLength + 1;
+                segment.Array[segment.Offset] = (byte)lengthPlusOne;
+                segment.Array[segment.Offset + 1] = (byte)(lengthPlusOne >> 8);
+                segment.Array[segment.Offset + 2] = (byte)(lengthPlusOne >> 16);
+                segment.Array[segment.Offset + 3] = (byte)(lengthPlusOne >> 24);
+                segment.Array[segment.Offset + 4 + actualLength] = 0;
+            }
+            else
+            {
+                byte[] bytes;
+                if (maxLength <= _tempUtf8.Length)
+                {
+                    bytes = _tempUtf8;
+                    actualLength = encoding.GetBytes(value, 0, value.Length, bytes, 0);
+                }
+                else
+                {
+                    bytes = encoding.GetBytes(value);
+                    actualLength = bytes.Length;
+                }
+
+                var lengthPlusOneBytes = BitConverter.GetBytes(actualLength + 1);
+
+                _buffer.SetBytes(_position, lengthPlusOneBytes, 0, 4);
+                _buffer.SetBytes(_position + 4, bytes, 0, actualLength);
+                _buffer.SetByte(_position + 4 + actualLength, 0);
+            }
+
+            SetPositionAfterWrite(_position + actualLength + 5);
+        }
+    }
+}

+ 12 - 0
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/ByteBufferStream.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: d2425732aba32f141b369fcc224c41cd
+timeCreated: 1503738735
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 76 - 0
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/CStringUtf8Encoding.cs

@@ -0,0 +1,76 @@
+/* Copyright 2016 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.IO;
+using System.Text;
+
+namespace MongoDB.Bson.IO
+{
+    internal static class CStringUtf8Encoding
+    {
+        public static int GetBytes(string value, byte[] bytes, int byteIndex, UTF8Encoding fallbackEncoding)
+        {
+            var charLength = value.Length;
+            var initialByteIndex = byteIndex;
+
+            for (var charIndex = 0; charIndex < charLength; charIndex++)
+            {
+                var c = (int)value[charIndex];
+                if (c == 0)
+                {
+                    throw new ArgumentException("A CString cannot contain null bytes.", "value");
+                }
+                else if (c <= 0x7f)
+                {
+                    bytes[byteIndex++] = (byte)c;
+                }
+                else if (c <= 0x7ff)
+                {
+                    var byte1 = 0xc0 | (c >> 6);
+                    var byte2 = 0x80 | (c & 0x3f);
+                    bytes[byteIndex++] = (byte)byte1;
+                    bytes[byteIndex++] = (byte)byte2;
+                }
+                else if (c <= 0xd7ff || c >= 0xe000)
+                {
+                    var byte1 = 0xe0 | (c >> 12);
+                    var byte2 = 0x80 | ((c >> 6) & 0x3f);
+                    var byte3 = 0x80 | (c & 0x3f);
+                    bytes[byteIndex++] = (byte)byte1;
+                    bytes[byteIndex++] = (byte)byte2;
+                    bytes[byteIndex++] = (byte)byte3;
+                }
+                else
+                {
+                    // let fallback encoding handle surrogate pairs
+                    var bytesWritten = fallbackEncoding.GetBytes(value, 0, value.Length, bytes, byteIndex);
+                    if (Array.IndexOf<byte>(bytes, 0, initialByteIndex, bytesWritten) != -1)
+                    {
+                        throw new ArgumentException("A CString cannot contain null bytes.", "value");
+                    }
+                    return bytesWritten;
+                }
+            }
+
+            return byteIndex - initialByteIndex;
+        }
+
+        public static int GetMaxByteCount(int charCount)
+        {
+            return charCount * 3;
+        }
+    }
+}

+ 12 - 0
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/CStringUtf8Encoding.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 1e7fafe72c161c54181aa369643439fc
+timeCreated: 1503738732
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/ContextType.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: 9c0cce13501704c4cad24f554835b647
+guid: b85045f8f2e8ffd46ad769aaba89c721
+timeCreated: 1503738735
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 16 - 10
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/Serialization/Conventions/Obsolete/ExtraElementsMemberConventions.cs → Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IBsonChunk.cs

@@ -1,4 +1,4 @@
-/* Copyright 2010-2014 MongoDB Inc.
+/* Copyright 2010-2015 MongoDB Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -15,19 +15,25 @@
 
 using System;
 
-namespace MongoDB.Bson.Serialization.Conventions
+namespace MongoDB.Bson.IO
 {
     /// <summary>
-    /// Represents an extra elements member convention.
+    /// Represents a chunk of bytes.
     /// </summary>
-    [Obsolete("Use IClassMapConvention instead.")]
-    public interface IExtraElementsMemberConvention
+    public interface IBsonChunk : IDisposable
     {
         /// <summary>
-        /// Finds the extra elements member of a class.
+        /// Gets the bytes.
         /// </summary>
-        /// <param name="type">The class.</param>
-        /// <returns>The extra elements member.</returns>
-        string FindExtraElementsMember(Type type);
+        /// <value>
+        /// The bytes.
+        /// </value>
+        ArraySegment<byte> Bytes { get; }
+
+        /// <summary>
+        /// Returns a new reference to the same chunk that can be independently disposed.
+        /// </summary>
+        /// <returns>A new reference to the same chunk.</returns>
+        IBsonChunk Fork();
     }
-}
+}

+ 12 - 0
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IBsonChunk.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 6a8085d2a662f044680e85b7c3674871
+timeCreated: 1503738734
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 10 - 10
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/Serialization/Conventions/Obsolete/IdMemberConventions.cs → Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IBsonChunkSource.cs

@@ -1,4 +1,4 @@
-/* Copyright 2010-2014 MongoDB Inc.
+/* Copyright 2010-2015 MongoDB Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -15,19 +15,19 @@
 
 using System;
 
-namespace MongoDB.Bson.Serialization.Conventions
+namespace MongoDB.Bson.IO
 {
     /// <summary>
-    /// Represents an Id member convention.
+    /// Represents a source of chunks.
     /// </summary>
-    [Obsolete("Use IClassMapConvention instead.")]
-    public interface IIdMemberConvention
+    public interface IBsonChunkSource : IDisposable
     {
         /// <summary>
-        /// Finds the Id member of a class.
+        /// Gets the chunk.
         /// </summary>
-        /// <param name="type">The class.</param>
-        /// <returns>The name of the Id member.</returns>
-        string FindIdMember(Type type);
+        /// <remarks>The chunk source is free to return a larger or smaller chunk than requested.</remarks>
+        /// <param name="requestedSize">Size of the requested.</param>
+        /// <returns>A chunk.</returns>
+        IBsonChunk GetChunk(int requestedSize);
     }
-}
+}

+ 12 - 0
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IBsonChunkSource.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 49b50c4a8f366ea47a4e723e064c71f6
+timeCreated: 1503738733
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 235 - 0
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IBsonReader.cs

@@ -0,0 +1,235 @@
+/* Copyright 2010-2016 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;
+
+namespace MongoDB.Bson.IO
+{
+    /// <summary>
+    /// Represents a BSON reader.
+    /// </summary>
+    public interface IBsonReader : IDisposable
+    {
+        // properties
+        /// <summary>
+        /// Gets the current BsonType.
+        /// </summary>
+        BsonType CurrentBsonType { get; }
+
+        /// <summary>
+        /// Gets the current state of the reader.
+        /// </summary>
+        BsonReaderState State { get; }
+
+        // methods
+        /// <summary>
+        /// Closes the reader.
+        /// </summary>
+        void Close();
+
+        /// <summary>
+        /// Gets a bookmark to the reader's current position and state.
+        /// </summary>
+        /// <returns>A bookmark.</returns>
+        BsonReaderBookmark GetBookmark();
+
+        /// <summary>
+        /// Gets the current BsonType (calls ReadBsonType if necessary).
+        /// </summary>
+        /// <returns>The current BsonType.</returns>
+        BsonType GetCurrentBsonType();
+
+        /// <summary>
+        /// Determines whether this reader is at end of file.
+        /// </summary>
+        /// <returns>
+        /// Whether this reader is at end of file.
+        /// </returns>
+        bool IsAtEndOfFile();
+
+        /// <summary>
+        /// Reads BSON binary data from the reader.
+        /// </summary>
+        /// <returns>A BsonBinaryData.</returns>
+        BsonBinaryData ReadBinaryData();
+
+        /// <summary>
+        /// Reads a BSON boolean from the reader.
+        /// </summary>
+        /// <returns>A Boolean.</returns>
+        bool ReadBoolean();
+
+        /// <summary>
+        /// Reads a BsonType from the reader.
+        /// </summary>
+        /// <returns>A BsonType.</returns>
+        BsonType ReadBsonType();
+
+        /// <summary>
+        /// Reads BSON binary data from the reader.
+        /// </summary>
+        /// <returns>A byte array.</returns>
+        byte[] ReadBytes();
+
+        /// <summary>
+        /// Reads a BSON DateTime from the reader.
+        /// </summary>
+        /// <returns>The number of milliseconds since the Unix epoch.</returns>
+        long ReadDateTime();
+
+        /// <summary>
+        /// Reads a BSON Decimal128 from the reader.
+        /// </summary>
+        /// <returns>A <see cref="Decimal128" />.</returns>
+        Decimal128 ReadDecimal128();
+
+        /// <summary>
+        /// Reads a BSON Double from the reader.
+        /// </summary>
+        /// <returns>A Double.</returns>
+        double ReadDouble();
+
+        /// <summary>
+        /// Reads the end of a BSON array from the reader.
+        /// </summary>
+        void ReadEndArray();
+
+        /// <summary>
+        /// Reads the end of a BSON document from the reader.
+        /// </summary>
+        void ReadEndDocument();
+
+        /// <summary>
+        /// Reads a BSON Int32 from the reader.
+        /// </summary>
+        /// <returns>An Int32.</returns>
+        int ReadInt32();
+
+        /// <summary>
+        /// Reads a BSON Int64 from the reader.
+        /// </summary>
+        /// <returns>An Int64.</returns>
+        long ReadInt64();
+
+        /// <summary>
+        /// Reads a BSON JavaScript from the reader.
+        /// </summary>
+        /// <returns>A string.</returns>
+        string ReadJavaScript();
+
+        /// <summary>
+        /// Reads a BSON JavaScript with scope from the reader (call ReadStartDocument next to read the scope).
+        /// </summary>
+        /// <returns>A string.</returns>
+        string ReadJavaScriptWithScope();
+
+        /// <summary>
+        /// Reads a BSON MaxKey from the reader.
+        /// </summary>
+        void ReadMaxKey();
+
+        /// <summary>
+        /// Reads a BSON MinKey from the reader.
+        /// </summary>
+        void ReadMinKey();
+
+        /// <summary>
+        /// Reads the name of an element from the reader (using the provided name decoder).
+        /// </summary>
+        /// <param name="nameDecoder">The name decoder.</param>
+        /// <returns>
+        /// The name of the element.
+        /// </returns>
+        string ReadName(INameDecoder nameDecoder);
+
+        /// <summary>
+        /// Reads a BSON null from the reader.
+        /// </summary>
+        void ReadNull();
+
+        /// <summary>
+        /// Reads a BSON ObjectId from the reader.
+        /// </summary>
+        /// <returns>An ObjectId.</returns>
+        ObjectId ReadObjectId();
+
+        /// <summary>
+        /// Reads a raw BSON array.
+        /// </summary>
+        /// <returns>The raw BSON array.</returns>
+        IByteBuffer ReadRawBsonArray();
+
+        /// <summary>
+        /// Reads a raw BSON document.
+        /// </summary>
+        /// <returns>The raw BSON document.</returns>
+        IByteBuffer ReadRawBsonDocument();
+
+        /// <summary>
+        /// Reads a BSON regular expression from the reader.
+        /// </summary>
+        /// <returns>A BsonRegularExpression.</returns>
+        BsonRegularExpression ReadRegularExpression();
+
+        /// <summary>
+        /// Reads the start of a BSON array.
+        /// </summary>
+        void ReadStartArray();
+
+        /// <summary>
+        /// Reads the start of a BSON document.
+        /// </summary>
+        void ReadStartDocument();
+
+        /// <summary>
+        /// Reads a BSON string from the reader.
+        /// </summary>
+        /// <returns>A String.</returns>
+        string ReadString();
+
+        /// <summary>
+        /// Reads a BSON symbol from the reader.
+        /// </summary>
+        /// <returns>A string.</returns>
+        string ReadSymbol();
+
+        /// <summary>
+        /// Reads a BSON timestamp from the reader.
+        /// </summary>
+        /// <returns>The combined timestamp/increment.</returns>
+        long ReadTimestamp();
+
+        /// <summary>
+        /// Reads a BSON undefined from the reader.
+        /// </summary>
+        void ReadUndefined();
+
+        /// <summary>
+        /// Returns the reader to previously bookmarked position and state.
+        /// </summary>
+        /// <param name="bookmark">The bookmark.</param>
+        void ReturnToBookmark(BsonReaderBookmark bookmark);
+
+        /// <summary>
+        /// Skips the name (reader must be positioned on a name).
+        /// </summary>
+        void SkipName();
+
+        /// <summary>
+        /// Skips the value (reader must be positioned on a value).
+        /// </summary>
+        void SkipValue();
+    }
+}

+ 12 - 0
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IBsonReader.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 8e5e5f65af1b50a4b9392d8231a658dd
+timeCreated: 1503738734
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 361 - 0
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IBsonReaderExtensions.cs

@@ -0,0 +1,361 @@
+/* Copyright 2010-2016 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;
+
+namespace MongoDB.Bson.IO
+{
+    /// <summary>
+    /// Contains extensions methods for IBsonReader.
+    /// </summary>
+    public static class IBsonReaderExtensions
+    {
+        /// <summary>
+        /// Positions the reader to an element by name.
+        /// </summary>
+        /// <param name="reader">The reader.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <returns>True if the element was found.</returns>
+        public static bool FindElement(this IBsonReader reader, string name)
+        {
+            while (reader.ReadBsonType() != BsonType.EndOfDocument)
+            {
+                var elementName = reader.ReadName();
+                if (elementName == name)
+                {
+                    return true;
+                }
+                reader.SkipValue();
+            }
+
+            return false;
+        }
+
+        /// <summary>
+        /// Positions the reader to a string element by name.
+        /// </summary>
+        /// <param name="reader">The reader.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <returns>True if the element was found.</returns>
+        public static string FindStringElement(this IBsonReader reader, string name)
+        {
+            BsonType bsonType;
+            while ((bsonType = reader.ReadBsonType()) != BsonType.EndOfDocument)
+            {
+                if (bsonType == BsonType.String)
+                {
+                    var elementName = reader.ReadName();
+                    if (elementName == name)
+                    {
+                        return reader.ReadString();
+                    }
+                    else
+                    {
+                        reader.SkipValue();
+                    }
+                }
+                else
+                {
+                    reader.SkipName();
+                    reader.SkipValue();
+                }
+            }
+
+            return null;
+        }
+
+        /// <summary>
+        /// Reads a BSON binary data element from the reader.
+        /// </summary>
+        /// <param name="reader">The reader.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <returns>A BsonBinaryData.</returns>
+        public static BsonBinaryData ReadBinaryData(this IBsonReader reader, string name)
+        {
+            VerifyName(reader, name);
+            return reader.ReadBinaryData();
+        }
+
+        /// <summary>
+        /// Reads a BSON boolean element from the reader.
+        /// </summary>
+        /// <param name="reader">The reader.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <returns>A Boolean.</returns>
+        public static bool ReadBoolean(this IBsonReader reader, string name)
+        {
+            VerifyName(reader, name);
+            return reader.ReadBoolean();
+        }
+
+        /// <summary>
+        /// Reads a BSON binary data element from the reader.
+        /// </summary>
+        /// <param name="reader">The reader.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <returns>A byte array.</returns>
+        public static byte[] ReadBytes(this IBsonReader reader, string name)
+        {
+            VerifyName(reader, name);
+            return reader.ReadBytes();
+        }
+
+        /// <summary>
+        /// Reads a BSON DateTime element from the reader.
+        /// </summary>
+        /// <param name="reader">The reader.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <returns>The number of milliseconds since the Unix epoch.</returns>
+        public static long ReadDateTime(this IBsonReader reader, string name)
+        {
+            VerifyName(reader, name);
+            return reader.ReadDateTime();
+        }
+
+        /// <summary>
+        /// Reads a BSON Decimal128 element from the reader.
+        /// </summary>
+        /// <param name="reader">The reader.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <returns>A <see cref="Decimal128"/>.</returns>
+        public static Decimal128 ReadDecimal128(this IBsonReader reader, string name)
+        {
+            VerifyName(reader, name);
+            return reader.ReadDecimal128();
+        }
+
+        /// <summary>
+        /// Reads a BSON Double element from the reader.
+        /// </summary>
+        /// <param name="reader">The reader.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <returns>A Double.</returns>
+        public static double ReadDouble(this IBsonReader reader, string name)
+        {
+            VerifyName(reader, name);
+            return reader.ReadDouble();
+        }
+
+        /// <summary>
+        /// Reads a BSON Int32 element from the reader.
+        /// </summary>
+        /// <param name="reader">The reader.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <returns>An Int32.</returns>
+        public static int ReadInt32(this IBsonReader reader, string name)
+        {
+            VerifyName(reader, name);
+            return reader.ReadInt32();
+        }
+
+        /// <summary>
+        /// Reads a BSON Int64 element from the reader.
+        /// </summary>
+        /// <param name="reader">The reader.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <returns>An Int64.</returns>
+        public static long ReadInt64(this IBsonReader reader, string name)
+        {
+            VerifyName(reader, name);
+            return reader.ReadInt64();
+        }
+
+        /// <summary>
+        /// Reads a BSON JavaScript element from the reader.
+        /// </summary>
+        /// <param name="reader">The reader.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <returns>A string.</returns>
+        public static string ReadJavaScript(this IBsonReader reader, string name)
+        {
+            VerifyName(reader, name);
+            return reader.ReadJavaScript();
+        }
+
+        /// <summary>
+        /// Reads a BSON JavaScript with scope element from the reader (call ReadStartDocument next to read the scope).
+        /// </summary>
+        /// <param name="reader">The reader.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <returns>A string.</returns>
+        public static string ReadJavaScriptWithScope(this IBsonReader reader, string name)
+        {
+            VerifyName(reader, name);
+            return reader.ReadJavaScriptWithScope();
+        }
+
+        /// <summary>
+        /// Reads a BSON MaxKey element from the reader.
+        /// </summary>
+        /// <param name="reader">The reader.</param>
+        /// <param name="name">The name of the element.</param>
+        public static void ReadMaxKey(this IBsonReader reader, string name)
+        {
+            VerifyName(reader, name);
+            reader.ReadMaxKey();
+        }
+
+        /// <summary>
+        /// Reads a BSON MinKey element from the reader.
+        /// </summary>
+        /// <param name="reader">The reader.</param>
+        /// <param name="name">The name of the element.</param>
+        public static void ReadMinKey(this IBsonReader reader, string name)
+        {
+            VerifyName(reader, name);
+            reader.ReadMinKey();
+        }
+
+        /// <summary>
+        /// Reads the name of an element from the reader.
+        /// </summary>
+        /// <param name="reader">The reader.</param>
+        /// <returns>The name of the element.</returns>
+        public static string ReadName(this IBsonReader reader)
+        {
+            return reader.ReadName(Utf8NameDecoder.Instance);
+        }
+
+        /// <summary>
+        /// Reads the name of an element from the reader.
+        /// </summary>
+        /// <param name="reader">The reader.</param>
+        /// <param name="name">The name of the element.</param>
+        public static void ReadName(this IBsonReader reader, string name)
+        {
+            VerifyName(reader, name);
+        }
+
+        /// <summary>
+        /// Reads a BSON null element from the reader.
+        /// </summary>
+        /// <param name="reader">The reader.</param>
+        /// <param name="name">The name of the element.</param>
+        public static void ReadNull(this IBsonReader reader, string name)
+        {
+            VerifyName(reader, name);
+            reader.ReadNull();
+        }
+
+        /// <summary>
+        /// Reads a BSON ObjectId element from the reader.
+        /// </summary>
+        /// <param name="reader">The reader.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <returns>An ObjectId.</returns>
+        public static ObjectId ReadObjectId(this IBsonReader reader, string name)
+        {
+            VerifyName(reader, name);
+            return reader.ReadObjectId();
+        }
+
+        /// <summary>
+        /// Reads a raw BSON array.
+        /// </summary>
+        /// <param name="reader">The reader.</param>
+        /// <param name="name">The name.</param>
+        /// <returns>
+        /// The raw BSON array.
+        /// </returns>
+        public static IByteBuffer ReadRawBsonArray(this IBsonReader reader, string name)
+        {
+            VerifyName(reader, name);
+            return reader.ReadRawBsonArray();
+        }
+
+        /// <summary>
+        /// Reads a raw BSON document.
+        /// </summary>
+        /// <param name="reader">The reader.</param>
+        /// <param name="name">The name.</param>
+        /// <returns>The raw BSON document.</returns>
+        public static IByteBuffer ReadRawBsonDocument(this IBsonReader reader, string name)
+        {
+            VerifyName(reader, name);
+            return reader.ReadRawBsonDocument();
+        }
+
+        /// <summary>
+        /// Reads a BSON regular expression element from the reader.
+        /// </summary>
+        /// <param name="reader">The reader.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <returns>A BsonRegularExpression.</returns>
+        public static BsonRegularExpression ReadRegularExpression(this IBsonReader reader, string name)
+        {
+            VerifyName(reader, name);
+            return reader.ReadRegularExpression();
+        }
+
+        /// <summary>
+        /// Reads a BSON string element from the reader.
+        /// </summary>
+        /// <param name="reader">The reader.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <returns>A String.</returns>
+        public static string ReadString(this IBsonReader reader, string name)
+        {
+            VerifyName(reader, name);
+            return reader.ReadString();
+        }
+
+        /// <summary>
+        /// Reads a BSON symbol element from the reader.
+        /// </summary>
+        /// <param name="reader">The reader.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <returns>A string.</returns>
+        public static string ReadSymbol(this IBsonReader reader, string name)
+        {
+            VerifyName(reader, name);
+            return reader.ReadSymbol();
+        }
+
+        /// <summary>
+        /// Reads a BSON timestamp element from the reader.
+        /// </summary>
+        /// <returns>The combined timestamp/increment.</returns>
+        /// <param name="reader">The reader.</param>
+        /// <param name="name">The name of the element.</param>
+        public static long ReadTimestamp(this IBsonReader reader, string name)
+        {
+            VerifyName(reader, name);
+            return reader.ReadTimestamp();
+        }
+
+        /// <summary>
+        /// Reads a BSON undefined element from the reader.
+        /// </summary>
+        /// <param name="reader">The reader.</param>
+        /// <param name="name">The name of the element.</param>
+        public static void ReadUndefined(this IBsonReader reader, string name)
+        {
+            VerifyName(reader, name);
+            reader.ReadUndefined();
+        }
+
+        private static void VerifyName(IBsonReader reader, string expectedName)
+        {
+            var actualName = reader.ReadName();
+            if (actualName != expectedName)
+            {
+                var message = string.Format(
+                    "Expected element name to be '{0}', not '{1}'.",
+                    expectedName, actualName);
+                throw new FormatException(message);
+            }
+        }
+    }
+}

+ 12 - 0
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IBsonReaderExtensions.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 0f1b743dbf2a563478e4e64b95e008e0
+timeCreated: 1503738732
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 213 - 0
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IBsonWriter.cs

@@ -0,0 +1,213 @@
+/* Copyright 2010-2016 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;
+
+namespace MongoDB.Bson.IO
+{
+    /// <summary>
+    /// Represents a BSON writer.
+    /// </summary>
+    public interface IBsonWriter : IDisposable
+    {
+        // properties
+        /// <summary>
+        /// Gets the current serialization depth.
+        /// </summary>
+        int SerializationDepth { get; }
+
+        /// <summary>
+        /// Gets the settings of the writer.
+        /// </summary>
+        BsonWriterSettings Settings { get; }
+
+        // methods
+        /// <summary>
+        /// Gets the current state of the writer.
+        /// </summary>
+        BsonWriterState State { get; }
+
+        // methods
+        /// <summary>
+        /// Closes the writer.
+        /// </summary>
+        void Close();
+
+        /// <summary>
+        /// Flushes any pending data to the output destination.
+        /// </summary>
+        void Flush();
+
+        /// <summary>
+        /// Pops the element name validator.
+        /// </summary>
+        /// <returns>The popped element validator.</returns>
+        void PopElementNameValidator();
+
+        /// <summary>
+        /// Pushes the element name validator.
+        /// </summary>
+        /// <param name="validator">The validator.</param>
+        void PushElementNameValidator(IElementNameValidator validator);
+
+        /// <summary>
+        /// Writes BSON binary data to the writer.
+        /// </summary>
+        /// <param name="binaryData">The binary data.</param>
+        void WriteBinaryData(BsonBinaryData binaryData);
+
+        /// <summary>
+        /// Writes a BSON Boolean to the writer.
+        /// </summary>
+        /// <param name="value">The Boolean value.</param>
+        void WriteBoolean(bool value);
+
+        /// <summary>
+        /// Writes BSON binary data to the writer.
+        /// </summary>
+        /// <param name="bytes">The bytes.</param>
+        void WriteBytes(byte[] bytes);
+
+        /// <summary>
+        /// Writes a BSON DateTime to the writer.
+        /// </summary>
+        /// <param name="value">The number of milliseconds since the Unix epoch.</param>
+        void WriteDateTime(long value);
+
+        /// <summary>
+        /// Writes a BSON Decimal128 to the writer.
+        /// </summary>
+        /// <param name="value">The <see cref="Decimal128"/> value.</param>
+        void WriteDecimal128(Decimal128 value);
+
+        /// <summary>
+        /// Writes a BSON Double to the writer.
+        /// </summary>
+        /// <param name="value">The Double value.</param>
+        void WriteDouble(double value);
+
+        /// <summary>
+        /// Writes the end of a BSON array to the writer.
+        /// </summary>
+        void WriteEndArray();
+
+        /// <summary>
+        /// Writes the end of a BSON document to the writer.
+        /// </summary>
+        void WriteEndDocument();
+
+        /// <summary>
+        /// Writes a BSON Int32 to the writer.
+        /// </summary>
+        /// <param name="value">The Int32 value.</param>
+        void WriteInt32(int value);
+
+        /// <summary>
+        /// Writes a BSON Int64 to the writer.
+        /// </summary>
+        /// <param name="value">The Int64 value.</param>
+        void WriteInt64(long value);
+
+        /// <summary>
+        /// Writes a BSON JavaScript to the writer.
+        /// </summary>
+        /// <param name="code">The JavaScript code.</param>
+        void WriteJavaScript(string code);
+
+        /// <summary>
+        /// Writes a BSON JavaScript to the writer (call WriteStartDocument to start writing the scope).
+        /// </summary>
+        /// <param name="code">The JavaScript code.</param>
+        void WriteJavaScriptWithScope(string code);
+
+        /// <summary>
+        /// Writes a BSON MaxKey to the writer.
+        /// </summary>
+        void WriteMaxKey();
+
+        /// <summary>
+        /// Writes a BSON MinKey to the writer.
+        /// </summary>
+        void WriteMinKey();
+
+        /// <summary>
+        /// Writes the name of an element to the writer.
+        /// </summary>
+        /// <param name="name">The name of the element.</param>
+        void WriteName(string name);
+
+        /// <summary>
+        /// Writes a BSON null to the writer.
+        /// </summary>
+        void WriteNull();
+
+        /// <summary>
+        /// Writes a BSON ObjectId to the writer.
+        /// </summary>
+        /// <param name="objectId">The ObjectId.</param>
+        void WriteObjectId(ObjectId objectId);
+
+        /// <summary>
+        /// Writes a raw BSON array.
+        /// </summary>
+        /// <param name="slice">The byte buffer containing the raw BSON array.</param>
+        void WriteRawBsonArray(IByteBuffer slice);
+
+        /// <summary>
+        /// Writes a raw BSON document.
+        /// </summary>
+        /// <param name="slice">The byte buffer containing the raw BSON document.</param>
+        void WriteRawBsonDocument(IByteBuffer slice);
+
+        /// <summary>
+        /// Writes a BSON regular expression to the writer.
+        /// </summary>
+        /// <param name="regex">A BsonRegularExpression.</param>
+        void WriteRegularExpression(BsonRegularExpression regex);
+
+        /// <summary>
+        /// Writes the start of a BSON array to the writer.
+        /// </summary>
+        void WriteStartArray();
+
+        /// <summary>
+        /// Writes the start of a BSON document to the writer.
+        /// </summary>
+        void WriteStartDocument();
+
+        /// <summary>
+        /// Writes a BSON String to the writer.
+        /// </summary>
+        /// <param name="value">The String value.</param>
+        void WriteString(string value);
+
+        /// <summary>
+        /// Writes a BSON Symbol to the writer.
+        /// </summary>
+        /// <param name="value">The symbol.</param>
+        void WriteSymbol(string value);
+
+        /// <summary>
+        /// Writes a BSON timestamp to the writer.
+        /// </summary>
+        /// <param name="value">The combined timestamp/increment value.</param>
+        void WriteTimestamp(long value);
+
+        /// <summary>
+        /// Writes a BSON undefined to the writer.
+        /// </summary>
+        void WriteUndefined();
+    }
+}

+ 12 - 0
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IBsonWriter.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: a252b38ae2240e943bd65b9f4a9cfc5a
+timeCreated: 1503738735
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 293 - 0
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IBsonWriterExtensions.cs

@@ -0,0 +1,293 @@
+/* Copyright 2010-2016 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.
+*/
+
+namespace MongoDB.Bson.IO
+{
+    /// <summary>
+    /// Contains extension methods for IBsonWriter.
+    /// </summary>
+    public static class IBsonWriterExtensions
+    {
+        /// <summary>
+        /// Writes a BSON binary data element to the writer.
+        /// </summary>
+        /// <param name="writer">The writer.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <param name="binaryData">The binary data.</param>
+        public static void WriteBinaryData(this IBsonWriter writer, string name, BsonBinaryData binaryData)
+        {
+            writer.WriteName(name);
+            writer.WriteBinaryData(binaryData);
+        }
+
+        /// <summary>
+        /// Writes a BSON Boolean element to the writer.
+        /// </summary>
+        /// <param name="writer">The writer.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <param name="value">The Boolean value.</param>
+        public static void WriteBoolean(this IBsonWriter writer, string name, bool value)
+        {
+            writer.WriteName(name);
+            writer.WriteBoolean(value);
+        }
+
+        /// <summary>
+        /// Writes a BSON binary data element to the writer.
+        /// </summary>
+        /// <param name="writer">The writer.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <param name="bytes">The bytes.</param>
+        public static void WriteBytes(this IBsonWriter writer, string name, byte[] bytes)
+        {
+            writer.WriteName(name);
+            writer.WriteBytes(bytes);
+        }
+
+        /// <summary>
+        /// Writes a BSON DateTime element to the writer.
+        /// </summary>
+        /// <param name="writer">The writer.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <param name="value">The number of milliseconds since the Unix epoch.</param>
+        public static void WriteDateTime(this IBsonWriter writer, string name, long value)
+        {
+            writer.WriteName(name);
+            writer.WriteDateTime(value);
+        }
+
+        /// <summary>
+        /// Writes a BSON Decimal128 element to the writer.
+        /// </summary>
+        /// <param name="writer">The writer.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <param name="value">The <see cref="Decimal128"/> value.</param>
+        public static void WriteDecimal128(this IBsonWriter writer, string name, Decimal128 value)
+        {
+            writer.WriteName(name);
+            writer.WriteDecimal128(value);
+        }
+
+        /// <summary>
+        /// Writes a BSON Double element to the writer.
+        /// </summary>
+        /// <param name="writer">The writer.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <param name="value">The Double value.</param>
+        public static void WriteDouble(this IBsonWriter writer, string name, double value)
+        {
+            writer.WriteName(name);
+            writer.WriteDouble(value);
+        }
+
+        /// <summary>
+        /// Writes a BSON Int32 element to the writer.
+        /// </summary>
+        /// <param name="writer">The writer.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <param name="value">The Int32 value.</param>
+        public static void WriteInt32(this IBsonWriter writer, string name, int value)
+        {
+            writer.WriteName(name);
+            writer.WriteInt32(value);
+        }
+
+        /// <summary>
+        /// Writes a BSON Int64 element to the writer.
+        /// </summary>
+        /// <param name="writer">The writer.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <param name="value">The Int64 value.</param>
+        public static void WriteInt64(this IBsonWriter writer, string name, long value)
+        {
+            writer.WriteName(name);
+            writer.WriteInt64(value);
+        }
+
+        /// <summary>
+        /// Writes a BSON JavaScript element to the writer.
+        /// </summary>
+        /// <param name="writer">The writer.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <param name="code">The JavaScript code.</param>
+        public static void WriteJavaScript(this IBsonWriter writer, string name, string code)
+        {
+            writer.WriteName(name);
+            writer.WriteJavaScript(code);
+        }
+
+        /// <summary>
+        /// Writes a BSON JavaScript element to the writer (call WriteStartDocument to start writing the scope).
+        /// </summary>
+        /// <param name="writer">The writer.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <param name="code">The JavaScript code.</param>
+        public static void WriteJavaScriptWithScope(this IBsonWriter writer, string name, string code)
+        {
+            writer.WriteName(name);
+            writer.WriteJavaScriptWithScope(code);
+        }
+
+        /// <summary>
+        /// Writes a BSON MaxKey element to the writer.
+        /// </summary>
+        /// <param name="writer">The writer.</param>
+        /// <param name="name">The name of the element.</param>
+        public static void WriteMaxKey(this IBsonWriter writer, string name)
+        {
+            writer.WriteName(name);
+            writer.WriteMaxKey();
+        }
+
+        /// <summary>
+        /// Writes a BSON MinKey element to the writer.
+        /// </summary>
+        /// <param name="writer">The writer.</param>
+        /// <param name="name">The name of the element.</param>
+        public static void WriteMinKey(this IBsonWriter writer, string name)
+        {
+            writer.WriteName(name);
+            writer.WriteMinKey();
+        }
+
+        /// <summary>
+        /// Writes a BSON null element to the writer.
+        /// </summary>
+        /// <param name="writer">The writer.</param>
+        /// <param name="name">The name of the element.</param>
+        public static void WriteNull(this IBsonWriter writer, string name)
+        {
+            writer.WriteName(name);
+            writer.WriteNull();
+        }
+
+        /// <summary>
+        /// Writes a BSON ObjectId element to the writer.
+        /// </summary>
+        /// <param name="writer">The writer.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <param name="objectId">The ObjectId.</param>
+        public static void WriteObjectId(this IBsonWriter writer, string name, ObjectId objectId)
+        {
+            writer.WriteName(name);
+            writer.WriteObjectId(objectId);
+        }
+
+        /// <summary>
+        /// Writes a raw BSON array.
+        /// </summary>
+        /// <param name="writer">The writer.</param>
+        /// <param name="name">The name.</param>
+        /// <param name="slice">The byte buffer containing the raw BSON array.</param>
+        public static void WriteRawBsonArray(this IBsonWriter writer, string name, IByteBuffer slice)
+        {
+            writer.WriteName(name);
+            writer.WriteRawBsonArray(slice);
+        }
+
+        /// <summary>
+        /// Writes a raw BSON document.
+        /// </summary>
+        /// <param name="writer">The writer.</param>
+        /// <param name="name">The name.</param>
+        /// <param name="slice">The byte buffer containing the raw BSON document.</param>
+        public static void WriteRawBsonDocument(this IBsonWriter writer, string name, IByteBuffer slice)
+        {
+            writer.WriteName(name);
+            writer.WriteRawBsonDocument(slice);
+        }
+
+        /// <summary>
+        /// Writes a BSON regular expression element to the writer.
+        /// </summary>
+        /// <param name="writer">The writer.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <param name="regex">A BsonRegularExpression.</param>
+        public static void WriteRegularExpression(this IBsonWriter writer, string name, BsonRegularExpression regex)
+        {
+            writer.WriteName(name);
+            writer.WriteRegularExpression(regex);
+        }
+
+        /// <summary>
+        /// Writes the start of a BSON array element to the writer.
+        /// </summary>
+        /// <param name="writer">The writer.</param>
+        /// <param name="name">The name of the element.</param>
+        public static void WriteStartArray(this IBsonWriter writer, string name)
+        {
+            writer.WriteName(name);
+            writer.WriteStartArray();
+        }
+
+        /// <summary>
+        /// Writes the start of a BSON document element to the writer.
+        /// </summary>
+        /// <param name="writer">The writer.</param>
+        /// <param name="name">The name of the element.</param>
+        public static void WriteStartDocument(this IBsonWriter writer, string name)
+        {
+            writer.WriteName(name);
+            writer.WriteStartDocument();
+        }
+
+        /// <summary>
+        /// Writes a BSON String element to the writer.
+        /// </summary>
+        /// <param name="writer">The writer.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <param name="value">The String value.</param>
+        public static void WriteString(this IBsonWriter writer, string name, string value)
+        {
+            writer.WriteName(name);
+            writer.WriteString(value);
+        }
+
+        /// <summary>
+        /// Writes a BSON Symbol element to the writer.
+        /// </summary>
+        /// <param name="writer">The writer.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <param name="value">The symbol.</param>
+        public static void WriteSymbol(this IBsonWriter writer, string name, string value)
+        {
+            writer.WriteName(name);
+            writer.WriteSymbol(value);
+        }
+
+        /// <summary>
+        /// Writes a BSON timestamp element to the writer.
+        /// </summary>
+        /// <param name="writer">The writer.</param>
+        /// <param name="name">The name of the element.</param>
+        /// <param name="value">The combined timestamp/increment value.</param>
+        public static void WriteTimestamp(this IBsonWriter writer, string name, long value)
+        {
+            writer.WriteName(name);
+            writer.WriteTimestamp(value);
+        }
+
+        /// <summary>
+        /// Writes a BSON undefined element to the writer.
+        /// </summary>
+        /// <param name="writer">The writer.</param>
+        /// <param name="name">The name of the element.</param>
+        public static void WriteUndefined(this IBsonWriter writer, string name)
+        {
+            writer.WriteName(name);
+            writer.WriteUndefined();
+        }
+    }
+}

+ 12 - 0
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IBsonWriterExtensions.cs.meta

@@ -0,0 +1,12 @@
+fileFormatVersion: 2
+guid: 5b3519bfb7ecf5e49a872683d62d2926
+timeCreated: 1503738734
+licenseType: Free
+MonoImporter:
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 

+ 36 - 76
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IByteBuffer.cs

@@ -1,4 +1,4 @@
-/* Copyright 2010-2014 MongoDB Inc.
+/* Copyright 2010-2015 MongoDB Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
@@ -25,12 +25,12 @@ namespace MongoDB.Bson.IO
     {
         // properties
         /// <summary>
-        /// Gets or sets the capacity.
+        /// Gets the capacity.
         /// </summary>
         /// <value>
         /// The capacity.
         /// </value>
-        int Capacity { get; set; }
+        int Capacity { get; }
 
         /// <summary>
         /// Gets a value indicating whether this instance is read only.
@@ -48,25 +48,31 @@ namespace MongoDB.Bson.IO
         /// </value>
         int Length { get; set; }
 
+        // methods
         /// <summary>
-        /// Gets or sets the position.
+        /// Access the backing bytes directly. The returned ArraySegment will point to the desired position and contain
+        /// as many bytes as possible up to the next chunk boundary (if any). If the returned ArraySegment does not
+        /// contain enough bytes for your needs you will have to call ReadBytes instead.
         /// </summary>
-        /// <value>
-        /// The position.
-        /// </value>
-        int Position { get; set; }
+        /// <param name="position">The position.</param>
+        /// <returns>
+        /// An ArraySegment pointing directly to the backing bytes for the position.
+        /// </returns>
+        ArraySegment<byte> AccessBackingBytes(int position);
 
-        // methods
         /// <summary>
-        /// Clears this instance.
+        /// Clears the specified bytes.
         /// </summary>
-        void Clear();
+        /// <param name="position">The position.</param>
+        /// <param name="count">The count.</param>
+        void Clear(int position, int count);
 
         /// <summary>
-        /// Finds the next null byte.
+        /// Ensure that the buffer has a minimum capacity. Depending on the buffer allocation strategy
+        /// calling this method may result in a higher capacity than the minimum (but never lower).
         /// </summary>
-        /// <returns>The position of the next null byte.</returns>
-        int FindNullByte();
+        /// <param name="minimumCapacity">The minimum capacity.</param>
+        void EnsureCapacity(int minimumCapacity);
 
         /// <summary>
         /// Gets a slice of this buffer.
@@ -76,87 +82,41 @@ namespace MongoDB.Bson.IO
         /// <returns>A slice of this buffer.</returns>
         IByteBuffer GetSlice(int position, int length);
 
-        /// <summary>
-        /// Loads the buffer from a stream.
-        /// </summary>
-        /// <param name="stream">The stream.</param>
-        /// <param name="count">The count.</param>
-        void LoadFrom(Stream stream, int count);
-
         /// <summary>
         /// Makes this buffer read only.
         /// </summary>
         void MakeReadOnly();
 
         /// <summary>
-        /// Read directly from the backing bytes. The returned ArraySegment points directly to the backing bytes for
-        /// the current position and you can read the bytes directly from there. If the backing bytes happen to span
-        /// a chunk boundary shortly after the current position there might not be enough bytes left in the current
-        /// chunk in which case the returned ArraySegment will have a Count of zero and you should call ReadBytes instead.
-        /// 
-        /// When ReadBackingBytes returns the position will have been advanced by count bytes *if and only if* there
-        /// were count bytes left in the current chunk.
-        /// </summary>
-        /// <param name="count">The number of bytes you need to read.</param>
-        /// <returns>An ArraySegment pointing directly to the backing bytes for the current position.</returns>
-        ArraySegment<byte> ReadBackingBytes(int count);
-
-        /// <summary>
-        /// Reads a byte.
+        /// Gets a byte.
         /// </summary>
+        /// <param name="position">The position.</param>
         /// <returns>A byte.</returns>
-        byte ReadByte();
+        byte GetByte(int position);
 
         /// <summary>
-        /// Reads bytes.
+        /// Gets bytes.
         /// </summary>
+        /// <param name="position">The position.</param>
         /// <param name="destination">The destination.</param>
-        /// <param name="destinationOffset">The destination offset.</param>
+        /// <param name="offset">The destination offset.</param>
         /// <param name="count">The count.</param>
-        void ReadBytes(byte[] destination, int destinationOffset, int count);
+        void GetBytes(int position, byte[] destination, int offset, int count);
 
         /// <summary>
-        /// Reads bytes.
+        /// Sets a byte.
         /// </summary>
-        /// <param name="count">The count.</param>
-        /// <returns>The bytes.</returns>
-        byte[] ReadBytes(int count);
+        /// <param name="position">The position.</param>
+        /// <param name="value">The value.</param>
+        void SetByte(int position, byte value);
 
         /// <summary>
-        /// Write directly to the backing bytes. The returned ArraySegment points directly to the backing bytes for
-        /// the current position and you can write the bytes directly to there. If the backing bytes happen to span
-        /// a chunk boundary shortly after the current position there might not be enough bytes left in the current
-        /// chunk in which case the returned ArraySegment will have a Count of zero and you should call WriteBytes instead.
-        /// 
-        /// When WriteBackingBytes returns the position has not been advanced. After you have written up to count
-        /// bytes directly to the backing bytes advance the position by the number of bytes actually written.
+        /// Sets bytes.
         /// </summary>
+        /// <param name="position">The position.</param>
+        /// <param name="source">The bytes.</param>
+        /// <param name="offset">The offset.</param>
         /// <param name="count">The count.</param>
-        /// <returns>An ArraySegment pointing directly to the backing bytes for the current position.</returns>
-        ArraySegment<byte> WriteBackingBytes(int count);
-        
-        /// <summary>
-        /// Writes a byte.
-        /// </summary>
-        /// <param name="source">The byte.</param>
-        void WriteByte(byte source);
-
-        /// <summary>
-        /// Writes bytes.
-        /// </summary>
-        /// <param name="source">The bytes (in the form of a byte array).</param>
-        void WriteBytes(byte[] source);
-
-        /// <summary>
-        /// Writes bytes.
-        /// </summary>
-        /// <param name="source">The bytes (in the form of an IByteBuffer).</param>
-        void WriteBytes(IByteBuffer source);
-
-        /// <summary>
-        /// Writes Length bytes from this buffer starting at Position 0 to a stream.
-        /// </summary>
-        /// <param name="stream">The stream.</param>
-        void WriteTo(Stream stream);
+        void SetBytes(int position, byte[] source, int offset, int count);
     }
 }

+ 5 - 1
Unity/Assets/Plugins/MongoDB/MongoDB.Bson/IO/IByteBuffer.cs.meta

@@ -1,8 +1,12 @@
 fileFormatVersion: 2
-guid: a5126352ea4a3a8419b35ff9fcab6f00
+guid: 6c4a6170e02b34d46b9f741738168eed
+timeCreated: 1503738734
+licenseType: Free
 MonoImporter:
   serializedVersion: 2
   defaultReferences: []
   executionOrder: 0
   icon: {instanceID: 0}
   userData: 
+  assetBundleName: 
+  assetBundleVariant: 

Неке датотеке нису приказане због велике количине промена