procedure setlength(p1,p2,p3,p4); begin VarArgStart(VAList); DynArraySetLength(A, TypeInfo, DimCnt, PNativeInt(VAList)); end;
procedure DynArraySetLength(A, TypeInfo, DimCnt, PNativeInt(VAList)); begin p := a; newLength := lengthVec^; if newLength <= 0 then if newLength < 0 then Error(reRangeError); _DynArrayClear(a, typeInfo); exit; oldLength := 0; if p <> nil then Dec(PByte(p), SizeOf(TDynArrayRec)); oldLength := PDynArrayRec(p).Length; Inc(PByte(typeInfo), PDynArrayTypeInfo(typeInfo).name); elSize := PDynArrayTypeInfo(typeInfo).elSize; if PDynArrayTypeInfo(typeInfo).elType <> nil then ElTypeInfo := PDynArrayTypeInfo(typeInfo).elType^ ElTypeInfo := nil; neededSize := newLength*elSize; if neededSize div newLength <> elSize then Error(reRangeError); Inc(neededSize, SizeOf(TDynArrayRec)); if neededSize < 0 then Error(reRangeError); if (p = nil) or (PDynArrayRec(p).RefCnt = 1) then pp := p; if (newLength < oldLength) and (ElTypeInfo <> nil) then FinalizeArray(PByte(p) + SizeOf(TDynArrayRec) + newLength*elSize, ElTypeInfo, oldLength - newLength); ReallocMem(pp, neededSize); p := pp; GetMem(p, neededSize); minLength := oldLength; if minLength > newLength then minLength := newLength; if ElTypeInfo <> nil then FillChar((PByte(p) + SizeOf(TDynArrayRec))^, minLength*elSize, 0); __CopyArray(PByte(p) + SizeOf(TDynArrayRec), a, ElTypeInfo, minLength) Move(PByte(a)^, (PByte(p) + SizeOf(TDynArrayRec))^, minLength*elSize); _DynArrayClear(a, typeInfo); PDynArrayRec(p).RefCnt := 1; PDynArrayRec(p).Length := newLength; Inc(PByte(p), SizeOf(TDynArrayRec)); if newLength > oldLength then FillChar((PByte(p) + elSize * oldLength)^, elSize * (newLength - oldLength), 0); if dimCnt > 1 then Inc(lengthVec); Dec(dimCnt); i := 0; try DynArraySetLength(PPointerArray(p)[i], ElTypeInfo, dimCnt, lengthVec); Inc(i); while i < newLength do _DynArrayClear(PPointerArray(p)[j], typeInfo); for j := 0 to i do _DynArrayClear(p, ElTypeInfo); raise; a := p; end;