astrings.inc 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762
  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. { declocked does a MT safe dec and returns true, if the counter is 0 }
  106. If declocked(l^) 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. inclocked(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. inclocked(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. l:=IndexChar(p^,-1,#0);
  237. Pointer(a):=NewAnsistring(L);
  238. SetLength(A,L);
  239. Move (P[0],Pointer(A)^,L)
  240. end;
  241. end;
  242. Procedure CharArray_To_AnsiStr(var a : ansistring;p : pchar;l:longint);[Public,Alias : 'FPC_CHARARRAY_TO_ANSISTR'];
  243. var
  244. i : longint;
  245. begin
  246. if p[0]=#0 Then
  247. Pointer(a):=nil
  248. else
  249. begin
  250. i:=IndexChar(p^,L,#0);
  251. Pointer(a):=NewAnsistring(i);
  252. SetLength(a,i);
  253. Move (P[0],Pointer(A)^,i);
  254. end;
  255. end;
  256. Function AnsiStr_Compare(S1,S2 : Pointer): Longint;[Public,Alias : 'FPC_ANSISTR_COMPARE'];
  257. {
  258. Compares 2 AnsiStrings;
  259. The result is
  260. <0 if S1<S2
  261. 0 if S1=S2
  262. >0 if S1>S2
  263. }
  264. Var
  265. MaxI,Temp : Longint;
  266. begin
  267. if S1=S2 then
  268. begin
  269. AnsiStr_Compare:=0;
  270. exit;
  271. end;
  272. Maxi:=Length(AnsiString(S1));
  273. temp:=Length(AnsiString(S2));
  274. If MaxI>Temp then
  275. MaxI:=Temp;
  276. Temp:=CompareByte(S1^,S2^,MaxI);
  277. if temp=0 then
  278. temp:=Length(AnsiString(S1))-Length(AnsiString(S2));
  279. AnsiStr_Compare:=Temp;
  280. end;
  281. Procedure AnsiStr_CheckZero(p : pointer);[Public,Alias : 'FPC_ANSISTR_CHECKZERO'];
  282. begin
  283. if p=nil then
  284. HandleErrorFrame(201,get_frame);
  285. end;
  286. Procedure AnsiStr_CheckRange(len,index : longint);[Public,Alias : 'FPC_ANSISTR_RANGECHECK'];
  287. begin
  288. if (index>len) or (Index<1) then
  289. HandleErrorFrame(201,get_frame);
  290. end;
  291. {$ifndef INTERNSETLENGTH}
  292. Procedure SetLength (Var S : AnsiString; l : Longint);
  293. {$else INTERNSETLENGTH}
  294. Procedure AnsiStr_SetLength (Var S : AnsiString; l : Longint);[Public,Alias : 'FPC_ANSISTR_SETLENGTH'];
  295. {$endif INTERNSETLENGTH}
  296. {
  297. Sets The length of string S to L.
  298. Makes sure S is unique, and contains enough room.
  299. }
  300. Var
  301. Temp : Pointer;
  302. movelen: longint;
  303. begin
  304. if (l>0) then
  305. begin
  306. if Pointer(S)=nil then
  307. begin
  308. { Need a complete new string...}
  309. Pointer(s):=NewAnsiString(l);
  310. end
  311. else
  312. If (PAnsiRec(Pointer(S)-FirstOff)^.Maxlen < L) or
  313. (PAnsiRec(Pointer(S)-FirstOff)^.Ref <> 1) then
  314. begin
  315. { Reallocation is needed... }
  316. Temp:=Pointer(NewAnsiString(L));
  317. if Length(S)>0 then
  318. begin
  319. if l < succ(length(s)) then
  320. movelen := l
  321. { also move terminating null }
  322. else movelen := succ(length(s));
  323. Move(Pointer(S)^,Temp^,movelen);
  324. end;
  325. ansistr_decr_ref(Pointer(S));
  326. Pointer(S):=Temp;
  327. end;
  328. { Force nil termination in case it gets shorter }
  329. PByte(Pointer(S)+l)^:=0;
  330. PAnsiRec(Pointer(S)-FirstOff)^.Len:=l;
  331. end
  332. else
  333. begin
  334. { Length=0 }
  335. if Pointer(S)<>nil then
  336. ansistr_decr_ref (Pointer(S));
  337. Pointer(S):=Nil;
  338. end;
  339. end;
  340. {$ifdef EXTRAANSISHORT}
  341. Function AnsiStr_ShortStr_Compare (Var S1 : Pointer; Var S2 : ShortString): Longint;
  342. {
  343. Compares a AnsiString with a ShortString;
  344. The result is
  345. <0 if S1<S2
  346. 0 if S1=S2
  347. >0 if S1>S2
  348. }
  349. Var
  350. i,MaxI,Temp : Longint;
  351. begin
  352. Temp:=0;
  353. i:=0;
  354. MaxI:=Length(AnsiString(S1));
  355. if MaxI>byte(S2[0]) then
  356. MaxI:=Byte(S2[0]);
  357. While (i<MaxI) and (Temp=0) do
  358. begin
  359. Temp:= PByte(S1+I)^ - Byte(S2[i+1]);
  360. inc(i);
  361. end;
  362. AnsiStr_ShortStr_Compare:=Temp;
  363. end;
  364. {$endif EXTRAANSISHORT}
  365. {*****************************************************************************
  366. Public functions, In interface.
  367. *****************************************************************************}
  368. {$ifndef INTERNLENGTH}
  369. Function Length (Const S : AnsiString) : Longint;
  370. {
  371. Returns the length of an AnsiString.
  372. Takes in acount that zero strings are NIL;
  373. }
  374. begin
  375. If Pointer(S)=Nil then
  376. Length:=0
  377. else
  378. Length:=PAnsiRec(Pointer(S)-FirstOff)^.Len;
  379. end;
  380. {$endif INTERNLENGTH}
  381. Procedure UniqueString(Var S : AnsiString); [Public,Alias : 'FPC_ANSISTR_UNIQUE'];
  382. {
  383. Make sure reference count of S is 1,
  384. using copy-on-write semantics.
  385. }
  386. Var
  387. SNew : Pointer;
  388. L : Longint;
  389. begin
  390. If Pointer(S)=Nil then
  391. exit;
  392. if PAnsiRec(Pointer(S)-Firstoff)^.Ref<>1 then
  393. begin
  394. L:=PAnsiRec(Pointer(S)-FirstOff)^.len;
  395. SNew:=NewAnsiString (L);
  396. Move (Pointer(S)^,SNew^,L+1);
  397. PAnsiRec(SNew-FirstOff)^.len:=L;
  398. ansistr_decr_ref (Pointer(S)); { Thread safe }
  399. Pointer(S):=SNew;
  400. end;
  401. end;
  402. Function Copy (Const S : AnsiString; Index,Size : Longint) : AnsiString;
  403. var
  404. ResultAddress : Pointer;
  405. begin
  406. ResultAddress:=Nil;
  407. dec(index);
  408. if Index < 0 then
  409. Index := 0;
  410. { Check Size. Accounts for Zero-length S, the double check is needed because
  411. Size can be maxint and will get <0 when adding index }
  412. if (Size>Length(S)) or
  413. (Index+Size>Length(S)) then
  414. Size:=Length(S)-Index;
  415. If Size>0 then
  416. begin
  417. If Index<0 Then
  418. Index:=0;
  419. ResultAddress:=Pointer(NewAnsiString (Size));
  420. if ResultAddress<>Nil then
  421. begin
  422. Move (Pointer(Pointer(S)+index)^,ResultAddress^,Size);
  423. PAnsiRec(ResultAddress-FirstOff)^.Len:=Size;
  424. PByte(ResultAddress+Size)^:=0;
  425. end;
  426. end;
  427. Pointer(Copy):=ResultAddress;
  428. end;
  429. Function Pos (Const Substr : AnsiString; Const Source : AnsiString) : Longint;
  430. var
  431. i,MaxLen : StrLenInt;
  432. pc : pchar;
  433. begin
  434. Pos:=0;
  435. if Length(SubStr)>0 then
  436. begin
  437. MaxLen:=Length(source)-Length(SubStr);
  438. i:=0;
  439. pc:=@source[1];
  440. while (i<=MaxLen) do
  441. begin
  442. inc(i);
  443. if (SubStr[1]=pc^) and
  444. (CompareChar(Substr[1],pc^,Length(SubStr))=0) then
  445. begin
  446. Pos:=i;
  447. exit;
  448. end;
  449. inc(pc);
  450. end;
  451. end;
  452. end;
  453. { Faster version for a char alone. Must be implemented because }
  454. { pos(c: char; const s: shortstring) also exists, so otherwise }
  455. { using pos(char,pchar) will always call the shortstring version }
  456. { (exact match for first argument), also with $h+ (JM) }
  457. Function Pos (c : Char; Const s : AnsiString) : Longint;
  458. var
  459. i: longint;
  460. pc : pchar;
  461. begin
  462. pc:=@s[1];
  463. for i:=1 to length(s) do
  464. begin
  465. if pc^=c then
  466. begin
  467. pos:=i;
  468. exit;
  469. end;
  470. inc(pc);
  471. end;
  472. pos:=0;
  473. end;
  474. Function ValAnsiFloat(Const S : AnsiString; Var Code : ValSInt): ValReal; [public, alias:'FPC_VAL_REAL_ANSISTR'];
  475. Var
  476. SS : String;
  477. begin
  478. AnsiStr_To_ShortStr(SS,Pointer(S));
  479. ValAnsiFloat := ValFloat(SS,Code);
  480. end;
  481. Function ValAnsiUnsignedInt (Const S : AnsiString; Var Code : ValSInt): ValUInt; [public, alias:'FPC_VAL_UINT_ANSISTR'];
  482. Var
  483. SS : ShortString;
  484. begin
  485. AnsiStr_To_ShortStr(SS,Pointer(S));
  486. ValAnsiUnsignedInt := ValUnsignedInt(SS,Code);
  487. end;
  488. Function ValAnsiSignedInt (DestSize: longint; Const S : AnsiString; Var Code : ValSInt): ValSInt; [public, alias:'FPC_VAL_SINT_ANSISTR'];
  489. Var
  490. SS : ShortString;
  491. begin
  492. ValAnsiSignedInt:=0;
  493. if length(S)>255 then
  494. code:=256
  495. else
  496. begin
  497. AnsiStr_To_ShortStr (SS,Pointer(S));
  498. ValAnsiSignedInt := ValSignedInt(DestSize,SS,Code);
  499. end;
  500. end;
  501. Function ValAnsiUnsignedint64 (Const S : AnsiString; Var Code : ValSInt): qword; [public, alias:'FPC_VAL_QWORD_ANSISTR'];
  502. Var
  503. SS : ShortString;
  504. begin
  505. ValAnsiUnsignedInt64:=0;
  506. if length(S)>255 then
  507. code:=256
  508. else
  509. begin
  510. AnsiStr_To_ShortStr(SS,Pointer(S));
  511. ValAnsiUnsignedInt64 := ValQWord(SS,Code);
  512. end;
  513. end;
  514. Function ValAnsiSignedInt64 (Const S : AnsiString; Var Code : ValSInt): Int64; [public, alias:'FPC_VAL_INT64_ANSISTR'];
  515. Var
  516. SS : ShortString;
  517. begin
  518. ValAnsiSignedInt64:=0;
  519. if length(S)>255 then
  520. code:=256
  521. else
  522. begin
  523. AnsiStr_To_ShortStr (SS,Pointer(S));
  524. ValAnsiSignedInt64 := valInt64(SS,Code);
  525. end;
  526. end;
  527. procedure AnsiStr_Float(d : ValReal;len,fr,rt : longint;var s : ansistring);[public,alias:'FPC_ANSISTR_FLOAT'];
  528. var
  529. ss : shortstring;
  530. begin
  531. str_real(len,fr,d,treal_type(rt),ss);
  532. s:=ss;
  533. end;
  534. Procedure AnsiStr_Cardinal(C : Cardinal;Len : Longint; Var S : AnsiString);[Public,Alias : 'FPC_ANSISTR_CARDINAL'];
  535. Var
  536. SS : ShortString;
  537. begin
  538. int_str_cardinal(C,Len,SS);
  539. S:=SS;
  540. end;
  541. Procedure AnsiStr_Longint(L : Longint; Len : Longint; Var S : AnsiString);[Public,Alias : 'FPC_ANSISTR_LONGINT'];
  542. Var
  543. SS : ShortString;
  544. begin
  545. int_Str_Longint (L,Len,SS);
  546. S:=SS;
  547. end;
  548. Procedure Delete (Var S : AnsiString; Index,Size: Longint);
  549. Var
  550. LS : Longint;
  551. begin
  552. If Length(S)=0 then
  553. exit;
  554. if index<=0 then
  555. begin
  556. inc(Size,index-1);
  557. index:=1;
  558. end;
  559. LS:=PAnsiRec(Pointer(S)-FirstOff)^.Len;
  560. if (Index<=LS) and (Size>0) then
  561. begin
  562. UniqueString (S);
  563. if Size+Index>LS then
  564. Size:=LS-Index+1;
  565. if Index+Size<=LS then
  566. begin
  567. Dec(Index);
  568. Move(PByte(Pointer(S))[Index+Size],PByte(Pointer(S))[Index],LS-Index+1);
  569. end;
  570. Setlength(s,LS-Size);
  571. end;
  572. end;
  573. Procedure Insert (Const Source : AnsiString; Var S : AnsiString; Index : Longint);
  574. var
  575. Temp : AnsiString;
  576. LS : Longint;
  577. begin
  578. If Length(Source)=0 then
  579. exit;
  580. if index <= 0 then
  581. index := 1;
  582. Ls:=Length(S);
  583. if index > LS then
  584. index := LS+1;
  585. Dec(Index);
  586. Pointer(Temp) := NewAnsiString(Length(Source)+LS);
  587. SetLength(Temp,Length(Source)+LS);
  588. If Index>0 then
  589. move (Pointer(S)^,Pointer(Temp)^,Index);
  590. Move (Pointer(Source)^,PByte(Temp)[Index],Length(Source));
  591. If (LS-Index)>0 then
  592. Move(PByte(Pointer(S))[Index],PByte(temp)[Length(Source)+index],LS-Index);
  593. S:=Temp;
  594. end;
  595. Function StringOfChar(c : char;l : longint) : AnsiString;
  596. begin
  597. SetLength(StringOfChar,l);
  598. FillChar(Pointer(StringOfChar)^,Length(StringOfChar),c);
  599. end;
  600. Procedure SetString (Var S : AnsiString; Buf : PChar; Len : Longint);
  601. begin
  602. SetLength(S,Len);
  603. Move (Buf[0],S[1],Len);
  604. end;
  605. function upcase(const s : ansistring) : ansistring;
  606. var
  607. i : longint;
  608. begin
  609. Setlength(result,length(s));
  610. for i := 1 to length (s) do
  611. result[i] := upcase(s[i]);
  612. end;
  613. function lowercase(const s : ansistring) : ansistring;
  614. var
  615. i : longint;
  616. begin
  617. Setlength(result,length(s));
  618. for i := 1 to length (s) do
  619. result[i] := lowercase(s[i]);
  620. end;
  621. {
  622. $Log$
  623. Revision 1.15 2001-07-09 21:15:41 peter
  624. * Length made internal
  625. * Add array support for Length
  626. Revision 1.14 2001/07/09 11:41:57 florian
  627. * another MT fix
  628. Revision 1.13 2001/07/08 21:00:18 peter
  629. * various widestring updates, it works now mostly without charset
  630. mapping supported
  631. Revision 1.12 2001/07/04 12:17:09 jonas
  632. * removed DestSize parameter from declaration of ValAnsiSignedInt64
  633. (merged)
  634. Revision 1.11 2001/05/27 14:28:44 florian
  635. + made the ref. couting MT safe
  636. Revision 1.10 2001/04/13 18:06:07 peter
  637. * upcase, lowercase for ansistring
  638. Revision 1.9 2000/12/10 15:00:14 florian
  639. * val for int64 hopefully works now correct
  640. Revision 1.8 2000/12/08 14:04:43 jonas
  641. + added pos(char,ansistring), because there is also a pos(char,shortstring)
  642. and without the ansistring version, the shortstring version is always
  643. called when calling pos(char,pchar), even when using $h+ (because the
  644. first parameter matches exactly) (merged)
  645. Revision 1.7 2000/11/06 20:34:24 peter
  646. * changed ver1_0 defines to temporary defs
  647. Revision 1.6 2000/10/21 18:20:17 florian
  648. * a lot of small changes:
  649. - setlength is internal
  650. - win32 graph unit extended
  651. ....
  652. Revision 1.5 2000/08/29 18:39:42 peter
  653. * fixed chararray to ansistring (merged)
  654. Revision 1.4 2000/08/24 07:37:21 jonas
  655. * fixed bug in setlength (it sometimes read after the end of the heap)
  656. and small improvement to ansistring_to_chararray conversion (merged
  657. from fixes branch)
  658. Revision 1.3 2000/08/09 19:31:18 marco
  659. * fixes for val(int64 or qword) to ansistring
  660. Revision 1.2 2000/07/13 11:33:42 michael
  661. + removed logs
  662. }