public String nextObjectContainingMember()

in server/pxf-json/src/main/java/org/greenplum/pxf/plugins/json/parser/PartitionedJsonParser.java [96:187]


	public String nextObjectContainingMember(String memberName) throws IOException {

		if (endOfStream) {
			return null;
		}

		int i;
		int objectCount = 0;
		StringBuilder currentObject = new StringBuilder();
		StringBuilder currentString = new StringBuilder();
		MemberSearchState memberState = MemberSearchState.SEARCHING;

		List<Integer> objectStack = new ArrayList<Integer>();

		if (!scanToFirstBeginObject()) {
			return null;
		}
		currentObject.append(START_BRACE);
		objectStack.add(0);

		while ((i = readNextChar()) != EOF) {
			char c = (char) i;

			lexer.lex(c);

			currentObject.append(c);

			switch (memberState) {
			case SEARCHING:
				if (lexer.getState() == JsonLexerState.BEGIN_STRING) {
					// we found the start of a string, so reset our string buffer
					currentString.setLength(0);
				} else if (inStringStates.contains(lexer.getState())) {
					// we're still inside a string, so keep appending to our buffer
					currentString.append(c);
				} else if (lexer.getState() == JsonLexerState.END_STRING && memberName.equals(currentString.toString())) {

					if (objectStack.size() > 0) {
						// we hit the end of the string and it matched the member name (yay)
						memberState = MemberSearchState.FOUND_STRING_NAME;
						currentString.setLength(0);
					}
				} else if (lexer.getState() == JsonLexerState.BEGIN_OBJECT) {
					// we are searching and found a '{', so we reset the current object string
					if (objectStack.size() == 0) {
						currentObject.setLength(0);
						currentObject.append(START_BRACE);
					}
					objectStack.add(currentObject.length() - 1);
				} else if (lexer.getState() == JsonLexerState.END_OBJECT) {
					if (objectStack.size() > 0) {
						objectStack.remove(objectStack.size() - 1);
					}
					if (objectStack.size() == 0) {
						currentObject.setLength(0);
					}
				}
				break;
			case FOUND_STRING_NAME:
				// keep popping whitespaces until we hit a different token
				if (lexer.getState() != JsonLexerState.WHITESPACE) {
					if (lexer.getState() == JsonLexerState.NAME_SEPARATOR) {
						// found our member!
						memberState = MemberSearchState.IN_MATCHING_OBJECT;
						objectCount = 0;

						if (objectStack.size() > 1) {
							currentObject.delete(0, objectStack.get(objectStack.size() - 1));
						}
						objectStack.clear();
					} else {
						// we didn't find a value-separator (:), so our string wasn't a member string. keep searching
						memberState = MemberSearchState.SEARCHING;
					}
				}
				break;
			case IN_MATCHING_OBJECT:
				if (lexer.getState() == JsonLexerState.BEGIN_OBJECT) {
					objectCount++;
				} else if (lexer.getState() == JsonLexerState.END_OBJECT) {
					objectCount--;
					if (objectCount < 0) {
						// we're done! we reached an "}" which is at the same level as the member we found
						return currentObject.toString();
					}
				}
				break;
			}
		}
		endOfStream = true;
		return null;
	}