str.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:8k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*****************************************************************************
  2.  *
  3.  * This program is free software ; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2 of the License, or
  6.  * (at your option) any later version.
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11.  * GNU General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this program; if not, write to the Free Software
  15.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  16.  *
  17.  * $Id: str.c 543 2006-01-07 22:06:24Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "common.h"
  24. typedef struct stringdef
  25. {
  26. int Class;
  27. int Id;
  28. // tchar_t s[]
  29. } stringdef;
  30. #define TABLEINIT 3072
  31. #define TABLEALIGN 1024
  32. #ifdef TARGET_PALMOS
  33. #define BUFFERSIZE 512*sizeof(tchar_t)
  34. #else
  35. #define BUFFERSIZE 2048*sizeof(tchar_t)
  36. #endif
  37. void StringAlloc()
  38. {
  39. context* p = Context();
  40. if (p->Lang != LANG_DEFAULT)
  41. ArrayAlloc(&p->StrTable[0],TABLEINIT,TABLEALIGN);
  42. ArrayAlloc(&p->StrTable[1],TABLEINIT,TABLEALIGN);
  43. p->StrLock = LockCreate();
  44. }
  45. void StringFree()
  46. {
  47. context* p = Context();
  48. array* i;
  49. for (i=ARRAYBEGIN(p->StrBuffer,array);i!=ARRAYEND(p->StrBuffer,array);++i)
  50. ArrayClear(i);
  51. ArrayClear(&p->StrTable[0]);
  52. ArrayClear(&p->StrTable[1]);
  53. ArrayClear(&p->StrBuffer);
  54. LockDelete(p->StrLock);
  55. p->StrLock = NULL;
  56. }
  57. static int CmpDef(const stringdef* const* pa, const stringdef* const* pb)
  58. {
  59. const stringdef* a = *pa;
  60. const stringdef* b = *pb;
  61. if (a->Class < b->Class || (a->Class == b->Class && a->Id < b->Id))
  62. return -1;
  63. if (a->Class > b->Class || a->Id > b->Id)
  64. return 1;
  65. return 0;
  66. }
  67. static void AddDef(context* p, bool_t Default, const stringdef* Def)
  68. {
  69. array* Table = &p->StrTable[Default?1:0];
  70. ArrayAdd(Table,ARRAYCOUNT(*Table,stringdef*),sizeof(stringdef*),&Def,(arraycmp)CmpDef,TABLEALIGN);
  71. }
  72. static void Filter(tchar_t* i)
  73. {
  74. tchar_t* j=i;
  75. for (;*i;++i,++j)
  76. {
  77. if (i[0]=='\' && i[1]=='n')
  78. {
  79. *j=10;
  80. ++i;
  81. }
  82. else
  83. *j=*i;
  84. }
  85. *j=0;
  86. }
  87. void StringAddText(const char* p, int n)
  88. {
  89. uint32_t UserLang = Context()->Lang;
  90. tchar_t* s = (tchar_t*)malloc(MAXLINE*sizeof(tchar_t));
  91. char* s8 = (char*)malloc(MAXLINE*sizeof(char));
  92. int CodePage = -1;
  93. uint32_t Lang = 0;
  94. tchar_t* q;
  95. int i,No;
  96. if (s && s8)
  97. {
  98. while (n>0)
  99. {
  100. for (;n>0 && (*p==9 || *p==32);++p,--n);
  101. for (i=0;n>0 && *p!=13 && *p!=10;++p,--n)
  102. if (i<MAXLINE-1)
  103. s8[i++] = *p;
  104. for (;n>0 && (*p==13 || *p==10);++p,--n)
  105. s8[i]=0;
  106. if (CodePage>=0 && s8[0]!='[' && s8[0]!=';')
  107. StrToTcsEx(s,MAXLINE,s8,CodePage);
  108. else
  109. AsciiToTcs(s,MAXLINE,s8);
  110. for (i=0;IsSpace(s[i]);++i);
  111. if (s[i]==0) continue;
  112. if (s[i]==';')
  113. {
  114. stscanf(s+i,T(";CODEPAGE = %d"),&CodePage);
  115. continue;
  116. }
  117. if (s[i]=='[')
  118. {
  119. ++i;
  120. q = tcschr(s+i,']');
  121. if (!q || CodePage<0) break; // invalid language file
  122. *q = 0;
  123. Lang = StringToFourCC(s+i,1);
  124. if (Lang == FOURCC('D','E','F','A'))
  125. Lang = LANG_DEFAULT;
  126. if (Lang != LANG_DEFAULT)
  127. {
  128. if (Lang != UserLang)
  129. break;
  130. Context()->CodePage = CodePage;
  131. }
  132. }
  133. else
  134. {
  135. q = tcschr(s+i,'=');
  136. if (!q || !Lang) break; // invalid language file
  137. *q = 0;
  138. ++q;
  139. if (tcslen(s+i)>4)
  140. {
  141. if (tcslen(s+i)<8)
  142. No = StringToFourCC(s+i+4,1);
  143. else
  144. {
  145. No = StringToInt(s+i+4,1);
  146. if (No >= 32768)
  147. No -= 65536;
  148. }
  149. }
  150. else
  151. No = 0;
  152. Filter(q);
  153. StringAdd(Lang==LANG_DEFAULT,StringToFourCC(s+i,1),No,q);
  154. }
  155. }
  156. }
  157. free(s);
  158. free(s8);
  159. }
  160. bool_t StringIsBinary(int Class,int Id)
  161. {
  162. bool_t Result = 1;
  163. context* p = Context();
  164. array* i;
  165. const tchar_t* Def = LangStrDef(Class,Id);
  166. if (Def[0])
  167. {
  168. LockEnter(p->StrLock);
  169. for (i=ARRAYBEGIN(p->StrBuffer,array);i!=ARRAYEND(p->StrBuffer,array);++i)
  170. if (ARRAYBEGIN(*i,const tchar_t)<=Def && ARRAYEND(*i,const tchar_t)>Def)
  171. {
  172. Result = 0;
  173. break;
  174. }
  175. LockLeave(p->StrLock);
  176. }
  177. return Result;
  178. }
  179. bool_t StringAddBinary(const void* Data, size_t Length)
  180. {
  181. context* p = Context();
  182. const uint8_t* Def = (const uint8_t*)Data + 2*sizeof(int);
  183. uint32_t Lang = *(const uint32_t*)Data;
  184. size_t Len;
  185. if (Lang != LANG_DEFAULT && Lang != p->Lang)
  186. return 0;
  187. LockEnter(p->StrLock);
  188. while (Length>sizeof(stringdef))
  189. {
  190. AddDef(p,Lang==LANG_DEFAULT,(const stringdef*)Def);
  191. Len = (tcslen((const tchar_t*)(Def+sizeof(stringdef)))+1)*sizeof(tchar_t);
  192. Len = sizeof(stringdef)+((Len+sizeof(int)-1) & ~(sizeof(int)-1));
  193. Def += Len;
  194. Length -= Len;
  195. }
  196. LockLeave(p->StrLock);
  197. return 1;
  198. }
  199. void StringAdd(bool_t Default, int Class, int Id, const tchar_t* s)
  200. {
  201. context* p = Context();
  202. int Pos,Len,Total;
  203. bool_t Found;
  204. array* Last = &p->StrTable[Default?1:0];
  205. stringdef Def;
  206. stringdef* Ptr = &Def;
  207. Def.Class = Class;
  208. Def.Id = Id;
  209. if (!s) s = T("");
  210. LockEnter(p->StrLock);
  211. // already the same?
  212. Pos = ArrayFind(Last,ARRAYCOUNT(*Last,stringdef*),sizeof(stringdef*),&Ptr,(arraycmp)CmpDef,&Found);
  213. if (Found && tcscmp(s,(tchar_t*)(ARRAYBEGIN(*Last,stringdef*)[Pos]+1))==0)
  214. {
  215. LockLeave(p->StrLock);
  216. return;
  217. }
  218. // add to buffer
  219. Len = (tcslen(s)+1)*sizeof(tchar_t);
  220. Total = sizeof(stringdef)+((Len+sizeof(int)-1) & ~(sizeof(int)-1));
  221. Last = ARRAYEND(p->StrBuffer,array)-1;
  222. if (ARRAYEMPTY(p->StrBuffer) || ARRAYCOUNT(*Last,uint8_t)+Total > ARRAYALLOCATED(*Last,uint8_t))
  223. {
  224. // add new buffer
  225. if (!ArrayAppend(&p->StrBuffer,NULL,sizeof(array),128))
  226. {
  227. LockLeave(p->StrLock);
  228. return;
  229. }
  230. Last = ARRAYEND(p->StrBuffer,array)-1;
  231. memset(Last,0,sizeof(array));
  232. if (!ArrayAlloc(Last,BUFFERSIZE,1))
  233. {
  234. LockLeave(p->StrLock);
  235. return;
  236. }
  237. }
  238. // no allocation needed here (can't fail)
  239. Ptr = (stringdef*)ARRAYEND(*Last,uint8_t);
  240. ArrayAppend(Last,&Def,sizeof(stringdef),1);
  241. ArrayAppend(Last,s,Len,1);
  242. ArrayAppend(Last,NULL,Total-Len-sizeof(stringdef),1);
  243. AddDef(p,Default,Ptr);
  244. LockLeave(p->StrLock);
  245. }
  246. void StringAddPrint(bool_t Default, int Class,int No,const tchar_t* Msg, ...)
  247. {
  248. tchar_t s[256];
  249. va_list Arg;
  250. va_start(Arg, Msg);
  251. vstprintf_s(s,TSIZEOF(s), Msg, Arg);
  252. va_end(Arg);
  253. StringAdd(Default,Class,No,s);
  254. }
  255. int LangEnum(int Class, int No)
  256. {
  257. int Result = 0;
  258. context* p = Context();
  259. stringdef **i;
  260. LockEnter(p->StrLock);
  261. for (i=ARRAYBEGIN(p->StrTable[1],stringdef*);i!=ARRAYEND(p->StrTable[1],stringdef*);++i)
  262. if ((*i)->Class==Class && No--==0)
  263. {
  264. Result = (*i)->Id;
  265. break;
  266. }
  267. LockLeave(p->StrLock);
  268. return Result;
  269. }
  270. const tchar_t* LangStr(int Class, int Id)
  271. {
  272. int n;
  273. context* p = Context();
  274. bool_t Found;
  275. stringdef Def;
  276. stringdef* Ptr = &Def;
  277. Def.Class = Class;
  278. Def.Id = Id;
  279. LockEnter(p->StrLock);
  280. for (n=0;n<2;++n)
  281. {
  282. int Pos = ArrayFind(&p->StrTable[n],ARRAYCOUNT(p->StrTable[n],stringdef*),
  283.                     sizeof(stringdef*),&Ptr,(arraycmp)CmpDef,&Found);
  284. if (Found)
  285. {
  286. LockLeave(p->StrLock);
  287. return (tchar_t*)(ARRAYBEGIN(p->StrTable[n],stringdef*)[Pos]+1);
  288. }
  289. }
  290. LockLeave(p->StrLock);
  291. return T("");
  292. }
  293. const tchar_t* LangStrDef(int Class, int Id)
  294. {
  295. int n;
  296. context* p = Context();
  297. bool_t Found;
  298. stringdef Def;
  299. stringdef* Ptr = &Def;
  300. Def.Class = Class;
  301. Def.Id = Id;
  302. LockEnter(p->StrLock);
  303. for (n=1;n>=0;--n)
  304. {
  305. int Pos = ArrayFind(&p->StrTable[n],ARRAYCOUNT(p->StrTable[n],stringdef*),
  306.                     sizeof(stringdef*),&Ptr,(arraycmp)CmpDef,&Found);
  307. if (Found)
  308. {
  309. LockLeave(p->StrLock);
  310. return (tchar_t*)(ARRAYBEGIN(p->StrTable[n],stringdef*)[Pos]+1);
  311. }
  312. }
  313. LockLeave(p->StrLock);
  314. return T("");
  315. }