idn_result_t idn_normalizer_add(idn_normalizer_t ctx, const char *scheme_name) { idn_result_t r; void *v; normalize_scheme_t *scheme; assert(ctx != NULL && scheme_name != NULL); TRACE(("idn_normalizer_add(scheme_name=%s)\n", scheme_name)); assert(INITIALIZED); if (idn__strhash_get(scheme_hash, scheme_name, &v) != idn_success) { ERROR(("idn_normalizer_add(): invalid scheme \"%-.30s\"\n", scheme_name)); r = idn_invalid_name; goto ret; } scheme = v; assert(ctx->nschemes <= ctx->scheme_size); if (ctx->nschemes == ctx->scheme_size && (r = expand_schemes(ctx)) != idn_success) { goto ret; } ctx->schemes[ctx->nschemes++] = scheme; r = idn_success; ret: TRACE(("idn_normalizer_add(): %s\n", idn_result_tostring(r))); return (r); }
idn_result_t idn_checker_add(idn_checker_t ctx, const char *scheme_name) { idn_result_t r; check_scheme_t *scheme; const char *scheme_prefix; const char *scheme_parameter; void *scheme_context = NULL; char *buffer = NULL; assert(scheme_hash != NULL); assert(ctx != NULL); TRACE(("idn_checker_add(scheme_name=%s)\n", idn__debug_xstring(scheme_name, 50))); /* * Split `scheme_name' into `scheme_prefix' and `scheme_parameter'. */ scheme_parameter = strchr(scheme_name, ':'); if (scheme_parameter == NULL) { scheme_prefix = scheme_name; scheme_parameter = NULL; } else { ptrdiff_t scheme_prefixlen; scheme_prefixlen = scheme_parameter - scheme_name; buffer = (char *) malloc(scheme_prefixlen + 1); if (buffer == NULL) { r = idn_nomemory; goto ret; } memcpy(buffer, scheme_name, scheme_prefixlen); *(buffer + scheme_prefixlen) = '\0'; scheme_prefix = buffer; scheme_parameter++; } /* * Find a scheme. */ if (idn__strhash_get(scheme_hash, scheme_prefix, (void **)&scheme) != idn_success) { ERROR(("idn_checker_add(): invalid scheme \"%-.30s\"\n", scheme_name)); r = idn_invalid_name; goto ret; } if (scheme_parameter == NULL && scheme->parameter != NULL) scheme_parameter = scheme->parameter; /* * Add the scheme. */ assert(ctx->nschemes <= ctx->scheme_size); if (ctx->nschemes == ctx->scheme_size) { check_scheme_t *new_schemes; new_schemes = (check_scheme_t *) realloc(ctx->schemes, sizeof(check_scheme_t) * ctx->scheme_size * 2); if (new_schemes == NULL) { r = idn_nomemory; goto ret; } ctx->schemes = new_schemes; ctx->scheme_size *= 2; } r = scheme->create(scheme_parameter, &scheme_context); if (r != idn_success) goto ret; memcpy(ctx->schemes + ctx->nschemes, scheme, sizeof(check_scheme_t)); ctx->schemes[ctx->nschemes].context = scheme_context; ctx->nschemes++; r = idn_success; ret: free(buffer); if (r != idn_success) free(scheme_context); TRACE(("idn_checker_add(): %s\n", idn_result_tostring(r))); return (r); }
idn_result_t idn_converter_create(const char *name, idn_converter_t *ctxp, int flags) { const char *realname; idn_converter_t ctx; idn_result_t r; void *v; assert(name != NULL && ctxp != NULL); TRACE(("idn_converter_create(%s)\n", name)); realname = idn_converter_getrealname(name); #ifdef DEBUG if (strcmp(name, realname) != 0) { TRACE(("idn_converter_create: realname=%s\n", realname)); } #endif *ctxp = NULL; /* Allocate memory for a converter context and the name. */ ctx = malloc(sizeof(struct idn_converter) + strlen(realname) + 1); if (ctx == NULL) { r = idn_nomemory; goto ret; } ctx->local_encoding_name = (char *)(ctx + 1); (void)strcpy(ctx->local_encoding_name, realname); ctx->flags = flags; ctx->reference_count = 1; ctx->opened_convfromucs4 = 0; ctx->opened_convtoucs4 = 0; ctx->private_data = NULL; assert(encoding_name_hash != NULL); if (strcmp(realname, IDN_UTF8_ENCODING_NAME) == 0) { /* No conversion needed */ ctx->ops = &none_converter_ops; } else if ((r = idn__strhash_get(encoding_name_hash, realname, &v)) == idn_success) { /* Special converter found */ ctx->ops = (converter_ops_t *)v; } else { /* General case */ #ifdef WITHOUT_ICONV free(ctx); *ctxp = NULL; r = idn_invalid_name; goto ret; #else ctx->ops = &iconv_converter_ops; #endif } if ((flags & IDN_CONVERTER_DELAYEDOPEN) == 0) { r = (ctx->ops->openfromucs4)(ctx, &(ctx->private_data)); if (r != idn_success) { WARNING(("idn_converter_create(): open failed " "(ucs4->local)\n")); free(ctx); *ctxp = NULL; goto ret; } ctx->opened_convfromucs4 = 1; r = (*ctx->ops->opentoucs4)(ctx, &(ctx->private_data)); if (r != idn_success) { WARNING(("idn_converter_create(): open failed " "(local->ucs4)\n")); free(ctx); *ctxp = NULL; goto ret; } ctx->opened_convtoucs4 = 1; } *ctxp = ctx; r = idn_success; ret: TRACE(("idn_converter_create(): %s\n", idn_result_tostring(r))); return (r); }