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; }