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(); } }
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(); } }
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); } }