thrifty-runtime/src/main/java/com/microsoft/thrifty/protocol/JsonProtocol.java
private ByteString readJsonString(boolean skipContext)
            throws IOException {
        Buffer buffer = new Buffer();
        ArrayList<Character> codeunits = new ArrayList<>();
        if (!skipContext) {
            context.read();
        }
        readJsonSyntaxChar(QUOTE);
        while (true) {
            byte ch = reader.read();
            if (ch == QUOTE[0]) {
                break;
            }
            if (ch == ESCSEQ[0]) {
                ch = reader.read();
                if (ch == ESCSEQ[1]) {
                    transport.read(tmpbuf, 0, 4);
                    short cu = (short) (
                            ((short) hexVal(tmpbuf[0]) << 12)
                                    + ((short) hexVal(tmpbuf[1]) << 8)
                                    + ((short) hexVal(tmpbuf[2]) << 4)
                                    + (short) hexVal(tmpbuf[3]));
                    try {
                        if (Character.isHighSurrogate((char) cu)) {
                            if (codeunits.size() > 0) {
                                throw new ProtocolException("Expected low surrogate char");
                            }
                            codeunits.add((char) cu);
                        } else if (Character.isLowSurrogate((char) cu)) {
                            if (codeunits.size() == 0) {
                                throw new ProtocolException("Expected high surrogate char");
                            }

                            codeunits.add((char) cu);
                            buffer.write(new String(new int[]{codeunits.get(0), codeunits.get(1)}, 0, 2)
                                    .getBytes("UTF-8"));
                            codeunits.clear();
                        } else {
                            buffer.write(new String(new int[]{cu}, 0, 1).getBytes("UTF-8"));
                        }
                        continue;
                    } catch (UnsupportedEncodingException e) {
                        throw new AssertionError(e);
                    } catch (IOException ex) {
                        throw new ProtocolException("Invalid unicode sequence");
                    }
                } else {
                    int off = ESCAPE_CHARS.indexOf(ch);
                    if (off == -1) {
                        throw new ProtocolException("Expected control char");
                    }
                    ch = ESCAPE_CHAR_VALS[off];
                }
            }
            buffer.write(new byte[]{ch});
        }
        return buffer.readByteString();
    }
private ByteString readJsonString(boolean skipContext)
            throws IOException {
        Buffer buffer = new Buffer();
        ArrayList<Character> codeunits = new ArrayList<>();
        if (!skipContext) {
            context.read();
        }
        readJsonSyntaxChar(QUOTE);
        while (true) {
            byte ch = reader.read();
            if (ch == QUOTE[0]) {
                break;
            }
            if (ch == ESCSEQ[0]) {
                ch = reader.read();
                if (ch == ESCSEQ[1]) {
                    transport.read(tmpbuf, 0, 4);
                    short cu = (short) (
                            ((short) hexVal(tmpbuf[0]) << 12)
                                    + ((short) hexVal(tmpbuf[1]) << 8)
                                    + ((short) hexVal(tmpbuf[2]) << 4)
                                    + (short) hexVal(tmpbuf[3]));
                    try {
                        if (Character.isHighSurrogate((char) cu)) {
                            if (codeunits.size() > 0) {
                                throw new ProtocolException("Expected low surrogate char");
                            }
                            codeunits.add((char) cu);
                        } else if (Character.isLowSurrogate((char) cu)) {
                            if (codeunits.size() == 0) {
                                throw new ProtocolException("Expected high surrogate char");
                            }

                            codeunits.add((char) cu);
                            buffer.write(new String(new int[]{codeunits.get(0), codeunits.get(1)}, 0, 2)
                                    .getBytes("UTF-8"));
                            codeunits.clear();
                        } else {
                            buffer.write(new String(new int[]{cu}, 0, 1).getBytes("UTF-8"));
                        }
                        continue;
                    } catch (UnsupportedEncodingException e) {
                        throw new AssertionError(e);
                    } catch (IOException ex) {
                        throw new ProtocolException("Invalid unicode sequence");
                    }
                } else {
                    int off = ESCAPE_CHARS.indexOf(ch);
                    if (off == -1) {
                        throw new ProtocolException("Expected control char");
                    }
                    ch = ESCAPE_CHAR_VALS[off];
                }
            }
            buffer.write(new byte[]{ch});
        }
        return buffer.readByteString();
    }
context if skipContext is true.