strings_test.ha (5054B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 use bytes; 5 use errors; 6 use fmt; 7 use io; 8 use strings; 9 10 11 fn c_checkrange(chars: []u8, f: *fn (c: u8) bool) void = { 12 for (let i = 0z; i < 256; i += 1) { 13 let expected = false; 14 for (let j = 0z; j < len(chars); j += 1) { 15 if (chars[j] == i: u8) { 16 expected = true; 17 break; 18 }; 19 }; 20 21 if (f(i: u8) != expected) { 22 fmt::println(i, expected, f(i: u8))!; 23 }; 24 assert(f(i: u8) == expected); 25 }; 26 }; 27 28 @test fn c_is_num() void = { 29 const chars: [_]u8 = [ 30 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ' ', 31 ]; 32 c_checkrange(chars, &c_is_num); 33 }; 34 35 @test fn c_is_print() void = { 36 const chars: [_]u8 = [ 37 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 38 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 39 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 40 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 41 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ' ', '\'', 42 '(', ')', '+', ',', '-', '.', '/', ':', '=', '?', 43 ]; 44 c_checkrange(chars, &c_is_print); 45 }; 46 47 @test fn utf8() void = { 48 let buf: [16]u8 = [0...]; 49 let b: [_]u8 = [ 50 0x55, 51 0x56, 52 0xd0, 0x98, 53 0xe0, 0xa4, 0xb9, 54 0xf0, 0x90, 0x8d, 0x88 55 ]; 56 const runesat: [_]size = [0, 1, 2, 2, 4, 4, 4, 7, 7, 7, 7, 8]; 57 58 let expected: str = strings::fromutf8([0xf0, 0x90, 0x8d, 0x88])!; 59 assert(read_utf8str(&d([0x0c, 0x04, 0xf0, 0x90, 0x8d, 0x88]), buf)! 60 == expected); 61 assert(read_utf8str(&d([0x0c, 0x03, 0xf0, 0x90, 0x8d]), buf) is invalid); 62 63 bytes::zero(buf); 64 let r = strreader(&d([0x0c, 0x04, 0xf0, 0x90, 0x8d, 0x88]), utag::UTF8_STRING)!; 65 assert(io::read(&r, buf)! == 4); 66 assert(bytes::equal(buf[..4], strings::toutf8(expected))); 67 68 bytes::zero(buf); 69 let expected: str = strings::fromutf8([0x55, 0x56, 0xf0, 0x90, 0x8d, 0x88])!; 70 assert(read_utf8str(&d([0x0c, 0x06, 0x55, 0x56, 0xf0, 0x90, 0x8d, 0x88]), buf)! 71 == expected); 72 assert(read_utf8str(&d([0x0c, 0x05, 0x55, 0x56, 0xf0, 0x90, 0x8d]), buf) is invalid); 73 74 bytes::zero(buf); 75 let r = strreader(&d([0x0c, 0x06, 0x55, 0x56, 0xf0, 0x90, 0x8d, 0x88]), utag::UTF8_STRING)!; 76 assert(io::read(&r, buf)! == 6); 77 assert(bytes::equal(buf[..6], strings::toutf8(expected))); 78 79 let r = strreader(&d([0x0c, 0x05, 0x55, 0x56, 0xf0, 0x90, 0x8d]), utag::UTF8_STRING)!; 80 assert(unwrap_err(io::readall(&r, buf[2..]) as io::error) is invalid); 81 82 bytes::zero(buf); 83 let r = strreader(&d([0x0c, 0x06, 0x55, 0x56, 0xf0, 0x90, 0x8d, 0x88]), utag::UTF8_STRING)!; 84 assert(io::read(&r, buf[..4])! == 2); 85 assert(io::read(&r, buf[2..])! == 4); 86 assert(bytes::equal(buf[..6], strings::toutf8(expected))); 87 88 bytes::zero(buf); 89 let r = strreader(&d([0x0c, 0x05, 0x55, 0x56, 0xf0, 0x90, 0x8d]), utag::UTF8_STRING)!; 90 assert(io::read(&r, buf[..4])! == 2); 91 assert(unwrap_err(io::readall(&r, buf[2..]) as io::error) is invalid); 92 }; 93 94 @test fn t61() void = { 95 let input: [_]u8 = [ 96 0x14, 0x29, 97 0x42, 0xc8, 0x61, 0x72, 0x65, 0x6e, 0x20, 0x76, 0x65, 0x72, 98 0x7a, 0x65, 0x68, 0x72, 0x65, 0x6e, 0x20, 0x67, 0x65, 0x72, 99 0x6e, 0x65, 0x20, 0xc8, 0x75, 0x62, 0x65, 0x72, 0x6d, 0xc8, 100 0x61, 0xfb, 0x69, 0x67, 0x20, 0x48, 0x6f, 0x6e, 0x69, 0x67, 101 0x0a, 102 ]; 103 104 const expected: [_]u8 = [ 105 0x42, 0xc3, 0xa4, 0x72, 0x65, 0x6e, 0x20, 0x76, 0x65, 0x72, 106 0x7a, 0x65, 0x68, 0x72, 0x65, 0x6e, 0x20, 0x67, 0x65, 0x72, 107 0x6e, 0x65, 0x20, 0xc3, 0xbc, 0x62, 0x65, 0x72, 0x6d, 0xc3, 108 0xa4, 0xc3, 0x9f, 0x69, 0x67, 0x20, 0x48, 0x6f, 0x6e, 0x69, 109 0x67, 0x0a, 110 ]; 111 112 let dec = d(input); 113 let r = strreader(&dec, utag::TELETEX_STRING)!; 114 let result = io::drain(&r)!; 115 defer free(result); 116 assert(bytes::equal(expected, result)); 117 assert(trypeek(&dec) is io::EOF); 118 119 // cut off multibyte char 120 input[1] = 0x2; 121 let r = strreader(&d(input[..4]), utag::TELETEX_STRING)!; 122 assert(unwrap_err(io::drain(&r) as io::error) is invalid); 123 124 // not enough space for multibyte char 125 let buf: [24]u8 = [0...]; 126 let in = input[..27]; 127 in[1] = (len(in) - 2): u8; 128 let dec = d(in); 129 let r = strreader(&dec, utag::TELETEX_STRING)!; 130 assert(io::read(&r, buf)! == 23); 131 assert(trypeek(&dec) is badformat); 132 133 let r = strreader(&d([ 134 0x14, 0x0f, 0x63, 0x6c, 0xc2, 0x65, 0x73, 0x20, 0x70, 0x75, 135 0x62, 0x6c, 0x69, 0x71, 0x75, 0x65, 0x73, 136 ]), utag::TELETEX_STRING)!; 137 let b = io::drain(&r)!; 138 defer free(b); 139 140 assert(strings::fromutf8(b)! == "cl\u00e9s publiques"); 141 }; 142 143 @test fn bmp() void = { 144 let input: [_]u8 = [ 145 0x1e, 0x26, 146 0x00, 0x48, 0x00, 0xe4, 0x00, 0x72, 0x00, 0x65, 0x00, 0x6c, 147 0x00, 0x61, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x20, 0x00, 0x69, 148 0x01, 0x61, 0x00, 0x20, 0x00, 0x6e, 0x00, 0x65, 0x00, 0x61, 149 0x00, 0x74, 0x00, 0x6f, 0x00, 0x20, 0x27, 0x64, 150 ]; 151 152 const expected: [_]u8 = [ 153 0x48, 0xc3, 0xa4, 0x72, 0x65, 0x6c, 0x61, 0x6e, 0x67, 0x20, 154 0x69, 0xc5, 0xa1, 0x20, 0x6e, 0x65, 0x61, 0x74, 0x6f, 0x20, 155 0xe2, 0x9d, 0xa4, 156 ]; 157 158 let dec = d(input); 159 let r = strreader(&dec, utag::BMP_STRING)!; 160 let result = io::drain(&r)!; 161 defer free(result); 162 assert(bytes::equal(expected, result)); 163 assert(trypeek(&dec) is io::EOF); 164 };