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