diff options
author | Andrei Zmievski <andrei@php.net> | 2006-06-13 23:46:04 +0000 |
---|---|---|
committer | Andrei Zmievski <andrei@php.net> | 2006-06-13 23:46:04 +0000 |
commit | a093762a6fd2fa1a4e0fe6754fa9432d8ed2cc16 (patch) | |
tree | b2025ba23bb415ed493db9a94f704036221feab2 /ext/unicode/transform.c | |
parent | b5f20ceb4843affaad918ab55e46c0a385d71c23 (diff) | |
download | php-git-a093762a6fd2fa1a4e0fe6754fa9432d8ed2cc16.tar.gz |
transliterate()
Diffstat (limited to 'ext/unicode/transform.c')
-rw-r--r-- | ext/unicode/transform.c | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/ext/unicode/transform.c b/ext/unicode/transform.c new file mode 100644 index 0000000000..bad23ff66f --- /dev/null +++ b/ext/unicode/transform.c @@ -0,0 +1,112 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 6 | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Andrei Zmievski <andrei@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#include "php_unicode.h" + +PHP_FUNCTION(transliterate) +{ + UChar *str, *from, *to, *variant = NULL; + int str_len, from_len, to_len, variant_len = 0; + UChar id[256]; + int id_len; + UChar *result = NULL; + int result_len = 0; + UTransliterator *trans = NULL; + UErrorCode status = U_ZERO_ERROR; + int32_t capacity, start, limit; + + /* + { + + char *str; + int32_t str_len; + UEnumeration *ids; + + ids = utrans_openIDs(&status); + printf("%d\n", uenum_count(ids, &status)); + str = (char*)uenum_next(ids, &str_len, &status); + while (str) { + printf("id: %s\n", str); + str = (char*)uenum_next(ids, &str_len, &status); + } + uenum_close(ids); + } + + return; + */ + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "uuu|u", &str, + &str_len, &from, &from_len, &to, &to_len, + &variant, &variant_len) == FAILURE) { + return; + } + + if (variant) { + id_len = u_snprintf(id, sizeof(id)-1, "%S-%S/%S", from, to, variant); + } else { + id_len = u_snprintf(id, sizeof(id)-1, "%S-%S", from, to); + } + + if (id_len < 0) { + php_error_docref("", E_WARNING, "Transliterator ID too long"); + return; + } + + id[id_len] = 0; + + trans = utrans_openU(id, id_len, UTRANS_FORWARD, NULL, 0, NULL, &status); + if (U_FAILURE(status)) { + php_error_docref("", E_WARNING, "Failed to create transliterator"); + return; + } + + result = eustrndup(str, str_len); + result_len = limit = str_len; + capacity = str_len + 1; + + while (1) { + utrans_transUChars(trans, result, &result_len, capacity, 0, &limit, &status); + if (status == U_BUFFER_OVERFLOW_ERROR) { + result = eurealloc(result, result_len + 1); + memcpy(result, str, UBYTES(str_len)); + capacity = result_len + 1; + result_len = limit = str_len; + status = U_ZERO_ERROR; + utrans_transUChars(trans, result, &result_len, capacity, 0, &limit, &status); + } else { + if (status == U_STRING_NOT_TERMINATED_WARNING) { + result = eurealloc(result, result_len + 1); + } + break; + } + } + + result[result_len] = 0; + utrans_close(trans); + + RETURN_UNICODEL(result, result_len, 0); +} + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ |