if (ctx == null) {
if (_currToken == JsonToken.END_OBJECT) {
//end of input
return null;
}
throw new JsonParseException("Found element outside the document",
getTokenLocation());
}
if (ctx.state == State.DONE) {
//next field
ctx.reset();
}
boolean readValue = true;
if (ctx.state == State.FIELDNAME) {
readValue = false;
while (true) {
//read field name or end of document
ctx.type = _in.readByte();
if (ctx.type == BsonConstants.TYPE_END) {
//end of document
_currToken = (ctx.array ? JsonToken.END_ARRAY : JsonToken.END_OBJECT);
_currentContext = _currentContext.parent;
} else if (ctx.type == BsonConstants.TYPE_UNDEFINED) {
//skip field name and then ignore this token
skipCString();
continue;
} else {
ctx.state = State.VALUE;
_currToken = JsonToken.FIELD_NAME;
if (ctx.array) {
//immediately read value of array element (discard field name)
readValue = true;
skipCString();
ctx.fieldName = null;
} else {
//read field name
ctx.fieldName = readCString();
}
}
break;
}
}
if (readValue) {
//parse element's value
switch (ctx.type) {
case BsonConstants.TYPE_DOUBLE:
ctx.value = _in.readDouble();
_currToken = JsonToken.VALUE_NUMBER_FLOAT;
break;
case BsonConstants.TYPE_STRING:
ctx.value = readString();
_currToken = JsonToken.VALUE_STRING;
break;
case BsonConstants.TYPE_DOCUMENT:
_currToken = handleNewDocument(false);
break;
case BsonConstants.TYPE_ARRAY:
_currToken = handleNewDocument(true);
break;
case BsonConstants.TYPE_BINARY:
_currToken = handleBinary();
break;
case BsonConstants.TYPE_OBJECTID:
ctx.value = readObjectId();
_currToken = JsonToken.VALUE_EMBEDDED_OBJECT;
break;
case BsonConstants.TYPE_BOOLEAN:
boolean b = _in.readBoolean();
ctx.value = b;
_currToken = (b ? JsonToken.VALUE_TRUE : JsonToken.VALUE_FALSE);
break;
case BsonConstants.TYPE_DATETIME:
ctx.value = new Date(_in.readLong());
_currToken = JsonToken.VALUE_EMBEDDED_OBJECT;
break;
case BsonConstants.TYPE_NULL:
_currToken = JsonToken.VALUE_NULL;
break;
case BsonConstants.TYPE_REGEX:
_currToken = handleRegEx();
break;
case BsonConstants.TYPE_DBPOINTER:
_currToken = handleDBPointer();
break;
case BsonConstants.TYPE_JAVASCRIPT:
ctx.value = new JavaScript(readString());
_currToken = JsonToken.VALUE_EMBEDDED_OBJECT;
break;
case BsonConstants.TYPE_SYMBOL:
ctx.value = readSymbol();
_currToken = JsonToken.VALUE_EMBEDDED_OBJECT;
break;
case BsonConstants.TYPE_JAVASCRIPT_WITH_SCOPE:
_currToken = handleJavascriptWithScope();
break;
case BsonConstants.TYPE_INT32:
ctx.value = _in.readInt();
_currToken = JsonToken.VALUE_NUMBER_INT;
break;
case BsonConstants.TYPE_TIMESTAMP:
ctx.value = readTimestamp();
_currToken = JsonToken.VALUE_EMBEDDED_OBJECT;
break;
case BsonConstants.TYPE_INT64:
ctx.value = _in.readLong();
_currToken = JsonToken.VALUE_NUMBER_INT;
break;
case BsonConstants.TYPE_MINKEY:
ctx.value = "MinKey";
_currToken = JsonToken.VALUE_STRING;
break;
case BsonConstants.TYPE_MAXKEY:
ctx.value = "MaxKey";
_currToken = JsonToken.VALUE_STRING;
break;
default:
throw new JsonParseException("Unknown element type " + ctx.type,
getTokenLocation());
}
ctx.state = State.DONE;
}
}