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; } }