123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- /***************************************************************************
- * *
- * _____ ____ *
- * | __ \ / __ \ _ _ _____ *
- * | | \ \ / / \_\ | | | | _ \ *
- * | | \ \| | | | | | |_| | *
- * | | | || | | | | | ___/ *
- * | | / /| | __ | | | | _ \ *
- * | |__/ / \ \__/ / | |___| | |_| | *
- * |_____/ \____/ |_____|_|_____/ *
- * *
- * Wiimms source code library *
- * *
- ***************************************************************************
- * *
- * Copyright (c) 2012-2022 by Dirk Clemens <wiimm@wiimm.de> *
- * *
- ***************************************************************************
- * *
- * This library is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This library is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * See file gpl-2.0.txt or http://www.gnu.org/licenses/gpl-2.0.txt *
- * *
- ***************************************************************************/
- #include "dclib-basics.h"
- #include "dclib-utf8.h"
- #include "dclib-punycode.h"
- #include <limits.h>
- #include "dclib-punycode.inc"
- //
- ///////////////////////////////////////////////////////////////////////////////
- /////////////// Domain2UTF8() ///////////////
- ///////////////////////////////////////////////////////////////////////////////
- uint Domain2UTF8
- (
- // returns the number of scanned bytes of 'source' or 0 on error
- char *buf, // valid destination buffer
- int buf_size, // size of 'buf' >= 4
- const void *source, // NULL or UTF-8 domain to translate
- int source_len // length of 'source'; if <0: use strlen(source)
- )
- {
- DASSERT(buf)
- DASSERT(source||!source_len);
- if ( buf_size < 4 || !source )
- return 0;
- if ( source_len < 0 )
- source_len = strlen(source);
- ccp src = source, src_end = source + source_len;
- char *buf_ptr = buf, *buf_end = buf + buf_size - 2;
- enum { MAX_LEN = 1000 };
- char name[MAX_LEN+10];
- punycode_uint pname[MAX_LEN+2];
- MARK_USED(name,pname);
- while ( src < src_end )
- {
- while ( buf_ptr < buf_end && src < src_end && *src == '.' )
- *buf_ptr++ = *src++;
- if ( buf_ptr >= buf_end )
- {
- if (!src)
- goto error;
- break;
- }
- if ( src >= src_end )
- break;
- ccp point = strchr(src,'.');
- if (!point)
- point = src_end;
- if ( src+4 > src_end || memcmp(src,"xn--",4 ))
- buf_ptr = StringCopyEM(buf_ptr,buf_end,src,point-src);
- else
- {
- src += 4;
- punycode_uint olen = MAX_LEN;
- const enum punycode_status stat
- = punycode_decode(point-src,src,&olen,pname,0);
- char *dest = name;
- if ( stat != punycode_success )
- dest = name + snprintf(name,sizeof(name),"!ERR=%d",stat);
- else
- {
- punycode_uint *src = pname, *src_end = pname + olen;
- char *dest_end = name + MAX_LEN;
- while ( src < src_end && dest < dest_end )
- dest = PrintUTF8Char(dest,*src++);
- *dest = 0;
- }
- buf_ptr = StringCopyEM(buf_ptr,buf_end,name,dest-name);
- }
- src = point;
- }
- *buf_ptr = 0;
- return src - (ccp)source;
- error:
- *buf = 0;
- return 0;
- }
- //
- ///////////////////////////////////////////////////////////////////////////////
- /////////////// Domain2ASCII() ///////////////
- ///////////////////////////////////////////////////////////////////////////////
- uint Domain2ASCII
- (
- // returns the number of scanned bytes of 'source' or 0 on error
- char *buf, // valid destination buffer
- int buf_size, // size of 'buf' >= 5
- const void *source, // NULL or ASCII domain to translate
- int source_len // length of 'source'; if <0: use strlen(source)
- )
- {
- DASSERT(buf)
- DASSERT(source||!source_len);
- if ( buf_size < 5 || !source )
- return 0;
- if ( source_len < 0 )
- source_len = strlen(source);
- ccp src = source, src_end = source + source_len;
- char *buf_ptr = buf, *buf_end = buf + buf_size - 5;
- enum { MAX_LEN = 1000 };
- char name[MAX_LEN+10];
- punycode_uint pname[MAX_LEN+2];
- while ( src < src_end )
- {
- while ( buf_ptr < buf_end && src < src_end && *src == '.' )
- *buf_ptr++ = *src++;
- if ( buf_ptr >= buf_end )
- {
- if (!src)
- goto error;
- break;
- }
- if ( src >= src_end )
- break;
- ccp point = strchr(src,'.');
- if (!point)
- point = src_end;
- punycode_uint *dest = pname, *dest_end = pname + MAX_LEN;
- while ( dest < dest_end && src < point )
- {
- u32 code = ScanUTF8AnsiCharE(&src,point);
- *dest++ = code;
- }
- punycode_uint olen = MAX_LEN;
- const enum punycode_status stat =
- punycode_encode(dest-pname,pname,0,&olen,name);
- if (stat)
- goto error;
- if ( olen > 0 && name[olen-1] == '-' )
- buf_ptr = StringCopyEM(buf_ptr,buf_end,name,olen-1);
- else
- {
- name[olen] = 0;
- buf_ptr = StringCat2E(buf_ptr,buf_end,"xn--",name);
- }
- }
- *buf_ptr = 0;
- return src - (ccp)source;
- error:
- *buf = 0;
- return 0;
- }
- //
- ///////////////////////////////////////////////////////////////////////////////
- /////////////// E N D ///////////////
- ///////////////////////////////////////////////////////////////////////////////
|