string_unicode.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. #define STRICT
  2. #include <windows.h>
  3. #include <stdio.h>
  4. #include "string_unicode.h"
  5. static bool is_nt()
  6. {
  7. OSVERSIONINFO os;
  8. memset(&os,0,sizeof(os));
  9. os.dwOSVersionInfoSize=sizeof(os);
  10. GetVersionEx(&os);
  11. return os.dwPlatformId == VER_PLATFORM_WIN32_NT;
  12. }
  13. void string_w::s_GetWindowText(HWND w)
  14. {
  15. if (!is_nt())
  16. {
  17. set_string_a(string_a(w));
  18. }
  19. else
  20. {
  21. reset();
  22. int len=GetWindowTextLengthW(w)+1;
  23. GetWindowTextW(w,string_buffer_w(*this,len),len);
  24. }
  25. }
  26. void string_w::set_string_a(const char * c)
  27. {
  28. int len= (int)strlen(c)+1;
  29. MultiByteToWideChar(CP_ACP,0,c,-1,string_buffer_w(*this,len),len);
  30. }
  31. void string_w::add_string_a(const char * c)
  32. {
  33. add_string(string_w(c));
  34. }
  35. void string_w::s_SetWindowText(HWND w)
  36. {
  37. if (!is_nt())
  38. {
  39. string_a(*this).s_SetWindowText(w);
  40. }
  41. else
  42. {
  43. SetWindowTextW(w,*this);
  44. }
  45. }
  46. void string_a::set_string_w(const WCHAR * c)
  47. {
  48. int len=((int)wcslen(c)+1)*2;
  49. WideCharToMultiByte(CP_ACP,0,c,-1,string_buffer_a(*this,len),len,0,0);
  50. }
  51. void string_a::add_string_w(const WCHAR * c)
  52. {
  53. add_string(string_a(c));
  54. }
  55. //utf8 stuff
  56. static const BYTE mask_tab[6]={0x80,0xE0,0xF0,0xF8,0xFC,0xFE};
  57. static const BYTE val_tab[6]={0,0xC0,0xE0,0xF0,0xF8,0xFC};
  58. static int utf82wide(int *wide,const BYTE *utf8)
  59. {
  60. int res=0;
  61. int n;
  62. int cnt=0;
  63. while(1)
  64. {
  65. if ((*utf8&mask_tab[cnt])==val_tab[cnt]) break;
  66. if (++cnt==6) return 0;
  67. }
  68. cnt++;
  69. if (cnt==2 && !(*utf8&0x1E)) return 0;
  70. if (cnt==1)
  71. res=*utf8;
  72. else
  73. res=(0xFF>>(cnt+1))&*utf8;
  74. for (n=1;n<cnt;n++)
  75. {
  76. if ((utf8[n]&0xC0) != 0x80)
  77. return 0;
  78. if (!res && n==2 && !((utf8[n]&0x7F) >> (7 - cnt)))
  79. return 0;
  80. res=(res<<6)|(utf8[n]&0x3F);
  81. }
  82. if (wide)
  83. *wide=res;
  84. return cnt;
  85. }
  86. static int wide2utf8(char *target, int wide,int max)
  87. {
  88. int count;
  89. if (wide < 0x80)
  90. count = 1;
  91. else if (wide < 0x800)
  92. count = 2;
  93. else if (wide < 0x10000)
  94. count = 3;
  95. else if (wide < 0x200000)
  96. count = 4;
  97. else if (wide < 0x4000000)
  98. count = 5;
  99. else if (wide <= 0x7FFFFFFF)
  100. count = 6;
  101. else
  102. return 0;
  103. if (count>max) return 0;
  104. if (target == 0)
  105. return count;
  106. switch (count)
  107. {
  108. case 6:
  109. target[5] = 0x80 | (wide & 0x3F);
  110. wide = wide >> 6;
  111. wide |= 0x4000000;
  112. case 5:
  113. target[4] = 0x80 | (wide & 0x3F);
  114. wide = wide >> 6;
  115. wide |= 0x200000;
  116. case 4:
  117. target[3] = 0x80 | (wide & 0x3F);
  118. wide = wide >> 6;
  119. wide |= 0x10000;
  120. case 3:
  121. target[2] = 0x80 | (wide & 0x3F);
  122. wide = wide >> 6;
  123. wide |= 0x800;
  124. case 2:
  125. target[1] = 0x80 | (wide & 0x3F);
  126. wide = wide >> 6;
  127. wide |= 0xC0;
  128. case 1:
  129. target[0] = wide;
  130. }
  131. return count;
  132. }
  133. void string_w::add_string_utf8(const char * z)
  134. {
  135. string_w temp;
  136. temp.set_string_utf8(z);
  137. add_string(temp);
  138. }
  139. void string_w::set_string_utf8(const char * src)
  140. //static int UTF8ToWide(const char* src,WCHAR* dst,int len,int out_len)
  141. {
  142. int cur_wchar;
  143. for(;;)
  144. {
  145. cur_wchar=0;
  146. int t=utf82wide(&cur_wchar,(const BYTE*)src);
  147. if (!t || !cur_wchar || cur_wchar>0xFFFF) break;
  148. src+=t;
  149. add_char((WCHAR)cur_wchar);
  150. }
  151. }
  152. string_printf_a::string_printf_a(const char * fmt,...)
  153. {
  154. va_list list;
  155. va_start(list,fmt);
  156. vsprintf(string_buffer_a(*this,1024),fmt,list);
  157. va_end(list);
  158. }
  159. string_printf_w::string_printf_w(const WCHAR * fmt,...)
  160. {
  161. va_list list;
  162. va_start(list,fmt);
  163. vswprintf(string_buffer_w(*this,1024),1024,fmt,list);
  164. va_end(list);
  165. }
  166. string_a::string_a(const string_w & z) {add_string_w(z);}
  167. void string_utf8::convert(const WCHAR * src)
  168. {
  169. char temp[8] = {0};
  170. while(src && *src)
  171. {
  172. int len=wide2utf8(temp,*src,7);
  173. if (!len) break;
  174. temp[len]=0;
  175. add_string(temp);
  176. src++;
  177. }
  178. }
  179. bool string_w::reg_read(HKEY hk,const WCHAR * name)
  180. {
  181. if (!is_nt())
  182. {
  183. string_a temp(*this);
  184. if (temp.reg_read(hk,string_a(name)))
  185. {
  186. set_string_a(temp);
  187. return 1;
  188. }
  189. else return 0;
  190. }
  191. else
  192. {
  193. DWORD sz=0,t=0;
  194. if (RegQueryValueExW(hk,name,0,&t,0,&sz)!=ERROR_SUCCESS) return 0;
  195. if (sz==0 || t!=REG_SZ) return 0;
  196. RegQueryValueExW(hk,name,0,0,(BYTE*)buffer_get(sz>>1),&sz);
  197. buffer_done();
  198. return 1;
  199. }
  200. }
  201. void string_w::reg_write(HKEY hk,const WCHAR * name)
  202. {
  203. if (!is_nt())
  204. {
  205. string_a(*this).reg_write(hk,string_a(name));
  206. }
  207. else
  208. {
  209. RegSetValueExW(hk,name,0,REG_SZ,(const BYTE*)(const WCHAR*)*this,((DWORD)length()+1)*2);
  210. }
  211. }
  212. bool string_w::test_os() {return is_nt();}