Exemple #1
0
enum punycode_status punycode_encode(
    punycode_uint input_length,
    const punycode_uint input[],
    const unsigned char case_flags[],
    punycode_uint *output_length,
    char output[] )
{
    punycode_uint n, delta, h, b, out, max_out, bias, j, m, q, k, t;

    /* Initialize the state: */

    n = initial_n;
    delta = out = 0;
    max_out = *output_length;
    bias = initial_bias;

    /* Handle the basic code points: */

    for (j = 0;  j < input_length;  ++j) {
        if (basic(input[j])) {
            if (max_out - out < 2) return punycode_big_output;
            output[out++] = (char)
                            (case_flags ?  encode_basic(input[j], case_flags[j]) : input[j]);
        }
        /* else if (input[j] < n) return punycode_bad_input; */
        /* (not needed for Punycode with unsigned code points) */
    }

    h = b = out;

    /* h is the number of code points that have been handled, b is the  */
    /* number of basic code points, and out is the number of characters */
    /* that have been output.                                           */

    if (b > 0) output[out++] = delimiter;

    /* Main encoding loop: */

    while (h < input_length) {
        /* All non-basic code points < n have been     */
        /* handled already.  Find the next larger one: */

        for (m = maxint, j = 0;  j < input_length;  ++j) {
            /* if (basic(input[j])) continue; */
            /* (not needed for Punycode) */
            if (input[j] >= n && input[j] < m) m = input[j];
        }

        /* Increase delta enough to advance the decoder's    */
        /* <n,i> state to <m,0>, but guard against overflow: */

        if (m - n > (maxint - delta) / (h + 1)) return punycode_overflow;
        delta += (m - n) * (h + 1);
        n = m;

        for (j = 0;  j < input_length;  ++j) {
            /* Punycode does not need to check whether input[j] is basic: */
            if (input[j] < n /* || basic(input[j]) */ ) {
                if (++delta == 0) return punycode_overflow;
            }

            if (input[j] == n) {
                /* Represent delta as a generalized variable-length integer: */

                for (q = delta, k = base;  ;  k += base) {
                    if (out >= max_out) return punycode_big_output;
                    t = k <= bias /* + tmin */ ? tmin :     /* +tmin not needed */
                        k >= bias + tmax ? tmax : k - bias;
                    if (q < t) break;
                    output[out++] = encode_digit(t + (q - t) % (base - t), 0);
                    q = (q - t) / (base - t);
                }

                output[out++] = encode_digit(q, case_flags && case_flags[j]);
                bias = adapt(delta, h + 1, h == b);
                delta = 0;
                ++h;
            }
        }

        ++delta, ++n;
    }

    *output_length = out;
    return punycode_success;
}
bool new_entry(                                                                 //don't use this directly, use the macros!
    frontend&          fe,
    sev::severity      sv,
    proto::str_literal fmt,
    A                  a,
    B                  b,
    C                  c,
    D                  d,
    E                  e,
    F                  f,
    G                  g,
    H                  h,
    I                  i,
    J                  j,
    K                  k,
    L                  l,
    M                  m,
    N                  n
    )
{
    typedef proto::encoder::null_type null_type;
    const uword arity = 1 +
            (std::is_same<A, null_type>::value ? 0 : 1) +
            (std::is_same<B, null_type>::value ? 0 : 1) +
            (std::is_same<C, null_type>::value ? 0 : 1) +
            (std::is_same<D, null_type>::value ? 0 : 1) +
            (std::is_same<E, null_type>::value ? 0 : 1) +
            (std::is_same<F, null_type>::value ? 0 : 1) +
            (std::is_same<G, null_type>::value ? 0 : 1) +
            (std::is_same<H, null_type>::value ? 0 : 1) +
            (std::is_same<I, null_type>::value ? 0 : 1) +
            (std::is_same<J, null_type>::value ? 0 : 1) +
            (std::is_same<K, null_type>::value ? 0 : 1) +
            (std::is_same<L, null_type>::value ? 0 : 1) +
            (std::is_same<M, null_type>::value ? 0 : 1) +
            (std::is_same<N, null_type>::value ? 0 : 1)
            ;

    uword length = proto::encoder::required_bytes_arity1(); //1
    length      += proto::encoder::required_bytes (a);      //2
    length      += proto::encoder::required_bytes (b);      //3
    length      += proto::encoder::required_bytes (c);      //4
    length      += proto::encoder::required_bytes (d);      //5
    length      += proto::encoder::required_bytes (e);      //6
    length      += proto::encoder::required_bytes (f);      //7
    length      += proto::encoder::required_bytes (g);      //8
    length      += proto::encoder::required_bytes (h);      //9
    length      += proto::encoder::required_bytes (i);      //10
    length      += proto::encoder::required_bytes (j);      //11
    length      += proto::encoder::required_bytes (k);      //12
    length      += proto::encoder::required_bytes (l);      //13
    length      += proto::encoder::required_bytes (m);      //14
    length      += proto::encoder::required_bytes (n);      //15
    auto enc = fe.get_encoder (length);
    if (enc.can_encode())
    {
        enc.encode_basic (sv, arity, fmt);
        if (!enc.encode (a)) { goto overflow; }
        if (!enc.encode (b)) { goto overflow; }
        if (!enc.encode (c)) { goto overflow; }
        if (!enc.encode (d)) { goto overflow; }
        if (!enc.encode (e)) { goto overflow; }
        if (!enc.encode (f)) { goto overflow; }
        if (!enc.encode (g)) { goto overflow; }
        if (!enc.encode (h)) { goto overflow; }
        if (!enc.encode (i)) { goto overflow; }
        if (!enc.encode (j)) { goto overflow; }
        if (!enc.encode (k)) { goto overflow; }
        if (!enc.encode (l)) { goto overflow; }
        if (!enc.encode (m)) { goto overflow; }
        if (!enc.encode (n)) { goto overflow; }
        fe.push_encoded (enc);
        return true;
    }
    log_error_call ("couldn't allocate encoder\n");
    return false;
overflow:
    fe.push_encoded (enc);
    log_error_call ("overflow when encoding\n");
    assert (false && "bug!");                                                   //The size is precomputed, so this should be unreachable.
    return false;
}