program test;
{$mode objfpc}{$h+}
{$modeswitch advancedrecords}
(*
procedure MyProc(aInteger: Integer; Bitness: byte);
var
myData16: array of word;
myData32: array of Dword;
begin
if Bitness = 16
then SetLength(myData16,xxx)
else SetLength(myData32,xxx);
//Select which var to use in each case necessary
end;
*)
type
// Bitness Adaptable Dynamic Array (sort of)
TBADynArrayBitness = (bad8, bad16, bad32, bad64);
TBADynArray =
record
Data : packed array of byte;
bitness : TBADynArrayBitness;
private
function GetItem(Index: integer): int64;
procedure SetItem(index : integer; value: int64);
procedure Dump(const contents: boolean = true);
procedure SetLength(Len: SizeInt);
function GetHigh: SizeInt;
function GetLow: SizeInt;
function GetLength: SizeInt;
public
property Items[index: integer]: int64 read getItem write SetItem; default;
end;
function Low(DynArr: TBADynArray): SizeInt;
begin
result := DynArr.GetLow;
end;
function High(DynArr: TBADynArray): SizeInt;
begin
result := DynArr.GetHigh;
end;
function Length(DynArr: TBADynArray): SizeInt;
begin
result := DynArr.GetLength;
end;
procedure SetLength(var DynArr: TBADynArray; Len: SizeInt);
begin
DynArr.SetLength(Len);
end;
{ TBADynArray }
function TBADynArray.GetLength: SizeInt;
begin
result := system.Length(Self.Data) shr ord(Self.Bitness);
end;
procedure TBADynArray.SetLength(Len: SizeInt);
begin
System.SetLength(Self.Data, Len * 1 shl ord(Self.Bitness));
end;
function TBADynArray.GetLow: SizeInt;
begin
result := System.Low(Self.Data);
end;
function TBADynArray.GetHigh: SizeInt;
begin
result := Self.GetLength - 1;
end;
function TBADynArray.GetItem(Index: integer): int64;
var
P8 : PByte;
P16 : PWord;
P32 : PDWord;
P64 : PQWord;
begin
case Self.Bitness of
bad8 : begin P8 := @Self.Data[0]; result := P8 [Index]; end;
bad16 : begin P16 := @Self.Data[0]; result := P16[Index]; end;
bad32 : begin P32 := @Self.Data[0]; result := P32[Index]; end;
bad64 : begin P64 := @Self.Data[0]; result := P64[Index]; end;
end;
end;
procedure TBADynArray.SetItem(index: integer; value: int64);
var
P8 : PByte;
P16 : PWord;
P32 : PDWord;
P64 : PQWord;
begin
case Self.bitness of
bad8 : begin P8 := @Self.Data[0]; P8 [index] := byte(value); end;
bad16 : begin P16 := @Self.Data[0]; P16[index] := word(value); end;
bad32 : begin P32 := @Self.Data[0]; P32[index] := dword(value); end;
bad64 : begin P64 := @Self.Data[0]; P64[index] := qword(value); end;
end;
end;
procedure TBADynArray.Dump(const contents: boolean = true);
var
i: integer;
begin
writeln('bitness = ', Self.Bitness);
writeln('#bytes in array = ', System.Length(Self.Data));
writeln('#items in array = ', Self.GetLength);
writeln('address of data = $', HexStr(@Self.Data[0]));
if contents then
for i := System.Low(Self.Data) to System.High(Self.Data)
do writeln(Self.Data[i]:3);
end;
///////////////////////////////////////////////////////////////////////////////
procedure Mfagnostic(var inData: TBADynArray);
var
i: integer;
begin
for i := low(inData) to High(inData)
do InData[i]:= i;
writeln;
inData.Dump;
writeln;
for i := low(inData) to High(inData)
do writeln(InData[i]);
end;
procedure example;
var
MyData : TBADynArray;
begin
MyData := default(TBADynArray);
MyData.Bitness := bad64;
SetLength(MyData, 10);
mfagnostic(MyData);
end;
procedure multitest;
var
MyData : TBADynArray;
bitness : TBADynArrayBitness;
begin
MyData := default(TBADynArray);
for bitness in TBADynArrayBitness do
begin
MyData.Bitness := bitness;
SetLength(MyData, 2);
MyData.Dump(false);
end;
end;
begin
multitest;
writeln;
example
end.