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;
}