1 2 /* 3 * UTF8BIN.C 4 * 5 * cc utf8bin.c -o ~/bin/utf8bin 6 * rehash 7 * setenv LANG en_US.UTF-8 8 * dd if=/dev/urandom bs=32k count=1024 | utf8bin 9 * 10 * Test round-trip UTF8-B binary escaping functions. 11 */ 12 #include <sys/types.h> 13 #include <sys/file.h> 14 #include <locale.h> 15 #include <stdio.h> 16 #include <unistd.h> 17 #include <string.h> 18 #include <wchar.h> 19 20 int 21 main(int ac, char **av) 22 { 23 char ibuf[1024]; 24 char obuf[1024]; 25 wchar_t warray[1024]; 26 ssize_t r1; 27 ssize_t r2; 28 ssize_t x; 29 ssize_t w1; 30 ssize_t w2; 31 ssize_t i; 32 ssize_t o; 33 int failed; 34 int flags; 35 36 /* 37 * NOTE: If we use WCSBIN_SURRO the round-trip will not be 8-bit 38 * clean. 39 * 40 * Typically use either 0 or WCSBIN_LONGCODE, both of which 41 * are 8-bit clean, will escape, and cannot error on input 42 * (or generate wchars that might error on output) given the 43 * same flags). 44 */ 45 flags = 0; 46 flags = WCSBIN_LONGCODES; 47 48 setlocale(LC_ALL, ""); 49 x = 0; 50 while ((flags & WCSBIN_EOF) == 0 && 51 (r1 = read(0, ibuf + x, sizeof(ibuf) - x)) >= 0) { 52 /* allow final loop for loose ends */ 53 if (r1 == 0) 54 flags |= WCSBIN_EOF; 55 r1 += x; 56 r2 = r1; 57 w1 = mbintowcr(warray, ibuf, 1024, &r2, flags); 58 59 /* round-trip, output buffer can be same size as input buffer */ 60 w2 = w1; 61 o = wcrtombin(obuf, warray, sizeof(obuf), &w2, flags); 62 fflush(stdout); 63 64 printf("read %4d/%-4d wc=%4d/%-4d write=%-4d\t", 65 r2, r1, w2, w1, o); 66 if (r2 == o) { 67 if (bcmp(ibuf, obuf, o) == 0) { 68 printf("ok%c", 69 (flags & WCSBIN_EOF) ? '\n' : '\r'); 70 fflush(stdout); 71 } else { 72 printf("compare-fail\n"); 73 } 74 } else if (r2 < o) { 75 if (bcmp(ibuf, obuf, r2) == 0) 76 printf("len-fail, rest-ok\n"); 77 else 78 printf("len-fail, compare-fail\n"); 79 } else if (o < r2) { 80 if (bcmp(ibuf, obuf, o) == 0) 81 printf("len-fail, rest-ok\n"); 82 else 83 printf("len-fail, compare-fail\n"); 84 } 85 for (i = failed = 0; i < r2 && i < o; ++i) { 86 if (ibuf[i] != obuf[i]) { 87 printf(" @%04x %02x %02x\n", 88 i, (uint8_t)ibuf[i], (uint8_t)obuf[i]); 89 failed = 16; 90 } else if (failed) { 91 --failed; 92 printf(" @%04x %02x %02x\n", 93 i, (uint8_t)ibuf[i], (uint8_t)obuf[i]); 94 } 95 } 96 97 x = r1 - r2; 98 if (x) 99 bcopy(ibuf + r2, ibuf, x); 100 } 101 } 102