revapi/src/main/java/org/revapi/configuration/JSONUtil.java
/**
     * @param json the JSON-encoded data
     * @return a reader that strips comments from json data provided as a reader.
     */
@param json the JSON-encoded data
@return a reader that strips comments from json data provided as a reader.
@param json the JSON - encoded data @return a reader that strips comments from json data provided as a reader .
public static Reader stripComments(final Reader json) {
        return new Reader() {
            State state = State.NORMAL;
            int lastChar = -1;
            @Override
            public int read() throws IOException {
                while (true) {
                    boolean cont = true;
                    int emit = lastChar;
                    switch (state) {
                    case NORMAL:
                        switch (lastChar) {
                        case '/':
                            state = State.FIRST_SLASH;
                            break;
                        case '"':
                            state = State.IN_STRING;
                        default:
                            if (lastChar != -1) {
                                lastChar = -1;
                                cont = false;
                            }
                        }
                        break;
                    case FIRST_SLASH:
                        switch (lastChar) {
                        case '/':
                            state = State.SINGLE_LINE;
                            break;
                        case '*':
                            state = State.MULTI_LINE;
                            break;
                        case '"':
                            emit = '/';
                            state = State.IN_STRING;
                            break;
                        default:
                            emit = '/';
                            state = State.NORMAL;
                            cont = false;
                        }
                        break;
                    case SINGLE_LINE:
                        switch (lastChar) {
                        case '\n':
                            state = State.NORMAL;
                            lastChar = -1;
                            cont = false;
                            break;
                        default: break;
                        }
                        break;
                    case MULTI_LINE:
                        switch (lastChar) {
                        case '*':
                            state = State.STAR_IN_MULTI_LINE;
                            break;
                        }
                        break;
                    case STAR_IN_MULTI_LINE:
                        switch (lastChar) {
                        case '/':
                            state = State.NORMAL;
                            break;
                        }
                        break;
                    case IN_STRING:
                        switch (lastChar) {
                        case '\\':
                            state = State.ESCAPE_IN_STRING;
                            break;
                        case '"':
                            state = State.NORMAL;
                            break;
                        }
                        if (lastChar != -1) {
                            cont = false;
                            lastChar = -1;
                        }
                        break;
                    case ESCAPE_IN_STRING:
                        if (lastChar != -1) {
                            cont = false;
                            lastChar = -1;
                            state = State.IN_STRING;
                        }
                        break;
                    }
                    if (cont) {
                        int ci = json.read();
                        if (ci == -1) {
                            lastChar = -1;
                            switch (state) {
                                case SINGLE_LINE: case MULTI_LINE: case STAR_IN_MULTI_LINE:
                                    return -1;
                                default:
                                    return emit;
                            }
                        }
                        lastChar = ci;
                    } else {
                        return emit;
                    }
                }
            }
            @Override
            public int read(@Nonnull char[] cbuf, int off, int len) throws IOException {
                for (int i = 0; i < len; ++i) {
                    int c = read();
                    if (c == -1) {
                        return i == 0 ? -1 : i;
                    }
                    cbuf[off + i] = (char) c;
                }
                return len;
            }
            @Override
            public void close() throws IOException {
                json.close();
            }
        };
    }
public static Reader stripComments ( final Reader json ) { return new Reader ( ) { State state = State . NORMAL ; int lastChar = - 1 ; @ Override public int read ( ) throws IOException { while ( true ) { boolean cont = true ; int emit = lastChar ; switch ( state ) { case NORMAL : switch ( lastChar ) { case '/' : state = State . FIRST_SLASH ; break ; case '"' : state = State . IN_STRING ; default : if ( lastChar != - 1 ) { lastChar = - 1 ; cont = false ; } } break ; case FIRST_SLASH : switch ( lastChar ) { case '/' : state = State . SINGLE_LINE ; break ; case '*' : state = State . MULTI_LINE ; break ; case '"' : emit = '/' ; state = State . IN_STRING ; break ; default : emit = '/' ; state = State . NORMAL ; cont = false ; } break ; case SINGLE_LINE : switch ( lastChar ) { case '\n' : state = State . NORMAL ; lastChar = - 1 ; cont = false ; break ; default : break ; } break ; case MULTI_LINE : switch ( lastChar ) { case '*' : state = State . STAR_IN_MULTI_LINE ; break ; } break ; case STAR_IN_MULTI_LINE : switch ( lastChar ) { case '/' : state = State . NORMAL ; break ; } break ; case IN_STRING : switch ( lastChar ) { case '\\' : state = State . ESCAPE_IN_STRING ; break ; case '"' : state = State . NORMAL ; break ; } if ( lastChar != - 1 ) { cont = false ; lastChar = - 1 ; } break ; case ESCAPE_IN_STRING : if ( lastChar != - 1 ) { cont = false ; lastChar = - 1 ; state = State . IN_STRING ; } break ; } if ( cont ) { int ci = json . read ( ) ; if ( ci == - 1 ) { lastChar = - 1 ; switch ( state ) { case SINGLE_LINE : case MULTI_LINE : case STAR_IN_MULTI_LINE : return - 1 ; default : return emit ; } } lastChar = ci ; } else { return emit ; } } } @ Override public int read ( @ Nonnull char [ ] cbuf , int off , int len ) throws IOException { for ( int i = 0 ; i < len ; ++ i ) { int c = read ( ) ; if ( c == - 1 ) { return i == 0 ? - 1 : i ; } cbuf [ off + i ] = ( char ) c ; } return len ; } @ Override public void close ( ) throws IOException { json . close ( ) ; } } ; }
@param json the JSON-encoded data
 @return a reader that strips comments from json data provided as a reader.
@param json the JSON - encoded data @return a reader that strips comments from json data provided as a reader .
//intentional fallthrough //the end of input.. emit something if we're in an emittable state..