c_src/ustring.c
ERL_NIF_TERM ustring_new(ErlNifEnv* env, int argc,
                         const ERL_NIF_TERM argv[]) {
    ErlNifBinary norm, in;
    int32_t size, used;
    UErrorCode ec = U_ZERO_ERROR;

    if(!enif_inspect_binary(env, argv[0], &in))
        return enif_make_badarg(env);
    size = in.size;

    do {
        if(!enif_alloc_binary_compat(env, size, &norm))
            return error_tuple(env, "failed to alloc normalized binary");

        used = unorm_normalize((UChar*)in.data, in.size/2, UNORM_NFC, 0,
                               (UChar*)norm.data, norm.size/2, &ec);
        if (ec == U_BUFFER_OVERFLOW_ERROR) {
            /* enlarge buffer if it was too small */
            enif_release_binary_compat(env, &norm);
            size = used*2;
        }
    } while (ec == U_BUFFER_OVERFLOW_ERROR);

    if (U_FAILURE(ec)) {
        enif_release_binary_compat(env, &norm);
        return error_tuple(env, u_errorName(ec));
    }

    if (used*2 != size) {
        /* shrink binary if it was too large */
        enif_realloc_binary_compat(env, &norm, used*2);
    }

    return enif_make_binary(env, &norm);
}
/*
 * Perform NFC normalization on the input string.
 * Inputs:
 *   0: binary(), the string to be normalized
 * Outputs (one of):
 *   binary(), normalized string
 *   {'error', Reason::string()}, something went wrong
 */
Perform NFC normalization on the input string.
Perform NFC normalization on the input string .
ERL_NIF_TERM ustring_new(ErlNifEnv* env, int argc,
                         const ERL_NIF_TERM argv[]) {
    ErlNifBinary norm, in;
    int32_t size, used;
    UErrorCode ec = U_ZERO_ERROR;
    if(!enif_inspect_binary(env, argv[0], &in))
        return enif_make_badarg(env);
    size = in.size;
    do {
        if(!enif_alloc_binary_compat(env, size, &norm))
            return error_tuple(env, "failed to alloc normalized binary");
        used = unorm_normalize((UChar*)in.data, in.size/2, UNORM_NFC, 0,
                               (UChar*)norm.data, norm.size/2, &ec);
        if (ec == U_BUFFER_OVERFLOW_ERROR) {
            enif_release_binary_compat(env, &norm);
            size = used*2;
        }
    } while (ec == U_BUFFER_OVERFLOW_ERROR);
    if (U_FAILURE(ec)) {
        enif_release_binary_compat(env, &norm);
        return error_tuple(env, u_errorName(ec));
    }
    if (used*2 != size) {
        enif_realloc_binary_compat(env, &norm, used*2);
    }
    return enif_make_binary(env, &norm);
}
ERL_NIF_TERM ustring_new ( ErlNifEnv * env , int argc , const ERL_NIF_TERM argv [ ] ) { ErlNifBinary norm , in ; int32_t size , used ; UErrorCode ec = U_ZERO_ERROR ; if ( ! enif_inspect_binary ( env , argv [ 0 ] , & in ) ) return enif_make_badarg ( env ) ; size = in . size ; do { if ( ! enif_alloc_binary_compat ( env , size , & norm ) ) return error_tuple ( env , " " ) ; used = unorm_normalize ( ( UChar * ) in . data , in . size / 2 , UNORM_NFC , 0 , ( UChar * ) norm . data , norm . size / 2 , & ec ) ; if ( ec == U_BUFFER_OVERFLOW_ERROR ) { enif_release_binary_compat ( env , & norm ) ; size = used * 2 ; } } while ( ec == U_BUFFER_OVERFLOW_ERROR ) ; if ( U_FAILURE ( ec ) ) { enif_release_binary_compat ( env , & norm ) ; return error_tuple ( env , u_errorName ( ec ) ) ; } if ( used * 2 != size ) { enif_realloc_binary_compat ( env , & norm , used * 2 ) ; } return enif_make_binary ( env , & norm ) ; }
Perform NFC normalization on the input string.
Perform NFC normalization on the input string .
/* enlarge buffer if it was too small */ /* shrink binary if it was too large */