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

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: tchar.c 271 2005-08-09 08:31:35Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "common.h"
  24. void tcscpy_s(tchar_t* Out,size_t OutLen,const tchar_t* In)
  25. {
  26. if (OutLen>0)
  27. {
  28. size_t n = min(tcslen(In),OutLen-1);
  29. memcpy(Out,In,n*sizeof(tchar_t));
  30. Out[n] = 0;
  31. }
  32. }
  33. void tcsncpy_s(tchar_t* Out,size_t OutLen,const tchar_t* In,size_t n)
  34. {
  35. if (OutLen>0)
  36. {
  37. n = min(min(tcslen(In),n),OutLen-1);
  38. memcpy(Out,In,n*sizeof(tchar_t));
  39. Out[n] = 0;
  40. }
  41. }
  42. void tcscat_s(tchar_t* Out,size_t OutLen,const tchar_t* In)
  43. {
  44. if (OutLen>0)
  45. {
  46. size_t n = tcslen(Out);
  47. tcscpy_s(Out+n,OutLen-n,In);
  48. }
  49. }
  50. tchar_t* tcsdup(const tchar_t* s)
  51. {
  52. size_t n = tcslen(s)+1;
  53. tchar_t* p = (tchar_t*)malloc(n*sizeof(tchar_t));
  54. if (p) tcscpy_s(p,n,s);
  55. return p;
  56. }
  57. void StrToTcs(tchar_t* Out,size_t OutLen,const char* In)
  58. {
  59. StrToTcsEx(Out,OutLen,In,Context()->CodePage);
  60. }
  61. void TcsToStr(char* Out,size_t OutLen,const tchar_t* In)
  62. {
  63. TcsToStrEx(Out,OutLen,In,Context()->CodePage);
  64. }
  65. void BoolToString(tchar_t* Out, size_t OutLen, bool_t Bool)
  66. {
  67. tcscpy_s(Out,OutLen,LangStrDef(PLATFORM_ID,Bool?PLATFORM_YES:PLATFORM_NO));
  68. };
  69. uint32_t StringToFourCC(const tchar_t* In, bool_t Upper)
  70. {
  71. char s[4+1];
  72. tchar_t Up[4+1];
  73. int i;
  74. if (Upper)
  75. {
  76. tcscpy_s(Up,TSIZEOF(Up),In);
  77. tcsupr(Up);
  78. In = Up;
  79. }
  80. TcsToAscii(s,sizeof(s),In);
  81. for (i=0;i<4;++i)
  82. if (!s[i])
  83. for (;i<4;++i)
  84. s[i] = '_';
  85. return FOURCC(s[0],s[1],s[2],s[3]);
  86. }
  87. void FourCCToString(tchar_t* Out, size_t OutLen, uint32_t FourCC)
  88. {
  89. uint32_t s[2];
  90. s[0] = FourCC;
  91. s[1] = 0;
  92. AsciiToTcs(Out,OutLen,(char*)s);
  93. }
  94. uint32_t UpperFourCC(uint32_t FourCC)
  95. {
  96. return (toupper((FourCC >> 0) & 255) << 0) |
  97.    (toupper((FourCC >> 8) & 255) << 8) |
  98.    (toupper((FourCC >> 16) & 255) << 16) |
  99.    (toupper((FourCC >> 24) & 255) << 24);
  100. }
  101. // gcc 2.97 bug...
  102. static const tchar_t mask_d[] = T("%d");
  103. static const tchar_t mask_X[] = T("%X");
  104. static const tchar_t mask_0x08X[] = T("0x%08X");
  105. void FractionToString(tchar_t* Out, size_t OutLen, const fraction* p, bool_t Percent, int Decimal)
  106. {
  107. int a,b,i;
  108. int Num = p->Num;
  109. int Den = p->Den;
  110. if (Percent)
  111. {
  112. while (abs(Num) > MAX_INT/100)
  113. {
  114. Num >>= 1;
  115. Den >>= 1;
  116. }
  117. Num *= 100;
  118. }
  119. if (Den)
  120. {
  121. if (Den<0)
  122. {
  123. Num = -Num;
  124. Den = -Den;
  125. }
  126. for (i=0,b=1;i<Decimal;++i,b*=10);
  127. if (Num>0)
  128. {
  129. // rounding
  130. a = Den/(2*b);
  131. if (Num<MAX_INT-a)
  132. Num += a;
  133. else
  134. Num = MAX_INT;
  135. }
  136. a=Num/Den;
  137. Num -= a*Den;
  138. b=(int)(((int64_t)Num*b)/Den);
  139. }
  140. else
  141. a=b=0;
  142. if (Decimal)
  143. stprintf_s(Out,OutLen,T("%d.%0*d"),a,Decimal,b);
  144. else
  145. stprintf_s(Out,OutLen,mask_d,a);
  146. if (Percent)
  147. tcscat_s(Out,OutLen,T("%"));
  148. }
  149. int StringToInt(const tchar_t* In, bool_t Hex)
  150. {
  151. int v=0;
  152. stscanf(In,Hex ? mask_X:mask_d,&v);
  153. return v;
  154. }
  155. void IntToString(tchar_t* Out, size_t OutLen, int p, bool_t Hex)
  156. {
  157. stprintf_s(Out,OutLen,Hex ? mask_0x08X:mask_d,p);
  158. }
  159. void TickToString(tchar_t* Out, size_t OutLen, tick_t Tick, bool_t MS, bool_t Extended, bool_t Fix)
  160. {
  161. tchar_t Sign[2] = {0};
  162. if (Tick<0) 
  163. {
  164. Sign[0] = '-';
  165. Tick = -Tick;
  166. }
  167. if (!MS)
  168. {
  169. int Hour,Min,Sec;
  170. Hour = Tick / 3600 / TICKSPERSEC;
  171. Tick -= Hour * 3600 * TICKSPERSEC;
  172. Min = Tick / 60 / TICKSPERSEC;
  173. Tick -= Min * 60 * TICKSPERSEC;
  174. Sec = Tick / TICKSPERSEC;
  175. Tick -= Sec * TICKSPERSEC;
  176. if (Hour)
  177. stprintf_s(Out,OutLen,T("%s%d:%02d"),Sign,Hour,Min);
  178. else
  179. stprintf_s(Out,OutLen,Fix?T("%s%02d"):T("%s%d"),Sign,Min);
  180. stcatprintf_s(Out,OutLen,T(":%02d"),Sec);
  181. if (Extended)
  182. stcatprintf_s(Out,OutLen,T(".%03d"),(Tick*1000)/TICKSPERSEC);
  183. }
  184. else
  185. {
  186. int i = Scale(Tick,100000,TICKSPERSEC);
  187. stprintf_s(Out,OutLen,T("%s%d.%02d ms"),Sign,i/100,i%100);
  188. }
  189. }
  190. void stprintf_s(tchar_t* Out,size_t OutLen,const tchar_t* Mask, ...)
  191. {
  192. va_list Arg;
  193. va_start(Arg, Mask);
  194. vstprintf_s(Out,OutLen,Mask,Arg);
  195. va_end(Arg);
  196. }
  197. void stcatprintf_s(tchar_t* Out,size_t OutLen,const tchar_t* Mask, ...)
  198. {
  199. size_t n = tcslen(Out);
  200. va_list Arg;
  201. va_start(Arg, Mask);
  202. vstprintf_s(Out+n,OutLen-n,Mask,Arg);
  203. va_end(Arg);
  204. }
  205. void vstprintf_s(tchar_t* Out,size_t OutLen,const tchar_t* Mask,va_list Arg)
  206. {
  207. int n,vs,Width;
  208. unsigned int v,w,q,w0;
  209. bool_t ZeroFill;
  210. bool_t Unsigned;
  211. bool_t Sign;
  212. bool_t AlignLeft;
  213. const tchar_t *In;
  214. while (OutLen>1 && *Mask)
  215. {
  216. switch (*Mask)
  217. {
  218. case '%':
  219. ++Mask;
  220. if (*Mask == '%')
  221. {
  222. *(Out++) = *(Mask++);
  223. --OutLen;
  224. break;
  225. }
  226. AlignLeft = *Mask=='-';
  227. if (AlignLeft)
  228. ++Mask;
  229. ZeroFill = *Mask=='0';
  230. if (ZeroFill) 
  231. ++Mask;
  232. Width = -1;
  233. if (IsDigit(*Mask))
  234. {
  235. Width = 0;
  236. for (;IsDigit(*Mask);++Mask)
  237. Width = Width*10 + (*Mask-'0');
  238. }
  239. if (*Mask == '*')
  240. {
  241. ++Mask;
  242. Width = va_arg(Arg,int);
  243. }
  244. Unsigned = *Mask=='u';
  245. if (Unsigned)
  246. ++Mask;
  247. switch (*Mask)
  248. {
  249. case 'd':
  250. case 'i':
  251. case 'X':
  252. case 'x':
  253. vs = va_arg(Arg,int);
  254. if (*Mask=='x' || *Mask=='X')
  255. {
  256. Unsigned = 1;
  257. q = 16;
  258. w = 0x10000000;
  259. }
  260. else
  261. {
  262. q = 10;
  263. w = 1000000000;
  264. }
  265. Sign = vs<0 && !Unsigned;
  266. if (Sign)
  267. {
  268. vs=-vs;
  269. --Width;
  270. }
  271. w0 = 1;
  272. for (n=1;n<Width;++n)
  273. w0 *= q;
  274. v = vs;
  275. while (v<w && w>w0)
  276. w/=q;
  277. while (w>0)
  278. {
  279. unsigned int i = v/w;
  280. v-=i*w;
  281. if (OutLen>1 && Sign && (w==1 || ZeroFill || i>0))
  282. {
  283. *(Out++) = '-';
  284. --OutLen;
  285. Sign = 0;
  286. }
  287. if (OutLen>1)
  288. {
  289. if (i==0 && !ZeroFill && w!=1)
  290. i = ' ';
  291. else
  292. {
  293. ZeroFill = 1;
  294. if (i>=10)
  295. {
  296. if (*Mask == 'X')
  297. i += 'A'-10;
  298. else
  299. i += 'a'-10;
  300. }
  301. else
  302. i+='0';
  303. }
  304. *(Out++) = (tchar_t)i;
  305. --OutLen;
  306. }
  307. w/=q;
  308. }
  309. break;
  310. case 'c':
  311. *(Out++) = (tchar_t)va_arg(Arg,int);
  312. --OutLen;
  313. break;
  314. case 's':
  315. In = va_arg(Arg,const tchar_t*);
  316. n = min(tcslen(In),OutLen-1);
  317. Width -= n;
  318. if (!AlignLeft)
  319. while (--Width>=0 && OutLen>1)
  320. {
  321. *Out++ = ' ';
  322. --OutLen;
  323. }
  324. memcpy(Out,In,n*sizeof(tchar_t));
  325. Out += n;
  326. OutLen -= n;
  327. while (--Width>=0 && OutLen>1)
  328. {
  329. *Out++ = ' ';
  330. --OutLen;
  331. }
  332. break;
  333. }
  334. ++Mask;
  335. break;
  336. default:
  337. *(Out++) = *(Mask++);
  338. --OutLen;
  339. break;
  340. }
  341. }
  342. if (OutLen>0)
  343. *Out=0;
  344. }
  345. int stscanf(const tchar_t* In, const tchar_t* Mask, ...)
  346. {
  347. va_list Arg;
  348. int n = 0;
  349. int Sign;
  350. int v;
  351. int Width;
  352. const tchar_t* In0;
  353. va_start(Arg, Mask);
  354. while (In && *In && *Mask)
  355. {
  356. switch (*Mask)
  357. {
  358. case '%':
  359. ++Mask;
  360. Width = -1;
  361. if (IsDigit(*Mask))
  362. {
  363. Width = 0;
  364. for (;IsDigit(*Mask);++Mask)
  365. Width = Width*10 + (*Mask-'0');
  366. }
  367. switch (*Mask)
  368. {
  369. case 'X':
  370. case 'x':
  371. for (;IsSpace(*In);++In);
  372. v = 0;
  373. Sign = *In == '-';
  374. In0 = In;
  375. if (Sign) { ++In; --Width; }
  376. for (;Width!=0 && *In;++In,--Width)
  377. {
  378. int h = Hex(*In);
  379. if (h<0) break;
  380. v=v*16+h;
  381. }
  382. if (Sign) v=-v;
  383. if (In != In0)
  384. {
  385. *va_arg(Arg,int*) = v;
  386. ++n;
  387. }
  388. else
  389. In = NULL;
  390. break;
  391. case 'd':
  392. case 'i':
  393. for (;IsSpace(*In);++In);
  394. v = 0;
  395. Sign = *In == '-';
  396. In0 = In;
  397. if (Sign) ++In;
  398. for (;Width!=0 && IsDigit(*In);++In,--Width)
  399. v=v*10+(*In-'0');
  400. if (Sign) v=-v;
  401. if (In != In0)
  402. {
  403. *va_arg(Arg,int*) = v;
  404. ++n;
  405. }
  406. else
  407. In = NULL;
  408. break;
  409. case 'o':
  410. for (;IsSpace(*In);++In);
  411. v = 0;
  412. Sign = *In == '-';
  413. In0 = In;
  414. if (Sign) ++In;
  415. for (;Width!=0 && *In;++In,--Width)
  416. {
  417. if (*In >= '0' && *In <= '7')
  418. v=v*8+(*In-'0');
  419. else
  420. break;
  421. }
  422. if (Sign) v=-v;
  423. if (In != In0)
  424. {
  425. *va_arg(Arg,int*) = v;
  426. ++n;
  427. }
  428. else
  429. In = NULL;
  430. break;
  431. }
  432. break;
  433. case 9:
  434. case ' ':
  435. for (;IsSpace(*In);++In);
  436. break;
  437. default:
  438. if (*Mask == *In)
  439. ++In;
  440. else
  441. {
  442. In = NULL;
  443. n = -1;
  444. }
  445. }
  446. ++Mask;
  447. }
  448. va_end(Arg);
  449. return n;
  450. }
  451. void GUIDToString(tchar_t* Out, size_t OutLen, const guid* p)
  452. {
  453. stprintf_s(Out,OutLen,T("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"),
  454. (int)p->v1,p->v2,p->v3,p->v4[0],p->v4[1],p->v4[2],p->v4[3],
  455. p->v4[4],p->v4[5],p->v4[6],p->v4[7]);
  456. }
  457. bool_t StringToGUID(const tchar_t* In, guid* p)
  458. {
  459. int i,v[10];
  460. if (stscanf(In,T("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"),
  461. &p->v1,v+0,v+1,v+2,v+3,v+4,v+5,v+6,v+7,v+8,v+9) < 11)
  462. {
  463. memset(p,0,sizeof(guid));
  464. return 0;
  465. }
  466. p->v2 = (uint16_t)v[0];
  467. p->v3 = (uint16_t)v[1];
  468. for (i=0;i<8;++i)
  469. p->v4[i] = (uint8_t)v[2+i];
  470. return 1;
  471. }
  472. bool_t IsSpace(int ch) { return ch==' ' || ch==9; }
  473. bool_t IsAlpha(int ch) { return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'); }
  474. bool_t IsDigit(int ch) { return ch>='0' && ch<='9'; }
  475. int Hex(int ch) 
  476. {
  477. if (IsDigit(ch))
  478. return ch-'0';
  479. if (ch >= 'a' && ch <= 'f')
  480. return ch-'a'+10;
  481. if (ch >= 'A' && ch <= 'F')
  482. return ch-'A'+10;
  483. return -1;
  484. }
  485. void tcsuprto(tchar_t* p, tchar_t Delimiter)
  486. {
  487. for (;*p && *p!=Delimiter;++p)
  488. *p = (char)toupper(*p);
  489. }
  490. void tcsupr(tchar_t* p) 
  491. {
  492. for (;*p;++p)
  493. *p = (char)toupper(*p);
  494. }