src/main/java/com/cedarsoftware/util/io/JsonParser.java
private String readString() throws IOException
    {
        final StringBuilder str = strBuf;
        final StringBuilder hex = hexBuf;
        str.setLength(0);
        int state = STRING_START;
        final FastPushbackReader in = input;

        while (true)
        {
            final int c = in.read();
            if (c == -1)
            {
                error("EOF reached while reading JSON string");
            }

            if (state == STRING_START)
            {
                if (c == '"')
                {
                    break;
                }
                else if (c == '\\')
                {
                    state = STRING_SLASH;
                }
                else
                {
                    str.appendCodePoint(c);
                }
            }
            else if (state == STRING_SLASH)
            {
                switch(c)
                {
                    case '\\':
                        str.appendCodePoint('\\');
                        break;
                    case '/':
                        str.appendCodePoint('/');
                        break;
                    case '"':
                        str.appendCodePoint('"');
                        break;
                    case '\'':
                        str.appendCodePoint('\'');
                        break;
                    case 'b':
                        str.appendCodePoint('\b');
                        break;
                    case 'f':
                        str.appendCodePoint('\f');
                        break;
                    case 'n':
                        str.appendCodePoint('\n');
                        break;
                    case 'r':
                        str.appendCodePoint('\r');
                        break;
                    case 't':
                        str.appendCodePoint('\t');
                        break;
                    case 'u':
                        hex.setLength(0);
                        state = HEX_DIGITS;
                        break;
                    default:
                        error("Invalid character escape sequence specified: " + c);
                }

                if (c != 'u')
                {
                    state = STRING_START;
                }
            }
            else
            {
                if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))
                {
                    hex.appendCodePoint((char) c);
                    if (hex.length() == 4)
                    {
                        int value = Integer.parseInt(hex.toString(), 16);
                        str.appendCodePoint(value);
                        state = STRING_START;
                    }
                }
                else
                {
                    error("Expected hexadecimal digits");
                }
            }
        }

        final String s = str.toString();
        final String translate =  stringCache.get(s);
        return translate == null ? s : translate;
    }
private String readString() throws IOException
    {
        final StringBuilder str = strBuf;
        final StringBuilder hex = hexBuf;
        str.setLength(0);
        int state = STRING_START;
        final FastPushbackReader in = input;

        while (true)
        {
            final int c = in.read();
            if (c == -1)
            {
                error("EOF reached while reading JSON string");
            }

            if (state == STRING_START)
            {
                if (c == '"')
                {
                    break;
                }
                else if (c == '\\')
                {
                    state = STRING_SLASH;
                }
                else
                {
                    str.appendCodePoint(c);
                }
            }
            else if (state == STRING_SLASH)
            {
                switch(c)
                {
                    case '\\':
                        str.appendCodePoint('\\');
                        break;
                    case '/':
                        str.appendCodePoint('/');
                        break;
                    case '"':
                        str.appendCodePoint('"');
                        break;
                    case '\'':
                        str.appendCodePoint('\'');
                        break;
                    case 'b':
                        str.appendCodePoint('\b');
                        break;
                    case 'f':
                        str.appendCodePoint('\f');
                        break;
                    case 'n':
                        str.appendCodePoint('\n');
                        break;
                    case 'r':
                        str.appendCodePoint('\r');
                        break;
                    case 't':
                        str.appendCodePoint('\t');
                        break;
                    case 'u':
                        hex.setLength(0);
                        state = HEX_DIGITS;
                        break;
                    default:
                        error("Invalid character escape sequence specified: " + c);
                }

                if (c != 'u')
                {
                    state = STRING_START;
                }
            }
            else
            {
                if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))
                {
                    hex.appendCodePoint((char) c);
                    if (hex.length() == 4)
                    {
                        int value = Integer.parseInt(hex.toString(), 16);
                        str.appendCodePoint(value);
                        state = STRING_START;
                    }
                }
                else
                {
                    error("Expected hexadecimal digits");
                }
            }
        }

        final String s = str.toString();
        final String translate =  stringCache.get(s);
        return translate == null ? s : translate;
    }
Read a JSON string
This method assumes the initial quote has already been read.

@return String read from JSON input stream.
@throws IOException for stream errors or parsing errors.