private void WriteType1Section(BsonBinaryWriter writer, Type1CommandMessageSection section, long messageStartPosition)
        {
            var stream     = writer.BsonStream;
            var serializer = section.DocumentSerializer;
            var context    = BsonSerializationContext.CreateRoot(writer);

            int?maxMessageSize;

            if (IsEncryptionConfigured)
            {
                var maxBatchSize          = 2 * 1024 * 1024; // 2 MiB
                var maxMessageEndPosition = stream.Position + maxBatchSize;
                maxMessageSize = (int)(maxMessageEndPosition - messageStartPosition);
            }
            else
            {
                maxMessageSize = MaxMessageSize;
            }

            var payloadStartPosition = stream.Position;

            stream.WriteInt32(0); // size
            stream.WriteCString(section.Identifier);

            var batch           = section.Documents;
            var maxDocumentSize = section.MaxDocumentSize ?? writer.Settings.MaxDocumentSize;

            writer.PushSettings(s => ((BsonBinaryWriterSettings)s).MaxDocumentSize = maxDocumentSize);
            writer.PushElementNameValidator(section.ElementNameValidator);
            try
            {
                var maxBatchCount  = Math.Min(batch.Count, section.MaxBatchCount ?? int.MaxValue);
                var processedCount = maxBatchCount;
                for (var i = 0; i < maxBatchCount; i++)
                {
                    var documentStartPosition = stream.Position;
                    var document = batch.Items[batch.Offset + i];
                    serializer.Serialize(context, document);

                    var messageSize = stream.Position - messageStartPosition;
                    if (messageSize > maxMessageSize && batch.CanBeSplit && i > 0)
                    {
                        stream.Position = documentStartPosition;
                        stream.SetLength(documentStartPosition);
                        processedCount = i;
                        break;
                    }
                }
                batch.SetProcessedCount(processedCount);
            }
            finally
            {
                writer.PopElementNameValidator();
                writer.PopSettings();
            }
            stream.BackpatchSize(payloadStartPosition);
        }
 private void WriteUpdate(BsonBinaryWriter binaryWriter, BsonDocument update, IElementNameValidator updateValidator)
 {
     binaryWriter.PushElementNameValidator(updateValidator);
     try
     {
         var context = BsonSerializationContext.CreateRoot <BsonDocument>(binaryWriter);
         BsonDocumentSerializer.Instance.Serialize(context, update);
     }
     finally
     {
         binaryWriter.PopElementNameValidator();
     }
 }
Beispiel #3
0
 private void WriteQuery(BsonBinaryWriter binaryWriter, BsonDocument query, IElementNameValidator queryValidator)
 {
     binaryWriter.PushElementNameValidator(queryValidator);
     try
     {
         var context = BsonSerializationContext.CreateRoot(binaryWriter);
         BsonDocumentSerializer.Instance.Serialize(context, query ?? new BsonDocument());
     }
     finally
     {
         binaryWriter.PopElementNameValidator();
     }
 }
 private void SerializeUpdate(BsonBinaryWriter bsonWriter, BsonDocument update, UpdateType updateType)
 {
     bsonWriter.PushElementNameValidator(ElementNameValidatorFactory.ForUpdateType(updateType));
     try
     {
         var context = BsonSerializationContext.CreateRoot(bsonWriter);
         BsonDocumentSerializer.Instance.Serialize(context, update);
     }
     finally
     {
         bsonWriter.PopElementNameValidator();
     }
 }
        private void WriteDocuments(BsonBinaryWriter writer, long messageStartPosition, InsertMessage <TDocument> message)
        {
            var stream  = writer.BsonStream;
            var context = BsonSerializationContext.CreateRoot(writer);

            var collectionNamespace       = message.CollectionNamespace;
            var isSystemIndexesCollection = collectionNamespace.Equals(collectionNamespace.DatabaseNamespace.SystemIndexesCollection);
            var elementNameValidator      = isSystemIndexesCollection ? (IElementNameValidator)NoOpElementNameValidator.Instance : CollectionElementNameValidator.Instance;

            writer.PushElementNameValidator(elementNameValidator);
            try
            {
                var documentSource = message.DocumentSource;
                var batchCount     = Math.Min(documentSource.Count, message.MaxBatchCount);
                if (batchCount < documentSource.Count && !documentSource.CanBeSplit)
                {
                    throw new BsonSerializationException("Batch is too large.");
                }

                for (var i = 0; i < batchCount; i++)
                {
                    var document = documentSource.Items[documentSource.Offset + i];
                    var documentStartPosition = stream.Position;

                    _serializer.Serialize(context, document);

                    var messageSize = stream.Position - messageStartPosition;
                    if (messageSize > message.MaxMessageSize)
                    {
                        if (i > 0 && documentSource.CanBeSplit)
                        {
                            stream.Position = documentStartPosition;
                            stream.SetLength(documentStartPosition);
                            documentSource.SetProcessedCount(i);
                            return;
                        }
                        else
                        {
                            throw new BsonSerializationException("Batch is too large.");
                        }
                    }
                }
                documentSource.SetProcessedCount(batchCount);
            }
            finally
            {
                writer.PopElementNameValidator();
            }
        }
            private void SerializeUpdate(BsonBinaryWriter bsonWriter, BsonDocument update)
            {
                var updateValidator = new UpdateOrReplacementElementNameValidator();

                bsonWriter.PushElementNameValidator(updateValidator);
                try
                {
                    var context = BsonSerializationContext.CreateRoot <BsonDocument>(bsonWriter);
                    BsonDocumentSerializer.Instance.Serialize(context, update);
                }
                finally
                {
                    bsonWriter.PopElementNameValidator();
                }
            }
        private void WriteQuery(BsonBinaryWriter binaryWriter, BsonDocument query, IElementNameValidator queryValidator)
        {
            var maxWireDocumentSize = MaxWireDocumentSize ?? MaxDocumentSize ?? binaryWriter.Settings.MaxDocumentSize;

            binaryWriter.PushSettings(s => ((BsonBinaryWriterSettings)s).MaxDocumentSize = maxWireDocumentSize);
            binaryWriter.PushElementNameValidator(queryValidator);
            try
            {
                var context = BsonSerializationContext.CreateRoot(binaryWriter);
                BsonDocumentSerializer.Instance.Serialize(context, query ?? new BsonDocument());
            }
            finally
            {
                binaryWriter.PopElementNameValidator();
                binaryWriter.PopSettings();
            }
        }
 private void SerializeUpdate(BsonBinaryWriter bsonWriter, BsonDocument update, UpdateType updateType)
 {
     bsonWriter.PushElementNameValidator(ElementNameValidatorFactory.ForUpdateType(updateType));
     try
     {
         var position = bsonWriter.BaseStream.Position;
         var context  = BsonSerializationContext.CreateRoot(bsonWriter);
         BsonDocumentSerializer.Instance.Serialize(context, update);
         if (updateType == UpdateType.Update && bsonWriter.BaseStream.Position == position + 8)
         {
             throw new BsonSerializationException("Update documents cannot be empty.");
         }
     }
     finally
     {
         bsonWriter.PopElementNameValidator();
     }
 }
