/fluffos/fliconv.c

https://github.com/quixadhal/bloodlines · C · 210 lines · 182 code · 28 blank · 0 comment · 31 complexity · 53418ae7778f57054b26638794d7c42c MD5 · raw file

  1. #include "fliconv.h"
  2. #include <errno.h>
  3. #include "std.h"
  4. #include "lpc_incl.h"
  5. #include "comm.h"
  6. #ifdef USE_ICONV
  7. struct translation *head;
  8. static struct translation *find_translator(const char *encoding){
  9. struct translation *cur = head;
  10. while(cur){
  11. if(!strcmp(cur->name, encoding))
  12. break;
  13. cur = cur->next;
  14. }
  15. return cur;
  16. }
  17. struct translation *get_translator(const char *encoding){
  18. struct translation *ret = find_translator(encoding);
  19. if(ret)
  20. return ret;
  21. ret = (struct translation *)MALLOC(sizeof(struct translation));
  22. char *name = (char *)MALLOC(strlen(encoding)+18+1);
  23. strcpy(name, encoding);
  24. #ifdef linux
  25. strcat(name, "//TRANSLIT//IGNORE");
  26. #endif
  27. ret->name = name;
  28. ret->incoming = iconv_open("UTF-8", encoding);
  29. ret->outgoing = iconv_open(name, "UTF-8");
  30. ret->next = 0;
  31. if(ret->incoming == (iconv_t)-1 || ret->outgoing == (iconv_t)-1){
  32. FREE(name);
  33. FREE(ret);
  34. return 0;
  35. }
  36. name[strlen(encoding)] = 0;
  37. if(!head)
  38. head = ret;
  39. else {
  40. struct translation *cur = head;
  41. while(cur->next)
  42. cur = cur->next;
  43. cur->next = ret;
  44. }
  45. return ret;
  46. }
  47. char *translate(iconv_t tr, const char *mes, int inlen, int *outlen){
  48. size_t len = inlen;
  49. size_t len2;
  50. unsigned char *tmp = (unsigned char *)mes;
  51. static char *res = 0;
  52. static size_t reslen = 0;
  53. char *tmp2;
  54. if(!res){
  55. res = (char *)MALLOC(1);
  56. reslen = 1;
  57. }
  58. tmp2 = res;
  59. len2 = reslen;
  60. while(len){
  61. iconv(tr, (char **)&tmp, &len, &tmp2, &len2);
  62. #ifdef PACKAGE_DWLIB
  63. if(len > 1 && tmp[0] == 0xff && tmp[1] == 0xf9){
  64. len -=2;
  65. tmp +=2;
  66. #else
  67. if(0){
  68. #endif
  69. } else {
  70. if(E2BIG == errno){
  71. errno = 0;
  72. tmp = (unsigned char *)mes;
  73. len = strlen(mes)+1;
  74. FREE(res);
  75. reslen *= 2;
  76. res = (char *)MALLOC(reslen);
  77. tmp2 = res;
  78. len2 = reslen;
  79. continue;
  80. }
  81. tmp2[0] = 0;
  82. *outlen = reslen - len2;
  83. return res;
  84. }
  85. }
  86. *outlen = reslen - len2;
  87. return res;
  88. }
  89. #else
  90. char *translate(iconv_t tr, const char *mes, int inlen, int *outlen){
  91. *outlen = inlen;
  92. return (char *)mes;
  93. }
  94. #endif
  95. char *translate_easy(iconv_t tr, char *mes){
  96. int dummy;
  97. char *res = translate(tr, mes, strlen(mes)+1, &dummy);
  98. return res;
  99. }
  100. #ifdef F_SET_ENCODING
  101. void f_set_encoding(){
  102. if(current_object->interactive){
  103. struct translation *newt = get_translator((char *)sp->u.string);
  104. if(newt){
  105. current_object->interactive->trans = newt;
  106. return;
  107. }
  108. }
  109. pop_stack();
  110. push_number(0);
  111. }
  112. #endif
  113. #ifdef F_TO_UTF8
  114. void f_to_utf8(){
  115. struct translation *newt = get_translator((char *)sp->u.string);
  116. pop_stack();
  117. if(!newt)
  118. error("unknown encoding");
  119. char *text = (char *)sp->u.string;
  120. char *translated = translate_easy(newt->incoming, text);
  121. pop_stack();
  122. copy_and_push_string(translated);
  123. }
  124. #endif
  125. #ifdef F_UTF8_TO
  126. void f_utf8_to(){
  127. struct translation *newt = get_translator((char *)sp->u.string);
  128. pop_stack();
  129. if(!newt)
  130. error("unknown encoding");
  131. char *text = (char *)sp->u.string;
  132. char *translated = translate_easy(newt->outgoing, text);
  133. pop_stack();
  134. copy_and_push_string(translated);
  135. }
  136. #endif
  137. #ifdef F_STR_TO_ARR
  138. void f_str_to_arr(){
  139. static struct translation *newt = 0;
  140. if(!newt){
  141. newt = get_translator("UTF-32");
  142. translate_easy(newt->outgoing, " ");
  143. }
  144. int len;
  145. int *trans = (int *)translate(newt->outgoing, sp->u.string, SVALUE_STRLEN(sp)+1, &len);
  146. len/=4;
  147. array_t *arr = allocate_array(len);
  148. while(len--)
  149. arr->item[len].u.number = trans[len];
  150. free_svalue(sp, "str_to_arr");
  151. put_array(arr);
  152. }
  153. #endif
  154. #ifdef F_ARR_TO_STR
  155. void f_arr_to_str(){
  156. static struct translation *newt = 0;
  157. if(!newt){
  158. newt = get_translator("UTF-32");
  159. }
  160. int len = sp->u.arr->size;
  161. int *in = (int *)MALLOC(sizeof(int)*(len+1));
  162. char *trans;
  163. in[len] = 0;
  164. while(len--)
  165. in[len] = sp->u.arr->item[len].u.number;
  166. trans = translate(newt->incoming, (char *)in, (sp->u.arr->size+1)*4, &len);
  167. FREE(in);
  168. pop_stack();
  169. copy_and_push_string(trans);
  170. }
  171. #endif
  172. #ifdef F_STRWIDTH
  173. void f_strwidth(){
  174. int len = SVALUE_STRLEN(sp);
  175. int width = 0;
  176. int i;
  177. for(i=0; i<len; i++)
  178. width += !(((sp->u.string[i]) & 0xc0) == 0x80);
  179. pop_stack();
  180. push_number(width);
  181. }
  182. #endif