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; mode: TTrimMode): unicodestring;
  13. var
  14. start, ed, ns: SizeInt;
  15. begin
  16. start := 1;
  17. ns := Length(S);
  18. ed := ns;
  19. if mode <> TTrimMode.Right then
  20. while (start <= ed) and (S[start] <= ' ') do
  21. inc(start);
  22. if mode <> TTrimMode.Left then
  23. while (start <= ed) and (S[ed] <= ' ') do
  24. dec(ed);
  25. if (start = 1) and (ed = ns) then
  26. Result := S
  27. else
  28. Result := Copy(S, start, ed - start + 1);
  29. end;
  30. function Trim(const S: unicodestring): unicodestring;
  31. begin
  32. result := Trim(S, TTrimMode.Both);
  33. end;
  34. { TrimLeft returns a copy of S with all blank characters on the left stripped off }
  35. function TrimLeft(const S: unicodestring): unicodestring;
  36. begin
  37. Result := Trim(S, TTrimMode.Left);
  38. end;
  39. { TrimRight returns a copy of S with all blank characters on the right stripped off }
  40. function TrimRight(const S: unicodestring): unicodestring;
  41. begin
  42. Result := Trim(S, TTrimMode.Right);
  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 Format (Const Fmt : UnicodeString; const Args : Array of const; Const FormatSettings: TFormatSettings) : UnicodeString;
  122. begin
  123. Result:=UnicodeFormat(Fmt,Args,FormatSettings);
  124. end;
  125. Function Format (Const Fmt : UnicodeString; const Args : Array of const) : UnicodeString;
  126. begin
  127. Result:=UnicodeFormat(Fmt,Args,DefaultFormatSettings);
  128. end;
  129. Function UnicodeFormatBuf (Var Buffer; BufLen : Cardinal;
  130. Const Fmt ; fmtLen : Cardinal;
  131. Const Args : Array of const; Const FormatSettings: TFormatSettings) : Cardinal;
  132. Var
  133. S,F : UnicodeString;
  134. begin
  135. Setlength(F,fmtlen);
  136. if fmtlen > 0 then
  137. Move(fmt,F[1],fmtlen*sizeof(Unicodechar));
  138. S:=UnicodeFormat (F,Args);
  139. If Cardinal(Length(S))<Buflen then
  140. Result:=Length(S)
  141. else
  142. Result:=Buflen;
  143. Move(S[1],Buffer,Result*SizeOf(UnicodeChar));
  144. end;
  145. Function UnicodeFormatBuf (Var Buffer; BufLen : Cardinal;
  146. Const Fmt; fmtLen : Cardinal;
  147. Const Args : Array of const) : Cardinal;
  148. begin
  149. Result:=UnicodeFormatBuf(Buffer,BufLEn,Fmt,FmtLen,Args,DefaultFormatSettings);
  150. end;
  151. Procedure UnicodeFmtStr(Var Res: UnicodeString; Const Fmt : UnicodeString; Const args: Array of const; Const FormatSettings: TFormatSettings);
  152. begin
  153. Res:=UnicodeFormat(fmt,Args);
  154. end;
  155. Procedure UnicodeFmtStr(Var Res: UnicodeString; Const Fmt : UnicodeString; Const args: Array of const);
  156. begin
  157. UnicodeFmtStr(Res,Fmt,Args,DefaultFormatSettings);
  158. end;
  159. function StrMove(dest,source : PWideChar;l : SizeInt) : PWideChar; overload;
  160. begin
  161. move(source^,dest^,l*2);
  162. Result:=dest;
  163. end;
  164. function StrPLCopy(Dest: PWideChar; const Source: UnicodeString; MaxLen: SizeUInt): PWideChar; overload;
  165. var Len: SizeUInt;
  166. begin
  167. Len := length(Source);
  168. if Len > MaxLen then
  169. Len := MaxLen;
  170. Move(Source[1], Dest^, Len*sizeof(WideChar));
  171. Dest[Len] := #0;
  172. StrPLCopy := Dest;
  173. end;
  174. function StrPCopy(Dest: PWideChar; const Source: UnicodeString): PWideChar; overload;
  175. begin
  176. StrPCopy := StrPLCopy(Dest, Source, length(Source));
  177. end;
  178. function StrScan(P: PWideChar; C: WideChar): PWideChar;
  179. Var
  180. count: SizeInt;
  181. Begin
  182. count := 0;
  183. { As in Borland Pascal, if looking for NULL return null }
  184. if C = #0 then
  185. begin
  186. StrScan := @(P[StrLen(P)]);
  187. exit;
  188. end;
  189. { Find first matching character of Ch in Str }
  190. while P[count] <> #0 do
  191. begin
  192. if C = P[count] then
  193. begin
  194. StrScan := @(P[count]);
  195. exit;
  196. end;
  197. Inc(count);
  198. end;
  199. { nothing found. }
  200. StrScan := nil;
  201. end;
  202. function StrPas(Str: PWideChar): UnicodeString;overload;
  203. begin
  204. Result:=Str;
  205. end;
  206. function strecopy(dest,source : pwidechar) : pwidechar;
  207. var
  208. counter: sizeint;
  209. begin
  210. counter := indexword(source^,-1,0);
  211. { counter+1 will move zero terminator }
  212. move(source^,dest^,(counter+1)*2);
  213. result:=dest+counter;
  214. end;
  215. function strend(p : pwidechar) : pwidechar;
  216. begin
  217. result:=p+indexword(p^,-1,0);
  218. end;
  219. function strcat(dest,source : pwidechar) : pwidechar;
  220. begin
  221. strcopy(strend(dest),source);
  222. strcat:=dest;
  223. end;
  224. function strcomp(str1,str2 : pwidechar) : SizeInt;
  225. var
  226. counter: sizeint;
  227. c1, c2: widechar;
  228. begin
  229. counter:=0;
  230. repeat
  231. c1:=str1[counter];
  232. c2:=str2[counter];
  233. inc(counter);
  234. until (c1<>c2) or
  235. (c1=#0) or
  236. (c2=#0);
  237. strcomp:=ord(c1)-ord(c2);
  238. end;
  239. function strlcomp(str1,str2 : pwidechar;l : SizeInt) : SizeInt;
  240. var
  241. counter: sizeint;
  242. c1, c2: widechar;
  243. begin
  244. if l = 0 then
  245. begin
  246. strlcomp := 0;
  247. exit;
  248. end;
  249. counter:=0;
  250. repeat
  251. c1:=str1[counter];
  252. c2:=str2[counter];
  253. inc(counter);
  254. until (c1<>c2) or (counter>=l) or
  255. (c1=#0) or (c2=#0);
  256. strlcomp:=ord(c1)-ord(c2);
  257. end;
  258. { the str* functions are not supposed to support internationalisation;
  259. system.upcase(widechar) does support it (although this is
  260. Delphi-incompatible) }
  261. function simplewideupcase(w: widechar): widechar;
  262. begin
  263. if w in ['a'..'z'] then
  264. result:=widechar(ord(w)-32)
  265. else
  266. result:=w;
  267. end;
  268. function stricomp(str1,str2 : pwidechar) : SizeInt;
  269. var
  270. counter: sizeint;
  271. c1, c2: widechar;
  272. begin
  273. counter := 0;
  274. c1:=simplewideupcase(str1[counter]);
  275. c2:=simplewideupcase(str2[counter]);
  276. while c1=c2 do
  277. begin
  278. if (c1=#0) or (c2=#0) then break;
  279. inc(counter);
  280. c1:=simplewideupcase(str1[counter]);
  281. c2:=simplewideupcase(str2[counter]);
  282. end;
  283. stricomp:=ord(c1)-ord(c2);
  284. end;
  285. function strlcat(dest,source : pwidechar;l : SizeInt) : pwidechar;
  286. var
  287. destend : pwidechar;
  288. begin
  289. destend:=strend(dest);
  290. dec(l,destend-dest);
  291. if l>0 then
  292. strlcopy(destend,source,l);
  293. strlcat:=dest;
  294. end;
  295. function strrscan(p : pwidechar;c : widechar) : pwidechar;
  296. var
  297. count: sizeint;
  298. index: sizeint;
  299. begin
  300. count:=strlen(p);
  301. { As in Borland Pascal , if looking for NULL return null }
  302. if c=#0 then
  303. begin
  304. strrscan:=@(p[count]);
  305. exit;
  306. end;
  307. dec(count);
  308. for index:=count downto 0 do
  309. begin
  310. if c=p[index] then
  311. begin
  312. strrscan:=@(p[index]);
  313. exit;
  314. end;
  315. end;
  316. { nothing found. }
  317. strrscan:=nil;
  318. end;
  319. function strlower(p : pwidechar) : pwidechar;
  320. var
  321. counter: SizeInt;
  322. c: widechar;
  323. begin
  324. counter:=0;
  325. repeat
  326. c:=p[counter];
  327. if c in [#65..#90] then
  328. p[counter]:=widechar(ord(c)+32);
  329. inc(counter);
  330. until c=#0;
  331. strlower:=p;
  332. end;
  333. function strupper(p : pwidechar) : pwidechar;
  334. var
  335. counter: SizeInt;
  336. c: widechar;
  337. begin
  338. counter:=0;
  339. repeat
  340. c:=p[counter];
  341. if c in [#97..#122] then
  342. p[counter]:=widechar(ord(c)-32);
  343. inc(counter);
  344. until c=#0;
  345. strupper:=p;
  346. end;
  347. function strlicomp(str1,str2 : pwidechar;l : SizeInt) : SizeInt;
  348. var
  349. counter: sizeint;
  350. c1, c2: AnsiChar;
  351. begin
  352. counter := 0;
  353. if l=0 then
  354. begin
  355. strlicomp := 0;
  356. exit;
  357. end;
  358. repeat
  359. c1:=simplewideupcase(str1[counter]);
  360. c2:=simplewideupcase(str2[counter]);
  361. if (c1=#0) or (c2=#0) then break;
  362. inc(counter);
  363. until (c1<>c2) or (counter>=l);
  364. strlicomp:=ord(c1)-ord(c2);
  365. end;
  366. function strpos(str1,str2 : pwidechar) : pwidechar;
  367. var
  368. p : pwidechar;
  369. lstr2 : SizeInt;
  370. begin
  371. strpos:=nil;
  372. if (str1=nil) or (str2=nil) then
  373. exit;
  374. p:=strscan(str1,str2^);
  375. if p=nil then
  376. exit;
  377. lstr2:=strlen(str2);
  378. while p<>nil do
  379. begin
  380. if strlcomp(p,str2,lstr2)=0 then
  381. begin
  382. strpos:=p;
  383. exit;
  384. end;
  385. inc(p);
  386. p:=strscan(p,str2^);
  387. end;
  388. end;
  389. function strnew(p : pwidechar) : pwidechar; overload;
  390. var
  391. len: sizeint;
  392. begin
  393. len:=strlen(p)+1;
  394. result:=WideStrAlloc(Len);
  395. if result<>nil then
  396. strmove(result,p,len);
  397. end;
  398. function WideStrAlloc(Size: cardinal): PWideChar;
  399. begin
  400. getmem(result,size*2+sizeof(cardinal));
  401. PCardinal(result)^:=size*2+sizeof(cardinal);
  402. result:=PWideChar(PByte(result)+sizeof(cardinal));
  403. end;
  404. function StrBufSize(str: pwidechar): cardinal;
  405. begin
  406. if assigned(str) then
  407. result:=(PCardinal(PByte(str)-sizeof(cardinal))^)-sizeof(cardinal)
  408. else
  409. result := 0;
  410. end;
  411. procedure StrDispose(str: pwidechar);
  412. begin
  413. if assigned(str) then
  414. begin
  415. str:=PWideChar(PByte(str)-sizeof(cardinal));
  416. freemem(str,PCardinal(str)^);
  417. end;
  418. end;
  419. function BytesOf(const Val: UnicodeString): TBytes;
  420. begin
  421. Result:=TEncoding.Default.GetBytes(Val);
  422. end;
  423. function BytesOf(const Val: WideChar): TBytes; overload;
  424. begin
  425. Result:=TEncoding.Default.GetBytes(Val);
  426. end;
  427. function StringOf(const Bytes: TBytes): UnicodeString;
  428. begin
  429. Result:=TEncoding.Default.GetString(Bytes);
  430. end;
  431. function WideBytesOf(const Value: UnicodeString): TBytes;
  432. var
  433. Len:Integer;
  434. begin
  435. Len:=Length(Value)*SizeOf(UnicodeChar);
  436. SetLength(Result,Len);
  437. if Len>0 then
  438. Move(Value[1],Result[0],Len);
  439. end;
  440. function WideStringOf(const Value: TBytes): UnicodeString;
  441. var
  442. Len:Integer;
  443. begin
  444. Len:=Length(Value) div SizeOf(UnicodeChar);
  445. SetLength(Result,Len);
  446. if Len>0 then
  447. Move(Value[0],Result[1],Len*SizeOf(UnicodeChar));
  448. end;
  449. function ByteLength(const S: UnicodeString): Integer;
  450. begin
  451. Result:=Length(S)*SizeOf(UnicodeChar);
  452. end;
  453. {$macro on}
  454. {$define INUNICODESTRINGREPLACE}
  455. {$define SRString:=UnicodeString}
  456. {$define SRUpperCase:=UnicodeUppercase}
  457. {$define SRPCHAR:=PUnicodeChar}
  458. {$define SRCHAR:=UnicodeChar}
  459. Function UnicodeStringReplace(const S, OldPattern, NewPattern: Unicodestring; Flags: TReplaceFlags): Unicodestring;
  460. Var
  461. C : Integer;
  462. begin
  463. Result:=UnicodeStringReplace(S,OldPattern,NewPattern,Flags,C);
  464. end;
  465. Function StringReplace(const S : UnicodeString; OldPattern, NewPattern: WideChar; Flags: TReplaceFlags): Unicodestring;
  466. Var
  467. C : Integer;
  468. begin
  469. Result:=UnicodeStringReplace(S,OldPattern,NewPattern,Flags,C);
  470. end;
  471. function UnicodeStringReplace(const S, OldPattern, NewPattern: UnicodeString; Flags: TReplaceFlags; Out aCount : Integer): UnicodeString;
  472. {$i syssr.inc}
  473. {$undef INUNICODESTRINGREPLACE}
  474. {$undef SRString}
  475. {$undef SRUpperCase}
  476. {$undef SRPCHAR}
  477. {$undef SRCHAR}
  478. function StringReplace(const S, OldPattern, NewPattern: UnicodeString; Flags: TReplaceFlags): UnicodeString;
  479. begin
  480. Result:=UnicodeStringReplace(S,OldPattern,NewPattern,Flags);
  481. end;
  482. function StringReplace(const S, OldPattern, NewPattern: UnicodeString; Flags: TReplaceFlags; Out aCount : Integer): UnicodeString;
  483. begin
  484. Result:=UnicodeStringReplace(S,OldPattern,NewPattern,Flags,aCount);
  485. end;