sstrings.inc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2005, 2011 by Florian Klaempfl, Jonas Maebe
  4. members of the Free Pascal development team.
  5. This file implements support routines for Shortstrings with FPC/JVM
  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. constructor ShortstringClass.Create(const arr: array of ansichar; maxlen: byte);
  13. begin
  14. setlength(fdata,maxlen);
  15. if high(arr)=-1 then
  16. exit;
  17. curlen:=min(high(arr)+1,maxlen);
  18. JLSystem.ArrayCopy(JLObject(@arr),0,JLObject(fdata),0,curlen);
  19. end;
  20. constructor ShortstringClass.Create(const arr: array of unicodechar; maxlen: byte);
  21. begin
  22. if high(arr)=-1 then
  23. begin
  24. setlength(fdata,maxlen);
  25. exit;
  26. end;
  27. fdata:=TAnsiCharArray(JLString.Create(arr).getBytes);
  28. setlength(fdata,maxlen);
  29. curlen:=min(high(fdata)+1,maxlen);
  30. end;
  31. constructor ShortstringClass.Create(const u: unicodestring; maxlen: byte);
  32. begin
  33. if system.length(u)=0 then
  34. begin
  35. setlength(fdata,maxlen);
  36. exit;
  37. end;
  38. fdata:=TAnsiCharArray(JLString(u).getBytes);
  39. setlength(fdata,maxlen);
  40. curlen:=min(high(fdata)+1,maxlen);
  41. end;
  42. constructor ShortstringClass.Create(const a: ansistring; maxlen: byte);
  43. var
  44. alen: jint;
  45. begin
  46. setlength(fdata,maxlen);
  47. alen:=system.length(a);
  48. if alen=0 then
  49. exit;
  50. curlen:=min(alen,maxlen);
  51. JLSystem.ArrayCopy(JLObject(AnsistringClass(a).fdata),0,JLObject(fdata),0,curlen);
  52. end;
  53. constructor ShortstringClass.Create(const s: shortstring; maxlen: byte);overload;
  54. begin
  55. setlength(fdata,maxlen);
  56. if system.length(s)=0 then
  57. exit;
  58. curlen:=min(system.length(s),maxlen);
  59. JLSystem.ArrayCopy(JLObject(ShortstringClass(@s).fdata),0,JLObject(fdata),0,min(system.length(s),maxlen));
  60. end;
  61. constructor ShortstringClass.Create(ch: ansichar; maxlen: byte);overload;
  62. begin
  63. setlength(fdata,maxlen);
  64. fdata[0]:=ch;
  65. curlen:=1;
  66. end;
  67. constructor ShortstringClass.Create(ch: unicodechar; maxlen: byte);overload;
  68. begin
  69. fdata:=TAnsiCharArray(JLString.Create(ch).getBytes);
  70. curlen:=min(system.length(fdata),maxlen);
  71. setlength(fdata,maxlen);
  72. end;
  73. class function ShortstringClass.CreateEmpty(maxlen: byte): ShortstringClass;
  74. begin
  75. result:=ShortstringClass.Create;
  76. setlength(result.fdata,maxlen);
  77. end;
  78. class function ShortstringClass.CreateFromLiteralStringBytes(const u: unicodestring): shortstring;
  79. var
  80. i: longint;
  81. begin
  82. { used to construct constant shortstrings from Java string constants }
  83. ShortstringClass(@result).curlen:=min(system.length(u),255);
  84. setlength(ShortstringClass(@result).fdata,ShortstringClass(@result).curlen);
  85. for i:=1 to ShortstringClass(@result).curlen do
  86. ShortstringClass(@result).fdata[i-1]:=ansichar(ord(u[i]));
  87. end;
  88. procedure ShortstringClass.FpcDeepCopy(dest: ShortstringClass);
  89. var
  90. destmaxlen,
  91. copylen: longint;
  92. begin
  93. dest.curlen:=curlen;
  94. copylen:=system.length(fdata);
  95. destmaxlen:=system.length(dest.fdata);
  96. if copylen>destmaxlen then
  97. begin
  98. copylen:=destmaxlen;
  99. dest.curlen:=destmaxlen;
  100. end;
  101. if copylen>0 then
  102. JLSystem.ArrayCopy(JLObject(fdata),0,JLObject(dest.fdata),0,copylen);
  103. end;
  104. procedure ShortstringClass.setChar(index: jint; char: ansichar);
  105. begin
  106. { index is 1-based here }
  107. { support accessing the length byte }
  108. if index=0 then
  109. curlen:=ord(char)
  110. else
  111. fdata[index-1]:=char;
  112. end;
  113. function ShortstringClass.charAt(index: jint): ansichar;
  114. begin
  115. { index is already decreased by one, because same calling code is used for
  116. JLString.charAt() }
  117. { support accessing the length byte }
  118. if (index=-1) then
  119. result:=ansichar(curlen)
  120. else
  121. result:=fdata[index];
  122. end;
  123. function ShortstringClass.toUnicodeString: unicodestring;
  124. begin
  125. result:=UnicodeString(JLString.Create(TJByteArray(fdata)));
  126. end;
  127. function ShortstringClass.toAnsistring: ansistring;
  128. begin
  129. result:=ansistring(AnsistringClass.Create(pshortstring(self)^));
  130. end;
  131. function ShortstringClass.toString: JLString;
  132. begin
  133. if curlen<>0 then
  134. result:=JLString.Create(TJByteArray(fdata),0,curlen-1)
  135. else
  136. result:='';
  137. end;
  138. function ShortstringClass.clone: JLObject;
  139. begin
  140. result:=ShortstringClass.Create(pshortstring(self)^,system.length(fdata));
  141. end;
  142. function ShortstringClass.length: jint;
  143. begin
  144. result:=curlen;
  145. end;
  146. class function AnsiCharArrayClass.CreateFromLiteralStringBytes(const u: unicodestring; maxlen: byte): TAnsiCharArray;
  147. var
  148. i: longint;
  149. begin
  150. { used to construct constant chararrays from Java string constants }
  151. setlength(result,maxlen);
  152. for i:=1 to system.length(u) do
  153. result[i-1]:=ansichar(ord(u[i]));
  154. end;
  155. procedure fpc_Shortstr_SetLength(var s:shortstring;len:SizeInt); compilerproc;
  156. begin
  157. if len>255 then
  158. len:=255;
  159. ShortstringClass(@s).curlen:=len;
  160. end;
  161. procedure fpc_shortstr_to_shortstr(out res:shortstring; const sstr: shortstring); compilerproc;
  162. var
  163. len: longint;
  164. begin
  165. len:=length(sstr);
  166. if len>high(res) then
  167. len:=high(res);
  168. ShortstringClass(@res).curlen:=len;
  169. JLSystem.ArrayCopy(JLObject(ShortstringClass(@sstr).fdata),0,JLObject(ShortstringClass(@res).fdata),0,len);
  170. end;
  171. procedure fpc_shortstr_concat(var dests:shortstring;const s1,s2:shortstring);compilerproc;
  172. var
  173. tmpres: ShortstringClass;
  174. s1l, s2l: longint;
  175. begin
  176. s1l:=length(s1);
  177. s2l:=length(s2);
  178. if (s1l+s2l)>high(dests) then
  179. begin
  180. if s1l>high(dests) then
  181. s1l:=high(dests);
  182. s2l:=high(dests)-s1l;
  183. end;
  184. if ShortstringClass(@dests)=ShortstringClass(@s1) then
  185. JLSystem.ArrayCopy(JLObject(ShortstringClass(@s2).fdata),0,JLObject(ShortstringClass(@dests).fdata),s1l,s2l)
  186. else if ShortstringClass(@dests)=ShortstringClass(@s2) then
  187. begin
  188. JLSystem.ArrayCopy(JLObject(ShortstringClass(@dests).fdata),0,JLObject(ShortstringClass(@dests).fdata),s1l,s2l);
  189. JLSystem.ArrayCopy(JLObject(ShortstringClass(@s1).fdata),0,JLObject(ShortstringClass(@dests).fdata),0,s1l);
  190. end
  191. else
  192. begin
  193. JLSystem.ArrayCopy(JLObject(ShortstringClass(@s1).fdata),0,JLObject(ShortstringClass(@dests).fdata),0,s1l);
  194. JLSystem.ArrayCopy(JLObject(ShortstringClass(@s2).fdata),0,JLObject(ShortstringClass(@dests).fdata),s1l,s2l)
  195. end;
  196. ShortstringClass(@dests).curlen:=s1l+s2l;
  197. end;
  198. procedure fpc_shortstr_concat_multi(var dests:shortstring;const sarr:array of ShortstringClass);compilerproc;
  199. var
  200. s2l : byte;
  201. LowStart,i,
  202. Len : longint;
  203. needtemp : boolean;
  204. tmpstr : shortstring;
  205. p,pdest : ShortstringClass;
  206. begin
  207. if high(sarr)=0 then
  208. begin
  209. DestS:='';
  210. exit;
  211. end;
  212. lowstart:=low(sarr);
  213. if ShortstringClass(@DestS)=sarr[lowstart] then
  214. inc(lowstart);
  215. { Check for another reuse, then we can't use
  216. the append optimization and need to use a temp }
  217. needtemp:=false;
  218. for i:=lowstart to high(sarr) do
  219. begin
  220. if ShortstringClass(@DestS)=sarr[i] then
  221. begin
  222. needtemp:=true;
  223. break;
  224. end;
  225. end;
  226. if needtemp then
  227. begin
  228. lowstart:=low(sarr);
  229. tmpstr:='';
  230. pdest:=ShortstringClass(@tmpstr)
  231. end
  232. else
  233. begin
  234. { Start with empty DestS if we start with concatting
  235. the first array element }
  236. if lowstart=low(sarr) then
  237. DestS:='';
  238. pdest:=ShortstringClass(@DestS);
  239. end;
  240. { Concat all strings, except the string we already
  241. copied in DestS }
  242. Len:=pdest.curlen;
  243. for i:=lowstart to high(sarr) do
  244. begin
  245. p:=sarr[i];
  246. if assigned(p) then
  247. begin
  248. s2l:=p.curlen;
  249. if Len+s2l>high(dests) then
  250. s2l:=high(dests)-Len;
  251. JLSystem.ArrayCopy(JLObject(p.fdata),0,JLObject(pdest.fdata),len,s2l);
  252. inc(Len,s2l);
  253. end;
  254. end;
  255. pdest.curlen:=len;
  256. if needtemp then
  257. DestS:=TmpStr;
  258. end;
  259. procedure fpc_shortstr_append_shortstr(var s1:shortstring;const s2:shortstring); compilerproc;
  260. var
  261. s1l, s2l : integer;
  262. begin
  263. s1l:=length(s1);
  264. s2l:=length(s2);
  265. if s1l+s2l>high(s1) then
  266. s2l:=high(s1)-s1l;
  267. JLSystem.ArrayCopy(JLObject(ShortstringClass(@s2).fdata),0,JLObject(ShortstringClass(@s1).fdata),s1l,s2l);
  268. s1[0]:=chr(s1l+s2l);
  269. end;
  270. function fpc_shortstr_compare(const left,right:shortstring) : longint; compilerproc;
  271. Var
  272. MaxI,Temp, i : SizeInt;
  273. begin
  274. if ShortstringClass(@left)=ShortstringClass(@right) then
  275. begin
  276. result:=0;
  277. exit;
  278. end;
  279. Maxi:=Length(left);
  280. temp:=Length(right);
  281. If MaxI>Temp then
  282. MaxI:=Temp;
  283. if MaxI>0 then
  284. begin
  285. for i:=0 to MaxI-1 do
  286. begin
  287. result:=ord(ShortstringClass(@left).fdata[i])-ord(ShortstringClass(@right).fdata[i]);
  288. if result<>0 then
  289. exit;
  290. end;
  291. result:=Length(left)-Length(right);
  292. end
  293. else
  294. result:=Length(left)-Length(right);
  295. end;
  296. function fpc_shortstr_compare_equal(const left,right:shortstring) : longint; compilerproc;
  297. Var
  298. MaxI,Temp : SizeInt;
  299. begin
  300. if ShortstringClass(@left)=ShortstringClass(@right) then
  301. begin
  302. result:=0;
  303. exit;
  304. end;
  305. result:=ord(not JUArrays.equals(TJByteArray(ShortstringClass(@left).fdata),TJByteArray(ShortstringClass(@right).fdata)));
  306. end;
  307. procedure fpc_chararray_to_shortstr(out res : shortstring;const arr: array of AnsiChar; zerobased: boolean = true); compilerproc;
  308. var
  309. l: longint;
  310. index: longint;
  311. len: byte;
  312. foundnull: boolean;
  313. begin
  314. l:=high(arr)+1;
  315. if l>=high(res)+1 then
  316. l:=high(res)
  317. else if l<0 then
  318. l:=0;
  319. if zerobased then
  320. begin
  321. foundnull:=false;
  322. for index:=low(arr) to l-1 do
  323. if arr[index]=#0 then
  324. begin
  325. foundnull:=true;
  326. break;
  327. end;
  328. if not foundnull then
  329. len:=l
  330. else
  331. len:=index;
  332. end
  333. else
  334. len:=l;
  335. JLSystem.ArrayCopy(JLObject(@arr),0,JLObject(ShortstringClass(@res).fdata),0,len);
  336. ShortstringClass(@res).curlen:=len;
  337. end;
  338. procedure fpc_shortstr_to_chararray(out res: array of AnsiChar; const src: ShortString); compilerproc;
  339. var
  340. len: longint;
  341. begin
  342. len:=length(src);
  343. if len>length(res) then
  344. len:=length(res);
  345. { make sure we don't access char 1 if length is 0 (JM) }
  346. if len>0 then
  347. JLSystem.ArrayCopy(JLObject(ShortstringClass(@src).fdata),0,JLObject(@res),0,len);
  348. if len<=high(res) then
  349. JUArrays.fill(TJByteArray(@res),len,high(res),0);
  350. end;
  351. procedure fpc_Char_To_ShortStr(out res : shortstring;const c : AnsiChar) compilerproc;
  352. {
  353. Converts a WideChar to a ShortString;
  354. }
  355. begin
  356. setlength(res,1);
  357. ShortstringClass(@res).fdata[0]:=c;
  358. end;
  359. Function fpc_shortstr_Copy(const s:shortstring;index:SizeInt;count:SizeInt):shortstring;compilerproc;
  360. begin
  361. if count<0 then
  362. count:=0;
  363. if index>1 then
  364. dec(index)
  365. else
  366. index:=0;
  367. if index>length(s) then
  368. count:=0
  369. else
  370. if count>length(s)-index then
  371. count:=length(s)-index;
  372. ShortstringClass(@result).curlen:=count;
  373. JLSystem.ArrayCopy(JLObject(ShortstringClass(@s).fdata),index,JLObject(ShortstringClass(@result).fdata),0,count);
  374. end;
  375. function fpc_char_copy(c:AnsiChar;index : SizeInt;count : SizeInt): shortstring;compilerproc;
  376. begin
  377. if (index=1) and (Count>0) then
  378. fpc_char_Copy:=c
  379. else
  380. fpc_char_Copy:='';
  381. end;
  382. function upcase(const s : shortstring) : shortstring;
  383. var
  384. u : unicodestring;
  385. begin
  386. u:=s;
  387. result:=upcase(u);
  388. end;
  389. function lowercase(const s : shortstring) : shortstring;
  390. var
  391. u : unicodestring;
  392. begin
  393. u:=s;
  394. result:=lowercase(u);
  395. end;
  396. Function Pos (Const Substr : Shortstring; Const Source : Shortstring) : SizeInt;
  397. var
  398. i,j,k,MaxLen, SubstrLen : SizeInt;
  399. begin
  400. Pos:=0;
  401. SubstrLen:=Length(SubStr);
  402. if SubstrLen>0 then
  403. begin
  404. MaxLen:=Length(source)-Length(SubStr);
  405. i:=0;
  406. while (i<=MaxLen) do
  407. begin
  408. inc(i);
  409. j:=0;
  410. k:=i-1;
  411. while (j<SubstrLen) and
  412. (ShortstringClass(@SubStr).fdata[j]=ShortstringClass(@Source).fdata[k]) do
  413. begin
  414. inc(j);
  415. inc(k);
  416. end;
  417. if (j=SubstrLen) then
  418. begin
  419. Pos:=i;
  420. exit;
  421. end;
  422. end;
  423. end;
  424. end;
  425. { Faster version for a char alone. Must be implemented because }
  426. { pos(c: char; const s: shortstring) also exists, so otherwise }
  427. { using pos(char,pchar) will always call the shortstring version }
  428. { (exact match for first argument), also with $h+ (JM) }
  429. Function Pos (c : AnsiChar; Const s : ShortString) : SizeInt;
  430. var
  431. i: SizeInt;
  432. begin
  433. for i:=1 to length(s) do
  434. begin
  435. if ShortstringClass(@s).fdata[i-1]=c then
  436. begin
  437. pos:=i;
  438. exit;
  439. end;
  440. end;
  441. pos:=0;
  442. end;