astrings.inc 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Michael Van Canneyt,
  5. member of the Free Pascal development team.
  6. This file implements AnsiStrings for FPC
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. { This will release some functions for special shortstring support }
  14. { define EXTRAANSISHORT}
  15. {
  16. This file contains the implementation of the AnsiString type,
  17. and all things that are needed for it.
  18. AnsiString is defined as a 'silent' pchar :
  19. a pchar that points to :
  20. @-12 : Longint for maximum size;
  21. @-8 : Longint for size;
  22. @-4 : Longint for reference count;
  23. @ : String + Terminating #0;
  24. Pchar(Ansistring) is a valid typecast.
  25. So AS[i] is converted to the address @AS+i-1.
  26. Constants should be assigned a reference count of -1
  27. Meaning that they can't be disposed of.
  28. }
  29. Type
  30. PAnsiRec = ^TAnsiRec;
  31. TAnsiRec = Packed Record
  32. Maxlen,
  33. len,
  34. ref : Longint;
  35. First : Char;
  36. end;
  37. Const
  38. AnsiRecLen = SizeOf(TAnsiRec);
  39. FirstOff = SizeOf(TAnsiRec)-1;
  40. {****************************************************************************
  41. Internal functions, not in interface.
  42. ****************************************************************************}
  43. {$ifdef AnsiStrDebug}
  44. Procedure DumpAnsiRec(S : Pointer);
  45. begin
  46. If S=Nil then
  47. Writeln ('String is nil')
  48. Else
  49. Begin
  50. With PAnsiRec(S-Firstoff)^ do
  51. begin
  52. Write ('(Maxlen: ',maxlen);
  53. Write (' Len:',len);
  54. Writeln (' Ref: ',ref,')');
  55. end;
  56. end;
  57. end;
  58. {$endif}
  59. Function NewAnsiString(Len : Longint) : Pointer;
  60. {
  61. Allocate a new AnsiString on the heap.
  62. initialize it to zero length and reference count 1.
  63. }
  64. Var
  65. P : Pointer;
  66. begin
  67. { Also add +1 for a terminating zero }
  68. GetMem(P,Len+AnsiRecLen);
  69. If P<>Nil then
  70. begin
  71. PAnsiRec(P)^.Maxlen:=Len; { Maximal length }
  72. PAnsiRec(P)^.Len:=0; { Initial length }
  73. PAnsiRec(P)^.Ref:=1; { Set reference count }
  74. PAnsiRec(P)^.First:=#0; { Terminating #0 }
  75. P:=P+FirstOff; { Points to string now }
  76. end;
  77. NewAnsiString:=P;
  78. end;
  79. Procedure DisposeAnsiString(Var S : Pointer);
  80. {
  81. Deallocates a AnsiString From the heap.
  82. }
  83. begin
  84. If S=Nil then
  85. exit;
  86. Dec (Longint(S),FirstOff);
  87. FreeMem (S);
  88. S:=Nil;
  89. end;
  90. Procedure AnsiStr_Decr_Ref (Var S : Pointer);[Public,Alias:'FPC_ANSISTR_DECR_REF'];
  91. {
  92. Decreases the ReferenceCount of a non constant ansistring;
  93. If the reference count is zero, deallocate the string;
  94. }
  95. Type
  96. plongint = ^longint;
  97. Var
  98. l : plongint;
  99. Begin
  100. { Zero string }
  101. If S=Nil then exit;
  102. { check for constant strings ...}
  103. l:=@PANSIREC(S-FirstOff)^.Ref;
  104. If l^<0 then exit;
  105. Dec(l^);
  106. If l^=0 then
  107. { Ref count dropped to zero }
  108. DisposeAnsiString (S); { Remove...}
  109. { this pointer is not valid anymore, so set it to zero }
  110. S:=nil;
  111. end;
  112. Procedure AnsiStr_Incr_Ref (Var S : Pointer);[Public,Alias:'FPC_ANSISTR_INCR_REF'];
  113. Begin
  114. If S=Nil then
  115. exit;
  116. { Let's be paranoid : Constant string ??}
  117. If PAnsiRec(S-FirstOff)^.Ref<0 then exit;
  118. Inc(PAnsiRec(S-FirstOff)^.Ref);
  119. end;
  120. Procedure AnsiStr_Assign (Var S1 : Pointer;S2 : Pointer);[Public,Alias:'FPC_ANSISTR_ASSIGN'];
  121. {
  122. Assigns S2 to S1 (S1:=S2), taking in account reference counts.
  123. }
  124. begin
  125. If S2<>nil then
  126. If PAnsiRec(S2-FirstOff)^.Ref>0 then
  127. Inc(PAnsiRec(S2-FirstOff)^.ref);
  128. { Decrease the reference count on the old S1 }
  129. ansistr_decr_ref (S1);
  130. { And finally, have S1 pointing to S2 (or its copy) }
  131. S1:=S2;
  132. end;
  133. Procedure AnsiStr_Concat (S1,S2 : Pointer;var S3 : Pointer);[Public, alias: 'FPC_ANSISTR_CONCAT'];
  134. {
  135. Concatenates 2 AnsiStrings : S1+S2.
  136. Result Goes to S3;
  137. }
  138. Var
  139. Size,Location : Longint;
  140. begin
  141. { create new result }
  142. if S3<>nil then
  143. AnsiStr_Decr_Ref(S3);
  144. { only assign if s1 or s2 is empty }
  145. if (S1=Nil) then
  146. AnsiStr_Assign(S3,S2)
  147. else
  148. if (S2=Nil) then
  149. AnsiStr_Assign(S3,S1)
  150. else
  151. begin
  152. Size:=PAnsiRec(S2-FirstOff)^.Len;
  153. Location:=Length(AnsiString(S1));
  154. SetLength (AnsiString(S3),Size+Location);
  155. Move (S1^,S3^,Location);
  156. Move (S2^,(S3+location)^,Size+1);
  157. end;
  158. end;
  159. {$ifdef EXTRAANSISHORT}
  160. Procedure AnsiStr_ShortStr_Concat (Var S1: AnsiString; Var S2 : ShortString);
  161. {
  162. Concatenates a Ansi with a short string; : S2 + S2
  163. }
  164. Var
  165. Size,Location : Longint;
  166. begin
  167. Size:=Length(S2);
  168. Location:=Length(S1);
  169. If Size=0 then
  170. exit;
  171. { Setlength takes case of uniqueness
  172. and alllocated memory. We need to use length,
  173. to take into account possibility of S1=Nil }
  174. SetLength (S1,Size+Length(S1));
  175. Move (S2[1],Pointer(Pointer(S1)+Location)^,Size);
  176. PByte( Pointer(S1)+length(S1) )^:=0; { Terminating Zero }
  177. end;
  178. {$endif EXTRAANSISHORT}
  179. Procedure AnsiStr_To_ShortStr (Var S1 : ShortString;S2 : Pointer);[Public, alias: 'FPC_ANSISTR_TO_SHORTSTR'];
  180. {
  181. Converts a AnsiString to a ShortString;
  182. }
  183. Var
  184. Size : Longint;
  185. begin
  186. if S2=nil then
  187. S1:=''
  188. else
  189. begin
  190. Size:=PAnsiRec(S2-FirstOff)^.Len;
  191. If Size>high(S1) then
  192. Size:=high(S1);
  193. Move (S2^,S1[1],Size);
  194. byte(S1[0]):=Size;
  195. end;
  196. end;
  197. Procedure ShortStr_To_AnsiStr (Var S1 : Pointer; Const S2 : ShortString);[Public, alias: 'FPC_SHORTSTR_TO_ANSISTR'];
  198. {
  199. Converts a ShortString to a AnsiString;
  200. }
  201. Var
  202. Size : Longint;
  203. begin
  204. Size:=Length(S2);
  205. Setlength (AnsiString(S1),Size);
  206. if Size>0 then
  207. begin
  208. Move (S2[1],Pointer(S1)^,Size);
  209. { Terminating Zero }
  210. PByte(Pointer(S1)+Size)^:=0;
  211. end;
  212. end;
  213. Procedure Char_To_AnsiStr(var S1 : Pointer; c : Char);[Public, alias: 'FPC_CHAR_TO_ANSISTR'];
  214. {
  215. Converts a ShortString to a AnsiString;
  216. }
  217. begin
  218. Setlength (AnsiString(S1),1);
  219. PByte(Pointer(S1))^:=byte(c);
  220. { Terminating Zero }
  221. PByte(Pointer(S1)+1)^:=0;
  222. end;
  223. Procedure PChar_To_AnsiStr(var a : ansistring;p : pchar);[Public,Alias : 'FPC_PCHAR_TO_ANSISTR'];
  224. Var
  225. L : Longint;
  226. begin
  227. if pointer(a)<>nil then
  228. begin
  229. AnsiStr_Decr_Ref(Pointer(a));
  230. pointer(a):=nil;
  231. end;
  232. if (not assigned(p)) or (p[0]=#0) Then
  233. Pointer(a):=nil
  234. else
  235. begin
  236. //!! Horribly inneficient, but I see no other way...
  237. L:=1;
  238. While P[l]<>#0 do
  239. inc (l);
  240. Pointer(a):=NewAnsistring(L);
  241. SetLength(A,L);
  242. Move (P[0],Pointer(A)^,L)
  243. end;
  244. end;
  245. Procedure CharArray_To_AnsiStr(var a : ansistring;p : pchar;l:longint);[Public,Alias : 'FPC_CHARARRAY_TO_ANSISTR'];
  246. var
  247. i : longint;
  248. hp : pchar;
  249. begin
  250. if p[0]=#0 Then
  251. Pointer(a):=nil
  252. else
  253. begin
  254. { p[0] <> #0, checked above (JM) }
  255. hp:=p+1;
  256. i:=1;
  257. while (i<l) and (hp^<>#0) do
  258. begin
  259. inc(hp);
  260. inc(i);
  261. end;
  262. Pointer(a):=NewAnsistring(i);
  263. SetLength(A,i);
  264. Move (P[0],Pointer(A)^,i);
  265. end;
  266. end;
  267. Function AnsiStr_Compare(S1,S2 : Pointer): Longint;[Public,Alias : 'FPC_ANSISTR_COMPARE'];
  268. {
  269. Compares 2 AnsiStrings;
  270. The result is
  271. <0 if S1<S2
  272. 0 if S1=S2
  273. >0 if S1>S2
  274. }
  275. Var
  276. i,MaxI,Temp : Longint;
  277. begin
  278. i:=0;
  279. Maxi:=Length(AnsiString(S1));
  280. temp:=Length(AnsiString(S2));
  281. If MaxI>Temp then
  282. MaxI:=Temp;
  283. Temp:=0;
  284. While (i<MaxI) and (Temp=0) do
  285. begin
  286. Temp:= PByte(S1+I)^ - PByte(S2+i)^;
  287. inc(i);
  288. end;
  289. if temp=0 then
  290. temp:=Length(AnsiString(S1))-Length(AnsiString(S2));
  291. AnsiStr_Compare:=Temp;
  292. end;
  293. Procedure AnsiStr_CheckZero(p : pointer);[Public,Alias : 'FPC_ANSISTR_CHECKZERO'];
  294. begin
  295. if p=nil then
  296. HandleErrorFrame(201,get_frame);
  297. end;
  298. Procedure AnsiStr_CheckRange(len,index : longint);[Public,Alias : 'FPC_ANSISTR_RANGECHECK'];
  299. begin
  300. if (index>len) or (Index<1) then
  301. HandleErrorFrame(201,get_frame);
  302. end;
  303. {$ifdef EXTRAANSISHORT}
  304. Function AnsiStr_ShortStr_Compare (Var S1 : Pointer; Var S2 : ShortString): Longint;
  305. {
  306. Compares a AnsiString with a ShortString;
  307. The result is
  308. <0 if S1<S2
  309. 0 if S1=S2
  310. >0 if S1>S2
  311. }
  312. Var
  313. i,MaxI,Temp : Longint;
  314. begin
  315. Temp:=0;
  316. i:=0;
  317. MaxI:=Length(AnsiString(S1));
  318. if MaxI>byte(S2[0]) then
  319. MaxI:=Byte(S2[0]);
  320. While (i<MaxI) and (Temp=0) do
  321. begin
  322. Temp:= PByte(S1+I)^ - Byte(S2[i+1]);
  323. inc(i);
  324. end;
  325. AnsiStr_ShortStr_Compare:=Temp;
  326. end;
  327. {$endif EXTRAANSISHORT}
  328. {*****************************************************************************
  329. Public functions, In interface.
  330. *****************************************************************************}
  331. Function Length (Const S : AnsiString) : Longint;
  332. {
  333. Returns the length of an AnsiString.
  334. Takes in acount that zero strings are NIL;
  335. }
  336. begin
  337. If Pointer(S)=Nil then
  338. Length:=0
  339. else
  340. Length:=PAnsiRec(Pointer(S)-FirstOff)^.Len;
  341. end;
  342. Procedure SetLength (Var S : AnsiString; l : Longint);
  343. {
  344. Sets The length of string S to L.
  345. Makes sure S is unique, and contains enough room.
  346. }
  347. Var
  348. Temp : Pointer;
  349. movelen: longint;
  350. begin
  351. if (l>0) then
  352. begin
  353. if Pointer(S)=nil then
  354. begin
  355. { Need a complete new string...}
  356. Pointer(s):=NewAnsiString(l);
  357. end
  358. else
  359. If (PAnsiRec(Pointer(S)-FirstOff)^.Maxlen < L) or
  360. (PAnsiRec(Pointer(S)-FirstOff)^.Ref <> 1) then
  361. begin
  362. { Reallocation is needed... }
  363. Temp:=Pointer(NewAnsiString(L));
  364. if Length(S)>0 then
  365. begin
  366. if l < succ(length(s)) then
  367. movelen := l
  368. { also move terminating null }
  369. else movelen := succ(length(s));
  370. Move(Pointer(S)^,Temp^,movelen);
  371. end;
  372. ansistr_decr_ref(Pointer(S));
  373. Pointer(S):=Temp;
  374. end;
  375. { Force nil termination in case it gets shorter }
  376. PByte(Pointer(S)+l)^:=0;
  377. PAnsiRec(Pointer(S)-FirstOff)^.Len:=l;
  378. end
  379. else
  380. begin
  381. { Length=0 }
  382. if Pointer(S)<>nil then
  383. ansistr_decr_ref (Pointer(S));
  384. Pointer(S):=Nil;
  385. end;
  386. end;
  387. Procedure UniqueString(Var S : AnsiString); [Public,Alias : 'FPC_ANSISTR_UNIQUE'];
  388. {
  389. Make sure reference count of S is 1,
  390. using copy-on-write semantics.
  391. }
  392. Var
  393. SNew : Pointer;
  394. begin
  395. If Pointer(S)=Nil then
  396. exit;
  397. if PAnsiRec(Pointer(S)-Firstoff)^.Ref<>1 then
  398. begin
  399. SNew:=NewAnsiString (PAnsiRec(Pointer(S)-FirstOff)^.len);
  400. Move (Pointer(S)^,SNew^,PAnsiRec(Pointer(S)-FirstOff)^.len+1);
  401. PAnsiRec(SNew-FirstOff)^.len:=PAnsiRec(Pointer(S)-FirstOff)^.len;
  402. ansistr_decr_ref (Pointer(S)); { Thread safe }
  403. Pointer(S):=SNew;
  404. end;
  405. end;
  406. Function Copy (Const S : AnsiString; Index,Size : Longint) : AnsiString;
  407. var
  408. ResultAddress : Pointer;
  409. begin
  410. ResultAddress:=Nil;
  411. dec(index);
  412. if Index < 0 then
  413. Index := 0;
  414. { Check Size. Accounts for Zero-length S, the double check is needed because
  415. Size can be maxint and will get <0 when adding index }
  416. if (Size>Length(S)) or
  417. (Index+Size>Length(S)) then
  418. Size:=Length(S)-Index;
  419. If Size>0 then
  420. begin
  421. If Index<0 Then
  422. Index:=0;
  423. ResultAddress:=Pointer(NewAnsiString (Size));
  424. if ResultAddress<>Nil then
  425. begin
  426. Move (Pointer(Pointer(S)+index)^,ResultAddress^,Size);
  427. PAnsiRec(ResultAddress-FirstOff)^.Len:=Size;
  428. PByte(ResultAddress+Size)^:=0;
  429. end;
  430. end;
  431. Pointer(Copy):=ResultAddress;
  432. end;
  433. Function Pos (Const Substr : AnsiString; Const Source : AnsiString) : Longint;
  434. var
  435. substrlen,
  436. maxi,
  437. i,j : longint;
  438. e : boolean;
  439. S : AnsiString;
  440. se : Pointer;
  441. begin
  442. i := 0;
  443. j := 0;
  444. substrlen:=Length(SubStr);
  445. maxi:=length(source)-substrlen;
  446. e:=(substrlen>0);
  447. while (e) and (i <= maxi) do
  448. begin
  449. inc (i);
  450. if Source[i]=SubStr[1] then
  451. begin
  452. S:=copy(Source,i,substrlen);
  453. Se:=pointer(SubStr);
  454. if AnsiStr_Compare(se,Pointer(S))=0 then
  455. begin
  456. j := i;
  457. break;
  458. end;
  459. end;
  460. end;
  461. pos := j;
  462. end;
  463. Function ValAnsiFloat(Const S : AnsiString; Var Code : ValSInt): ValReal; [public, alias:'FPC_VAL_REAL_ANSISTR'];
  464. Var
  465. SS : String;
  466. begin
  467. AnsiStr_To_ShortStr(SS,Pointer(S));
  468. ValAnsiFloat := ValFloat(SS,Code);
  469. end;
  470. Function ValAnsiUnsignedInt (Const S : AnsiString; Var Code : ValSInt): ValUInt; [public, alias:'FPC_VAL_UINT_ANSISTR'];
  471. Var
  472. SS : ShortString;
  473. begin
  474. AnsiStr_To_ShortStr(SS,Pointer(S));
  475. ValAnsiUnsignedInt := ValUnsignedInt(SS,Code);
  476. end;
  477. Function ValAnsiSignedInt (DestSize: longint; Const S : AnsiString; Var Code : ValSInt): ValSInt; [public, alias:'FPC_VAL_SINT_ANSISTR'];
  478. Var
  479. SS : ShortString;
  480. begin
  481. AnsiStr_To_ShortStr (SS,Pointer(S));
  482. ValAnsiSignedInt := ValSignedInt(DestSize,SS,Code);
  483. end;
  484. Function ValAnsiUnsignedint64 (Const S : AnsiString; Var Code : ValSInt): qword; [public, alias:'FPC_VAL_UINT64_ANSISTR'];
  485. Var
  486. SS : ShortString;
  487. begin
  488. AnsiStr_To_ShortStr(SS,Pointer(S));
  489. ValAnsiUnsignedInt64 := ValQWord(SS,Code);
  490. end;
  491. Function ValAnsiSignedInt64 (DestSize: longint; Const S : AnsiString; Var Code : ValSInt): Int64; [public, alias:'FPC_VAL_INT64_ANSISTR'];
  492. Var
  493. SS : ShortString;
  494. begin
  495. AnsiStr_To_ShortStr (SS,Pointer(S));
  496. ValAnsiSignedInt64 := valInt64(SS,Code);
  497. end;
  498. {$IfDef SUPPORT_FIXED}
  499. Function ValAnsiFixed(Const S : AnsiString; Var Code : ValSint): ValReal; [public, alias:'FPC_VAL_FIXED_ANSISTR'];
  500. Var
  501. SS : String;
  502. begin
  503. AnsiStr_To_ShortStr (SS,Pointer(S));
  504. ValAnsiFixed := Fixed(ValFloat(SS,Code));
  505. end;
  506. {$EndIf SUPPORT_FIXED}
  507. procedure AnsiStr_Float(d : ValReal;len,fr,rt : longint;var s : ansistring);[public,alias:'FPC_ANSISTR_FLOAT'];
  508. var
  509. ss : shortstring;
  510. begin
  511. str_real(len,fr,d,treal_type(rt),ss);
  512. s:=ss;
  513. end;
  514. Procedure AnsiStr_Cardinal(C : Cardinal;Len : Longint; Var S : AnsiString);[Public,Alias : 'FPC_ANSISTR_CARDINAL'];
  515. Var
  516. SS : ShortString;
  517. begin
  518. int_str_cardinal(C,Len,SS);
  519. S:=SS;
  520. end;
  521. Procedure AnsiStr_Longint(L : Longint; Len : Longint; Var S : AnsiString);[Public,Alias : 'FPC_ANSISTR_LONGINT'];
  522. Var
  523. SS : ShortString;
  524. begin
  525. int_Str_Longint (L,Len,SS);
  526. S:=SS;
  527. end;
  528. Procedure Delete (Var S : AnsiString; Index,Size: Longint);
  529. Var
  530. LS : Longint;
  531. begin
  532. If Length(S)=0 then
  533. exit;
  534. if index<=0 then
  535. begin
  536. inc(Size,index-1);
  537. index:=1;
  538. end;
  539. LS:=PAnsiRec(Pointer(S)-FirstOff)^.Len;
  540. if (Index<=LS) and (Size>0) then
  541. begin
  542. UniqueString (S);
  543. if Size+Index>LS then
  544. Size:=LS-Index+1;
  545. if Index+Size<=LS then
  546. begin
  547. Dec(Index);
  548. Move(PByte(Pointer(S))[Index+Size],PByte(Pointer(S))[Index],LS-Index+1);
  549. end;
  550. Setlength(s,LS-Size);
  551. end;
  552. end;
  553. Procedure Insert (Const Source : AnsiString; Var S : AnsiString; Index : Longint);
  554. var
  555. Temp : AnsiString;
  556. LS : Longint;
  557. begin
  558. If Length(Source)=0 then
  559. exit;
  560. if index <= 0 then
  561. index := 1;
  562. Ls:=Length(S);
  563. if index > LS then
  564. index := LS+1;
  565. Dec(Index);
  566. Pointer(Temp) := NewAnsiString(Length(Source)+LS);
  567. SetLength(Temp,Length(Source)+LS);
  568. If Index>0 then
  569. move (Pointer(S)^,Pointer(Temp)^,Index);
  570. Move (Pointer(Source)^,PByte(Temp)[Index],Length(Source));
  571. If (LS-Index)>0 then
  572. Move(PByte(Pointer(S))[Index],PByte(temp)[Length(Source)+index],LS-Index);
  573. S:=Temp;
  574. end;
  575. Function StringOfChar(c : char;l : longint) : AnsiString;
  576. begin
  577. SetLength(StringOfChar,l);
  578. FillChar(Pointer(StringOfChar)^,Length(StringOfChar),c);
  579. end;
  580. Procedure SetString (Var S : AnsiString; Buf : PChar; Len : Longint);
  581. begin
  582. SetLength(S,Len);
  583. Move (Buf[0],S[1],Len);
  584. end;
  585. {
  586. $Log$
  587. Revision 1.5 2000-08-29 18:39:42 peter
  588. * fixed chararray to ansistring (merged)
  589. Revision 1.4 2000/08/24 07:37:21 jonas
  590. * fixed bug in setlength (it sometimes read after the end of the heap)
  591. and small improvement to ansistring_to_chararray conversion (merged
  592. from fixes branch)
  593. Revision 1.3 2000/08/09 19:31:18 marco
  594. * fixes for val(int64 or qword) to ansistring
  595. Revision 1.2 2000/07/13 11:33:42 michael
  596. + removed logs
  597. }