private static Json_Value parse_scalar()

in dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/JsonConversion.java [106:200]


    private static Json_Value parse_scalar(int type, LogBuffer buffer, long len, Charset charset) {
        switch (type) {
            case JSONB_TYPE_LITERAL:
                /* purecov: inspected */
                int data = buffer.getUint8();
                switch (data) {
                    case JSONB_NULL_LITERAL:
                        return new Json_Value(Json_enum_type.LITERAL_NULL);
                    case JSONB_TRUE_LITERAL:
                        return new Json_Value(Json_enum_type.LITERAL_TRUE);
                    case JSONB_FALSE_LITERAL:
                        return new Json_Value(Json_enum_type.LITERAL_FALSE);
                    default:
                        throw new IllegalArgumentException("illegal json data");
                }
            case JSONB_TYPE_INT16:
                return new Json_Value(Json_enum_type.INT, buffer.getInt16());
            case JSONB_TYPE_INT32:
                return new Json_Value(Json_enum_type.INT, buffer.getInt32());
            case JSONB_TYPE_INT64:
                return new Json_Value(Json_enum_type.INT, buffer.getLong64());
            case JSONB_TYPE_UINT16:
                return new Json_Value(Json_enum_type.UINT, buffer.getUint16());
            case JSONB_TYPE_UINT32:
                return new Json_Value(Json_enum_type.UINT, buffer.getUint32());
            case JSONB_TYPE_UINT64:
                return new Json_Value(Json_enum_type.UINT, buffer.getUlong64());
            case JSONB_TYPE_DOUBLE:
                return new Json_Value(Json_enum_type.DOUBLE, Double.valueOf(buffer.getDouble64()));
            case JSONB_TYPE_STRING:
                int max_bytes = (int) Math.min(len, 5);
                long tlen = 0;
                long str_len = 0;
                long n = 0;
                byte[] datas = buffer.getData(max_bytes);
                for (int i = 0; i < max_bytes; i++) {
                    // Get the next 7 bits of the length.
                    tlen |= (datas[i] & 0x7f) << (7 * i);
                    if ((datas[i] & 0x80) == 0) {
                        // The length shouldn't exceed 32 bits.
                        if (tlen > 4294967296L) {
                            throw new IllegalArgumentException("illegal json data");
                        }

                        // This was the last byte. Return successfully.
                        n = i + 1;
                        str_len = tlen;
                        break;
                    }
                }

                if (len < n + str_len) {
                    throw new IllegalArgumentException("illegal json data");
                }
                return new Json_Value(Json_enum_type.STRING,
                    buffer.rewind().forward((int) n).getFixString((int) str_len, charset));
            case JSONB_TYPE_OPAQUE:
                /*
                 * There should always be at least one byte, which tells the field type of the
                 * opaque value.
                 */
                // The type is encoded as a uint8 that maps to an
                // enum_field_types.
                int type_byte = buffer.getUint8();
                int position = buffer.position();
                // Then there's the length of the value.
                int q_max_bytes = (int) Math.min(len - 1, 5);
                long q_tlen = 0;
                long q_str_len = 0;
                long q_n = 0;
                byte[] q_datas = buffer.getData(q_max_bytes);
                for (int i = 0; i < q_max_bytes; i++) {
                    // Get the next 7 bits of the length.
                    q_tlen |= (q_datas[i] & 0x7f) << (7 * i);
                    if ((q_datas[i] & 0x80) == 0) {
                        // The length shouldn't exceed 32 bits.
                        if (q_tlen > 4294967296L) {
                            throw new IllegalArgumentException("illegal json data");
                        }

                        // This was the last byte. Return successfully.
                        q_n = i + 1;
                        q_str_len = q_tlen;
                        break;
                    }
                }

                if (q_str_len == 0 || len < q_n + q_str_len) {
                    throw new IllegalArgumentException("illegal json data");
                }
                return new Json_Value(type_byte, buffer.position(position).forward((int) q_n), q_str_len);
            default:
                throw new IllegalArgumentException("illegal json data");
        }
    }