123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- unit arrayutils;
- {$mode objfpc}
- {$modeswitch typehelpers}
- interface
- uses
- Types, SysUtils;
- Type
- TBytesHelper = type helper for TBytes
- strict private
- function get_Length: Integer;
- procedure set_Length(const AValue: Integer);
- public
- function Compare(const ARight: TBytes): Integer;
- function High: Integer;
- function Low: Integer;
- function SubBytes(const AStartIndex: Integer): TBytes; overload; inline;
- function SubBytes(const AStartIndex, ALength: Integer): TBytes; overload; inline;
- property Length: Integer read get_Length write set_Length;
- end;
- TWords = TWordDynArray;
- TWordDynArrayHelper = type helper for TWordDynArray
- private
- function get_Length: Integer;
- procedure set_Length(const AValue: Integer);
- public
- class function FromBytes(const ABytes: TBytes): TWords; static;
- function High: Integer;
- function Low: Integer;
- function ToBytes: TBytes;
- property Length: Integer read get_Length write set_Length;
- end;
- implementation
- Const
- GreaterThanValue = 1;
- LessThanValue = -1;
- EqualsValue = 0;
- { TBytesHelper }
- function TBytesHelper.Compare(const ARight: TBytes): Integer;
- var
- lCount: Integer;
- begin
- if Length > ARight.Length then
- Exit(GreaterThanValue);
- if Length < ARight.Length then
- Exit(LessThanValue);
- Result := EqualsValue;
- for lCount := Low to High do
- begin
- if Self[lCount] > ARight[lCount] then
- Exit(GreaterThanValue);
- if Self[lCount] < ARight[lCount] then
- Exit(LessThanValue);
- end;
- end;
- function TBytesHelper.get_Length: Integer;
- begin
- Result := System.Length(Self);
- end;
- function TBytesHelper.High: Integer;
- begin
- Result := System.High(Self);
- end;
- function TBytesHelper.Low: Integer;
- begin
- Result := System.Low(Self);
- end;
- procedure TBytesHelper.set_Length(const AValue: Integer);
- begin
- System.SetLength(Self, AValue);
- end;
- function TBytesHelper.SubBytes(const AStartIndex: Integer): TBytes;
- begin
- Result := System.Copy(Self, AStartIndex, Length);
- end;
- function TBytesHelper.SubBytes(const AStartIndex, ALength: Integer): TBytes;
- begin
- Result := System.Copy(Self, AStartIndex, ALength);
- end;
- function WordFromBytes(const ALow, AHigh: Byte): Word;
- const
- cMask: Byte = $FF;
- cBitPerByte = 8;
- begin
- Result := ALow + (AHigh and (cMask shl cBitPerByte));
- end;
- Type
- TWordBytes = Record
- aLow, aHigh: Byte;
- end;
- Function WordToBytes(aValue : Word) : TWordBytes;
- const
- cMask: Byte = $FF;
- cBitPerByte = 8;
- begin
- Result.aLow := aValue and cMask;
- Result.aHigh := aValue and (cMask shl cBitPerByte);
- end;
- class function TWordDynArrayHelper.FromBytes(const ABytes: TBytes): TWords;
- const
- cBytesPerWord = 2;
- var
- lCount: Integer;
- lLow: Byte;
- lHigh: Byte;
- begin
- lCount := ABytes.Length;
- if Odd(lCount) then
- Inc(lCount);
- Result.Length := lCount div cBytesPerWord;
- lCount := ABytes.Low;
- while lCount <= ABytes.High do
- begin
- lLow := ABytes[lCount];
- if lCount + 1 <= ABytes.High then
- lHigh := ABytes[lCount + 1]
- else
- lHigh := 0;
- Result[lCount div cBytesPerWord] := WordFromBytes(lLow, lHigh);
- Inc(lCount, cBytesPerWord);
- end;
- end;
- function TWordDynArrayHelper.get_Length: Integer;
- begin
- Result := System.Length(Self);
- end;
- function TWordDynArrayHelper.High: Integer;
- begin
- Result := System.High(Self);
- end;
- function TWordDynArrayHelper.Low: Integer;
- begin
- Result := System.Low(Self);
- end;
- procedure TWordDynArrayHelper.set_Length(const AValue: Integer);
- begin
- System.SetLength(Self, AValue);
- end;
- function TWordDynArrayHelper.ToBytes: TBytes;
- const
- cBytesPerWord = 2;
- var
- lCount: Integer;
- lNewIndex: Integer;
- aBytes : TWordBytes;
- begin
- Result.Length := Length * cBytesPerWord;
- for lCount := Low to High do
- begin
- aBytes:=WordToBytes(Self[lCount]);
- lNewIndex := lCount * cBytesPerWord;
- Result[lNewIndex] := aBytes.aLow;
- Result[lNewIndex + 1] := aBytes.aHigh;
- end;
- end;
- end.
|