/**
 * Calculates the UTF8 byte length of a string
 */
export function length(string) {
    let len = 0;
    let c = 0;
    for (let i = 0; i < string.length; ++i) {
        c = string.charCodeAt(i);
        if (c < 128) {
            len += 1;
        }
        else if (c < 2048) {
            len += 2;
        }
        else if ((c & 0xFC00) === 0xD800 && (string.charCodeAt(i + 1) & 0xFC00) === 0xDC00) {
            ++i;
            len += 4;
        }
        else {
            len += 3;
        }
    }
    return len;
}
/**
 * Reads UTF8 bytes as a string
 */
export function read(buffer, start, end) {
    const len = end - start;
    if (len < 1) {
        return '';
    }
    let parts;
    const chunk = [];
    let i = 0; // char offset
    let t; // temporary
    while (start < end) {
        t = buffer[start++];
        if (t < 128) {
            chunk[i++] = t;
        }
        else if (t > 191 && t < 224) {
            chunk[i++] = (t & 31) << 6 | buffer[start++] & 63;
        }
        else if (t > 239 && t < 365) {
            t = ((t & 7) << 18 | (buffer[start++] & 63) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63) - 0x10000;
            chunk[i++] = 0xD800 + (t >> 10);
            chunk[i++] = 0xDC00 + (t & 1023);
        }
        else {
            chunk[i++] = (t & 15) << 12 | (buffer[start++] & 63) << 6 | buffer[start++] & 63;
        }
        if (i > 8191) {
            (parts ?? (parts = [])).push(String.fromCharCode.apply(String, chunk));
            i = 0;
        }
    }
    if (parts != null) {
        if (i > 0) {
            parts.push(String.fromCharCode.apply(String, chunk.slice(0, i)));
        }
        return parts.join('');
    }
    return String.fromCharCode.apply(String, chunk.slice(0, i));
}
/**
 * Writes a string as UTF8 bytes
 */
export function write(string, buffer, offset) {
    const start = offset;
    let c1; // character 1
    let c2; // character 2
    for (let i = 0; i < string.length; ++i) {
        c1 = string.charCodeAt(i);
        if (c1 < 128) {
            buffer[offset++] = c1;
        }
        else if (c1 < 2048) {
            buffer[offset++] = c1 >> 6 | 192;
            buffer[offset++] = c1 & 63 | 128;
        }
        else if ((c1 & 0xFC00) === 0xD800 && ((c2 = string.charCodeAt(i + 1)) & 0xFC00) === 0xDC00) {
            c1 = 0x10000 + ((c1 & 0x03FF) << 10) + (c2 & 0x03FF);
            ++i;
            buffer[offset++] = c1 >> 18 | 240;
            buffer[offset++] = c1 >> 12 & 63 | 128;
            buffer[offset++] = c1 >> 6 & 63 | 128;
            buffer[offset++] = c1 & 63 | 128;
        }
        else {
            buffer[offset++] = c1 >> 12 | 224;
            buffer[offset++] = c1 >> 6 & 63 | 128;
            buffer[offset++] = c1 & 63 | 128;
        }
    }
    return offset - start;
}
//# sourceMappingURL=utf8.js.map