📄 iconv.c
字号:
continue; } /* it's a hex character */ if (*inbytesleft < 5) { errno = EINVAL; return -1; } if (sscanf(&(*inbuf)[1], "%04x", &v) != 1) { errno = EILSEQ; return -1; } (*outbuf)[0] = v&0xff; (*outbuf)[1] = v>>8; (*inbytesleft) -= 5; (*outbytesleft) -= 2; (*inbuf) += 5; (*outbuf) += 2; } if (*inbytesleft > 0) { errno = E2BIG; return -1; } return 0;}static size_t ucs2hex_push(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft){ while (*inbytesleft >= 2 && *outbytesleft >= 1) { char buf[6]; if ((*inbuf)[1] == 0 && ((*inbuf)[0] & 0x80) == 0 && (*inbuf)[0] != '@') { (*outbuf)[0] = (*inbuf)[0]; (*inbytesleft) -= 2; (*outbytesleft) -= 1; (*inbuf) += 2; (*outbuf) += 1; continue; } if (*outbytesleft < 5) { errno = E2BIG; return -1; } snprintf(buf, 6, "@%04x", SVAL(*inbuf, 0)); memcpy(*outbuf, buf, 5); (*inbytesleft) -= 2; (*outbytesleft) -= 5; (*inbuf) += 2; (*outbuf) += 5; } if (*inbytesleft == 1) { errno = EINVAL; return -1; } if (*inbytesleft > 1) { errno = E2BIG; return -1; } return 0;}static size_t iconv_swab(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft){ int n; n = MIN(*inbytesleft, *outbytesleft); swab(*inbuf, *outbuf, (n&~1)); if (n&1) { (*outbuf)[n-1] = 0; } (*inbytesleft) -= n; (*outbytesleft) -= n; (*inbuf) += n; (*outbuf) += n; if (*inbytesleft > 0) { errno = E2BIG; return -1; } return 0;}static size_t iconv_copy(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft){ int n; n = MIN(*inbytesleft, *outbytesleft); memmove(*outbuf, *inbuf, n); (*inbytesleft) -= n; (*outbytesleft) -= n; (*inbuf) += n; (*outbuf) += n; if (*inbytesleft > 0) { errno = E2BIG; return -1; } return 0;}static size_t utf8_pull(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft){ size_t in_left=*inbytesleft, out_left=*outbytesleft; const uint8_t *c = (const uint8_t *)*inbuf; uint8_t *uc = (uint8_t *)*outbuf; while (in_left >= 1 && out_left >= 2) { if ((c[0] & 0x80) == 0) { uc[0] = c[0]; uc[1] = 0; c += 1; in_left -= 1; out_left -= 2; uc += 2; continue; } if ((c[0] & 0xe0) == 0xc0) { if (in_left < 2 || (c[1] & 0xc0) != 0x80) { errno = EILSEQ; goto error; } uc[1] = (c[0]>>2) & 0x7; uc[0] = (c[0]<<6) | (c[1]&0x3f); c += 2; in_left -= 2; out_left -= 2; uc += 2; continue; } if ((c[0] & 0xf0) == 0xe0) { if (in_left < 3 || (c[1] & 0xc0) != 0x80 || (c[2] & 0xc0) != 0x80) { errno = EILSEQ; goto error; } uc[1] = ((c[0]&0xF)<<4) | ((c[1]>>2)&0xF); uc[0] = (c[1]<<6) | (c[2]&0x3f); c += 3; in_left -= 3; out_left -= 2; uc += 2; continue; } if ((c[0] & 0xf8) == 0xf0) { unsigned int codepoint; if (in_left < 4 || (c[1] & 0xc0) != 0x80 || (c[2] & 0xc0) != 0x80 || (c[3] & 0xc0) != 0x80) { errno = EILSEQ; goto error; } codepoint = (c[3]&0x3f) | ((c[2]&0x3f)<<6) | ((c[1]&0x3f)<<12) | ((c[0]&0x7)<<18); if (codepoint < 0x10000) { /* accept UTF-8 characters that are not minimally packed, but pack the result */ uc[0] = (codepoint & 0xFF); uc[1] = (codepoint >> 8); c += 4; in_left -= 4; out_left -= 2; uc += 2; continue; } codepoint -= 0x10000; if (out_left < 4) { errno = E2BIG; goto error; } uc[0] = (codepoint>>10) & 0xFF; uc[1] = (codepoint>>18) | 0xd8; uc[2] = codepoint & 0xFF; uc[3] = ((codepoint>>8) & 0x3) | 0xdc; c += 4; in_left -= 4; out_left -= 4; uc += 4; continue; } /* we don't handle 5 byte sequences */ errno = EINVAL; goto error; } if (in_left > 0) { errno = E2BIG; goto error; } *inbytesleft = in_left; *outbytesleft = out_left; *inbuf = (const char *)c; *outbuf = (char *)uc; return 0;error: *inbytesleft = in_left; *outbytesleft = out_left; *inbuf = (const char *)c; *outbuf = (char *)uc; return -1;}static size_t utf8_push(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft){ size_t in_left=*inbytesleft, out_left=*outbytesleft; uint8_t *c = (uint8_t *)*outbuf; const uint8_t *uc = (const uint8_t *)*inbuf; while (in_left >= 2 && out_left >= 1) { unsigned int codepoint; if (uc[1] == 0 && !(uc[0] & 0x80)) { /* simplest case */ c[0] = uc[0]; in_left -= 2; out_left -= 1; uc += 2; c += 1; continue; } if ((uc[1]&0xf8) == 0) { /* next simplest case */ if (out_left < 2) { errno = E2BIG; goto error; } c[0] = 0xc0 | (uc[0]>>6) | (uc[1]<<2); c[1] = 0x80 | (uc[0] & 0x3f); in_left -= 2; out_left -= 2; uc += 2; c += 2; continue; } if ((uc[1] & 0xfc) == 0xdc) { /* its the second part of a 4 byte sequence. Illegal */ if (in_left < 4) { errno = EINVAL; } else { errno = EILSEQ; } goto error; } if ((uc[1] & 0xfc) != 0xd8) { codepoint = uc[0] | (uc[1]<<8); if (out_left < 3) { errno = E2BIG; goto error; } c[0] = 0xe0 | (codepoint >> 12); c[1] = 0x80 | ((codepoint >> 6) & 0x3f); c[2] = 0x80 | (codepoint & 0x3f); in_left -= 2; out_left -= 3; uc += 2; c += 3; continue; } /* its the first part of a 4 byte sequence */ if (in_left < 4) { errno = EINVAL; goto error; } if ((uc[3] & 0xfc) != 0xdc) { errno = EILSEQ; goto error; } codepoint = 0x10000 + (uc[2] | ((uc[3] & 0x3)<<8) | (uc[0]<<10) | ((uc[1] & 0x3)<<18)); if (out_left < 4) { errno = E2BIG; goto error; } c[0] = 0xf0 | (codepoint >> 18); c[1] = 0x80 | ((codepoint >> 12) & 0x3f); c[2] = 0x80 | ((codepoint >> 6) & 0x3f); c[3] = 0x80 | (codepoint & 0x3f); in_left -= 4; out_left -= 4; uc += 4; c += 4; } if (in_left == 1) { errno = EINVAL; goto error; } if (in_left > 1) { errno = E2BIG; goto error; } *inbytesleft = in_left; *outbytesleft = out_left; *inbuf = (const char *)uc; *outbuf = (char *)c; return 0;error: *inbytesleft = in_left; *outbytesleft = out_left; *inbuf = (const char *)uc; *outbuf = (char *)c; return -1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -