Exemple #1
0
        // public methods
        /// <inheritdoc />
        public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, BatchableSource <TItem> value)
        {
            Ensure.IsNotNull(value, nameof(value));

            var writer = context.Writer;

            while (writer is WrappingBsonWriter)
            {
                writer = ((WrappingBsonWriter)writer).Wrapped;
            }

            var binaryWriter  = writer as BsonBinaryWriter;
            var startPosition = binaryWriter?.Position;

            writer.PushSettings(s => { var bs = s as BsonBinaryWriterSettings; if (bs != null)
                                       {
                                           bs.MaxDocumentSize = _maxItemSize;
                                       }
                                });
            writer.PushElementNameValidator(_itemElementNameValidator);
            try
            {
                var batchCount = Math.Min(value.Count, _maxBatchCount);
                if (batchCount != value.Count && !value.CanBeSplit)
                {
                    throw new ArgumentException("Batch is too large.");
                }

                for (var i = 0; i < batchCount; i++)
                {
                    var itemPosition = binaryWriter?.Position;

                    var item = value.Items[value.Offset + i];
                    _itemSerializer.Serialize(context, args, item);

                    var batchSize = binaryWriter?.Position - startPosition;
                    if (batchSize > _maxBatchSize)
                    {
                        if (i > 0 && value.CanBeSplit)
                        {
                            binaryWriter.BaseStream.Position = itemPosition.Value; // remove the last item
                            binaryWriter.BaseStream.SetLength(itemPosition.Value);
                            value.SetProcessedCount(i);
                            return;
                        }
                        else
                        {
                            throw new ArgumentException("Batch is too large.");
                        }
                    }
                }
                value.SetProcessedCount(batchCount);
            }
            finally
            {
                writer.PopElementNameValidator();
                writer.PopSettings();
            }
        }