jdynarr.inc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2011 by Jonas Maebe
  4. member of the Free Pascal development team.
  5. This file implements the helper routines for dyn. Arrays in 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. }
  13. function min(a,b : longint) : longint;
  14. begin
  15. if a<=b then
  16. min:=a
  17. else
  18. min:=b;
  19. end;
  20. {$i jrec.inc}
  21. {$i jset.inc}
  22. {$i jpvar.inc}
  23. {$i jsystem.inc}
  24. { copying helpers }
  25. procedure fpc_copy_shallow_array(src, dst: JLObject; srcstart: jint = -1; srccopylen: jint = -1);
  26. var
  27. srclen, dstlen: jint;
  28. begin
  29. if assigned(src) then
  30. srclen:=JLRArray.getLength(src)
  31. else
  32. srclen:=0;
  33. if assigned(dst) then
  34. dstlen:=JLRArray.getLength(dst)
  35. else
  36. dstlen:=0;
  37. if srcstart=-1 then
  38. srcstart:=0
  39. else if srcstart>=srclen then
  40. exit;
  41. if srccopylen=-1 then
  42. srccopylen:=srclen
  43. else if srcstart+srccopylen>srclen then
  44. srccopylen:=srclen-srcstart;
  45. { causes exception in JLSystem.arraycopy }
  46. if (srccopylen=0) or
  47. (dstlen=0) then
  48. exit;
  49. JLSystem.arraycopy(src,srcstart,dst,0,min(srccopylen,dstlen));
  50. end;
  51. procedure fpc_copy_jrecord_array(src, dst: TJRecordArray; srcstart: jint = -1; srccopylen: jint = -1);
  52. var
  53. i: longint;
  54. srclen, dstlen: jint;
  55. begin
  56. srclen:=length(src);
  57. dstlen:=length(dst);
  58. if srcstart=-1 then
  59. srcstart:=0
  60. else if srcstart>=srclen then
  61. exit;
  62. if srccopylen=-1 then
  63. srccopylen:=srclen
  64. else if srcstart+srccopylen>srclen then
  65. srccopylen:=srclen-srcstart;
  66. { no arraycopy, have to clone each element }
  67. for i:=0 to min(srccopylen,dstlen)-1 do
  68. src[srcstart+i].fpcDeepCopy(dst[i]);
  69. end;
  70. procedure fpc_copy_jenumset_array(src, dst: TJEnumSetArray; srcstart: jint = -1; srccopylen: jint = -1);
  71. var
  72. i: longint;
  73. srclen, dstlen: jint;
  74. begin
  75. srclen:=length(src);
  76. dstlen:=length(dst);
  77. if srcstart=-1 then
  78. srcstart:=0
  79. else if srcstart>=srclen then
  80. exit;
  81. if srccopylen=-1 then
  82. srccopylen:=srclen
  83. else if srcstart+srccopylen>srclen then
  84. srccopylen:=srclen-srcstart;
  85. { no arraycopy, have to clone each element }
  86. for i:=0 to min(srccopylen,dstlen)-1 do
  87. begin
  88. dst[i].clear;
  89. dst[i].addAll(src[srcstart+i]);
  90. end;
  91. end;
  92. procedure fpc_copy_jbitset_array(src, dst: TJBitSetArray; srcstart: jint = -1; srccopylen: jint = -1);
  93. var
  94. i: longint;
  95. srclen, dstlen: jint;
  96. begin
  97. srclen:=length(src);
  98. dstlen:=length(dst);
  99. if srcstart=-1 then
  100. srcstart:=0
  101. else if srcstart>=srclen then
  102. exit;
  103. if srccopylen=-1 then
  104. srccopylen:=srclen
  105. else if srcstart+srccopylen>srclen then
  106. srccopylen:=srclen-srcstart;
  107. { no arraycopy, have to clone each element }
  108. for i:=0 to min(srccopylen,dstlen)-1 do
  109. begin
  110. dst[i].clear;
  111. dst[i].addAll(src[srcstart+i]);
  112. end;
  113. end;
  114. procedure fpc_copy_jprocvar_array(src, dst: TJProcVarArray; srcstart: jint = -1; srccopylen: jint = -1);
  115. var
  116. i: longint;
  117. srclen, dstlen: jint;
  118. begin
  119. srclen:=length(src);
  120. dstlen:=length(dst);
  121. if srcstart=-1 then
  122. srcstart:=0
  123. else if srcstart>=srclen then
  124. exit;
  125. if srccopylen=-1 then
  126. srccopylen:=srclen
  127. else if srcstart+srccopylen>srclen then
  128. srccopylen:=srclen-srcstart;
  129. { no arraycopy, have to clone each element }
  130. for i:=0 to min(srccopylen,dstlen)-1 do
  131. src[srcstart+i].fpcDeepCopy(dst[i]);
  132. end;
  133. procedure fpc_copy_jshortstring_array(src, dst: TShortstringArray; srcstart: jint = -1; srccopylen: jint = -1);
  134. var
  135. i: longint;
  136. srclen, dstlen: jint;
  137. begin
  138. srclen:=length(src);
  139. dstlen:=length(dst);
  140. if srcstart=-1 then
  141. srcstart:=0
  142. else if srcstart>=srclen then
  143. exit;
  144. if srccopylen=-1 then
  145. srccopylen:=srclen
  146. else if srcstart+srccopylen>srclen then
  147. srccopylen:=srclen-srcstart;
  148. { no arraycopy, have to clone each element }
  149. for i:=0 to min(srccopylen,dstlen)-1 do
  150. pshortstring(src[srcstart+i])^:=pshortstring(dst[i])^;
  151. end;
  152. { 1-dimensional setlength routines }
  153. function fpc_setlength_dynarr_generic(aorg, anew: JLObject; deepcopy: boolean; docopy: boolean = true): JLObject;
  154. var
  155. orglen, newlen: jint;
  156. begin
  157. orglen:=0;
  158. newlen:=0;
  159. if not deepcopy then
  160. begin
  161. if assigned(aorg) then
  162. orglen:=JLRArray.getLength(aorg)
  163. else
  164. orglen:=0;
  165. if assigned(anew) then
  166. newlen:=JLRArray.getLength(anew)
  167. else
  168. newlen:=0;
  169. end;
  170. if deepcopy or
  171. (orglen<>newlen) then
  172. begin
  173. if docopy then
  174. fpc_copy_shallow_array(aorg,anew);
  175. result:=anew
  176. end
  177. else
  178. result:=aorg;
  179. end;
  180. function fpc_setlength_dynarr_jrecord(aorg, anew: TJRecordArray; deepcopy: boolean): TJRecordArray;
  181. begin
  182. if deepcopy or
  183. (length(aorg)<>length(anew)) then
  184. begin
  185. fpc_copy_jrecord_array(aorg,anew);
  186. result:=anew
  187. end
  188. else
  189. result:=aorg;
  190. end;
  191. function fpc_setlength_dynarr_jenumset(aorg, anew: TJEnumSetArray; deepcopy: boolean): TJEnumSetArray;
  192. begin
  193. if deepcopy or
  194. (length(aorg)<>length(anew)) then
  195. begin
  196. fpc_copy_jenumset_array(aorg,anew);
  197. result:=anew
  198. end
  199. else
  200. result:=aorg;
  201. end;
  202. function fpc_setlength_dynarr_jbitset(aorg, anew: TJBitSetArray; deepcopy: boolean): TJBitSetArray;
  203. begin
  204. if deepcopy or
  205. (length(aorg)<>length(anew)) then
  206. begin
  207. fpc_copy_jbitset_array(aorg,anew);
  208. result:=anew
  209. end
  210. else
  211. result:=aorg;
  212. end;
  213. function fpc_setlength_dynarr_jprocvar(aorg, anew: TJProcVarArray; deepcopy: boolean): TJProcVarArray;
  214. begin
  215. if deepcopy or
  216. (length(aorg)<>length(anew)) then
  217. begin
  218. fpc_copy_jprocvar_array(aorg,anew);
  219. result:=anew
  220. end
  221. else
  222. result:=aorg;
  223. end;
  224. function fpc_setlength_dynarr_jshortstring(aorg, anew: TShortstringArray; deepcopy: boolean): TShortstringArray;
  225. begin
  226. if deepcopy or
  227. (length(aorg)<>length(anew)) then
  228. begin
  229. fpc_copy_jshortstring_array(aorg,anew);
  230. result:=anew
  231. end
  232. else
  233. result:=aorg;
  234. end;
  235. { multi-dimensional setlength routine }
  236. function fpc_setlength_dynarr_multidim(aorg, anew: TJObjectArray; deepcopy: boolean; ndim: longint; eletype: jchar): TJObjectArray;
  237. var
  238. partdone,
  239. i: longint;
  240. begin
  241. { resize the current dimension; no need to copy the subarrays of the old
  242. array, as the subarrays will be (re-)initialised immediately below }
  243. { the srcstart/srccopylen always refers to the first dimension (since copy()
  244. performs a shallow copy of a dynamic array }
  245. result:=TJObjectArray(fpc_setlength_dynarr_generic(JLObject(aorg),JLObject(anew),deepcopy,false));
  246. { if aorg was empty, there's nothing else to do since result will now
  247. contain anew, of which all other dimensions are already initialised
  248. correctly since there are no aorg elements to copy }
  249. if not assigned(aorg) and
  250. not deepcopy then
  251. exit;
  252. partdone:=min(high(result),high(aorg));
  253. { ndim must be >=2 when this routine is called, since it has to return
  254. an array of java.lang.Object! (arrays are also objects, but primitive
  255. types are not) }
  256. if ndim=2 then
  257. begin
  258. { final dimension -> copy the primitive arrays }
  259. case eletype of
  260. FPCJDynArrTypeRecord:
  261. begin
  262. for i:=low(result) to partdone do
  263. result[i]:=JLObject(fpc_setlength_dynarr_jrecord(TJRecordArray(aorg[i]),TJRecordArray(anew[i]),deepcopy));
  264. for i:=succ(partdone) to high(result) do
  265. result[i]:=JLObject(fpc_setlength_dynarr_jrecord(nil,TJRecordArray(anew[i]),deepcopy));
  266. end;
  267. FPCJDynArrTypeEnumSet:
  268. begin
  269. for i:=low(result) to partdone do
  270. result[i]:=JLObject(fpc_setlength_dynarr_jenumset(TJEnumSetArray(aorg[i]),TJEnumSetArray(anew[i]),deepcopy));
  271. for i:=succ(partdone) to high(result) do
  272. result[i]:=JLObject(fpc_setlength_dynarr_jenumset(nil,TJEnumSetArray(anew[i]),deepcopy));
  273. end;
  274. FPCJDynArrTypeBitSet:
  275. begin
  276. for i:=low(result) to partdone do
  277. result[i]:=JLObject(fpc_setlength_dynarr_jbitset(TJBitSetArray(aorg[i]),TJBitSetArray(anew[i]),deepcopy));
  278. for i:=succ(partdone) to high(result) do
  279. result[i]:=JLObject(fpc_setlength_dynarr_jbitset(nil,TJBitSetArray(anew[i]),deepcopy));
  280. end;
  281. FPCJDynArrTypeProcVar:
  282. begin
  283. for i:=low(result) to partdone do
  284. result[i]:=JLObject(fpc_setlength_dynarr_jprocvar(TJProcVarArray(aorg[i]),TJProcVarArray(anew[i]),deepcopy));
  285. for i:=succ(partdone) to high(result) do
  286. result[i]:=JLObject(fpc_setlength_dynarr_jprocvar(nil,TJProcVarArray(anew[i]),deepcopy));
  287. end;
  288. FPCJDynArrTypeShortstring:
  289. begin
  290. for i:=low(result) to partdone do
  291. result[i]:=JLObject(fpc_setlength_dynarr_jshortstring(TShortstringArray(aorg[i]),TShortstringArray(anew[i]),deepcopy));
  292. for i:=succ(partdone) to high(result) do
  293. result[i]:=JLObject(fpc_setlength_dynarr_jshortstring(nil,TShortstringArray(anew[i]),deepcopy));
  294. end;
  295. else
  296. begin
  297. for i:=low(result) to partdone do
  298. result[i]:=fpc_setlength_dynarr_generic(aorg[i],anew[i],deepcopy);
  299. for i:=succ(partdone) to high(result) do
  300. result[i]:=fpc_setlength_dynarr_generic(nil,anew[i],deepcopy);
  301. end;
  302. end;
  303. end
  304. else
  305. begin
  306. { recursively handle the next dimension }
  307. for i:=low(result) to partdone do
  308. result[i]:=JLObject(fpc_setlength_dynarr_multidim(TJObjectArray(aorg[i]),TJObjectArray(anew[i]),deepcopy,pred(ndim),eletype));
  309. for i:=succ(partdone) to high(result) do
  310. result[i]:=JLObject(fpc_setlength_dynarr_multidim(nil,TJObjectArray(anew[i]),deepcopy,pred(ndim),eletype));
  311. end;
  312. end;
  313. function fpc_dynarray_copy(src: JLObject; start, len: longint; ndim: longint; eletype: jchar): JLObject;
  314. var
  315. i: longint;
  316. srclen: longint;
  317. begin
  318. if not assigned(src) then
  319. begin
  320. result:=nil;
  321. exit;
  322. end;
  323. srclen:=JLRArray.getLength(src);
  324. if (start=-1) and
  325. (len=-1) then
  326. begin
  327. len:=srclen;
  328. start:=0;
  329. end
  330. else if (start+len>srclen) then
  331. len:=srclen-start+1;
  332. result:=JLRArray.newInstance(src.getClass.getComponentType,len);
  333. if ndim=1 then
  334. begin
  335. case eletype of
  336. FPCJDynArrTypeRecord:
  337. fpc_copy_jrecord_array(TJRecordArray(src),TJRecordArray(result),start,len);
  338. FPCJDynArrTypeEnumSet:
  339. fpc_copy_jenumset_array(TJEnumSetArray(src),TJEnumSetArray(result),start,len);
  340. FPCJDynArrTypeBitSet:
  341. fpc_copy_jbitset_array(TJBitSetArray(src),TJBitSetArray(result),start,len);
  342. FPCJDynArrTypeProcvar:
  343. fpc_copy_jprocvar_array(TJProcVarArray(src),TJProcVarArray(result),start,len);
  344. FPCJDynArrTypeShortstring:
  345. fpc_copy_jshortstring_array(TShortstringArray(src),TShortstringArray(result),start,len);
  346. else
  347. fpc_copy_shallow_array(src,result,start,len);
  348. end
  349. end
  350. else
  351. begin
  352. for i:=0 to len-1 do
  353. TJObjectArray(result)[i]:=fpc_dynarray_copy(TJObjectArray(src)[start+i],-1,-1,ndim-1,eletype);
  354. end;
  355. end;