sysuni.inc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  1. {
  2. *********************************************************************
  3. Copyright (C) 2002-2005 by Florian Klaempfl
  4. See the file COPYING.FPC, included in this distribution,
  5. for details about the copyright.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  9. *********************************************************************
  10. }
  11. function Trim(const S: unicodestring): unicodestring;
  12. var
  13. Ofs, Len: sizeint;
  14. begin
  15. len := Length(S);
  16. while (Len>0) and (S[Len]<=' ') do
  17. dec(Len);
  18. Ofs := 1;
  19. while (Ofs<=Len) and (S[Ofs]<=' ') do
  20. Inc(Ofs);
  21. result := Copy(S, Ofs, 1 + Len - Ofs);
  22. end;
  23. { TrimLeft returns a copy of S with all blank characters on the left stripped off }
  24. function TrimLeft(const S: unicodestring): unicodestring;
  25. var
  26. i,l:sizeint;
  27. begin
  28. l := length(s);
  29. i := 1;
  30. while (i<=l) and (s[i]<=' ') do
  31. inc(i);
  32. Result := copy(s, i, l);
  33. end;
  34. { TrimRight returns a copy of S with all blank characters on the right stripped off }
  35. function TrimRight(const S: unicodestring): unicodestring;
  36. var
  37. l:sizeint;
  38. begin
  39. l := length(s);
  40. while (l>0) and (s[l]<=' ') do
  41. dec(l);
  42. result := copy(s,1,l);
  43. end;
  44. Function InternalChangeCase(Const S : UnicodeString; const Chars: TSysCharSet; const Adjustment: Longint): UnicodeString;
  45. var
  46. i : Integer;
  47. P : PWideChar;
  48. Unique : Boolean;
  49. begin
  50. Result := S;
  51. if Result='' then
  52. exit;
  53. Unique:=false;
  54. P:=PWideChar(Result);
  55. for i:=1 to Length(Result) do
  56. begin
  57. if CharInSet(P^,Chars) then
  58. begin
  59. if not Unique then
  60. begin
  61. UniqueString(Result);
  62. p:=@Result[i];
  63. Unique:=true;
  64. end;
  65. P^:=WideChar(Ord(P^)+Adjustment);
  66. end;
  67. Inc(P);
  68. end;
  69. end;
  70. { UpperCase returns a copy of S where all lowercase characters ( from a to z )
  71. have been converted to uppercase }
  72. Function UpperCase(Const S : UnicodeString) : UnicodeString;
  73. begin
  74. Result:=InternalChangeCase(S,['a'..'z'],-32);
  75. end;
  76. { LowerCase returns a copy of S where all uppercase characters ( from A to Z )
  77. have been converted to lowercase }
  78. Function Lowercase(Const S : UnicodeString) : UnicodeString;
  79. begin
  80. Result:=InternalChangeCase(S,['A'..'Z'],32);
  81. end;
  82. function UnicodeUpperCase(const s : UnicodeString) : UnicodeString;{$ifdef SYSUTILSINLINE}inline;{$endif}
  83. begin
  84. result:=widestringmanager.UpperUnicodeStringProc(s);
  85. end;
  86. function UnicodeLowerCase(const s : UnicodeString) : UnicodeString;{$ifdef SYSUTILSINLINE}inline;{$endif}
  87. begin
  88. result:=widestringmanager.LowerUnicodeStringProc(s);
  89. end;
  90. function UnicodeCompareStr(const s1, s2 : UnicodeString) : PtrInt;{$ifdef SYSUTILSINLINE}inline;{$endif}
  91. begin
  92. result:=widestringmanager.CompareUnicodeStringProc(s1,s2,[]);
  93. end;
  94. function UnicodeSameStr(const s1, s2 : UnicodeString) : Boolean;{$ifdef SYSUTILSINLINE}inline;{$endif}
  95. begin
  96. result:=widestringmanager.CompareUnicodeStringProc(s1,s2,[])=0;
  97. end;
  98. function UnicodeCompareText(const s1, s2 : UnicodeString) : PtrInt;{$ifdef SYSUTILSINLINE}inline;{$endif}
  99. begin
  100. result:=widestringmanager.CompareUnicodeStringProc(s1,s2,[coIgnoreCase]);
  101. end;
  102. function UnicodeSameText(const s1, s2 : UnicodeString) : Boolean;{$ifdef SYSUTILSINLINE}inline;{$endif}
  103. begin
  104. result:=widestringmanager.CompareUnicodeStringProc(s1,s2,[coIgnoreCase])=0;
  105. end;
  106. { we've no templates, but with includes we can simulate this :) }
  107. {$macro on}
  108. {$define INWIDEFORMAT}
  109. {$define TFormatString:=unicodestring}
  110. {$define TFormatChar:=unicodechar}
  111. Function UnicodeFormat (Const Fmt : UnicodeString; const Args : Array of const; Const FormatSettings: TFormatSettings) : UnicodeString;
  112. {$i sysformt.inc}
  113. {$undef TFormatString}
  114. {$undef TFormatChar}
  115. {$undef INWIDEFORMAT}
  116. {$macro off}
  117. Function UnicodeFormat (Const Fmt : UnicodeString; const Args : Array of const) : UnicodeString;
  118. begin
  119. Result:=UnicodeFormat(Fmt,Args,DefaultFormatSettings);
  120. end;
  121. Function UnicodeFormatBuf (Var Buffer; BufLen : Cardinal;
  122. Const Fmt; fmtLen : Cardinal;
  123. Const Args : Array of const; Const FormatSettings: TFormatSettings) : Cardinal;
  124. Var
  125. S,F : UnicodeString;
  126. begin
  127. Setlength(F,fmtlen);
  128. if fmtlen > 0 then
  129. Move(fmt,F[1],fmtlen*sizeof(Unicodechar));
  130. S:=UnicodeFormat (F,Args);
  131. If Cardinal(Length(S))<Buflen then
  132. Result:=Length(S)
  133. else
  134. Result:=Buflen;
  135. Move(S[1],Buffer,Result);
  136. end;
  137. Function UnicodeFormatBuf (Var Buffer; BufLen : Cardinal;
  138. Const Fmt; fmtLen : Cardinal;
  139. Const Args : Array of const) : Cardinal;
  140. begin
  141. Result:=UnicodeFormatBuf(Buffer,BufLEn,Fmt,FmtLen,Args,DefaultFormatSettings);
  142. end;
  143. Procedure UnicodeFmtStr(Var Res: UnicodeString; Const Fmt : UnicodeString; Const args: Array of const; Const FormatSettings: TFormatSettings);
  144. begin
  145. Res:=UnicodeFormat(fmt,Args);
  146. end;
  147. Procedure UnicodeFmtStr(Var Res: UnicodeString; Const Fmt : UnicodeString; Const args: Array of const);
  148. begin
  149. UnicodeFmtStr(Res,Fmt,Args,DefaultFormatSettings);
  150. end;
  151. function StrMove(dest,source : PWideChar;l : SizeInt) : PWideChar; overload;
  152. begin
  153. move(source^,dest^,l*2);
  154. Result:=dest;
  155. end;
  156. function StrPLCopy(Dest: PWideChar; const Source: UnicodeString; MaxLen: SizeUInt): PWideChar; overload;
  157. var Len: SizeUInt;
  158. begin
  159. Len := length(Source);
  160. if Len > MaxLen then
  161. Len := MaxLen;
  162. Move(Source[1], Dest^, Len*sizeof(WideChar));
  163. Dest[Len] := #0;
  164. StrPLCopy := Dest;
  165. end;
  166. function StrPCopy(Dest: PWideChar; const Source: UnicodeString): PWideChar; overload;
  167. begin
  168. StrPCopy := StrPLCopy(Dest, Source, length(Source));
  169. end;
  170. function StrScan(P: PWideChar; C: WideChar): PWideChar;
  171. Var
  172. count: SizeInt;
  173. Begin
  174. count := 0;
  175. { As in Borland Pascal, if looking for NULL return null }
  176. if C = #0 then
  177. begin
  178. StrScan := @(P[StrLen(P)]);
  179. exit;
  180. end;
  181. { Find first matching character of Ch in Str }
  182. while P[count] <> #0 do
  183. begin
  184. if C = P[count] then
  185. begin
  186. StrScan := @(P[count]);
  187. exit;
  188. end;
  189. Inc(count);
  190. end;
  191. { nothing found. }
  192. StrScan := nil;
  193. end;
  194. function StrPas(Str: PWideChar): UnicodeString;overload;
  195. begin
  196. Result:=Str;
  197. end;
  198. function strecopy(dest,source : pwidechar) : pwidechar;
  199. var
  200. counter: sizeint;
  201. begin
  202. counter := indexword(source^,-1,0);
  203. { counter+1 will move zero terminator }
  204. move(source^,dest^,(counter+1)*2);
  205. result:=dest+counter;
  206. end;
  207. function strend(p : pwidechar) : pwidechar;
  208. begin
  209. result:=p+indexword(p^,-1,0);
  210. end;
  211. function strcat(dest,source : pwidechar) : pwidechar;
  212. begin
  213. strcopy(strend(dest),source);
  214. strcat:=dest;
  215. end;
  216. function strcomp(str1,str2 : pwidechar) : SizeInt;
  217. var
  218. counter: sizeint;
  219. c1, c2: widechar;
  220. begin
  221. counter:=0;
  222. repeat
  223. c1:=str1[counter];
  224. c2:=str2[counter];
  225. inc(counter);
  226. until (c1<>c2) or
  227. (c1=#0) or
  228. (c2=#0);
  229. strcomp:=ord(c1)-ord(c2);
  230. end;
  231. function strlcomp(str1,str2 : pwidechar;l : SizeInt) : SizeInt;
  232. var
  233. counter: sizeint;
  234. c1, c2: widechar;
  235. begin
  236. if l = 0 then
  237. begin
  238. strlcomp := 0;
  239. exit;
  240. end;
  241. counter:=0;
  242. repeat
  243. c1:=str1[counter];
  244. c2:=str2[counter];
  245. inc(counter);
  246. until (c1<>c2) or (counter>=l) or
  247. (c1=#0) or (c2=#0);
  248. strlcomp:=ord(c1)-ord(c2);
  249. end;
  250. { the str* functions are not supposed to support internationalisation;
  251. system.upcase(widechar) does support it (although this is
  252. Delphi-incompatible) }
  253. function simplewideupcase(w: widechar): widechar;
  254. begin
  255. if w in ['a'..'z'] then
  256. result:=widechar(ord(w)-32)
  257. else
  258. result:=w;
  259. end;
  260. function stricomp(str1,str2 : pwidechar) : SizeInt;
  261. var
  262. counter: sizeint;
  263. c1, c2: widechar;
  264. begin
  265. counter := 0;
  266. c1:=simplewideupcase(str1[counter]);
  267. c2:=simplewideupcase(str2[counter]);
  268. while c1=c2 do
  269. begin
  270. if (c1=#0) or (c2=#0) then break;
  271. inc(counter);
  272. c1:=simplewideupcase(str1[counter]);
  273. c2:=simplewideupcase(str2[counter]);
  274. end;
  275. stricomp:=ord(c1)-ord(c2);
  276. end;
  277. function strlcat(dest,source : pwidechar;l : SizeInt) : pwidechar;
  278. var
  279. destend : pwidechar;
  280. begin
  281. destend:=strend(dest);
  282. dec(l,destend-dest);
  283. if l>0 then
  284. strlcopy(destend,source,l);
  285. strlcat:=dest;
  286. end;
  287. function strrscan(p : pwidechar;c : widechar) : pwidechar;
  288. var
  289. count: sizeint;
  290. index: sizeint;
  291. begin
  292. count:=strlen(p);
  293. { As in Borland Pascal , if looking for NULL return null }
  294. if c=#0 then
  295. begin
  296. strrscan:=@(p[count]);
  297. exit;
  298. end;
  299. dec(count);
  300. for index:=count downto 0 do
  301. begin
  302. if c=p[index] then
  303. begin
  304. strrscan:=@(p[index]);
  305. exit;
  306. end;
  307. end;
  308. { nothing found. }
  309. strrscan:=nil;
  310. end;
  311. function strlower(p : pwidechar) : pwidechar;
  312. var
  313. counter: SizeInt;
  314. c: widechar;
  315. begin
  316. counter:=0;
  317. repeat
  318. c:=p[counter];
  319. if c in [#65..#90] then
  320. p[counter]:=widechar(ord(c)+32);
  321. inc(counter);
  322. until c=#0;
  323. strlower:=p;
  324. end;
  325. function strupper(p : pwidechar) : pwidechar;
  326. var
  327. counter: SizeInt;
  328. c: widechar;
  329. begin
  330. counter:=0;
  331. repeat
  332. c:=p[counter];
  333. if c in [#97..#122] then
  334. p[counter]:=widechar(ord(c)-32);
  335. inc(counter);
  336. until c=#0;
  337. strupper:=p;
  338. end;
  339. function strlicomp(str1,str2 : pwidechar;l : SizeInt) : SizeInt;
  340. var
  341. counter: sizeint;
  342. c1, c2: char;
  343. begin
  344. counter := 0;
  345. if l=0 then
  346. begin
  347. strlicomp := 0;
  348. exit;
  349. end;
  350. repeat
  351. c1:=simplewideupcase(str1[counter]);
  352. c2:=simplewideupcase(str2[counter]);
  353. if (c1=#0) or (c2=#0) then break;
  354. inc(counter);
  355. until (c1<>c2) or (counter>=l);
  356. strlicomp:=ord(c1)-ord(c2);
  357. end;
  358. function strpos(str1,str2 : pwidechar) : pwidechar;
  359. var
  360. p : pwidechar;
  361. lstr2 : SizeInt;
  362. begin
  363. strpos:=nil;
  364. if (str1=nil) or (str2=nil) then
  365. exit;
  366. p:=strscan(str1,str2^);
  367. if p=nil then
  368. exit;
  369. lstr2:=strlen(str2);
  370. while p<>nil do
  371. begin
  372. if strlcomp(p,str2,lstr2)=0 then
  373. begin
  374. strpos:=p;
  375. exit;
  376. end;
  377. inc(p);
  378. p:=strscan(p,str2^);
  379. end;
  380. end;
  381. function strnew(p : pwidechar) : pwidechar; overload;
  382. var
  383. len: sizeint;
  384. begin
  385. len:=strlen(p)+1;
  386. result:=WideStrAlloc(Len);
  387. if result<>nil then
  388. strmove(result,p,len);
  389. end;
  390. function WideStrAlloc(Size: cardinal): PWideChar;
  391. begin
  392. getmem(result,size*2+sizeof(cardinal));
  393. PCardinal(result)^:=size*2+sizeof(cardinal);
  394. result:=PWideChar(PByte(result)+sizeof(cardinal));
  395. end;
  396. function StrBufSize(str: pwidechar): cardinal;
  397. begin
  398. if assigned(str) then
  399. result:=(PCardinal(PByte(str)-sizeof(cardinal))^)-sizeof(cardinal)
  400. else
  401. result := 0;
  402. end;
  403. procedure StrDispose(str: pwidechar);
  404. begin
  405. if assigned(str) then
  406. begin
  407. str:=PWideChar(PByte(str)-sizeof(cardinal));
  408. freemem(str,PCardinal(str)^);
  409. end;
  410. end;
  411. function BytesOf(const Val: UnicodeString): TBytes;
  412. begin
  413. Result:=TEncoding.Default.GetBytes(Val);
  414. end;
  415. function BytesOf(const Val: WideChar): TBytes; overload;
  416. begin
  417. Result:=TEncoding.Default.GetBytes(Val);
  418. end;
  419. function StringOf(const Bytes: TBytes): UnicodeString;
  420. begin
  421. Result:=TEncoding.Default.GetString(Bytes);
  422. end;
  423. function WideBytesOf(const Value: UnicodeString): TBytes;
  424. var
  425. Len:Integer;
  426. begin
  427. Len:=Length(Value)*SizeOf(UnicodeChar);
  428. SetLength(Result,Len);
  429. if Len>0 then
  430. Move(Value[1],Result[0],Len);
  431. end;
  432. function WideStringOf(const Value: TBytes): UnicodeString;
  433. var
  434. Len:Integer;
  435. begin
  436. Len:=Length(Value) div SizeOf(UnicodeChar);
  437. SetLength(Result,Len);
  438. if Len>0 then
  439. Move(Value[0],Result[1],Len*SizeOf(UnicodeChar));
  440. end;
  441. function ByteLength(const S: UnicodeString): Integer;
  442. begin
  443. Result:=Length(S)*SizeOf(UnicodeChar);
  444. end;
  445. {$macro on}
  446. {$define INUNICODESTRINGREPLACE}
  447. {$define SRString:=UnicodeString}
  448. {$define SRUpperCase:=UnicodeUppercase}
  449. {$define SRPCHAR:=PUnicodeChar}
  450. {$define SRCHAR:=UnicodeChar}
  451. Function UnicodeStringReplace(const S, OldPattern, NewPattern: Unicodestring; Flags: TReplaceFlags): Unicodestring;
  452. Var
  453. C : Integer;
  454. begin
  455. Result:=UnicodeStringReplace(S,OldPattern,NewPattern,Flags,C);
  456. end;
  457. function UnicodeStringReplace(const S, OldPattern, NewPattern: UnicodeString; Flags: TReplaceFlags; Out aCount : Integer): UnicodeString;
  458. {$i syssr.inc}
  459. {$undef INUNICODESTRINGREPLACE}
  460. {$undef SRString}
  461. {$undef SRUpperCase}
  462. {$undef SRPCHAR}
  463. {$undef SRCHAR}