jdynarr.inc 12 KB

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