17898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project/*
27898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Copyright (C) 2009 The Android Open Source Project
37898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project *
47898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
57898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * you may not use this file except in compliance with the License.
67898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * You may obtain a copy of the License at
77898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project *
87898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
97898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project *
107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * See the License for the specific language governing permissions and
147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project * limitations under the License.
157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project */
167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project#include <stdlib.h>
187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project#include "../include/utf16char.h"
197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectnamespace ime_pinyin {
217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project#ifdef __cplusplus
237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Projectextern "C" {
247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project#endif
257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project  char16* utf16_strtok(char16 *utf16_str, size_t *token_size,
277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project                       char16 **utf16_str_next) {
287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    if (NULL == utf16_str || NULL == token_size || NULL == utf16_str_next) {
297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      return NULL;
307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    // Skip the splitters
337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    size_t pos = 0;
347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    while ((char16)' ' == utf16_str[pos] || (char16)'\n' == utf16_str[pos]
357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project           || (char16)'\t' == utf16_str[pos])
367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      pos++;
377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    utf16_str += pos;
397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    pos = 0;
407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    while ((char16)'\0' != utf16_str[pos] && (char16)' ' != utf16_str[pos]
427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project           && (char16)'\n' != utf16_str[pos]
437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project           && (char16)'\t' != utf16_str[pos]) {
447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      pos++;
457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    char16 *ret_val = utf16_str;
487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    if ((char16)'\0' == utf16_str[pos]) {
497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      *utf16_str_next = NULL;
507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      if (0 == pos)
517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        return NULL;
527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    } else {
537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      *utf16_str_next = utf16_str + pos + 1;
547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    utf16_str[pos] = (char16)'\0';
577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    *token_size = pos;
587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    return ret_val;
607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project  }
617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project  int utf16_atoi(const char16 *utf16_str) {
637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    if (NULL == utf16_str)
647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      return 0;
657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    int value = 0;
677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    int sign = 1;
687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    size_t pos = 0;
697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    if ((char16)'-' == utf16_str[pos]) {
717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      sign = -1;
727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      pos++;
737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    while ((char16)'0' <=  utf16_str[pos] &&
767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project           (char16)'9' >= utf16_str[pos]) {
777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      value = value * 10 + static_cast<int>(utf16_str[pos] - (char16)'0');
787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      pos++;
797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    return value*sign;
827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project  }
837898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
847898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project  float utf16_atof(const char16 *utf16_str) {
857898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    // A temporary implemetation.
867898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    char char8[256];
877898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    if (utf16_strlen(utf16_str) >= 256) return 0;
887898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
897898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    utf16_strcpy_tochar(char8, utf16_str);
907898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    return atof(char8);
917898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project  }
927898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
937898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project  size_t utf16_strlen(const char16 *utf16_str) {
947898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    if (NULL == utf16_str)
957898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      return 0;
967898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
977898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    size_t size = 0;
987898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    while ((char16)'\0' != utf16_str[size])
997898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      size++;
1007898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    return size;
1017898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project  }
1027898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1037898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project  int utf16_strcmp(const char16* str1, const char16* str2) {
1047898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    size_t pos = 0;
1057898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    while (str1[pos] == str2[pos] && (char16)'\0' != str1[pos])
1067898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      pos++;
1077898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1087898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    return static_cast<int>(str1[pos]) - static_cast<int>(str2[pos]);
1097898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project  }
1107898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1117898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project  int utf16_strncmp(const char16 *str1, const char16 *str2, size_t size) {
1127898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    size_t pos = 0;
1137898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    while (pos < size && str1[pos] == str2[pos] && (char16)'\0' != str1[pos])
1147898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      pos++;
1157898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1167898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    if (pos == size)
1177898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      return 0;
1187898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1197898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    return static_cast<int>(str1[pos]) - static_cast<int>(str2[pos]);
1207898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project  }
1217898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1227898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project  // we do not consider overlapping
1237898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project  char16* utf16_strcpy(char16 *dst, const char16 *src) {
1247898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    if (NULL == src || NULL == dst)
1257898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      return NULL;
1267898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1277898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    char16* cp = dst;
1287898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1297898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    while ((char16)'\0' != *src) {
1307898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      *cp = *src;
1317898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      cp++;
1327898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      src++;
1337898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
1347898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1357898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    *cp = *src;
1367898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1377898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    return dst;
1387898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project  }
1397898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1407898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project  char16* utf16_strncpy(char16 *dst, const char16 *src, size_t size) {
1417898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    if (NULL == src || NULL == dst || 0 == size)
1427898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      return NULL;
1437898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1447898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    if (src == dst)
1457898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      return dst;
1467898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1477898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    char16* cp = dst;
1487898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1497898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    if (dst < src || (dst > src && dst >= src + size)) {
1507898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      while (size-- && (*cp++ = *src++))
1517898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        ;
1527898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    } else {
1537898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      cp += size - 1;
1547898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      src += size - 1;
1557898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      while (size-- && (*cp-- == *src--))
1567898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project        ;
1577898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
1587898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    return dst;
1597898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project  }
1607898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1617898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project  // We do not handle complicated cases like overlapping, because in this
1627898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project  // codebase, it is not necessary.
1637898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project  char* utf16_strcpy_tochar(char *dst, const char16 *src) {
1647898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    if (NULL == src || NULL == dst)
1657898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      return NULL;
1667898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1677898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    char* cp = dst;
1687898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1697898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    while ((char16)'\0' != *src) {
1707898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      *cp = static_cast<char>(*src);
1717898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      cp++;
1727898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project      src++;
1737898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    }
1747898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    *cp = *src;
1757898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1767898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project    return dst;
1777898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project  }
1787898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project
1797898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project#ifdef __cplusplus
1807898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project}
1817898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project#endif
1827898d76cc005bbe1c5893a9f57439561e0771ccThe Android Open Source Project}  // namespace ime_pinyin
183