in src/main/java/org/apache/sling/engine/impl/parameters/Util.java [232:351]
private static void parseNVPairString(
InputStream data,
String encoding,
ParameterMap map,
char separator,
boolean allowSpaces,
boolean prependNew)
throws UnsupportedEncodingException, IOException {
ByteArrayOutputStream keyBuffer = new ByteArrayOutputStream(256);
ByteArrayOutputStream valueBuffer = new ByteArrayOutputStream(256);
char[] chCode = new char[2];
int state = BEFORE_NAME;
int subState = 0;
for (int in = data.read(); in >= 0; in = data.read()) {
char ch = (char) in;
switch (state) {
case BEFORE_NAME:
if (ch == ' ') {
continue;
} else if (ch == '%') {
state = ESC_NAME;
subState = 0;
} else if (ch == '+' && !allowSpaces) {
keyBuffer.write(' ');
state = INSIDE_NAME;
} else {
keyBuffer.write(ch);
state = INSIDE_NAME;
}
break;
case INSIDE_NAME:
if (ch == '=') {
state = BEFORE_VALUE;
} else if (ch == '+' && !allowSpaces) {
keyBuffer.write(' ');
} else if (ch == '%') {
state = ESC_NAME;
subState = 0;
} else if (ch == '&') {
addNVPair(map, keyBuffer, valueBuffer, encoding, prependNew);
state = BEFORE_NAME;
} else {
keyBuffer.write(ch);
}
break;
case ESC_NAME:
chCode[subState++] = ch;
if (subState == chCode.length) {
String code = new String(chCode);
try {
keyBuffer.write(Integer.parseInt(code, 16));
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Bad escape sequence: %" + code);
}
state = INSIDE_NAME;
}
break;
case BEFORE_EQU:
if (ch == '=') {
state = BEFORE_VALUE;
}
break;
case BEFORE_VALUE:
if (ch == ' ') {
continue;
} else if (ch == '%') {
state = ESC_VALUE;
subState = 0;
} else if (ch == '+' && !allowSpaces) {
valueBuffer.write(' ');
state = INSIDE_VALUE;
} else if (ch == separator) {
addNVPair(map, keyBuffer, valueBuffer, encoding, prependNew);
state = BEFORE_NAME;
} else {
valueBuffer.write(ch);
state = INSIDE_VALUE;
}
break;
case INSIDE_VALUE:
if (ch == separator) {
addNVPair(map, keyBuffer, valueBuffer, encoding, prependNew);
state = BEFORE_NAME;
} else if (ch == '+' && !allowSpaces) {
valueBuffer.write(' ');
} else if (ch == '%') {
state = ESC_VALUE;
subState = 0;
} else {
valueBuffer.write(ch);
}
break;
case ESC_VALUE:
chCode[subState++] = ch;
if (subState == chCode.length) {
String code = new String(chCode);
try {
valueBuffer.write(Integer.parseInt(code, 16));
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Bad escape sequence: %" + code);
}
state = INSIDE_VALUE;
}
break;
case BEFORE_SEP:
if (ch == separator) {
state = BEFORE_NAME;
}
break;
}
}
if (keyBuffer.size() > 0) {
addNVPair(map, keyBuffer, valueBuffer, encoding, prependNew);
}
}