Sordie.co.uk

libsassy/libSassy.Pointers.pas

Raw

{(
 )) libSassy.Pointers
((    Pointer helper
 ))
((  Copyright  Sordie Aranka Solomon-Smith 2018
 ))
((  This work is made available under the terms of the Creative Commons
 )) Attribution-NonCommercial-ShareAlike 3.0 Unported license
((  http://creativecommons.org/licenses/by-nc-sa/3.0/
 )}

unit libSassy.Pointers;

interface

type
  TPointer<T> = record
    type PtrT = ^T;
    var  PtrV: PtrT;

    function Void: Pointer; inline;

    class operator Implicit(Value: TPointer<T>): Pointer;     inline;
    class operator Implicit(Value: Pointer):     TPointer<T>; inline;

    function  Read (                const Increment: Boolean = True): T; inline;
    procedure Write(const Value: T; const Increment: Boolean = True);    inline;

    procedure Inc(const Count: Integer = 1); inline;
    procedure Dec(const Count: Integer = 1); inline;

    function  ValueRead(Index: Integer): T;
    procedure ValueWrite(Index: Integer; Value: T);

    property Value[Index: Integer]: T read ValueRead write ValueWrite; default;
  end;

  TPointerHelper = record helper for Pointer
    procedure Read (var   Data; const Size: Integer; const Increment: Boolean = True); overload;
    procedure Write(const Data; const Size: Integer; const Increment: Boolean = True); overload;

    function  Read<T> (                const Increment: Boolean = True): T; overload; inline;
    procedure Write<T>(const Value: T; const Increment: Boolean = True);    overload; inline;
  end;

implementation

function TPointer<T>.Void;
begin
  Result := Pointer(PtrV);
end;

class operator TPointer<T>.Implicit(Value: TPointer<T>): Pointer;
begin
  Result := Value.PtrV;
end;

class operator TPointer<T>.Implicit(Value: Pointer): TPointer<T>;
begin
  Result.PtrV := Value;
end;

function TPointer<T>.Read;
begin
  Result := Void.Read<T>(Increment);
end;

procedure TPointer<T>.Write;
begin
  Void.Write<T>(Value, Increment);
end;

procedure TPointer<T>.Inc;
begin
  PtrV := PtrT(Cardinal(PtrV) + Cardinal(Count * Sizeof(PtrT)));
end;

procedure TPointer<T>.Dec;
begin
  PtrV := PtrT(Cardinal(PtrV) - Cardinal(Count * Sizeof(PtrT)));
end;

function TPointer<T>.ValueRead;
begin
  Result := PtrT(Cardinal(PtrV) + Cardinal(Index * SizeOf(PtrT)))^;
end;

procedure TPointer<T>.ValueWrite;
begin
  PtrT(Cardinal(PtrV) + Cardinal(Index * SizeOf(PtrT)))^ := Value;
end;

procedure TPointerHelper.Read(var Data; const Size: Integer; const Increment: Boolean = True);
begin
  Move(Self^, Data, Size);

  if Increment then
    Self := Pointer(Cardinal(Self) + Cardinal(Size));
end;

procedure TPointerHelper.Write(const Data; const Size: Integer; const Increment: Boolean = True);
begin
  Move(Data, Self^, Size);

  if Increment then
    Self := Pointer(Cardinal(Self) + Cardinal(Size));
end;

function TPointerHelper.Read<T>(const Increment: Boolean = True): T;
begin
  Read(Result, SizeOf(Result), Increment);
end;

procedure TPointerHelper.Write<T>(const Value: T; const Increment: Boolean = True);
begin
  Write(Value, SizeOf(Value), Increment);
end;

end.