123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395 |
- {
- This file is part of the Free Pascal run time library.
- Copyright (c) 2011 by Jonas Maebe
- member of the Free Pascal development team.
- This file implements the helper routines for dyn. Arrays in FPC
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- **********************************************************************
- }
- { copying helpers }
- procedure fpc_copy_shallow_array(src, dst: JLObject; srcstart: jint = -1; srccopylen: jint = -1);
- var
- srclen, dstlen: jint;
- begin
- if assigned(src) then
- srclen:=JLRArray.getLength(src)
- else
- srclen:=0;
- if assigned(dst) then
- dstlen:=JLRArray.getLength(dst)
- else
- dstlen:=0;
- if srcstart=-1 then
- srcstart:=0
- else if srcstart>=srclen then
- exit;
- if srccopylen=-1 then
- srccopylen:=srclen
- else if srcstart+srccopylen>srclen then
- srccopylen:=srclen-srcstart;
- { causes exception in JLSystem.arraycopy }
- if (srccopylen=0) or
- (dstlen=0) then
- exit;
- JLSystem.arraycopy(src,srcstart,dst,0,min(srccopylen,dstlen));
- end;
- procedure fpc_copy_jrecord_array(src, dst: TJRecordArray; srcstart: jint = -1; srccopylen: jint = -1);
- var
- i: longint;
- srclen, dstlen: jint;
- begin
- srclen:=length(src);
- dstlen:=length(dst);
- if srcstart=-1 then
- srcstart:=0
- else if srcstart>=srclen then
- exit;
- if srccopylen=-1 then
- srccopylen:=srclen
- else if srcstart+srccopylen>srclen then
- srccopylen:=srclen-srcstart;
- { no arraycopy, have to clone each element }
- for i:=0 to min(srccopylen,dstlen)-1 do
- src[srcstart+i].fpcDeepCopy(dst[i]);
- end;
- procedure fpc_copy_jenumset_array(src, dst: TJEnumSetArray; srcstart: jint = -1; srccopylen: jint = -1);
- var
- i: longint;
- srclen, dstlen: jint;
- begin
- srclen:=length(src);
- dstlen:=length(dst);
- if srcstart=-1 then
- srcstart:=0
- else if srcstart>=srclen then
- exit;
- if srccopylen=-1 then
- srccopylen:=srclen
- else if srcstart+srccopylen>srclen then
- srccopylen:=srclen-srcstart;
- { no arraycopy, have to clone each element }
- for i:=0 to min(srccopylen,dstlen)-1 do
- begin
- dst[i].clear;
- dst[i].addAll(src[srcstart+i]);
- end;
- end;
- procedure fpc_copy_jbitset_array(src, dst: TJBitSetArray; srcstart: jint = -1; srccopylen: jint = -1);
- var
- i: longint;
- srclen, dstlen: jint;
- begin
- srclen:=length(src);
- dstlen:=length(dst);
- if srcstart=-1 then
- srcstart:=0
- else if srcstart>=srclen then
- exit;
- if srccopylen=-1 then
- srccopylen:=srclen
- else if srcstart+srccopylen>srclen then
- srccopylen:=srclen-srcstart;
- { no arraycopy, have to clone each element }
- for i:=0 to min(srccopylen,dstlen)-1 do
- begin
- dst[i].clear;
- dst[i].addAll(src[srcstart+i]);
- end;
- end;
- procedure fpc_copy_jprocvar_array(src, dst: TJProcVarArray; srcstart: jint = -1; srccopylen: jint = -1);
- var
- i: longint;
- srclen, dstlen: jint;
- begin
- srclen:=length(src);
- dstlen:=length(dst);
- if srcstart=-1 then
- srcstart:=0
- else if srcstart>=srclen then
- exit;
- if srccopylen=-1 then
- srccopylen:=srclen
- else if srcstart+srccopylen>srclen then
- srccopylen:=srclen-srcstart;
- { no arraycopy, have to clone each element }
- for i:=0 to min(srccopylen,dstlen)-1 do
- src[srcstart+i].fpcDeepCopy(dst[i]);
- end;
- procedure fpc_copy_jshortstring_array(src, dst: TShortstringArray; srcstart: jint = -1; srccopylen: jint = -1);
- var
- i: longint;
- srclen, dstlen: jint;
- begin
- srclen:=length(src);
- dstlen:=length(dst);
- if srcstart=-1 then
- srcstart:=0
- else if srcstart>=srclen then
- exit;
- if srccopylen=-1 then
- srccopylen:=srclen
- else if srcstart+srccopylen>srclen then
- srccopylen:=srclen-srcstart;
- { no arraycopy, have to clone each element }
- for i:=0 to min(srccopylen,dstlen)-1 do
- pshortstring(src[srcstart+i])^:=pshortstring(dst[i])^;
- end;
- { 1-dimensional setlength routines }
- function fpc_setlength_dynarr_generic(aorg, anew: JLObject; deepcopy: boolean; docopy: boolean = true): JLObject;
- var
- orglen, newlen: jint;
- begin
- orglen:=0;
- newlen:=0;
- if not deepcopy then
- begin
- if assigned(aorg) then
- orglen:=JLRArray.getLength(aorg)
- else
- orglen:=0;
- if assigned(anew) then
- newlen:=JLRArray.getLength(anew)
- else
- newlen:=0;
- end;
- if deepcopy or
- (orglen<>newlen) then
- begin
- if docopy then
- fpc_copy_shallow_array(aorg,anew);
- result:=anew
- end
- else
- result:=aorg;
- end;
- function fpc_setlength_dynarr_jrecord(aorg, anew: TJRecordArray; deepcopy: boolean): TJRecordArray;
- begin
- if deepcopy or
- (length(aorg)<>length(anew)) then
- begin
- fpc_copy_jrecord_array(aorg,anew);
- result:=anew
- end
- else
- result:=aorg;
- end;
- function fpc_setlength_dynarr_jenumset(aorg, anew: TJEnumSetArray; deepcopy: boolean): TJEnumSetArray;
- begin
- if deepcopy or
- (length(aorg)<>length(anew)) then
- begin
- fpc_copy_jenumset_array(aorg,anew);
- result:=anew
- end
- else
- result:=aorg;
- end;
- function fpc_setlength_dynarr_jbitset(aorg, anew: TJBitSetArray; deepcopy: boolean): TJBitSetArray;
- begin
- if deepcopy or
- (length(aorg)<>length(anew)) then
- begin
- fpc_copy_jbitset_array(aorg,anew);
- result:=anew
- end
- else
- result:=aorg;
- end;
- function fpc_setlength_dynarr_jprocvar(aorg, anew: TJProcVarArray; deepcopy: boolean): TJProcVarArray;
- begin
- if deepcopy or
- (length(aorg)<>length(anew)) then
- begin
- fpc_copy_jprocvar_array(aorg,anew);
- result:=anew
- end
- else
- result:=aorg;
- end;
- function fpc_setlength_dynarr_jshortstring(aorg, anew: TShortstringArray; deepcopy: boolean): TShortstringArray;
- begin
- if deepcopy or
- (length(aorg)<>length(anew)) then
- begin
- fpc_copy_jshortstring_array(aorg,anew);
- result:=anew
- end
- else
- result:=aorg;
- end;
- { multi-dimensional setlength routine }
- function fpc_setlength_dynarr_multidim(aorg, anew: TJObjectArray; deepcopy: boolean; ndim: longint; eletype: jchar): TJObjectArray;
- var
- partdone,
- i: longint;
- begin
- { resize the current dimension; no need to copy the subarrays of the old
- array, as the subarrays will be (re-)initialised immediately below }
- { the srcstart/srccopylen always refers to the first dimension (since copy()
- performs a shallow copy of a dynamic array }
- result:=TJObjectArray(fpc_setlength_dynarr_generic(JLObject(aorg),JLObject(anew),deepcopy,false));
- { if aorg was empty, there's nothing else to do since result will now
- contain anew, of which all other dimensions are already initialised
- correctly since there are no aorg elements to copy }
- if not assigned(aorg) and
- not deepcopy then
- exit;
- partdone:=min(high(result),high(aorg));
- { ndim must be >=2 when this routine is called, since it has to return
- an array of java.lang.Object! (arrays are also objects, but primitive
- types are not) }
- if ndim=2 then
- begin
- { final dimension -> copy the primitive arrays }
- case eletype of
- FPCJDynArrTypeRecord:
- begin
- for i:=low(result) to partdone do
- result[i]:=JLObject(fpc_setlength_dynarr_jrecord(TJRecordArray(aorg[i]),TJRecordArray(anew[i]),deepcopy));
- for i:=succ(partdone) to high(result) do
- result[i]:=JLObject(fpc_setlength_dynarr_jrecord(nil,TJRecordArray(anew[i]),deepcopy));
- end;
- FPCJDynArrTypeEnumSet:
- begin
- for i:=low(result) to partdone do
- result[i]:=JLObject(fpc_setlength_dynarr_jenumset(TJEnumSetArray(aorg[i]),TJEnumSetArray(anew[i]),deepcopy));
- for i:=succ(partdone) to high(result) do
- result[i]:=JLObject(fpc_setlength_dynarr_jenumset(nil,TJEnumSetArray(anew[i]),deepcopy));
- end;
- FPCJDynArrTypeBitSet:
- begin
- for i:=low(result) to partdone do
- result[i]:=JLObject(fpc_setlength_dynarr_jbitset(TJBitSetArray(aorg[i]),TJBitSetArray(anew[i]),deepcopy));
- for i:=succ(partdone) to high(result) do
- result[i]:=JLObject(fpc_setlength_dynarr_jbitset(nil,TJBitSetArray(anew[i]),deepcopy));
- end;
- FPCJDynArrTypeProcVar:
- begin
- for i:=low(result) to partdone do
- result[i]:=JLObject(fpc_setlength_dynarr_jprocvar(TJProcVarArray(aorg[i]),TJProcVarArray(anew[i]),deepcopy));
- for i:=succ(partdone) to high(result) do
- result[i]:=JLObject(fpc_setlength_dynarr_jprocvar(nil,TJProcVarArray(anew[i]),deepcopy));
- end;
- FPCJDynArrTypeShortstring:
- begin
- for i:=low(result) to partdone do
- result[i]:=JLObject(fpc_setlength_dynarr_jshortstring(TShortstringArray(aorg[i]),TShortstringArray(anew[i]),deepcopy));
- for i:=succ(partdone) to high(result) do
- result[i]:=JLObject(fpc_setlength_dynarr_jshortstring(nil,TShortstringArray(anew[i]),deepcopy));
- end;
- else
- begin
- for i:=low(result) to partdone do
- result[i]:=fpc_setlength_dynarr_generic(aorg[i],anew[i],deepcopy);
- for i:=succ(partdone) to high(result) do
- result[i]:=fpc_setlength_dynarr_generic(nil,anew[i],deepcopy);
- end;
- end;
- end
- else
- begin
- { recursively handle the next dimension }
- for i:=low(result) to partdone do
- result[i]:=JLObject(fpc_setlength_dynarr_multidim(TJObjectArray(aorg[i]),TJObjectArray(anew[i]),deepcopy,pred(ndim),eletype));
- for i:=succ(partdone) to high(result) do
- result[i]:=JLObject(fpc_setlength_dynarr_multidim(nil,TJObjectArray(anew[i]),deepcopy,pred(ndim),eletype));
- end;
- end;
- function fpc_dynarray_copy(src: JLObject; start, len: longint; ndim: longint; eletype: jchar): JLObject;
- var
- i: longint;
- srclen: longint;
- begin
- if not assigned(src) then
- begin
- result:=nil;
- exit;
- end;
- srclen:=JLRArray.getLength(src);
- if (start=-1) and
- (len=-1) then
- begin
- len:=srclen;
- start:=0;
- end
- else if (start+len>srclen) then
- len:=srclen-start+1;
- result:=JLRArray.newInstance(src.getClass.getComponentType,len);
- if ndim=1 then
- begin
- case eletype of
- FPCJDynArrTypeRecord:
- begin
- for i:=0 to len-1 do
- TJObjectArray(result)[i]:=FpcBaseRecordType(TJObjectArray(src)[i]).clone;
- end;
- FPCJDynArrTypeEnumSet:
- begin
- for i:=0 to len-1 do
- TJObjectArray(result)[i]:=JUEnumSet(TJObjectArray(src)[i]).clone;
- end;
- FPCJDynArrTypeBitSet:
- begin
- for i:=0 to len-1 do
- TJObjectArray(result)[i]:=FpcBitSet(TJObjectArray(src)[i]).clone;
- end;
- FPCJDynArrTypeProcvar:
- begin
- for i:=0 to len-1 do
- TJObjectArray(result)[i]:=FpcBaseProcVarType(TJObjectArray(src)[i]).clone;
- end;
- FPCJDynArrTypeShortstring:
- begin
- for i:=0 to len-1 do
- TJObjectArray(result)[i]:=ShortStringClass(TJObjectArray(src)[i]).clone;
- end;
- else
- fpc_copy_shallow_array(src,result,start,len);
- end
- end
- else
- begin
- for i:=0 to len-1 do
- TJObjectArray(result)[i]:=fpc_dynarray_copy(TJObjectArray(src)[start+i],-1,-1,ndim-1,eletype);
- end;
- end;
|