Dynamic lists fixes and additions

# Conflicts:
#	src/include/lists.pas
This commit is contained in:
Aaron Hance 2022-02-08 21:28:47 +00:00 committed by Aaron
parent 0855abfd41
commit 6cd9ae4f46

View File

@ -44,6 +44,19 @@ type
ElementSize : uint32; ElementSize : uint32;
end; end;
{ Dynamic List }
PDList = ^TDList;
TDList = record
Count : uint32;
Data : void;
ElementSize : uint32;
DataSize : uint32;
end;
{ Dynamic List Iterator }
{ String Linked List } { String Linked List }
procedure STRLL_Add(LinkedList : PLinkedListBase; str : pchar); procedure STRLL_Add(LinkedList : PLinkedListBase; str : pchar);
@ -66,6 +79,24 @@ function LL_Get(LinkedList : PLinkedListBase; idx : uint32) : Void;
procedure LL_Free(LinkedList : PLinkedListBase); procedure LL_Free(LinkedList : PLinkedListBase);
function LL_FromString(str : pchar; delimter : char) : PLinkedListBase; function LL_FromString(str : pchar; delimter : char) : PLinkedListBase;
{ Dynamic List }
function DL_New(ElementSize : uint32) : PDList;
function DL_Add(DList : PDList) : Void;
function DL_Delete(DList : PDList; idx : uint32) : boolean;
function DL_Size(DList : PDList) : uint32;
function DL_Set(DList : PDList; idx : uint32; elm : puint32) : boolean;
function DL_Get(DList : PDList; idx : uint32) : Void;
procedure DL_Free(DList : PDList);
function DL_IndexOf(DList : PDList; elm : puint32) : uint32;
function DL_Contains(DList : PDList; elm : puint32) : boolean;
function DL_Concat(DList1 : PDList; DList2 : PDList) : PDList;
{ Dynamic List Iterator }
implementation implementation
uses uses
@ -351,4 +382,227 @@ begin
end; end;
end; end;
{ Dynamic List }
function DL_New(ElementSize : uint32) : PDList;
var
DL : PDList;
begin
DL := PDList(kalloc(sizeof(DL)));
DL^.ElementSize:= ElementSize;
DL^.count := 0;
if ElementSize > 128 then begin
DL^.data := kalloc(ElementSize * 4);
Dl^.DataSize:= ElementSize * 4;
end else if ElementSize > 64 then begin
DL^.data := kalloc(ElementSize * 8);
Dl^.DataSize:= ElementSize * 8;
end else if ElementSize > 32 then begin
DL^.data := kalloc(ElementSize * 16);
Dl^.DataSize:= ElementSize * 16;
end else if ElementSize > 16 then begin
DL^.data := kalloc(ElementSize * 32);
Dl^.DataSize:= ElementSize * 32;
end else begin
DL^.data := kalloc(ElementSize * 64);
Dl^.DataSize:= ElementSize * 64;
end;
DL_New := DL;
end;
function DL_Add(DList : PDList) : Void;
var
elm : puint32;
tempList : puint32;
begin
//check if we need to resize
if (DList^.count + 1) * DList^.ElementSize > DList^.DataSize then begin
push_trace('lists.DL_Add: Resizing');
tempList := DList^.Data;
DList^.Data := kalloc(DList^.DataSize * 2);
memset(uint32(DList^.Data), 0, DList^.DataSize * 2);
memcpy(uint32(tempList), uint32(DList^.Data), DList^.DataSize);
DList^.DataSize:= DList^.DataSize * 2;
kfree(void(tempList));
end;
push_trace('lists.DL_Add');
elm := puint32(@puint8(DList^.Data)[(DList^.count * DList^.ElementSize)]);
elm^ := 0;
push_trace('lists.DL_Add: Adding');
DList^.count := DList^.count + 1;
DL_Add := elm;
end;
function DL_Delete(DList : PDList; idx : uint32) : boolean;
var
elm : puint32;
tempList : puint32;
begin
if idx >= DList^.count then begin
DL_Delete := false;
exit;
end;
elm := puint32( puint8(DList^.Data) + (idx * DList^.ElementSize));
memcpy(uint32( puint8(elm) + DList^.ElementSize), uInt32(elm), (DList^.count - idx) * DList^.ElementSize);
DList^.count := DList^.count - 1;
if (DList^.count * DList^.ElementSize) < DList^.DataSize DIV 2 then begin
tempList := DList^.Data;
DList^.DataSize:= DList^.DataSize DIV 2;
DList^.Data := kalloc(DList^.DataSize);
memcpy(uint32(tempList), uint32(DList^.Data), DList^.DataSize);
kfree(void(tempList));
end;
DL_Delete := true;
end;
function DL_Get(DList : PDList; idx : uint32) : Void;
var
elm : puint32;
begin
if idx >= DList^.count then begin
DL_Get := nil;
exit;
end;
elm := puint32(DList^.Data + (idx * DList^.ElementSize));
DL_Get := elm;
end;
function DL_Set(DList : PDList; idx : uint32; elm : puint32) : boolean;
var
tempList : PuInt32;
size : uint32;
begin
if idx >= DList^.count then begin
DL_Set := false;
exit;
end;
//check if we need to resize
if (idx + 1) * Dlist^.ElementSize > DList^.DataSize then begin
console.writestring('resising thisthinghere');
size := idx * DList^.ElementSize * 2;
tempList := DList^.Data;
DList^.Data := kalloc(size);
memset(uint32(DList^.Data), 0, size);
memcpy(uint32(tempList), uint32(DList^.Data), DList^.DataSize);
DList^.DataSize := size;
kfree(void(tempList));
end;
console.writeString('offset: ');
console.writeintln(idx * DList^.ElementSize);
memcpy(uint32(elm), uint32( PuInt8(DList^.Data) + (idx * DList^.ElementSize)), DList^.ElementSize);
//check if count is smaller than idx and if so, increase count
if DList^.count < idx then DList^.count := idx;
DL_Set := true;
end;
function DL_Size(DList : PDList) : uint32;
begin
DL_Size := DList^.count;
end;
procedure DL_Free(DList : PDList);
begin
kfree(void(DList^.Data));
kfree(void(DList));
end;
function DL_IndexOf(DList : PDList; elm : puint32) : uint32;
var
i : uint32;
temp : puint32;
begin
for i := 0 to DList^.count - 1 do begin
temp := puint32( puint8(DList^.Data) + (i * DList^.ElementSize));
if temp = elm then begin
DL_IndexOf := i;
exit;
end;
end;
DL_IndexOf := -1;
end;
function DL_Contains(DList : PDList; elm : puint32) : boolean;
var
i : uint32;
begin
i := DL_IndexOf(DList, elm);
if i = -1 then begin
DL_Contains := false;
exit;
end;
DL_Contains := true;
end;
function DL_Concat(DList1 : PDList; DList2 : PDList) : PDList;
var
i : uint32;
temp : puint32;
begin
//check element size
if DList1^.ElementSize <> DList2^.ElementSize then begin
DL_Concat := nil;
exit;
end;
//check if we need to resize
while true do begin
if (DList1^.count + DList2^.count) * DList1^.ElementSize > DList1^.DataSize then begin
temp := DList1^.Data;
DList1^.Data := kalloc(DList1^.DataSize * 2);
memset(uint32(DList1^.Data), 0, DList1^.DataSize * 2);
memcpy(uint32(temp), uint32(DList1^.Data), DList1^.DataSize);
DList1^.DataSize:= DList1^.DataSize * 2;
kfree(void(temp));
end else Break;
end;
for i := 0 to DList2^.count - 1 do begin
temp := DL_Add(DList1);
memcpy(uint32(DL_Get(DList2, i)), uint32(temp), DList1^.ElementSize);
end;
DL_Concat := DList1;
end;
end. end.