5

Basically, I have a data set where a document can contain an array of variable length. I'm writing a codec, so all I have is BsonReader. The problem is readStartArray() returns void rather than returning, for example, the number of elements. Also, I don't see any methods that allow one to test when the end of the array has been reached (apart from trying readEndArray() and catching the exception).

Any ideas?

1
  • 1
    Hi Hypertable, can you post some code samples for others so they can better assist you? Welcome to Stackoverflow Commented Sep 3, 2018 at 0:48

3 Answers 3

4

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);
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks - I found that unless you explicitly call ReadBsonType() when the state of the reader is context.Reader.State == BsonReaderState.Type, that the CurrentBsonType and State properties of the reader are stale and invalid.
0

If you're using java, then you need to use BsonArrayCodec. Although I think something similar can be found in client libraries for other programming languages ​​too.

For example:

List<String> names = new ArrayList<>();
BsonArray underlyingBsonArray = bsonArrayCodec.decode(reader, context);
for (BsonValue bsonValue : underlyingBsonArray) {
   names.add(bsonValue.asDocument().getString("name").getValue());
}

Comments

-1

Ah, it's done with:

while (reader.readBsonType() == BsonType.DOCUMENT) {
  reader.readStartDocument();
  // ...
  reader.readEndDocument();
}

(it's an array of documents in this case, I'm still new to BSON so I don't know how it would work for an array of values).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.