private Object readValue() throws JSONException {
        switch (read(2)) {
        case 0:
            return new Integer(read(!bit() ? 4 : !bit() ? 7 : 14));
        case 1:
            byte[] bytes = new byte[256];
            int length = 0;
            while (true) {
                int c = read(4);
                if (c == endOfNumber) {
                    break;
                }
                bytes[length] = bcd[c];
                length += 1;
            }
            Object value;
            try {
                value = JSONObject.stringToValue(new String(bytes, 0, length,
                        "US-ASCII"));
            } catch (UnsupportedEncodingException e) {
                throw new JSONException(e);
            }
            this.values.register(value);
            return value;
        case 2:
            return getAndTick(this.values, this.bitreader);
        case 3:
            return readJSON();
        default:
            throw new JSONException("Impossible.");
        }
    }