All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.quarkus.qson.parser.ParsePrimitives Maven / Gradle / Ivy

package io.quarkus.qson.parser;

import io.quarkus.qson.QsonException;

import static io.quarkus.qson.util.IntChar.*;

public class ParsePrimitives {

    public static String readString(byte[] buffer, int tokenStart, int tokenEnd) {
        char[] charbuf = new char[tokenEnd - tokenStart];
        int count = 0;
        int ptr = tokenStart;
        while (ptr < tokenEnd) {
            int c = buffer[ptr++] & 0xFF;
            if (c == '\\') {
                c = buffer[ptr++] & 0xFF;
                boolean encoded = false;
                switch (c) {
                    // First, ones that are mapped
                    case 'b':
                        charbuf[count++] = '\b';
                        break;
                    case 't':
                        charbuf[count++] = '\t';
                        break;
                    case 'n':
                        charbuf[count++] = '\n';
                        break;
                    case 'f':
                        charbuf[count++] = '\f';
                        break;
                    case 'r':
                        charbuf[count++] = '\r';
                        break;

                    // And these are to be returned as they are
                    case '"':
                    case '/':
                    case '\\':
                        charbuf[count++] = (char) c;
                        break;

                    case 'u': // and finally hex-escaped
                        encoded = true;
                        break;

                    default:
                        throw new QsonException("Unknown character format in string");
                }

                if (encoded) {
                    // Ok, a hex escape. Need 4 characters
                    int value = 0;
                    for (int i = 0; i < 4; ++i) {
                        int ch = buffer[ptr++] & 0xFF;
                        int digit = CharArrays.sHexValues[ch & 0xFF];
                        if (digit < 0) {
                            throw new QsonException("expected a hex-digit for character escape sequence");
                        }
                        value = (value << 4) | digit;
                    }
                    charbuf[count++] = (char) value;
                }
            } else {
                if (c < 128) { // Assume 1 byte chars are most common.
                    charbuf[count++] = (char) c;
                } else {
                    int tmp = c & 0xF0; // mask out top 4 bits to test for multibyte
                    if (tmp == 0xC0 || tmp == 0xD0) {
                        // 2 byte
                        int d = (int) buffer[ptr++];
                        if ((d & 0xC0) != 0x080) {
                            throw new QsonException("Invalid UTF8 2 byte encoding");
                        }
                        c = ((c & 0x1F) << 6) | (d & 0x3F);
                    } else if (tmp == 0xE0) {
                        // 3 byte
                        c &= 0x0F;
                        int d = (int) buffer[ptr++];
                        if ((d & 0xC0) != 0x080) {
                            throw new QsonException("Invalid UTF8 3 byte encoding");
                        }
                        c = (c << 6) | (d & 0x3F);
                        d = (int) buffer[ptr++];
                        if ((d & 0xC0) != 0x080) {
                            throw new QsonException("Invalid UTF8 3 byte encoding");
                        }
                        c = (c << 6) | (d & 0x3F);
                    } else if (tmp == 0xF0) {
                        // 4 byte
                        int d = (int) buffer[ptr++];
                        if ((d & 0xC0) != 0x080) {
                            throw new QsonException("Invalid UTF8 4 byte encoding");
                        }
                        c = ((c & 0x07) << 6) | (d & 0x3F);
                        d = (int) buffer[ptr++];
                        if ((d & 0xC0) != 0x080) {
                            throw new QsonException("Invalid UTF8 4 byte encoding");
                        }
                        c = (c << 6) | (d & 0x3F);
                        d = (int) buffer[ptr++];
                        if ((d & 0xC0) != 0x080) {
                            throw new QsonException("Invalid UTF8 4 byte encoding");
                        }
                        c = ((c << 6) | (d & 0x3F)) - 0x10000;
                        charbuf[count++] = (char) (0xD800 | (c >> 10));
                        c = 0xDC00 | (c & 0x3FF);
                    }
                    charbuf[count++] = (char) c;
                }
            }

        }
        return new String(charbuf, 0, count);
    }

    public static boolean readBoolean(byte[] buffer, int tokenStart, int tokenEnd) {
        int len = tokenEnd - tokenStart;
        if (len == 4) {
            for (int i = 0; i < 4; i++) {
                if (CharArrays.TRUE_VALUE[i] != ((int) buffer[tokenStart + i] & 0xFF)) {
                    throw new QsonException("Illegal boolean syntax");
                }
            }
            return true;
        } else if (len == 5) {
            for (int i = 0; i < 5; i++) {
                if (CharArrays.FALSE_VALUE[i] != ((int) buffer[tokenStart + i] & 0xFF)) {
                    throw new QsonException("Illegal boolean syntax");
                }
            }
            return false;

        }
        throw new QsonException("Illegal boolean syntax");
    }

    public static Boolean readBooleanObject(byte[] buffer, int tokenStart, int tokenEnd) {
        int len = tokenEnd - tokenStart;
        if (len == 4) {
            for (int i = 0; i < 4; i++) {
                if (CharArrays.TRUE_VALUE[i] != ((int) buffer[tokenStart + i] & 0xFF)) {
                    throw new QsonException("Illegal boolean syntax");
                }
            }
            return Boolean.TRUE;
        } else if (len == 5) {
            for (int i = 0; i < 5; i++) {
                if (CharArrays.FALSE_VALUE[i] != ((int) buffer[tokenStart + i] & 0xFF)) {
                    throw new QsonException("Illegal boolean syntax");
                }
            }
            return Boolean.FALSE;

        }
        throw new QsonException("Illegal boolean syntax");
    }

    public static long readLong(byte[] buffer, int tokenStart, int tokenEnd) {
        boolean negative = false;
        int i = 0;
        int len = tokenEnd - tokenStart;
        long limit = -9223372036854775807L;
        if (len <= 0) {
            return 0;
        } else {
            int firstChar = buffer[tokenStart] & 0xFF;
            if (firstChar < INT_0) {
                if (firstChar == INT_MINUS) {
                    negative = true;
                    limit = -9223372036854775808L;
                } else if (firstChar != INT_PLUS) {
                    throw new QsonException("Illegal number format");
                }

                if (len == 1) {
                    throw new QsonException("Illegal number format");
                }

                ++i;
            }

            long multmin = limit / (long) 10;

            long result;
            int digit;
            for (result = 0L; i < len; result -= (long) digit) {
                digit = (buffer[i++ + tokenStart] & 0xFF) - INT_0;
                if (digit < 0 || result < multmin) {
                    throw new QsonException("Illegal number format");
                }

                result *= 10L;
                if (result < limit + (long) digit) {
                    throw new QsonException("Illegal number format");
                }
            }

            return negative ? result : -result;
        }
    }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy