I found the documentation for custom serialization to be lacking too, but you just need to work with the Reader.State property. Once you've identified the start of the array you need to iterate over each of the elements until state == BsonReaderState.EndOfArray. You need to ensure that you only call ReadBsonType when the state is "type".
The following example deserializes an array of documents:
context.Reader.ReadStartArray();
bool ctn = true;
do
{
//If in "type" state we can call ReadBsonType. The order is important.
if (context.Reader.State == BsonReaderState.Type)
{
context.Reader.ReadBsonType();
}
//Now that we're in a value state we can read the value safely
if (context.Reader.State == BsonReaderState.Value)
{
if (context.Reader.CurrentBsonType == BsonType.Document)
{
//Handle the document here. In this case pass I it to a private method
DeserializeChild(context, args, node);
}
//state will now be "type", so continue do loop and recheck type
continue;
}
if ( BsonReaderState.EndOfArray == BsonReaderState.EndOfArray)
{
context.Reader.ReadEndArray();
ctn = false;
}
} while (ctn);