astrings.inc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Michael Van Canneyt,
  4. member of the Free Pascal development team.
  5. This file implements AnsiStrings for FPC
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  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.
  11. **********************************************************************}
  12. { This will release some functions for special shortstring support }
  13. { define EXTRAANSISHORT}
  14. {
  15. This file contains the implementation of the AnsiString type,
  16. and all things that are needed for it.
  17. AnsiString is defined as a 'silent' pchar :
  18. a pchar that points to :
  19. @-8 : SizeInt for reference count;
  20. @-4 : SizeInt for size;
  21. @ : String + Terminating #0;
  22. Pchar(Ansistring) is a valid typecast.
  23. So AS[i] is converted to the address @AS+i-1.
  24. Constants should be assigned a reference count of -1
  25. Meaning that they can't be disposed of.
  26. }
  27. Type
  28. PAnsiRec = ^TAnsiRec;
  29. TAnsiRec = Packed Record
  30. Ref,
  31. Len : SizeInt;
  32. First : Char;
  33. end;
  34. Const
  35. AnsiRecLen = SizeOf(TAnsiRec);
  36. FirstOff = SizeOf(TAnsiRec)-1;
  37. {****************************************************************************
  38. Internal functions, not in interface.
  39. ****************************************************************************}
  40. Function NewAnsiString(Len : SizeInt) : Pointer;
  41. {
  42. Allocate a new AnsiString on the heap.
  43. initialize it to zero length and reference count 1.
  44. }
  45. Var
  46. P : Pointer;
  47. begin
  48. { request a multiple of 16 because the heap manager alloctes anyways chunks of 16 bytes }
  49. GetMem(P,Len+AnsiRecLen);
  50. If P<>Nil then
  51. begin
  52. PAnsiRec(P)^.Ref:=1; { Set reference count }
  53. PAnsiRec(P)^.Len:=0; { Initial length }
  54. PAnsiRec(P)^.First:=#0; { Terminating #0 }
  55. inc(p,firstoff); { Points to string now }
  56. end;
  57. NewAnsiString:=P;
  58. end;
  59. Procedure DisposeAnsiString(Var S : Pointer);
  60. {
  61. Deallocates a AnsiString From the heap.
  62. }
  63. begin
  64. If S=Nil then
  65. exit;
  66. Dec (S,FirstOff);
  67. FreeMem (S);
  68. S:=Nil;
  69. end;
  70. Procedure fpc_AnsiStr_Decr_Ref (Var S : Pointer);{$ifndef NOSAVEREGISTERS}saveregisters;{$endif}[Public,Alias:'FPC_ANSISTR_DECR_REF']; compilerproc;
  71. {
  72. Decreases the ReferenceCount of a non constant ansistring;
  73. If the reference count is zero, deallocate the string;
  74. }
  75. Type
  76. pSizeInt = ^SizeInt;
  77. Var
  78. l : pSizeInt;
  79. Begin
  80. { Zero string }
  81. If S=Nil then exit;
  82. { check for constant strings ...}
  83. l:=@PANSIREC(S-FirstOff)^.Ref;
  84. If l^<0 then exit;
  85. { declocked does a MT safe dec and returns true, if the counter is 0 }
  86. If declocked(l^) then
  87. { Ref count dropped to zero }
  88. DisposeAnsiString (S); { Remove...}
  89. {$ifndef decrrefnotnil}
  90. s:=nil;
  91. {$endif}
  92. end;
  93. { also define alias for internal use in the system unit }
  94. Procedure fpc_AnsiStr_Decr_Ref (Var S : Pointer);{$ifndef NOSAVEREGISTERS}saveregisters;{$endif} [external name 'FPC_ANSISTR_DECR_REF'];
  95. Procedure fpc_AnsiStr_Incr_Ref (S : Pointer);{$ifndef NOSAVEREGISTERS}saveregisters;{$endif}[Public,Alias:'FPC_ANSISTR_INCR_REF']; compilerproc;
  96. Begin
  97. If S=Nil then
  98. exit;
  99. { Let's be paranoid : Constant string ??}
  100. If PAnsiRec(S-FirstOff)^.Ref<0 then exit;
  101. inclocked(PAnsiRec(S-FirstOff)^.Ref);
  102. end;
  103. { also define alias which can be used inside the system unit }
  104. Procedure fpc_AnsiStr_Incr_Ref (S : Pointer);{$ifndef NOSAVEREGISTERS}saveregisters;{$endif}[external name 'FPC_ANSISTR_INCR_REF'];
  105. Procedure fpc_AnsiStr_Assign (Var S1 : Pointer;S2 : Pointer);[Public,Alias:'FPC_ANSISTR_ASSIGN']; compilerproc;
  106. {
  107. Assigns S2 to S1 (S1:=S2), taking in account reference counts.
  108. }
  109. begin
  110. If S2<>nil then
  111. If PAnsiRec(S2-FirstOff)^.Ref>0 then
  112. inclocked(PAnsiRec(S2-FirstOff)^.ref);
  113. { Decrease the reference count on the old S1 }
  114. fpc_ansistr_decr_ref (S1);
  115. { And finally, have S1 pointing to S2 (or its copy) }
  116. S1:=S2;
  117. end;
  118. { alias for internal use }
  119. Procedure fpc_AnsiStr_Assign (Var S1 : Pointer;S2 : Pointer);[external name 'FPC_ANSISTR_ASSIGN'];
  120. function fpc_AnsiStr_Concat (const S1,S2 : AnsiString): ansistring; compilerproc;
  121. var
  122. S3: ansistring absolute result;
  123. {
  124. Concatenates 2 AnsiStrings : S1+S2.
  125. Result Goes to S3;
  126. }
  127. Var
  128. Size,Location : SizeInt;
  129. begin
  130. { only assign if s1 or s2 is empty }
  131. if (S1='') then
  132. s3 := s2
  133. else if (S2='') then
  134. s3 := s1
  135. else
  136. begin
  137. Size:=length(S2);
  138. Location:=Length(S1);
  139. SetLength (S3,Size+Location);
  140. { the cast to a pointer avoids the unique call }
  141. { and we don't need an unique call }
  142. { because of the SetLength S3 is unique }
  143. Move (S1[1],pointer(S3)^,Location);
  144. Move (S2[1],pointer(pointer(S3)+location)^,Size+1);
  145. end;
  146. end;
  147. {$ifdef EXTRAANSISHORT}
  148. Procedure AnsiStr_ShortStr_Concat (Var S1: AnsiString; Var S2 : ShortString);
  149. {
  150. Concatenates a Ansi with a short string; : S2 + S2
  151. }
  152. Var
  153. Size,Location : SizeInt;
  154. begin
  155. Size:=Length(S2);
  156. Location:=Length(S1);
  157. If Size=0 then
  158. exit;
  159. { Setlength takes case of uniqueness
  160. and alllocated memory. We need to use length,
  161. to take into account possibility of S1=Nil }
  162. SetLength (S1,Size+Length(S1));
  163. Move (S2[1],Pointer(Pointer(S1)+Location)^,Size);
  164. PByte( Pointer(S1)+length(S1) )^:=0; { Terminating Zero }
  165. end;
  166. {$endif EXTRAANSISHORT}
  167. { the following declaration has exactly the same effect as }
  168. { procedure fpc_AnsiStr_To_ShortStr (Var S1 : ShortString;S2 : Pointer); }
  169. { which is what the old helper was, so we don't need an extra implementation }
  170. { of the old helper (JM) }
  171. function fpc_AnsiStr_To_ShortStr (high_of_res: SizeInt;const S2 : Ansistring): shortstring;[Public, alias: 'FPC_ANSISTR_TO_SHORTSTR']; compilerproc;
  172. {
  173. Converts a AnsiString to a ShortString;
  174. }
  175. Var
  176. Size : SizeInt;
  177. begin
  178. if S2='' then
  179. fpc_AnsiStr_To_ShortStr:=''
  180. else
  181. begin
  182. Size:=Length(S2);
  183. If Size>high_of_res then
  184. Size:=high_of_res;
  185. Move (S2[1],fpc_AnsiStr_To_ShortStr[1],Size);
  186. byte(fpc_AnsiStr_To_ShortStr[0]):=byte(Size);
  187. end;
  188. end;
  189. Function fpc_ShortStr_To_AnsiStr (Const S2 : ShortString): ansistring; compilerproc;
  190. {
  191. Converts a ShortString to a AnsiString;
  192. }
  193. Var
  194. Size : SizeInt;
  195. begin
  196. Size:=Length(S2);
  197. Setlength (fpc_ShortStr_To_AnsiStr,Size);
  198. if Size>0 then
  199. Move(S2[1],Pointer(fpc_ShortStr_To_AnsiStr)^,Size);
  200. end;
  201. Function fpc_Char_To_AnsiStr(const c : Char): AnsiString; compilerproc;
  202. {
  203. Converts a Char to a AnsiString;
  204. }
  205. begin
  206. Setlength (fpc_Char_To_AnsiStr,1);
  207. PByte(Pointer(fpc_Char_To_AnsiStr))^:=byte(c);
  208. { Terminating Zero }
  209. PByte(Pointer(fpc_Char_To_AnsiStr)+1)^:=0;
  210. end;
  211. Function fpc_PChar_To_AnsiStr(const p : pchar): ansistring; compilerproc;
  212. Var
  213. L : SizeInt;
  214. begin
  215. if (not assigned(p)) or (p[0]=#0) Then
  216. { result is automatically set to '' }
  217. exit;
  218. l:=IndexChar(p^,-1,#0);
  219. SetLength(fpc_PChar_To_AnsiStr,L);
  220. Move (P[0],Pointer(fpc_PChar_To_AnsiStr)^,L)
  221. end;
  222. Function fpc_CharArray_To_AnsiStr(const arr: array of char): ansistring; compilerproc;
  223. var
  224. i : SizeInt;
  225. begin
  226. if arr[0]=#0 Then
  227. { result is automatically set to '' }
  228. exit;
  229. i:=IndexChar(arr,high(arr)+1,#0);
  230. if i = -1 then
  231. i := high(arr)+1;
  232. SetLength(fpc_CharArray_To_AnsiStr,i);
  233. Move (arr[0],Pointer(fpc_CharArray_To_AnsiStr)^,i);
  234. end;
  235. { note: inside the compiler, the resulttype is modified to be the length }
  236. { of the actual chararray to which we convert (JM) }
  237. function fpc_ansistr_to_chararray(arraysize: SizeInt; const src: ansistring): fpc_big_chararray; [public, alias: 'FPC_ANSISTR_TO_CHARARRAY']; compilerproc;
  238. var
  239. len: SizeInt;
  240. begin
  241. len := length(src);
  242. if len > arraysize then
  243. len := arraysize;
  244. { make sure we don't try to access element 1 of the ansistring if it's nil }
  245. if len > 0 then
  246. move(src[1],fpc_ansistr_to_chararray[0],len);
  247. fillchar(fpc_ansistr_to_chararray[len],arraysize-len,0);
  248. end;
  249. Function fpc_AnsiStr_Compare(const S1,S2 : AnsiString): SizeInt;[Public,Alias : 'FPC_ANSISTR_COMPARE']; compilerproc;
  250. {
  251. Compares 2 AnsiStrings;
  252. The result is
  253. <0 if S1<S2
  254. 0 if S1=S2
  255. >0 if S1>S2
  256. }
  257. Var
  258. MaxI,Temp : SizeInt;
  259. begin
  260. if pointer(S1)=pointer(S2) then
  261. begin
  262. result:=0;
  263. exit;
  264. end;
  265. Maxi:=Length(S1);
  266. temp:=Length(S2);
  267. If MaxI>Temp then
  268. MaxI:=Temp;
  269. if MaxI>0 then
  270. begin
  271. result:=CompareByte(S1[1],S2[1],MaxI);
  272. if result=0 then
  273. result:=Length(S1)-Length(S2);
  274. end
  275. else
  276. result:=Length(S1)-Length(S2);
  277. end;
  278. Procedure fpc_AnsiStr_CheckZero(p : pointer);[Public,Alias : 'FPC_ANSISTR_CHECKZERO']; compilerproc;
  279. begin
  280. if p=nil then
  281. HandleErrorFrame(201,get_frame);
  282. end;
  283. Procedure fpc_AnsiStr_CheckRange(len,index : SizeInt);[Public,Alias : 'FPC_ANSISTR_RANGECHECK']; compilerproc;
  284. begin
  285. if (index>len) or (Index<1) then
  286. HandleErrorFrame(201,get_frame);
  287. end;
  288. Procedure fpc_AnsiStr_SetLength (Var S : AnsiString; l : SizeInt);[Public,Alias : 'FPC_ANSISTR_SETLENGTH']; compilerproc;
  289. {
  290. Sets The length of string S to L.
  291. Makes sure S is unique, and contains enough room.
  292. }
  293. Var
  294. Temp : Pointer;
  295. movelen : SizeInt;
  296. begin
  297. if (l>0) then
  298. begin
  299. if Pointer(S)=nil then
  300. begin
  301. { Need a complete new string...}
  302. Pointer(s):=NewAnsiString(l);
  303. end
  304. else if (PAnsiRec(Pointer(S)-FirstOff)^.Ref = 1) then
  305. begin
  306. Dec(Pointer(S),FirstOff);
  307. if AnsiRecLen+L>MemSize(Pointer(s)) then
  308. reallocmem(pointer(S),AnsiRecLen+L);
  309. Inc(Pointer(S),FirstOff);
  310. end
  311. else
  312. begin
  313. { Reallocation is needed... }
  314. Temp:=Pointer(NewAnsiString(L));
  315. if Length(S)>0 then
  316. begin
  317. if l < succ(length(s)) then
  318. movelen := l
  319. { also move terminating null }
  320. else movelen := succ(length(s));
  321. Move(Pointer(S)^,Temp^,movelen);
  322. end;
  323. fpc_ansistr_decr_ref(Pointer(S));
  324. Pointer(S):=Temp;
  325. end;
  326. { Force nil termination in case it gets shorter }
  327. PByte(Pointer(S)+l)^:=0;
  328. PAnsiRec(Pointer(S)-FirstOff)^.Len:=l;
  329. end
  330. else
  331. begin
  332. { Length=0 }
  333. if Pointer(S)<>nil then
  334. fpc_ansistr_decr_ref (Pointer(S));
  335. Pointer(S):=Nil;
  336. end;
  337. end;
  338. {$ifdef EXTRAANSISHORT}
  339. Function fpc_AnsiStr_ShortStr_Compare (Var S1 : Pointer; Var S2 : ShortString): SizeInt; compilerproc;
  340. {
  341. Compares a AnsiString with a ShortString;
  342. The result is
  343. <0 if S1<S2
  344. 0 if S1=S2
  345. >0 if S1>S2
  346. }
  347. Var
  348. i,MaxI,Temp : SizeInt;
  349. begin
  350. Temp:=0;
  351. i:=0;
  352. MaxI:=Length(AnsiString(S1));
  353. if MaxI>byte(S2[0]) then
  354. MaxI:=Byte(S2[0]);
  355. While (i<MaxI) and (Temp=0) do
  356. begin
  357. Temp:= PByte(S1+I)^ - Byte(S2[i+1]);
  358. inc(i);
  359. end;
  360. AnsiStr_ShortStr_Compare:=Temp;
  361. end;
  362. {$endif EXTRAANSISHORT}
  363. {*****************************************************************************
  364. Public functions, In interface.
  365. *****************************************************************************}
  366. Function fpc_ansistr_Unique(Var S : Pointer): Pointer; [Public,Alias : 'FPC_ANSISTR_UNIQUE']; compilerproc;
  367. {
  368. Make sure reference count of S is 1,
  369. using copy-on-write semantics.
  370. }
  371. Var
  372. SNew : Pointer;
  373. L : SizeInt;
  374. begin
  375. pointer(result) := pointer(s);
  376. If Pointer(S)=Nil then
  377. exit;
  378. if PAnsiRec(Pointer(S)-Firstoff)^.Ref<>1 then
  379. begin
  380. L:=PAnsiRec(Pointer(S)-FirstOff)^.len;
  381. SNew:=NewAnsiString (L);
  382. Move (Pointer(S)^,SNew^,L+1);
  383. PAnsiRec(SNew-FirstOff)^.len:=L;
  384. fpc_ansistr_decr_ref (Pointer(S)); { Thread safe }
  385. pointer(S):=SNew;
  386. pointer(result):=SNew;
  387. end;
  388. end;
  389. Procedure fpc_ansistr_append_char(Var S : AnsiString;c : char); [Public,Alias : 'FPC_ANSISTR_APPEND_CHAR']; compilerproc;
  390. begin
  391. SetLength(S,length(S)+1);
  392. S[length(S)]:=c;
  393. PByte(Pointer(S)+length(S))^:=0; { Terminating Zero }
  394. end;
  395. Procedure fpc_ansistr_append_shortstring(Var S : AnsiString;Str : ShortString); [Public,Alias : 'FPC_ANSISTR_APPEND_SHORTSTRING']; compilerproc;
  396. var
  397. ofs : SizeInt;
  398. begin
  399. if Str='' then
  400. exit;
  401. ofs:=Length(S);
  402. SetLength(S,ofs+length(Str));
  403. move(Str[1],S[ofs+1],length(Str));
  404. PByte(Pointer(S)+length(S))^:=0; { Terminating Zero }
  405. end;
  406. Procedure fpc_ansistr_append_ansistring(Var S : AnsiString;Str : AnsiString); [Public,Alias : 'FPC_ANSISTR_APPEND_ANSISTRING']; compilerproc;
  407. var
  408. ofs : SizeInt;
  409. begin
  410. if Str='' then
  411. exit;
  412. ofs:=Length(S);
  413. SetLength(S,ofs+length(Str));
  414. move(Str[1],S[ofs+1],length(Str)+1);
  415. end;
  416. Function Fpc_Ansistr_Copy (Const S : AnsiString; Index,Size : SizeInt) : AnsiString;compilerproc;
  417. var
  418. ResultAddress : Pointer;
  419. begin
  420. ResultAddress:=Nil;
  421. dec(index);
  422. if Index < 0 then
  423. Index := 0;
  424. { Check Size. Accounts for Zero-length S, the double check is needed because
  425. Size can be maxint and will get <0 when adding index }
  426. if (Size>Length(S)) or
  427. (Index+Size>Length(S)) then
  428. Size:=Length(S)-Index;
  429. If Size>0 then
  430. begin
  431. If Index<0 Then
  432. Index:=0;
  433. ResultAddress:=Pointer(NewAnsiString (Size));
  434. if ResultAddress<>Nil then
  435. begin
  436. Move (Pointer(Pointer(S)+index)^,ResultAddress^,Size);
  437. PAnsiRec(ResultAddress-FirstOff)^.Len:=Size;
  438. PByte(ResultAddress+Size)^:=0;
  439. end;
  440. end;
  441. Pointer(fpc_ansistr_Copy):=ResultAddress;
  442. end;
  443. Function Pos (Const Substr : AnsiString; Const Source : AnsiString) : SizeInt;
  444. var
  445. i,MaxLen : SizeInt;
  446. pc : pchar;
  447. begin
  448. Pos:=0;
  449. if Length(SubStr)>0 then
  450. begin
  451. MaxLen:=Length(source)-Length(SubStr);
  452. i:=0;
  453. pc:=@source[1];
  454. while (i<=MaxLen) do
  455. begin
  456. inc(i);
  457. if (SubStr[1]=pc^) and
  458. (CompareByte(Substr[1],pc^,Length(SubStr))=0) then
  459. begin
  460. Pos:=i;
  461. exit;
  462. end;
  463. inc(pc);
  464. end;
  465. end;
  466. end;
  467. { Faster version for a char alone. Must be implemented because }
  468. { pos(c: char; const s: shortstring) also exists, so otherwise }
  469. { using pos(char,pchar) will always call the shortstring version }
  470. { (exact match for first argument), also with $h+ (JM) }
  471. Function Pos (c : Char; Const s : AnsiString) : SizeInt;
  472. var
  473. i: SizeInt;
  474. pc : pchar;
  475. begin
  476. pc:=@s[1];
  477. for i:=1 to length(s) do
  478. begin
  479. if pc^=c then
  480. begin
  481. pos:=i;
  482. exit;
  483. end;
  484. inc(pc);
  485. end;
  486. pos:=0;
  487. end;
  488. Function fpc_Val_Real_AnsiStr(Const S : AnsiString; Var Code : ValSInt): ValReal; [public, alias:'FPC_VAL_REAL_ANSISTR']; compilerproc;
  489. Var
  490. SS : String;
  491. begin
  492. fpc_Val_Real_AnsiStr := 0;
  493. if length(S) > 255 then
  494. code := 256
  495. else
  496. begin
  497. SS := S;
  498. Val(SS,fpc_Val_Real_AnsiStr,code);
  499. end;
  500. end;
  501. Function fpc_Val_UInt_AnsiStr (Const S : AnsiString; Var Code : ValSInt): ValUInt; [public, alias:'FPC_VAL_UINT_ANSISTR']; compilerproc;
  502. Var
  503. SS : ShortString;
  504. begin
  505. fpc_Val_UInt_AnsiStr := 0;
  506. if length(S) > 255 then
  507. code := 256
  508. else
  509. begin
  510. SS := S;
  511. Val(SS,fpc_Val_UInt_AnsiStr,code);
  512. end;
  513. end;
  514. Function fpc_Val_SInt_AnsiStr (DestSize: SizeInt; Const S : AnsiString; Var Code : ValSInt): ValSInt; [public, alias:'FPC_VAL_SINT_ANSISTR']; compilerproc;
  515. Var
  516. SS : ShortString;
  517. begin
  518. fpc_Val_SInt_AnsiStr:=0;
  519. if length(S)>255 then
  520. code:=256
  521. else
  522. begin
  523. SS := S;
  524. fpc_Val_SInt_AnsiStr := int_Val_SInt_ShortStr(DestSize,SS,Code);
  525. end;
  526. end;
  527. {$ifndef CPU64}
  528. Function fpc_Val_qword_AnsiStr (Const S : AnsiString; Var Code : ValSInt): qword; [public, alias:'FPC_VAL_QWORD_ANSISTR']; compilerproc;
  529. Var
  530. SS : ShortString;
  531. begin
  532. fpc_Val_qword_AnsiStr:=0;
  533. if length(S)>255 then
  534. code:=256
  535. else
  536. begin
  537. SS := S;
  538. Val(SS,fpc_Val_qword_AnsiStr,Code);
  539. end;
  540. end;
  541. Function fpc_Val_int64_AnsiStr (Const S : AnsiString; Var Code : ValSInt): Int64; [public, alias:'FPC_VAL_INT64_ANSISTR']; compilerproc;
  542. Var
  543. SS : ShortString;
  544. begin
  545. fpc_Val_int64_AnsiStr:=0;
  546. if length(S)>255 then
  547. code:=256
  548. else
  549. begin
  550. SS := s;
  551. Val(SS,fpc_Val_int64_AnsiStr,Code);
  552. end;
  553. end;
  554. {$endif CPU64}
  555. procedure fpc_AnsiStr_Float(d : ValReal;len,fr,rt : SizeInt;var s : ansistring);[public,alias:'FPC_ANSISTR_FLOAT']; compilerproc;
  556. var
  557. ss: ShortString;
  558. begin
  559. str_real(len,fr,d,treal_type(rt),ss);
  560. s:=ss;
  561. end;
  562. {$ifdef STR_USES_VALINT}
  563. Procedure fpc_AnsiStr_UInt(v : ValUInt;Len : SizeInt; Var S : AnsiString);[Public,Alias : 'FPC_ANSISTR_VALUINT']; compilerproc;
  564. {$else}
  565. Procedure fpc_AnsiStr_Longword(v : Longword;Len : SizeInt; Var S : AnsiString);[Public,Alias : 'FPC_ANSISTR_CARDINAL']; compilerproc;
  566. {$endif}
  567. Var
  568. SS : ShortString;
  569. begin
  570. str(v:Len,SS);
  571. S:=SS;
  572. end;
  573. {$ifdef STR_USES_VALINT}
  574. Procedure fpc_AnsiStr_SInt(v : ValSInt;Len : SizeInt; Var S : AnsiString);[Public,Alias : 'FPC_ANSISTR_VALSINT']; compilerproc;
  575. {$else}
  576. Procedure fpc_AnsiStr_Longint(v : Longint; Len : SizeInt; Var S : AnsiString);[Public,Alias : 'FPC_ANSISTR_LONGINT']; compilerproc;
  577. {$endif}
  578. Var
  579. SS : ShortString;
  580. begin
  581. str (v:Len,SS);
  582. S:=SS;
  583. end;
  584. {$ifndef CPU64}
  585. Procedure fpc_AnsiStr_QWord(v : QWord;Len : SizeInt; Var S : AnsiString);[Public,Alias : 'FPC_ANSISTR_QWORD']; compilerproc;
  586. Var
  587. SS : ShortString;
  588. begin
  589. str(v:Len,SS);
  590. S:=SS;
  591. end;
  592. Procedure fpc_AnsiStr_Int64(v : Int64; Len : SizeInt; Var S : AnsiString);[Public,Alias : 'FPC_ANSISTR_INT64']; compilerproc;
  593. Var
  594. SS : ShortString;
  595. begin
  596. str (v:Len,SS);
  597. S:=SS;
  598. end;
  599. {$endif CPU64}
  600. Procedure Delete (Var S : AnsiString; Index,Size: SizeInt);
  601. Var
  602. LS : SizeInt;
  603. begin
  604. ls:=Length(S);
  605. If (Index>LS) or (Index<=0) or (Size<=0) then
  606. exit;
  607. UniqueString (S);
  608. If (Size>LS-Index) then // Size+Index gives overflow ??
  609. Size:=LS-Index+1;
  610. If (Size<=LS-Index) then
  611. begin
  612. Dec(Index);
  613. Move(PByte(Pointer(S))[Index+Size],PByte(Pointer(S))[Index],LS-Index-Size+1);
  614. end;
  615. Setlength(S,LS-Size);
  616. end;
  617. Procedure Insert (Const Source : AnsiString; Var S : AnsiString; Index : SizeInt);
  618. var
  619. Temp : AnsiString;
  620. LS : SizeInt;
  621. begin
  622. If Length(Source)=0 then
  623. exit;
  624. if index <= 0 then
  625. index := 1;
  626. Ls:=Length(S);
  627. if index > LS then
  628. index := LS+1;
  629. Dec(Index);
  630. Pointer(Temp) := NewAnsiString(Length(Source)+LS);
  631. SetLength(Temp,Length(Source)+LS);
  632. If Index>0 then
  633. move (Pointer(S)^,Pointer(Temp)^,Index);
  634. Move (Pointer(Source)^,PByte(Temp)[Index],Length(Source));
  635. If (LS-Index)>0 then
  636. Move(PByte(Pointer(S))[Index],PByte(temp)[Length(Source)+index],LS-Index);
  637. S:=Temp;
  638. end;
  639. Function StringOfChar(c : char;l : SizeInt) : AnsiString;
  640. begin
  641. SetLength(StringOfChar,l);
  642. FillChar(Pointer(StringOfChar)^,Length(StringOfChar),c);
  643. end;
  644. Procedure SetString (Var S : AnsiString; Buf : PChar; Len : SizeInt);
  645. begin
  646. SetLength(S,Len);
  647. If (Buf<>Nil) then
  648. begin
  649. Move (Buf[0],S[1],Len);
  650. end;
  651. end;
  652. function upcase(const s : ansistring) : ansistring;
  653. var
  654. i : SizeInt;
  655. begin
  656. Setlength(result,length(s));
  657. for i := 1 to length (s) do
  658. result[i] := upcase(s[i]);
  659. end;
  660. function lowercase(const s : ansistring) : ansistring;
  661. var
  662. i : SizeInt;
  663. begin
  664. Setlength(result,length(s));
  665. for i := 1 to length (s) do
  666. result[i] := lowercase(s[i]);
  667. end;