Beispiel #9
0
 private void WriteUpdate(BsonBinaryWriter binaryWriter, BsonDocument update, IElementNameValidator updateValidator)
 {
     binaryWriter.PushElementNameValidator(updateValidator);
     try
     {
         var position = binaryWriter.BaseStream.Position;
         var context  = BsonSerializationContext.CreateRoot(binaryWriter);
         BsonDocumentSerializer.Instance.Serialize(context, update);
         if (updateValidator is UpdateElementNameValidator && binaryWriter.BaseStream.Position == position + 5)
         {
             throw new BsonSerializationException("Update documents cannot be empty.");
         }
     }
     finally
     {
         binaryWriter.PopElementNameValidator();
     }
 }
        public void BsonWriter_should_validate_child_elements_names(
            [Values(1, 2, 3)]
            int levelsCount,
            [Values(true, false)]
            bool addValidatorOnRoot)
        {
            var levelNames      = Enumerable.Range(0, levelsCount).Select(i => $"level{i}").ToArray();
            var validatorsMocks = CreatePrefixValidatorsNestedMock(levelNames);

            using (var stream = new MemoryStream())
                using (var writer = new BsonBinaryWriter(stream))
                {
                    if (addValidatorOnRoot)
                    {
                        writer.PushElementNameValidator(validatorsMocks[0].Object);
                    }

                    writer.WriteStartDocument();

                    if (!addValidatorOnRoot)
                    {
                        writer.PushElementNameValidator(validatorsMocks[0].Object);
                    }

                    foreach (var levelName in levelNames)
                    {
                        writer.WriteInt32($"{levelName}_int", 1);

                        writer.WriteStartDocument($"{levelName}_nested_empty");
                        writer.WriteEndDocument();

                        writer.WriteStartDocument($"{levelName}_nested");
                    }

                    // Add additional level
                    writer.WriteStartDocument($"{levelsCount}_nested");
                    writer.WriteEndDocument(); // $"{levelsCount}_nested"

                    for (int i = 0; i < levelsCount; i++)
                    {
                        writer.WriteEndDocument(); // $"{levelName}_nested"
                    }

                    // Pop validator
                    if (!addValidatorOnRoot)
                    {
                        writer.PopElementNameValidator();
                        writer.WriteInt32("nonvalidatedname", 1);
                    }
                    writer.WriteEndDocument();
                }

            for (int i = 0; i < levelsCount; i++)
            {
                var levelName     = levelNames[i];
                var validatorMock = validatorsMocks[i];

                var children  = new[] { $"{levelName}_nested_empty", $"{levelName}_nested" };
                var fieldsAll = children.Concat(new[] { $"{levelName}_int" }).ToArray();

                foreach (var field in fieldsAll)
                {
                    validatorMock.Verify(v => v.IsValidElementName(field), Times.Once);
                }

                foreach (var child in children)
                {
                    validatorMock.Verify(v => v.GetValidatorForChildContent(child), Times.Once);
                }

                validatorMock.Verify(v => v.IsValidElementName(It.IsNotIn(fieldsAll)), Times.Never);
                validatorMock.Verify(v => v.GetValidatorForChildContent(It.IsNotIn(children)), Times.Never);
            }
        }