private static void parseNVPairString()

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