2
0

sysuni.inc 14 KB

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