Ctrl K
ComunidadGuías…

std/utf8.zc

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import "./core.zc"

struct Utf8 {}

impl Utf8 {
    fn is_digit(r: rune) -> bool {
        return r >= '0' && r <= '9';
    }

    fn is_alpha(r: rune) -> bool {
        if ((r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z')) {
            return true;
        }
        // Latin-1 Supplement Letters
        if ((r >= (rune)0xC0 && r <= (rune)0xD6) || (r >= (rune)0xD8 && r <= (rune)0xF6) || (r >= (rune)0xF8 && r <= (rune)0xFF)) {
            return true;
        }
        return false;
    }

    fn is_whitespace(r: rune) -> bool {
        return r == ' ' || r == '\t' || r == '\n' || r == '\r';
    }

    fn is_upper(r: rune) -> bool {
        if (r >= 'A' && r <= 'Z') return true;
        if (r >= (rune)0xC0 && r <= (rune)0xD6) return true;
        if (r >= (rune)0xD8 && r <= (rune)0xDE) return true;
        return false;
    }

    fn is_lower(r: rune) -> bool {
        if (r >= 'a' && r <= 'z') return true;
        if (r >= (rune)0xDF && r <= (rune)0xF6) return true;
        if (r >= (rune)0xF8 && r <= (rune)0xFF) return true;
        return false;
    }

    fn to_upper(r: rune) -> rune {
        if (r >= 'a' && r <= 'z') return r - (rune)32;
        if (r >= (rune)0xE0 && r <= (rune)0xF6) return r - (rune)32;
        if (r >= (rune)0xF8 && r <= (rune)0xFE) return r - (rune)32;
        return r;
    }

    fn to_lower(r: rune) -> rune {
        if (r >= 'A' && r <= 'Z') return r + (rune)32;
        if (r >= (rune)0xC0 && r <= (rune)0xD6) return r + (rune)32;
        if (r >= (rune)0xD8 && r <= (rune)0xDE) return r + (rune)32;
        return r;
    }

    fn encode(r: rune, buf: char*) -> usize {
        let val = (uint32_t)r;
        if (val < 0x80) {
            buf[0] = (char)val;
            return 1;
        } else if (val < 0x800) {
            buf[0] = (char)(0xC0 | (val >> 6));
            buf[1] = (char)(0x80 | (val & 0x3F));
            return 2;
        } else if (val < 0x10000) {
            buf[0] = (char)(0xE0 | (val >> 12));
            buf[1] = (char)(0x80 | ((val >> 6) & 0x3F));
            buf[2] = (char)(0x80 | (val & 0x3F));
            return 3;
        } else {
            buf[0] = (char)(0xF0 | (val >> 18));
            buf[1] = (char)(0x80 | ((val >> 12) & 0x3F));
            buf[2] = (char)(0x80 | ((val >> 6) & 0x3F));
            buf[3] = (char)(0x80 | (val & 0x3F));
            return 4;
        }
    }

    fn rune_len(r: rune) -> usize {
        let val = (uint32_t)r;
        if (val < 0x80) return 1;
        if (val < 0x800) return 2;
        if (val < 0x10000) return 3;
        return 4;
    }

    fn is_valid(data: char*, len: usize) -> bool {
        let i: usize = 0;
        while i < len {
            let b1 = (byte)data[i];
            if ((b1 & 0x80) == 0) {
                i = i + 1;
            } else if ((b1 & 0xE0) == 0xC0) {
                if (i + 1 >= len) return false;
                if (((byte)data[i + 1] & 0xC0) != 0x80) return false;
                i = i + 2;
            } else if ((b1 & 0xF0) == 0xE0) {
                if (i + 2 >= len) return false;
                if (((byte)data[i + 1] & 0xC0) != 0x80) return false;
                if (((byte)data[i + 2] & 0xC0) != 0x80) return false;
                i = i + 3;
            } else if ((b1 & 0xF8) == 0xF0) {
                if (i + 3 >= len) return false;
                if (((byte)data[i + 1] & 0xC0) != 0x80) return false;
                if (((byte)data[i + 2] & 0xC0) != 0x80) return false;
                if (((byte)data[i + 3] & 0xC0) != 0x80) return false;
                i = i + 4;
            } else {
                return false;
            }
        }
        return true;
    }

    fn decode(data: char*, len: usize, consumed: usize*) -> rune {
        if (len == 0) {
            if (consumed != NULL) { consumed[0] = 0; }
            return (rune)0;
        }
        let b1 = (byte)data[0];
        if ((b1 & 0x80) == 0) {
            if (consumed != NULL) { consumed[0] = 1; }
            return (rune)b1;
        } else if ((b1 & 0xE0) == 0xC0) {
            if (len < 2) { if (consumed != NULL) { consumed[0] = 1; } return (rune)0; }
            if (consumed != NULL) { consumed[0] = 2; }
            return (rune)(((int)(b1 & 0x1F) << 6) | ((int)(byte)data[1] & 0x3F));
        } else if ((b1 & 0xF0) == 0xE0) {
            if (len < 3) { if (consumed != NULL) { consumed[0] = 1; } return (rune)0; }
            if (consumed != NULL) { consumed[0] = 3; }
            return (rune)(((int)(b1 & 0x0F) << 12) | (((int)(byte)data[1] & 0x3F) << 6) | ((int)(byte)data[2] & 0x3F));
        } else if ((b1 & 0xF8) == 0xF0) {
            if (len < 4) { if (consumed != NULL) { consumed[0] = 1; } return (rune)0; }
            if (consumed != NULL) { consumed[0] = 4; }
            return (rune)(((int)(b1 & 0x07) << 18) | (((int)(byte)data[1] & 0x3F) << 12) | (((int)(byte)data[2] & 0x3F) << 6) | ((int)(byte)data[3] & 0x3F));
        }
        if (consumed != NULL) { consumed[0] = 1; }
        return (rune)0;
    }
}