- char psz_enc[3 * strlen( psz_url ) + 1], *out = psz_enc;
- const uint8_t *in;
-
- for( in = (const uint8_t *)psz_url; *in; in++ )
- {
- uint8_t c = *in;
-
- if( isurlsafe( c ) )
- {
- *out++ = (char)c;
- }
- else
- {
- uint16_t cp;
-
- *out++ = '%';
- /* UTF-8 to UCS-2 conversion */
- if( ( c & 0x80 ) == 0 )
- {
- cp = c;
- }
- else if( ( c & 0xe0 ) == 0xc0 )
- {
- cp = (((uint16_t)c & 0x1f) << 6) | (in[1] & 0x3f);
- in++;
- }
- else if( ( c & 0xf0 ) == 0xe0 )
- {
- cp = (((uint16_t)c & 0xf) << 12) | (((uint16_t)(in[1]) & 0x3f) << 6) | (in[2] & 0x3f);
- in += 2;
- }
- else
- {
- /* cannot URL-encode code points outside the BMP */
- /* better a wrong conversion than a crash */
- cp = '?';
- }
-
- if( cp < 0xff )
- {
- /* Encode ISO-8859-1 characters */
- *out++ = url_hexchar( cp >> 4 );
- *out++ = url_hexchar( cp & 0xf );
- }
- else
- {
- /* Encode non-Latin-1 characters */
- *out++ = 'u';
- *out++ = url_hexchar( cp >> 12 );
- *out++ = url_hexchar((cp >> 8) & 0xf );
- *out++ = url_hexchar((cp >> 4) & 0xf );
- *out++ = url_hexchar( cp & 0xf );
- }
- }
- }
- *out++ = '\0';
-
- return strdup( psz_enc );