idn_result_t idn__filemapper_map(idn__filemapper_t ctx, const unsigned long *from, unsigned long *to, size_t tolen) { idn_result_t r = idn_success; ucsbuf_t ub; assert(ctx != NULL && from != NULL && to != NULL); TRACE(("idn__filemapper_map(from=\"%s\")\n", idn__debug_ucs4xstring(from, 50))); /* Initialize temporary buffer. */ ucsbuf_init(&ub); while (*from != '\0') { /* Try mapping. */ r = idn_ucsmap_map(ctx->map, *from, ub.ucs, ub.size, &ub.len); switch (r) { case idn_buffer_overflow: /* Temporary buffer too small. Enlarge and retry. */ if ((r = ucsbuf_grow(&ub)) != idn_success) break; continue; case idn_nomapping: /* There is no mapping. */ r = idn_success; /* fallthrough */ case idn_success: if (tolen < ub.len) { r = idn_buffer_overflow; goto ret; } memcpy(to, ub.ucs, sizeof(*to) * ub.len); to += ub.len; tolen -= ub.len; break; default: goto ret; } from++; } ret: ucsbuf_free(&ub); if (r == idn_success) { /* Terminate with NUL. */ if (tolen == 0) return (idn_buffer_overflow); *to = '\0'; } return (r); }
static idn_result_t read_file(const char *file, FILE *fp, idn_ucsmap_t map) { char line[1024]; ucsbuf_t ub; idn_result_t r = idn_success; int lineno = 0; ucsbuf_init(&ub); while (fgets(line, sizeof(line), fp) != NULL) { char *p = line; lineno++; while (isspace((unsigned char)*p)) p++; if (*p == '\0' || *p == '#') continue; #ifdef SUPPORT_VERSIONING /* Skip version tag. */ if (lineno == 1 && strncmp("version=", line, 8) == 0) continue; #endif again: ub.len = 0; r = get_map(p, &ub); switch (r) { case idn_success: r = idn_ucsmap_add(map, ub.ucs[0], &ub.ucs[1], ub.len - 1); break; case idn_buffer_overflow: if ((r = ucsbuf_grow(&ub)) != idn_success) break; goto again; case idn_invalid_syntax: WARNING(("syntax error in file \"%-.100s\" line %d: " "%-.100s", file, lineno, line)); /* fall through */ default: ucsbuf_free(&ub); return (r); } } ucsbuf_free(&ub); return (r); }
static mdn_result_t amcaceo_encode(const char *from, size_t fromlen, char *to, size_t tolen) { ucsbuf_t ucsb; amcaceo_encode_ctx ctx; size_t len; mdn_result_t r; int literal_mode = 0; int i; /* * Convert to UCS-4. */ ucsbuf_init(&ucsb); if ((r = utf8_to_ucs4(from, fromlen, &ucsb)) != mdn_success) return (r); /* * Verify that all the code points are within 0-0x10FFFF range. */ for (i = 0; i < ucsb.len; i++) { if (ucsb.ucs[i] > 0x10FFFF) { ucsbuf_free(&ucsb); return (mdn_invalid_encoding); } } init_encode_ctx(&ctx); ctx.input = ucsb.ucs; ctx.input_len = ucsb.len; choose_refpoints(&ctx); if ((len = encode_refpoints(&ctx, to, tolen)) == 0) goto overflow; to += len; tolen -= len; for (i = 0; i < ctx.input_len; i++) { unsigned long v = ctx.input[i]; if (v == '-') { /* * Convert "-" to "--". */ if (tolen < 2) goto overflow; to[0] = to[1] = '-'; to += 2; tolen -= 2; } else if (is_ldh(v)) { /* * LDH characters. */ if (literal_mode == 0) { /* * Go into literal mode. */ if (tolen < 1) goto overflow; *to++ = '-'; tolen--; literal_mode = 1; } if (tolen < 1) goto overflow; *to++ = v; tolen--; } else { /* * Non-LDH characters. */ if (literal_mode != 0) { /* * Get out of literal mode. */ if (tolen < 1) goto overflow; *to++ = '-'; tolen--; literal_mode = 0; } len = encode_point(ctx.refpoint, v, to, tolen); if (len == 0) goto overflow; to += len; tolen -= len; } } /* * Terminate with NUL. */ if (tolen < 1) return (mdn_buffer_overflow); to[0] = '\0'; ucsbuf_free(&ucsb); return (mdn_success); overflow: ucsbuf_free(&ucsb); return (mdn_buffer_overflow); }