2
0

lstrings.pp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  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. 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. This file contains the implementation of the LongString type,
  13. and all things that are needed for it.
  14. LongSTring is defined as a 'silent' pansichar :
  15. a pansichar that points to :
  16. @ : Longint for size
  17. @+4 : Unused byte;
  18. @+5 : AnsiString;
  19. So LS[i] is converted to the address @LS+4+i.
  20. pansichar[0]-pansichar[3] : Longint Size
  21. pansichar [4] : Unused
  22. pansichar[5] : AnsiString;
  23. }
  24. {$ifdef lstrings_unit}
  25. { Compile as a separate unit - development only}
  26. {$IFNDEF FPC_DOTTEDUNITS}
  27. unit lstrings;
  28. {$ENDIF FPC_DOTTEDUNITS}
  29. Interface
  30. Type longstring = pansichar;
  31. ShortString = string;
  32. { Internal functions, will not appear in systemh.inc }
  33. Function NewLongString (Len : Longint) : LongString;
  34. Procedure DisposeLongString (Var S : LongString; Len : Longint);
  35. Procedure Long_String_Concat (Var S1 : LongString; Const S2 : LongString; maxlen : Longint);
  36. Procedure Long_ShortString_Concat (Var S1: LongString; Const S2 : ShortString; maxlen : Longint);
  37. Procedure Long_To_ShortString (Var S1 : ShortString; Const S2 : LongString; Maxlen : Longint);
  38. Procedure Short_To_LongString (Var S1 : LongString; Const S2 : ShortString; Maxlen : Longint);
  39. Function LongCompare (Const S1,S2 : Longstring): Longint;
  40. Function LongCompare (Const S1 : LongString; Const S2 : ShortString): Longint;
  41. { Public functions, Will end up in systemh.inc }
  42. Procedure SetLength (Var S : LongString; l : Longint);
  43. Procedure Write_Text_LongString (Len : Longint; T : Textrec; Var S : LongString);
  44. Function Length (Const S : LongString) : Longint;
  45. Function Copy (Const S : LongString; Index,Size : Longint) : LongString;
  46. Function Pos (Const Substr : LongString; Const Source : Longstring) : Longint;
  47. Procedure Insert (Const Source : LongString; Var S : LongString; Index : Longint);
  48. Procedure Delete (Var S : LongString; Index,Size: Longint);
  49. Procedure Val (Const S : LongString; var R : real; Var Code : Integer);
  50. {Procedure Val (Const S : LongString; var D : Double; Var Code : Integer);}
  51. Procedure Val (Const S : LongString; var E : Extended; Code : Integer);
  52. Procedure Val (Const S : LongString; var C : Cardinal; Code : Integer);
  53. Procedure Val (Const S : LongString; var L : Longint; Var Code : Integer);
  54. Procedure Val (Const S : LongString; var W : Word; Var Code : Integer);
  55. Procedure Val (Const S : LongString; var I : Integer; Var Code : Integer);
  56. Procedure Val (Const S : LongString; var B : Byte; Var Code : Integer);
  57. Procedure Val (Const S : LongString; var SI : ShortInt; Var Code : Integer);
  58. Procedure Str (Const R : Real;Len, fr : longint; Var S : LongString);
  59. {Procedure Str (Const D : Double;Len,fr : longint; Var S : LongString);}
  60. Procedure Str (Const E : Extended;Len,fr : longint; Var S : LongString);
  61. Procedure Str (Const C : Cardinal;len : Longint; Var S : LongString);
  62. Procedure Str (Const L : LongInt;len : longint; Var S : LongString);
  63. Procedure Str (Const W : Word;len : longint; Var S : LongString);
  64. Procedure Str (Const I : Integer;len : Longint; Var S : LongString);
  65. Procedure Str (Const B : Byte; Len : longint; Var S : LongString);
  66. Procedure Str (Const SI : ShortInt; Len : longint; Var S : LongString);
  67. Implementation
  68. {$endif}
  69. Type PLongint = ^Longint;
  70. { ---------------------------------------------------------------------
  71. Internal functions, not in interface.
  72. ---------------------------------------------------------------------}
  73. Function NewLongString (Len : Longint) : LongString;
  74. {
  75. Allocate a new string on the heap.
  76. initialize it to zero length
  77. }
  78. Var P : Pointer;
  79. begin
  80. GetMem(P,Len+5);
  81. If P<>Nil then
  82. begin
  83. PLongint(P)^:=0;
  84. pansichar(P+4)^:=#0;
  85. end;
  86. NewLongString:=P;
  87. end;
  88. Procedure DisposeLongString (Var S : LongString; Len : Longint);
  89. {
  90. DeAllocates a LongString From the heap.
  91. }
  92. begin
  93. FreeMem (Pointer(S),Len+5);
  94. end;
  95. Procedure Long_String_Concat (Var S1 : LongString; Const S2 : LongString; maxlen : Longint);
  96. {
  97. Concatenates 2 LongStrings : S1+S2
  98. If maxlen<>-1 then the result has maximal length maxlen.
  99. }
  100. Var Size : Longint;
  101. begin
  102. Size:=PLongint(S2)^;
  103. If maxlen<>-1 then
  104. if Size+PLongint(S1)^>MaxLen then
  105. Size:=Maxlen-PLongint(S1)^;
  106. If Size<=0 then exit;
  107. Move (pansichar(S2)[5],ansipchar(S1)[PLongint(S1)^+5],Size);
  108. PLongint(S1)^:=PLongint(S1)^+Size;
  109. end;
  110. Procedure Long_ShortString_Concat (Var S1: LongString; Const S2 : ShortString; maxlen : Longint);
  111. {
  112. Concatenates a long with a short string; : S2 + S2
  113. If maxlen<>-1 then the result has maximal length maxlen.
  114. }
  115. Var Size : Longint;
  116. begin
  117. Size:=Byte(S2[0]);
  118. if MaxLen<>-1 then
  119. if Size+PLongint(S1)^>Maxlen then
  120. Size:=Maxlen-PLongint(S1)^;
  121. If Size<=0 then exit;
  122. Move (S2[1],PAnsiChar(S1)[PLongint(S1)^+5],Size);
  123. PLongint(S1)^:=PLongint(S1)^+Size;
  124. end;
  125. Procedure Long_To_ShortString (Var S1 : ShortString; Const S2 : LongString; Maxlen : Longint);
  126. {
  127. Converts a LongString to a longstring;
  128. if maxlen<>-1, the resulting string has maximal length maxlen
  129. else a default length of 255 is taken.
  130. }
  131. Var Size : Longint;
  132. begin
  133. Size:=PLongint(S2)^;
  134. if maxlen=-1 then maxlen:=255;
  135. If Size>maxlen then Size:=maxlen;
  136. Move (PAnsiChar(S2)[5],S1[1],Size);
  137. S1[0]:=chr(Size);
  138. end;
  139. Procedure Short_To_LongString (Var S1 : LongString; Const S2 : ShortString; Maxlen : Longint);
  140. {
  141. Converts a ShortString to a LongString;
  142. if maxlen<>-1 then the resulting string has length maxlen.
  143. }
  144. Var Size : Longint;
  145. begin
  146. Size:=Byte(S2[0]);
  147. if maxlen=-1 then maxlen:=255;
  148. If Size>maxlen then Size:=maxlen;
  149. Move (S2[1],PAnsiChar(S1)[5],Size);
  150. PLongint(S1)^:=Size;
  151. end;
  152. Function LongCompare (Const S1,S2 : Longstring): Longint;
  153. {
  154. Compares 2 longStrings;
  155. The result is
  156. <0 if S1<S2
  157. 0 if S1=S2
  158. >0 if S1>S2
  159. }
  160. Var i,MaxI,Temp : Longint;
  161. begin
  162. Temp:=0;
  163. i:=1;
  164. MaxI:=PLongint(S1)^;
  165. if MaxI>PLOngint(S2)^ then MaxI:=PLongint(S2)^;
  166. While (i<=MaxI) and (Temp=0) do
  167. begin
  168. Temp:= Byte( PAnsiChar(S1)[i+4] ) - Byte( PAnsiChar(S2)[I+4] );
  169. inc(i);
  170. end;
  171. if temp=0 then temp:=Plongint(S1)^-PLongint(S2)^;
  172. LongCompare:=Temp;
  173. end;
  174. Function LongCompare (Const S1 : LongString; Const S2 : ShortString): Longint;
  175. {
  176. Compares a longString with a ShortString;
  177. The result is
  178. <0 if S1<S2
  179. 0 if S1=S2
  180. >0 if S1>S2
  181. }
  182. Var i,MaxI,Temp : Longint;
  183. begin
  184. Temp:=0;
  185. i:=1;
  186. MaxI:=PLongint(S1)^;
  187. if MaxI>byte(S2[0]) then MaxI:=Byte(S2[0]);
  188. While (i<=MaxI) and (Temp=0) do
  189. begin
  190. Temp:=(Byte(PAnsiChar(S1)[i+4])-Byte(S2[I]));
  191. inc(i);
  192. end;
  193. LongCompare:=Temp;
  194. end;
  195. Procedure Write_Text_LongString (Len : Longint; T : TextRec; Var S : LongString);
  196. {
  197. Writes a LongString to the Text file T
  198. }
  199. begin
  200. end;
  201. { ---------------------------------------------------------------------
  202. Public functions, In interface.
  203. ---------------------------------------------------------------------}
  204. Function Length (Const S : LongString) : Longint;
  205. begin
  206. Length:=PLongint(S)^;
  207. end;
  208. Procedure SetLength (Var S : LongString; l : Longint);
  209. begin
  210. PLongint(S)^:=l;
  211. end;
  212. Function Copy (Const S : LongString; Index,Size : Longint) : LongString;
  213. var ResultAddress : PAnsiChar;
  214. begin
  215. ResultAddress:=NewLongString (Size);
  216. if ResultAddress=Nil then
  217. {We're in deep shit here !!}
  218. exit;
  219. dec(index);
  220. if PLongint(S)^<Index+Size then
  221. Size:=PLongint(S)^-Index;
  222. if Size>0 then
  223. Move (PAnsiChar(S)[Index+5],ResultAddress[5],Size)
  224. Else
  225. Size:=0;
  226. PLongint(ResultAddress)^:=Size;
  227. Copy:=ResultAddress
  228. end;
  229. Function Pos (Const Substr : LongString; Const Source : Longstring) : Longint;
  230. var i,j : longint;
  231. e : boolean;
  232. s : longstring;
  233. begin
  234. i := 0;
  235. j := 0;
  236. e := true;
  237. if Plongint(substr)^=0 then e := false;
  238. while (e) and (i <= length (Source) - length (substr)) do
  239. begin
  240. inc (i);
  241. s :=copy(Source,i,length(Substr));
  242. if LongCompare(substr,s)=0 then
  243. begin
  244. j := i;
  245. e := false;
  246. end;
  247. DisposeLongString(s,length(Substr));
  248. end;
  249. pos := j;
  250. end;
  251. Procedure Val (Const S : LongString; var R : real; Var Code : Integer);
  252. Var SS : String;
  253. begin
  254. Long_To_ShortString (SS,S,255);
  255. System.Val(SS,R,Code);
  256. end;
  257. {
  258. Procedure Val (Const S : LongString; var D : Double; Var Code : Integer);
  259. Var SS : ShortString;
  260. begin
  261. Long_To_ShortString (SS,S,255);
  262. Val(SS,D,Code);
  263. end;
  264. }
  265. Procedure Val (Const S : LongString; var E : Extended; Code : Integer);
  266. Var SS : ShortString;
  267. begin
  268. Long_To_ShortString (SS,S,255);
  269. System.Val(SS,E,Code);
  270. end;
  271. Procedure Val (Const S : LongString; var C : Cardinal; Code : Integer);
  272. Var SS : ShortString;
  273. begin
  274. Long_To_ShortString (SS,S,255);
  275. System.Val(SS,C,Code);
  276. end;
  277. Procedure Val (Const S : LongString; var L : Longint; Var Code : Integer);
  278. Var SS : ShortString;
  279. begin
  280. Long_To_ShortString (SS,S,255);
  281. System.Val(SS,L,Code);
  282. end;
  283. Procedure Val (Const S : LongString; var W : Word; Var Code : Integer);
  284. Var SS : ShortString;
  285. begin
  286. Long_To_ShortString (SS,S,255);
  287. System.Val(SS,W,Code);
  288. end;
  289. Procedure Val (Const S : LongString; var I : Integer; Var Code : Integer);
  290. Var SS : ShortString;
  291. begin
  292. Long_To_ShortString (SS,S,255);
  293. System.Val(SS,I,Code);
  294. end;
  295. Procedure Val (Const S : LongString; var B : Byte; Var Code : Integer);
  296. Var SS : ShortString;
  297. begin
  298. Long_To_ShortString (SS,S,255);
  299. System.Val(SS,B,Code);
  300. end;
  301. Procedure Val (Const S : LongString; var SI : ShortInt; Var Code : Integer);
  302. Var SS : ShortString;
  303. begin
  304. Long_To_ShortString (SS,S,255);
  305. System.Val(SS,SI,Code);
  306. end;
  307. Procedure Str (Const R : Real;Len,fr : Longint; Var S : LongString);
  308. Var SS : ShortString;
  309. begin
  310. {int_Str_Real (R,Len,fr,SS);}
  311. Short_To_LongString (S,SS,255);
  312. end;
  313. {
  314. Procedure Str (Const D : Double;Len,fr: Longint; Var S : LongString);
  315. Var SS : ShortString;
  316. begin
  317. {int_Str_Double (D,Len,fr,SS);}
  318. Short_To_LongString (S,SS,255);
  319. end;
  320. }
  321. Procedure Str (Const E : Extended;Lenf,Fr: Longint; Var S : LongString);
  322. Var SS : ShortString;
  323. begin
  324. {int_Str_Extended (E,Len,fr,SS);}
  325. Short_To_LongString (S,SS,255);
  326. end;
  327. Procedure Str (Const C : Cardinal;Len : Longint; Var S : LongString);
  328. begin
  329. end;
  330. Procedure Str (Const L : Longint; Len : Longint; Var S : LongString);
  331. Var SS : ShortString;
  332. begin
  333. {int_Str_Longint (L,Len,fr,SS);}
  334. Short_To_LongString (S,SS,255);
  335. end;
  336. Procedure Str (Const W : Word;Len : Longint; Var S : LongString);
  337. begin
  338. end;
  339. Procedure Str (Const I : Integer;Len : Longint; Var S : LongString);
  340. begin
  341. end;
  342. Procedure Str (Const B : Byte; Len : Longint; Var S : LongString);
  343. begin
  344. end;
  345. Procedure Str (Const SI : ShortInt; Len : Longint; Var S : LongString);
  346. begin
  347. end;
  348. Procedure Delete (Var S : LongString; Index,Size: Longint);
  349. begin
  350. if index<=0 then
  351. begin
  352. Size:=Size+index-1;
  353. index:=1;
  354. end;
  355. if (Index<=PLongint(s)^) and (Size>0) then
  356. begin
  357. if Size+Index>PLongint(s)^ then
  358. Size:=PLongint(s)^-Index+1;
  359. PLongint(s)^:=PLongint(s)^-Size;
  360. if Index<=Length(s) then
  361. Move(PAnsiChar(s)[Index+Size+4],PAnsiChar(s)[Index+4],Length(s)-Index+1);
  362. end;
  363. end;
  364. Procedure Insert (Const Source : LongString; Var S : LongString; Index : Longint);
  365. var s3,s4 : PAnsiChar;
  366. begin
  367. if index <= 0 then index := 1;
  368. s3 := longString(copy (s, index, length(s)));
  369. if index > PLongint(s)^ then index := PLongint(S)^+1;
  370. PLongint(s)^ := index - 1;
  371. s4 :=PAnsiChar ( NewLongString (Plongint(Source)^) );
  372. Long_String_Concat(LongString(s4),Source,-1);
  373. Long_String_Concat(LongString(S4),LongString(s3),-1);
  374. Long_String_Concat(S,LongString(S4),-1);
  375. DisposeLongstring(LongString(S3),PLongint(S3)^);
  376. DisposeLongString(LongString(S4),PLongint(S4)^);
  377. end;
  378. {$ifdef lstrings_unit}
  379. end.