in juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParserSession.java [455:540]
private <K,V> Map<K,V> parseIntoMap(UonReader r, Map<K,V> m, ClassMeta<K> keyType, ClassMeta<V> valueType,
BeanPropertyMeta pMeta) throws IOException, ParseException, ExecutableException {
if (keyType == null)
keyType = (ClassMeta<K>)string();
int c = r.read();
if (c == -1 || c == AMP)
return null;
if (c == 'n')
return (Map<K,V>)parseNull(r);
if (c != '(')
throw new ParseException(this, "Expected '(' at beginning of object.");
final int S1=1; // Looking for attrName start.
final int S2=2; // Found attrName end, looking for =.
final int S3=3; // Found =, looking for valStart.
final int S4=4; // Looking for , or )
boolean isInEscape = false;
int state = S1;
K currAttr = null;
while (c != -1 && c != AMP) {
c = r.read();
if (! isInEscape) {
if (state == S1) {
if (c == ')')
return m;
if (Character.isWhitespace(c))
skipSpace(r);
else {
r.unread();
Object attr = parseAttr(r, decoding);
currAttr = attr == null ? null : convertAttrToType(m, trim(attr.toString()), keyType);
state = S2;
c = 0; // Avoid isInEscape if c was '\'
}
} else if (state == S2) {
if (c == EQ || c == '=')
state = S3;
else if (c == -1 || c == ',' || c == ')' || c == AMP) {
if (currAttr == null) {
// Value was '%00'
r.unread();
return null;
}
m.put(currAttr, null);
if (c == ')' || c == -1 || c == AMP)
return m;
state = S1;
}
} else if (state == S3) {
if (c == -1 || c == ',' || c == ')' || c == AMP) {
V value = convertAttrToType(m, "", valueType);
m.put(currAttr, value);
if (c == -1 || c == ')' || c == AMP)
return m;
state = S1;
} else {
V value = parseAnything(valueType, r.unread(), m, false, pMeta);
setName(valueType, value, currAttr);
m.put(currAttr, value);
state = S4;
c = 0; // Avoid isInEscape if c was '\'
}
} else if (state == S4) {
if (c == ',')
state = S1;
else if (c == ')' || c == -1 || c == AMP) {
return m;
}
}
}
isInEscape = isInEscape(c, r, isInEscape);
}
if (state == S1)
throw new ParseException(this, "Could not find attribute name on object.");
if (state == S2)
throw new ParseException(this, "Could not find '=' following attribute name on object.");
if (state == S3)
throw new ParseException(this, "Dangling '=' found in object entry");
if (state == S4)
throw new ParseException(this, "Could not find ')' marking end of object.");
return null; // Unreachable.
}