Ejemplo n.º 1
0
  @Override
  public JsonToken nextToken() throws IOException, JsonParseException {
    Context ctx = _contexts.peek();
    if (_currToken == null && ctx == null) {
      _currToken = handleNewDocument(false);
    } else {
      _tokenPos = _counter.getPosition();
      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);
            _contexts.pop();
          } 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;
      }
    }
    return _currToken;
  }