#include #include #include #include static int fails_iteratively_with_reset(char *input) { iconv_t cd = iconv_open("UTF-8", "UTF-16"); if (cd == (iconv_t)-1) return -1; char output[6]; // UTF-8-BOM (possibly) + "23" + NUL char *inbuf = input; size_t inbytesleft = 4; char *outbuf = output; size_t outbytesleft = 6; size_t res = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); if (res == (size_t)-1) { iconv_close(cd); return -1; } iconv(cd, NULL, NULL, NULL, NULL); inbytesleft = 6 - (4 - inbytesleft); res = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); iconv_close(cd); if (res == (size_t)-1) return -1; *outbuf = 0; /* remove UTF-8 BOM if present (unlikely) */ int offset = 0; if ((outbuf - output >= 3) && !memcmp(output, "\xef\xbb\xbf", 3)) offset = 3; if (!memcmp(output + offset, "23", 3)) return 0; /* success, conversion works iteratively */ else return 1; /* wrong result */ } int main(void) { unsigned words[] = { 0xfeff /* BOM */, 0x32 /* 2 */, 0x33 /* 3 */}; char little[6]; char big[6]; for(int i = 0; i < 6; i += 2) { unsigned w = words[i/2]; big[i] = little[i+1] = (char) (w >> 8); big[i+1] = little[i] = w & 0xff; } switch(fails_iteratively_with_reset(little)) { case 0: printf("Conversion works iteratively (little-endian).\n"); break; case 1: printf("Iterative conversion fails with reset (little-endian).\n"); break; case -1: default: printf("Test error (little-endian)."); break; } switch(fails_iteratively_with_reset(big)) { case 0: printf("Conversion works iteratively (big-endian).\n"); break; case 1: printf("Iterative conversion fails with reset (big-endian).\n"); break; case -1: default: printf("Test error (big-endian)."); break; } }