From 670150d66ad9df9709a7b3a8df1f958346e7606e Mon Sep 17 00:00:00 2001 From: Ugochukwu Mmaduekwe Date: Sun, 14 Jun 2026 23:41:06 +0100 Subject: [PATCH] update binaryprimitives --- SimpleBaseLib/src/Include/SimpleBaseLib.inc | 8 + .../src/Include/SimpleBaseLibFPC.inc | 10 + .../src/Misc/SbpBinaryPrimitives.pas | 662 +++++++++++++----- 3 files changed, 519 insertions(+), 161 deletions(-) diff --git a/SimpleBaseLib/src/Include/SimpleBaseLib.inc b/SimpleBaseLib/src/Include/SimpleBaseLib.inc index 88f5f04..8ce2449 100644 --- a/SimpleBaseLib/src/Include/SimpleBaseLib.inc +++ b/SimpleBaseLib/src/Include/SimpleBaseLib.inc @@ -27,6 +27,14 @@ {$STRINGCHECKS OFF} {$WARN DUPLICATE_CTOR_DTOR OFF} +{============================== CPU Architecture ==============================} + +{$DEFINE SIMPLEBASELIB_LITTLE_ENDIAN} + +{$IFDEF CPUARM} + {$DEFINE SIMPLEBASELIB_REQUIRES_PROPER_ALIGNMENT} +{$ENDIF} + {$ENDIF} {========================== Common Compiler Settings ==========================} diff --git a/SimpleBaseLib/src/Include/SimpleBaseLibFPC.inc b/SimpleBaseLib/src/Include/SimpleBaseLibFPC.inc index dbfc05d..a74d1da 100644 --- a/SimpleBaseLib/src/Include/SimpleBaseLibFPC.inc +++ b/SimpleBaseLib/src/Include/SimpleBaseLibFPC.inc @@ -15,6 +15,16 @@ {$MESSAGE ERROR 'This Library requires FreePascal 3.2.2 or higher.'} {$IFEND} +{============================== CPU Architecture ==============================} + +{$IFDEF FPC_LITTLE_ENDIAN} + {$DEFINE SIMPLEBASELIB_LITTLE_ENDIAN} +{$ENDIF} + +{$IFDEF FPC_REQUIRES_PROPER_ALIGNMENT} + {$DEFINE SIMPLEBASELIB_REQUIRES_PROPER_ALIGNMENT} +{$ENDIF} + {========================= Compiler Mode & Optimizations ======================} {$MODE DELPHI} diff --git a/SimpleBaseLib/src/Misc/SbpBinaryPrimitives.pas b/SimpleBaseLib/src/Misc/SbpBinaryPrimitives.pas index 61e2d42..ec4300a 100644 --- a/SimpleBaseLib/src/Misc/SbpBinaryPrimitives.pas +++ b/SimpleBaseLib/src/Misc/SbpBinaryPrimitives.pas @@ -5,6 +5,7 @@ interface uses + SbpBitOperations, SysUtils, SbpSimpleBaseLibTypes; @@ -13,232 +14,573 @@ TBinaryPrimitives = class private class procedure CheckBounds(const AData: TSimpleBaseLibByteArray; AOffset, ANeeded: Integer); static; inline; - // UInt16 helpers - class procedure WriteUInt16LEInternal(AValue: UInt16; const AData: TSimpleBaseLibByteArray; AOffset: Integer); static; inline; - class procedure WriteUInt16BEInternal(AValue: UInt16; const AData: TSimpleBaseLibByteArray; AOffset: Integer); static; inline; - class function ReadUInt16LEInternal(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt16; static; inline; - class function ReadUInt16BEInternal(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt16; static; inline; + // Wire LE/BE value to native integer + class function LeToNativeUInt16(AValue: UInt16): UInt16; static; inline; + class function LeToNativeUInt32(AValue: UInt32): UInt32; static; inline; + class function LeToNativeUInt64(AValue: UInt64): UInt64; static; inline; + class function BeToNativeUInt16(AValue: UInt16): UInt16; static; inline; + class function BeToNativeUInt32(AValue: UInt32): UInt32; static; inline; + class function BeToNativeUInt64(AValue: UInt64): UInt64; static; inline; + + // Copy with byte-reversal within each 32/64-bit lane + class procedure SwapCopyUInt32(ASource: Pointer; ASourceIndex: Integer; + ADestination: Pointer; ADestinationIndex: Integer; ASize: Integer); static; + class procedure SwapCopyUInt64(ASource: Pointer; ASourceIndex: Integer; + ADestination: Pointer; ADestinationIndex: Integer; ASize: Integer); static; + + // Semantic LE/BE read/write at PByte+Offset + class function ReadUInt16LEAt(AInput: PByte; AOffset: Integer): UInt16; static; inline; + class function ReadUInt16BEAt(AInput: PByte; AOffset: Integer): UInt16; static; inline; + class function ReadUInt32LEAt(AInput: PByte; AOffset: Integer): UInt32; static; inline; + class function ReadUInt32BEAt(AInput: PByte; AOffset: Integer): UInt32; static; inline; + class function ReadUInt64LEAt(AInput: PByte; AOffset: Integer): UInt64; static; inline; + class function ReadUInt64BEAt(AInput: PByte; AOffset: Integer): UInt64; static; inline; + + class procedure WriteUInt16LEAt(AOutput: PByte; AOffset: Integer; AValue: UInt16); static; inline; + class procedure WriteUInt16BEAt(AOutput: PByte; AOffset: Integer; AValue: UInt16); static; inline; + class procedure WriteUInt32LEAt(AOutput: PByte; AOffset: Integer; AValue: UInt32); static; inline; + class procedure WriteUInt32BEAt(AOutput: PByte; AOffset: Integer; AValue: UInt32); static; inline; + class procedure WriteUInt64LEAt(AOutput: PByte; AOffset: Integer; AValue: UInt64); static; inline; + class procedure WriteUInt64BEAt(AOutput: PByte; AOffset: Integer; AValue: UInt64); static; inline; - // UInt32 helpers - class procedure WriteUInt32LEInternal(AValue: UInt32; const AData: TSimpleBaseLibByteArray; AOffset: Integer); static; inline; - class procedure WriteUInt32BEInternal(AValue: UInt32; const AData: TSimpleBaseLibByteArray; AOffset: Integer); static; inline; - class function ReadUInt32LEInternal(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt32; static; inline; - class function ReadUInt32BEInternal(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt32; static; inline; + public + /// Alignment-safe native-order word load (not a wire-endian read). + class function LoadUInt16(AInput: PWord): UInt16; static; inline; + /// Alignment-safe native-order dword load (not a wire-endian read). + class function LoadUInt32(AInput: PCardinal): UInt32; static; inline; + /// Alignment-safe native-order qword load (not a wire-endian read). + class function LoadUInt64(AInput: PUInt64): UInt64; static; inline; + /// Alignment-safe native-order word store (not a wire-endian write). + class procedure StoreUInt16(AOutput: PWord; AValue: UInt16); static; inline; + /// Alignment-safe native-order dword store (not a wire-endian write). + class procedure StoreUInt32(AOutput: PCardinal; AValue: UInt32); static; inline; + /// Alignment-safe native-order qword store (not a wire-endian write). + class procedure StoreUInt64(AOutput: PUInt64; AValue: UInt64); static; inline; + + // Copy block; preserve LE or BE wire layout + class procedure CopyUInt32LittleEndian(ASource: Pointer; ASourceIndex: Integer; + ADestination: Pointer; ADestinationIndex: Integer; ASize: Integer); static; inline; + class procedure CopyUInt32BigEndian(ASource: Pointer; ASourceIndex: Integer; + ADestination: Pointer; ADestinationIndex: Integer; ASize: Integer); static; inline; + class procedure CopyUInt64LittleEndian(ASource: Pointer; ASourceIndex: Integer; + ADestination: Pointer; ADestinationIndex: Integer; ASize: Integer); static; inline; + class procedure CopyUInt64BigEndian(ASource: Pointer; ASourceIndex: Integer; + ADestination: Pointer; ADestinationIndex: Integer; ASize: Integer); static; inline; + + class procedure WriteUInt16LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: UInt16); overload; static; inline; + class procedure WriteUInt32LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: UInt32); overload; static; inline; + class procedure WriteUInt64LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: UInt64); overload; static; inline; + + class procedure WriteInt16LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Int16); static; inline; + class procedure WriteInt32LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Int32); static; inline; + class procedure WriteInt64LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Int64); static; inline; + + class procedure WriteSingleLittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Single); static; inline; + class procedure WriteDoubleLittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Double); static; inline; + + class procedure WriteUInt16BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: UInt16); overload; static; inline; + class procedure WriteUInt32BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: UInt32); overload; static; inline; + class procedure WriteUInt64BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: UInt64); overload; static; inline; + + class procedure WriteInt16BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Int16); static; inline; + class procedure WriteInt32BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Int32); static; inline; + class procedure WriteInt64BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Int64); static; inline; + + class procedure WriteSingleBigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Single); static; inline; + class procedure WriteDoubleBigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Double); static; inline; + + class function ReadUInt16LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt16; overload; static; inline; + class function ReadUInt32LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt32; overload; static; inline; + class function ReadUInt64LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt64; overload; static; inline; + + class function ReadInt16LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Int16; static; inline; + class function ReadInt32LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Int32; static; inline; + class function ReadInt64LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Int64; static; inline; + + class function ReadSingleLittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Single; static; inline; + class function ReadDoubleLittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Double; static; inline; + + class function ReadUInt16BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt16; overload; static; inline; + class function ReadUInt32BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt32; overload; static; inline; + class function ReadUInt64BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt64; overload; static; inline; + + class function ReadInt16BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Int16; static; inline; + class function ReadInt32BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Int32; static; inline; + class function ReadInt64BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Int64; static; inline; + + class function ReadSingleBigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Single; static; inline; + class function ReadDoubleBigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Double; static; inline; + + // PByte+Offset overloads + class procedure WriteUInt16LittleEndian(AOutput: PByte; AOffset: Integer; AValue: UInt16); overload; static; inline; + class procedure WriteUInt32LittleEndian(AOutput: PByte; AOffset: Integer; AValue: UInt32); overload; static; inline; + class procedure WriteUInt64LittleEndian(AOutput: PByte; AOffset: Integer; AValue: UInt64); overload; static; inline; + + class procedure WriteUInt16BigEndian(AOutput: PByte; AOffset: Integer; AValue: UInt16); overload; static; inline; + class procedure WriteUInt32BigEndian(AOutput: PByte; AOffset: Integer; AValue: UInt32); overload; static; inline; + class procedure WriteUInt64BigEndian(AOutput: PByte; AOffset: Integer; AValue: UInt64); overload; static; inline; + + class function ReadUInt16LittleEndian(AInput: PByte; AOffset: Integer): UInt16; overload; static; inline; + class function ReadUInt32LittleEndian(AInput: PByte; AOffset: Integer): UInt32; overload; static; inline; + class function ReadUInt64LittleEndian(AInput: PByte; AOffset: Integer): UInt64; overload; static; inline; + + class function ReadUInt16BigEndian(AInput: PByte; AOffset: Integer): UInt16; overload; static; inline; + class function ReadUInt32BigEndian(AInput: PByte; AOffset: Integer): UInt32; overload; static; inline; + class function ReadUInt64BigEndian(AInput: PByte; AOffset: Integer): UInt64; overload; static; inline; + end; - // UInt64 helpers - class procedure WriteUInt64LEInternal(AValue: UInt64; const AData: TSimpleBaseLibByteArray; AOffset: Integer); static; inline; - class procedure WriteUInt64BEInternal(AValue: UInt64; const AData: TSimpleBaseLibByteArray; AOffset: Integer); static; inline; - class function ReadUInt64LEInternal(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt64; static; inline; - class function ReadUInt64BEInternal(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt64; static; inline; +implementation - public - class procedure WriteUInt16LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: UInt16); static; - class procedure WriteUInt32LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: UInt32); static; - class procedure WriteUInt64LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: UInt64); static; +{ TBinaryPrimitives } - class procedure WriteInt16LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Int16); static; - class procedure WriteInt32LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Int32); static; - class procedure WriteInt64LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Int64); static; +class procedure TBinaryPrimitives.CheckBounds(const AData: TSimpleBaseLibByteArray; AOffset, ANeeded: Integer); +begin + if (AOffset < 0) or (AOffset + ANeeded > Length(AData)) then + raise EArgumentOutOfRangeException.Create('AOffset'); +end; - class procedure WriteSingleLittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Single); static; - class procedure WriteDoubleLittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Double); static; +// ============================================================================ +// Host-endian conversion +// ============================================================================ - class procedure WriteUInt16BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: UInt16); static; - class procedure WriteUInt32BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: UInt32); static; - class procedure WriteUInt64BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: UInt64); static; +class function TBinaryPrimitives.LeToNativeUInt16(AValue: UInt16): UInt16; +begin +{$IFDEF SIMPLEBASELIB_LITTLE_ENDIAN} + Result := AValue; +{$ELSE} + Result := TBitOperations.ReverseBytesUInt16(AValue); +{$ENDIF} +end; - class procedure WriteInt16BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Int16); static; - class procedure WriteInt32BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Int32); static; - class procedure WriteInt64BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Int64); static; +class function TBinaryPrimitives.LeToNativeUInt32(AValue: UInt32): UInt32; +begin +{$IFDEF SIMPLEBASELIB_LITTLE_ENDIAN} + Result := AValue; +{$ELSE} + Result := TBitOperations.ReverseBytesUInt32(AValue); +{$ENDIF} +end; + +class function TBinaryPrimitives.LeToNativeUInt64(AValue: UInt64): UInt64; +begin +{$IFDEF SIMPLEBASELIB_LITTLE_ENDIAN} + Result := AValue; +{$ELSE} + Result := TBitOperations.ReverseBytesUInt64(AValue); +{$ENDIF} +end; - class procedure WriteSingleBigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Single); static; - class procedure WriteDoubleBigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Double); static; +class function TBinaryPrimitives.BeToNativeUInt16(AValue: UInt16): UInt16; +begin +{$IFDEF SIMPLEBASELIB_LITTLE_ENDIAN} + Result := TBitOperations.ReverseBytesUInt16(AValue); +{$ELSE} + Result := AValue; +{$ENDIF} +end; - class function ReadUInt16LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt16; static; - class function ReadUInt32LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt32; static; - class function ReadUInt64LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt64; static; +class function TBinaryPrimitives.BeToNativeUInt32(AValue: UInt32): UInt32; +begin +{$IFDEF SIMPLEBASELIB_LITTLE_ENDIAN} + Result := TBitOperations.ReverseBytesUInt32(AValue); +{$ELSE} + Result := AValue; +{$ENDIF} +end; - class function ReadInt16LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Int16; static; - class function ReadInt32LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Int32; static; - class function ReadInt64LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Int64; static; +class function TBinaryPrimitives.BeToNativeUInt64(AValue: UInt64): UInt64; +begin +{$IFDEF SIMPLEBASELIB_LITTLE_ENDIAN} + Result := TBitOperations.ReverseBytesUInt64(AValue); +{$ELSE} + Result := AValue; +{$ENDIF} +end; - class function ReadSingleLittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Single; static; - class function ReadDoubleLittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Double; static; +// ============================================================================ +// Raw memory load/store +// ============================================================================ - class function ReadUInt16BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt16; static; - class function ReadUInt32BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt32; static; - class function ReadUInt64BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt64; static; +class function TBinaryPrimitives.LoadUInt16(AInput: PWord): UInt16; +begin +{$IFDEF SIMPLEBASELIB_REQUIRES_PROPER_ALIGNMENT} + Move(AInput^, Result, SizeOf(UInt16)); +{$ELSE} + Result := AInput^; +{$ENDIF} +end; - class function ReadInt16BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Int16; static; - class function ReadInt32BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Int32; static; - class function ReadInt64BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Int64; static; +class function TBinaryPrimitives.LoadUInt32(AInput: PCardinal): UInt32; +begin +{$IFDEF SIMPLEBASELIB_REQUIRES_PROPER_ALIGNMENT} + Move(AInput^, Result, SizeOf(UInt32)); +{$ELSE} + Result := AInput^; +{$ENDIF} +end; - class function ReadSingleBigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Single; static; - class function ReadDoubleBigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Double; static; - end; +class function TBinaryPrimitives.LoadUInt64(AInput: PUInt64): UInt64; +begin +{$IFDEF SIMPLEBASELIB_REQUIRES_PROPER_ALIGNMENT} + Move(AInput^, Result, SizeOf(UInt64)); +{$ELSE} + Result := AInput^; +{$ENDIF} +end; -implementation +class procedure TBinaryPrimitives.StoreUInt16(AOutput: PWord; AValue: UInt16); +begin +{$IFDEF SIMPLEBASELIB_REQUIRES_PROPER_ALIGNMENT} + Move(AValue, AOutput^, SizeOf(UInt16)); +{$ELSE} + AOutput^ := AValue; +{$ENDIF} +end; -{ TBinaryPrimitives } +class procedure TBinaryPrimitives.StoreUInt32(AOutput: PCardinal; AValue: UInt32); +begin +{$IFDEF SIMPLEBASELIB_REQUIRES_PROPER_ALIGNMENT} + Move(AValue, AOutput^, SizeOf(UInt32)); +{$ELSE} + AOutput^ := AValue; +{$ENDIF} +end; -class procedure TBinaryPrimitives.CheckBounds(const AData: TSimpleBaseLibByteArray; AOffset, ANeeded: Integer); +class procedure TBinaryPrimitives.StoreUInt64(AOutput: PUInt64; AValue: UInt64); begin - if (AOffset < 0) or (AOffset + ANeeded > Length(AData)) then - raise EArgumentOutOfRangeSimpleBaseLibException.Create('AOffset'); +{$IFDEF SIMPLEBASELIB_REQUIRES_PROPER_ALIGNMENT} + Move(AValue, AOutput^, SizeOf(UInt64)); +{$ELSE} + AOutput^ := AValue; +{$ENDIF} end; // ============================================================================ -// UInt16 Internal Helpers +// Bulk copy // ============================================================================ -class procedure TBinaryPrimitives.WriteUInt16LEInternal(AValue: UInt16; const AData: TSimpleBaseLibByteArray; AOffset: Integer); +class procedure TBinaryPrimitives.SwapCopyUInt32(ASource: Pointer; ASourceIndex: Integer; + ADestination: Pointer; ADestinationIndex: Integer; ASize: Integer); +var + LSrcWord, LDestWord, LSrcWordEnd: PCardinal; + LSrcByte, LDestByte: PByte; + LByteIdx: Integer; +begin + if ((NativeUInt(PByte(ADestination)) or NativeUInt(PByte(ASource)) or + NativeUInt(ASourceIndex) or NativeUInt(ADestinationIndex) or NativeUInt(ASize)) and 3) = 0 then + begin + LSrcWord := PCardinal(PByte(ASource) + ASourceIndex); + LSrcWordEnd := PCardinal(PByte(ASource) + ASourceIndex + ASize); + LDestWord := PCardinal(PByte(ADestination) + ADestinationIndex); + while LSrcWord < LSrcWordEnd do + begin + LDestWord^ := TBitOperations.ReverseBytesUInt32(LSrcWord^); + Inc(LDestWord); + Inc(LSrcWord); + end; + end + else + begin + LSrcByte := PByte(ASource) + ASourceIndex; + LDestByte := PByte(ADestination) + ADestinationIndex; + LByteIdx := 0; + while LByteIdx < ASize do + begin + LDestByte[LByteIdx] := LSrcByte[LByteIdx xor 3]; + Inc(LByteIdx); + end; + end; +end; + +class procedure TBinaryPrimitives.SwapCopyUInt64(ASource: Pointer; ASourceIndex: Integer; + ADestination: Pointer; ADestinationIndex: Integer; ASize: Integer); +var + LSrcWord, LDestWord, LSrcWordEnd: PUInt64; + LSrcByte, LDestByte: PByte; + LByteIdx: Integer; +begin + if ((NativeUInt(PByte(ADestination)) or NativeUInt(PByte(ASource)) or + NativeUInt(ASourceIndex) or NativeUInt(ADestinationIndex) or NativeUInt(ASize)) and 7) = 0 then + begin + LSrcWord := PUInt64(PByte(ASource) + ASourceIndex); + LSrcWordEnd := PUInt64(PByte(ASource) + ASourceIndex + ASize); + LDestWord := PUInt64(PByte(ADestination) + ADestinationIndex); + while LSrcWord < LSrcWordEnd do + begin + LDestWord^ := TBitOperations.ReverseBytesUInt64(LSrcWord^); + Inc(LDestWord); + Inc(LSrcWord); + end; + end + else + begin + LSrcByte := PByte(ASource) + ASourceIndex; + LDestByte := PByte(ADestination) + ADestinationIndex; + LByteIdx := 0; + while LByteIdx < ASize do + begin + LDestByte[LByteIdx] := LSrcByte[LByteIdx xor 7]; + Inc(LByteIdx); + end; + end; +end; + +class procedure TBinaryPrimitives.CopyUInt32LittleEndian(ASource: Pointer; ASourceIndex: Integer; + ADestination: Pointer; ADestinationIndex: Integer; ASize: Integer); begin - AData[AOffset] := Byte(AValue); - AData[AOffset + 1] := Byte(AValue shr 8); +{$IFDEF SIMPLEBASELIB_LITTLE_ENDIAN} + Move(Pointer(PByte(ASource) + ASourceIndex)^, + Pointer(PByte(ADestination) + ADestinationIndex)^, ASize); +{$ELSE} + SwapCopyUInt32(ASource, ASourceIndex, ADestination, ADestinationIndex, ASize); +{$ENDIF} end; -class procedure TBinaryPrimitives.WriteUInt16BEInternal(AValue: UInt16; const AData: TSimpleBaseLibByteArray; AOffset: Integer); +class procedure TBinaryPrimitives.CopyUInt32BigEndian(ASource: Pointer; ASourceIndex: Integer; + ADestination: Pointer; ADestinationIndex: Integer; ASize: Integer); begin - AData[AOffset] := Byte(AValue shr 8); - AData[AOffset + 1] := Byte(AValue); +{$IFDEF SIMPLEBASELIB_LITTLE_ENDIAN} + SwapCopyUInt32(ASource, ASourceIndex, ADestination, ADestinationIndex, ASize); +{$ELSE} + Move(Pointer(PByte(ASource) + ASourceIndex)^, + Pointer(PByte(ADestination) + ADestinationIndex)^, ASize); +{$ENDIF} end; -class function TBinaryPrimitives.ReadUInt16LEInternal(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt16; +class procedure TBinaryPrimitives.CopyUInt64LittleEndian(ASource: Pointer; ASourceIndex: Integer; + ADestination: Pointer; ADestinationIndex: Integer; ASize: Integer); begin - Result := UInt16(AData[AOffset]) or (UInt16(AData[AOffset + 1]) shl 8); +{$IFDEF SIMPLEBASELIB_LITTLE_ENDIAN} + Move(Pointer(PByte(ASource) + ASourceIndex)^, + Pointer(PByte(ADestination) + ADestinationIndex)^, ASize); +{$ELSE} + SwapCopyUInt64(ASource, ASourceIndex, ADestination, ADestinationIndex, ASize); +{$ENDIF} end; -class function TBinaryPrimitives.ReadUInt16BEInternal(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt16; +class procedure TBinaryPrimitives.CopyUInt64BigEndian(ASource: Pointer; ASourceIndex: Integer; + ADestination: Pointer; ADestinationIndex: Integer; ASize: Integer); begin - Result := (UInt16(AData[AOffset]) shl 8) or UInt16(AData[AOffset + 1]); +{$IFDEF SIMPLEBASELIB_LITTLE_ENDIAN} + SwapCopyUInt64(ASource, ASourceIndex, ADestination, ADestinationIndex, ASize); +{$ELSE} + Move(Pointer(PByte(ASource) + ASourceIndex)^, + Pointer(PByte(ADestination) + ADestinationIndex)^, ASize); +{$ENDIF} end; // ============================================================================ -// UInt32 Internal Helpers +// Pointer read/write cores // ============================================================================ -class procedure TBinaryPrimitives.WriteUInt32LEInternal(AValue: UInt32; const AData: TSimpleBaseLibByteArray; AOffset: Integer); +class function TBinaryPrimitives.ReadUInt16LEAt(AInput: PByte; AOffset: Integer): UInt16; begin - AData[AOffset] := Byte(AValue); - AData[AOffset + 1] := Byte(AValue shr 8); - AData[AOffset + 2] := Byte(AValue shr 16); - AData[AOffset + 3] := Byte(AValue shr 24); + Result := LeToNativeUInt16(LoadUInt16(PWord(AInput + AOffset))); end; -class procedure TBinaryPrimitives.WriteUInt32BEInternal(AValue: UInt32; const AData: TSimpleBaseLibByteArray; AOffset: Integer); +class function TBinaryPrimitives.ReadUInt16BEAt(AInput: PByte; AOffset: Integer): UInt16; begin - AData[AOffset] := Byte(AValue shr 24); - AData[AOffset + 1] := Byte(AValue shr 16); - AData[AOffset + 2] := Byte(AValue shr 8); - AData[AOffset + 3] := Byte(AValue); + Result := BeToNativeUInt16(LoadUInt16(PWord(AInput + AOffset))); end; -class function TBinaryPrimitives.ReadUInt32LEInternal(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt32; +class function TBinaryPrimitives.ReadUInt32LEAt(AInput: PByte; AOffset: Integer): UInt32; begin - Result := UInt32(AData[AOffset]) or - (UInt32(AData[AOffset + 1]) shl 8) or - (UInt32(AData[AOffset + 2]) shl 16) or - (UInt32(AData[AOffset + 3]) shl 24); + Result := LeToNativeUInt32(LoadUInt32(PCardinal(AInput + AOffset))); end; -class function TBinaryPrimitives.ReadUInt32BEInternal(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt32; +class function TBinaryPrimitives.ReadUInt32BEAt(AInput: PByte; AOffset: Integer): UInt32; begin - Result := (UInt32(AData[AOffset]) shl 24) or - (UInt32(AData[AOffset + 1]) shl 16) or - (UInt32(AData[AOffset + 2]) shl 8) or - UInt32(AData[AOffset + 3]); + Result := BeToNativeUInt32(LoadUInt32(PCardinal(AInput + AOffset))); +end; + +class function TBinaryPrimitives.ReadUInt64LEAt(AInput: PByte; AOffset: Integer): UInt64; +begin + Result := LeToNativeUInt64(LoadUInt64(PUInt64(AInput + AOffset))); +end; + +class function TBinaryPrimitives.ReadUInt64BEAt(AInput: PByte; AOffset: Integer): UInt64; +begin + Result := BeToNativeUInt64(LoadUInt64(PUInt64(AInput + AOffset))); +end; + +class procedure TBinaryPrimitives.WriteUInt16LEAt(AOutput: PByte; AOffset: Integer; AValue: UInt16); +begin +{$IFDEF SIMPLEBASELIB_LITTLE_ENDIAN} + StoreUInt16(PWord(AOutput + AOffset), AValue); +{$ELSE} + AOutput[AOffset] := Byte(AValue); + AOutput[AOffset + 1] := Byte(AValue shr 8); +{$ENDIF} +end; + +class procedure TBinaryPrimitives.WriteUInt16BEAt(AOutput: PByte; AOffset: Integer; AValue: UInt16); +begin +{$IFDEF SIMPLEBASELIB_LITTLE_ENDIAN} + AOutput[AOffset] := Byte(AValue shr 8); + AOutput[AOffset + 1] := Byte(AValue); +{$ELSE} + StoreUInt16(PWord(AOutput + AOffset), AValue); +{$ENDIF} +end; + +class procedure TBinaryPrimitives.WriteUInt32LEAt(AOutput: PByte; AOffset: Integer; AValue: UInt32); +begin +{$IFDEF SIMPLEBASELIB_LITTLE_ENDIAN} + StoreUInt32(PCardinal(AOutput + AOffset), AValue); +{$ELSE} + AOutput[AOffset] := Byte(AValue); + AOutput[AOffset + 1] := Byte(AValue shr 8); + AOutput[AOffset + 2] := Byte(AValue shr 16); + AOutput[AOffset + 3] := Byte(AValue shr 24); +{$ENDIF} +end; + +class procedure TBinaryPrimitives.WriteUInt32BEAt(AOutput: PByte; AOffset: Integer; AValue: UInt32); +begin +{$IFDEF SIMPLEBASELIB_LITTLE_ENDIAN} + AOutput[AOffset] := Byte(AValue shr 24); + AOutput[AOffset + 1] := Byte(AValue shr 16); + AOutput[AOffset + 2] := Byte(AValue shr 8); + AOutput[AOffset + 3] := Byte(AValue); +{$ELSE} + StoreUInt32(PCardinal(AOutput + AOffset), AValue); +{$ENDIF} +end; + +class procedure TBinaryPrimitives.WriteUInt64LEAt(AOutput: PByte; AOffset: Integer; AValue: UInt64); +begin +{$IFDEF SIMPLEBASELIB_LITTLE_ENDIAN} + StoreUInt64(PUInt64(AOutput + AOffset), AValue); +{$ELSE} + AOutput[AOffset] := Byte(AValue); + AOutput[AOffset + 1] := Byte(AValue shr 8); + AOutput[AOffset + 2] := Byte(AValue shr 16); + AOutput[AOffset + 3] := Byte(AValue shr 24); + AOutput[AOffset + 4] := Byte(AValue shr 32); + AOutput[AOffset + 5] := Byte(AValue shr 40); + AOutput[AOffset + 6] := Byte(AValue shr 48); + AOutput[AOffset + 7] := Byte(AValue shr 56); +{$ENDIF} +end; + +class procedure TBinaryPrimitives.WriteUInt64BEAt(AOutput: PByte; AOffset: Integer; AValue: UInt64); +begin +{$IFDEF SIMPLEBASELIB_LITTLE_ENDIAN} + AOutput[AOffset] := Byte(AValue shr 56); + AOutput[AOffset + 1] := Byte(AValue shr 48); + AOutput[AOffset + 2] := Byte(AValue shr 40); + AOutput[AOffset + 3] := Byte(AValue shr 32); + AOutput[AOffset + 4] := Byte(AValue shr 24); + AOutput[AOffset + 5] := Byte(AValue shr 16); + AOutput[AOffset + 6] := Byte(AValue shr 8); + AOutput[AOffset + 7] := Byte(AValue); +{$ELSE} + StoreUInt64(PUInt64(AOutput + AOffset), AValue); +{$ENDIF} end; // ============================================================================ -// UInt64 Internal Helpers +// Public pointer read/write overloads // ============================================================================ -class procedure TBinaryPrimitives.WriteUInt64LEInternal(AValue: UInt64; const AData: TSimpleBaseLibByteArray; AOffset: Integer); +class procedure TBinaryPrimitives.WriteUInt16LittleEndian(AOutput: PByte; AOffset: Integer; AValue: UInt16); begin - AData[AOffset] := Byte(AValue); - AData[AOffset + 1] := Byte(AValue shr 8); - AData[AOffset + 2] := Byte(AValue shr 16); - AData[AOffset + 3] := Byte(AValue shr 24); - AData[AOffset + 4] := Byte(AValue shr 32); - AData[AOffset + 5] := Byte(AValue shr 40); - AData[AOffset + 6] := Byte(AValue shr 48); - AData[AOffset + 7] := Byte(AValue shr 56); + WriteUInt16LEAt(AOutput, AOffset, AValue); end; -class procedure TBinaryPrimitives.WriteUInt64BEInternal(AValue: UInt64; const AData: TSimpleBaseLibByteArray; AOffset: Integer); +class procedure TBinaryPrimitives.WriteUInt32LittleEndian(AOutput: PByte; AOffset: Integer; AValue: UInt32); begin - AData[AOffset] := Byte(AValue shr 56); - AData[AOffset + 1] := Byte(AValue shr 48); - AData[AOffset + 2] := Byte(AValue shr 40); - AData[AOffset + 3] := Byte(AValue shr 32); - AData[AOffset + 4] := Byte(AValue shr 24); - AData[AOffset + 5] := Byte(AValue shr 16); - AData[AOffset + 6] := Byte(AValue shr 8); - AData[AOffset + 7] := Byte(AValue); + WriteUInt32LEAt(AOutput, AOffset, AValue); end; -class function TBinaryPrimitives.ReadUInt64LEInternal(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt64; +class procedure TBinaryPrimitives.WriteUInt64LittleEndian(AOutput: PByte; AOffset: Integer; AValue: UInt64); begin - Result := UInt64(AData[AOffset]) or - (UInt64(AData[AOffset + 1]) shl 8) or - (UInt64(AData[AOffset + 2]) shl 16) or - (UInt64(AData[AOffset + 3]) shl 24) or - (UInt64(AData[AOffset + 4]) shl 32) or - (UInt64(AData[AOffset + 5]) shl 40) or - (UInt64(AData[AOffset + 6]) shl 48) or - (UInt64(AData[AOffset + 7]) shl 56); + WriteUInt64LEAt(AOutput, AOffset, AValue); end; -class function TBinaryPrimitives.ReadUInt64BEInternal(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt64; +class procedure TBinaryPrimitives.WriteUInt16BigEndian(AOutput: PByte; AOffset: Integer; AValue: UInt16); begin - Result := (UInt64(AData[AOffset]) shl 56) or - (UInt64(AData[AOffset + 1]) shl 48) or - (UInt64(AData[AOffset + 2]) shl 40) or - (UInt64(AData[AOffset + 3]) shl 32) or - (UInt64(AData[AOffset + 4]) shl 24) or - (UInt64(AData[AOffset + 5]) shl 16) or - (UInt64(AData[AOffset + 6]) shl 8) or - UInt64(AData[AOffset + 7]); + WriteUInt16BEAt(AOutput, AOffset, AValue); +end; + +class procedure TBinaryPrimitives.WriteUInt32BigEndian(AOutput: PByte; AOffset: Integer; AValue: UInt32); +begin + WriteUInt32BEAt(AOutput, AOffset, AValue); +end; + +class procedure TBinaryPrimitives.WriteUInt64BigEndian(AOutput: PByte; AOffset: Integer; AValue: UInt64); +begin + WriteUInt64BEAt(AOutput, AOffset, AValue); +end; + +class function TBinaryPrimitives.ReadUInt16LittleEndian(AInput: PByte; AOffset: Integer): UInt16; +begin + Result := ReadUInt16LEAt(AInput, AOffset); +end; + +class function TBinaryPrimitives.ReadUInt32LittleEndian(AInput: PByte; AOffset: Integer): UInt32; +begin + Result := ReadUInt32LEAt(AInput, AOffset); +end; + +class function TBinaryPrimitives.ReadUInt64LittleEndian(AInput: PByte; AOffset: Integer): UInt64; +begin + Result := ReadUInt64LEAt(AInput, AOffset); +end; + +class function TBinaryPrimitives.ReadUInt16BigEndian(AInput: PByte; AOffset: Integer): UInt16; +begin + Result := ReadUInt16BEAt(AInput, AOffset); +end; + +class function TBinaryPrimitives.ReadUInt32BigEndian(AInput: PByte; AOffset: Integer): UInt32; +begin + Result := ReadUInt32BEAt(AInput, AOffset); +end; + +class function TBinaryPrimitives.ReadUInt64BigEndian(AInput: PByte; AOffset: Integer): UInt64; +begin + Result := ReadUInt64BEAt(AInput, AOffset); end; // ============================================================================ -// Public Write Methods - Little Endian +// Public Write Methods - Little Endian (TArray) // ============================================================================ class procedure TBinaryPrimitives.WriteUInt16LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: UInt16); begin CheckBounds(AData, AOffset, SizeOf(UInt16)); - WriteUInt16LEInternal(AValue, AData, AOffset); + WriteUInt16LEAt(PByte(AData), AOffset, AValue); end; class procedure TBinaryPrimitives.WriteUInt32LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: UInt32); begin CheckBounds(AData, AOffset, SizeOf(UInt32)); - WriteUInt32LEInternal(AValue, AData, AOffset); + WriteUInt32LEAt(PByte(AData), AOffset, AValue); end; class procedure TBinaryPrimitives.WriteUInt64LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: UInt64); begin CheckBounds(AData, AOffset, SizeOf(UInt64)); - WriteUInt64LEInternal(AValue, AData, AOffset); + WriteUInt64LEAt(PByte(AData), AOffset, AValue); end; class procedure TBinaryPrimitives.WriteInt16LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Int16); begin CheckBounds(AData, AOffset, SizeOf(Int16)); - WriteUInt16LEInternal(UInt16(AValue), AData, AOffset); + WriteUInt16LEAt(PByte(AData), AOffset, UInt16(AValue)); end; class procedure TBinaryPrimitives.WriteInt32LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Int32); begin CheckBounds(AData, AOffset, SizeOf(Int32)); - WriteUInt32LEInternal(UInt32(AValue), AData, AOffset); + WriteUInt32LEAt(PByte(AData), AOffset, UInt32(AValue)); end; class procedure TBinaryPrimitives.WriteInt64LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Int64); begin CheckBounds(AData, AOffset, SizeOf(Int64)); - WriteUInt64LEInternal(UInt64(AValue), AData, AOffset); + WriteUInt64LEAt(PByte(AData), AOffset, UInt64(AValue)); end; class procedure TBinaryPrimitives.WriteSingleLittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Single); @@ -247,7 +589,7 @@ class procedure TBinaryPrimitives.WriteSingleLittleEndian(const AData: TSimpleBa begin CheckBounds(AData, AOffset, SizeOf(Single)); Move(AValue, LBits, SizeOf(Single)); - WriteUInt32LEInternal(LBits, AData, AOffset); + WriteUInt32LEAt(PByte(AData), AOffset, LBits); end; class procedure TBinaryPrimitives.WriteDoubleLittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Double); @@ -256,47 +598,47 @@ class procedure TBinaryPrimitives.WriteDoubleLittleEndian(const AData: TSimpleBa begin CheckBounds(AData, AOffset, SizeOf(Double)); Move(AValue, LBits, SizeOf(Double)); - WriteUInt64LEInternal(LBits, AData, AOffset); + WriteUInt64LEAt(PByte(AData), AOffset, LBits); end; // ============================================================================ -// Public Write Methods - Big Endian +// Public Write Methods - Big Endian (TArray) // ============================================================================ class procedure TBinaryPrimitives.WriteUInt16BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: UInt16); begin CheckBounds(AData, AOffset, SizeOf(UInt16)); - WriteUInt16BEInternal(AValue, AData, AOffset); + WriteUInt16BEAt(PByte(AData), AOffset, AValue); end; class procedure TBinaryPrimitives.WriteUInt32BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: UInt32); begin CheckBounds(AData, AOffset, SizeOf(UInt32)); - WriteUInt32BEInternal(AValue, AData, AOffset); + WriteUInt32BEAt(PByte(AData), AOffset, AValue); end; class procedure TBinaryPrimitives.WriteUInt64BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: UInt64); begin CheckBounds(AData, AOffset, SizeOf(UInt64)); - WriteUInt64BEInternal(AValue, AData, AOffset); + WriteUInt64BEAt(PByte(AData), AOffset, AValue); end; class procedure TBinaryPrimitives.WriteInt16BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Int16); begin CheckBounds(AData, AOffset, SizeOf(Int16)); - WriteUInt16BEInternal(UInt16(AValue), AData, AOffset); + WriteUInt16BEAt(PByte(AData), AOffset, UInt16(AValue)); end; class procedure TBinaryPrimitives.WriteInt32BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Int32); begin CheckBounds(AData, AOffset, SizeOf(Int32)); - WriteUInt32BEInternal(UInt32(AValue), AData, AOffset); + WriteUInt32BEAt(PByte(AData), AOffset, UInt32(AValue)); end; class procedure TBinaryPrimitives.WriteInt64BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Int64); begin CheckBounds(AData, AOffset, SizeOf(Int64)); - WriteUInt64BEInternal(UInt64(AValue), AData, AOffset); + WriteUInt64BEAt(PByte(AData), AOffset, UInt64(AValue)); end; class procedure TBinaryPrimitives.WriteSingleBigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Single); @@ -305,7 +647,7 @@ class procedure TBinaryPrimitives.WriteSingleBigEndian(const AData: TSimpleBaseL begin CheckBounds(AData, AOffset, SizeOf(Single)); Move(AValue, LBits, SizeOf(Single)); - WriteUInt32BEInternal(LBits, AData, AOffset); + WriteUInt32BEAt(PByte(AData), AOffset, LBits); end; class procedure TBinaryPrimitives.WriteDoubleBigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer; AValue: Double); @@ -314,47 +656,47 @@ class procedure TBinaryPrimitives.WriteDoubleBigEndian(const AData: TSimpleBaseL begin CheckBounds(AData, AOffset, SizeOf(Double)); Move(AValue, LBits, SizeOf(Double)); - WriteUInt64BEInternal(LBits, AData, AOffset); + WriteUInt64BEAt(PByte(AData), AOffset, LBits); end; // ============================================================================ -// Public Read Methods - Little Endian +// Public Read Methods - Little Endian (TArray) // ============================================================================ class function TBinaryPrimitives.ReadUInt16LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt16; begin CheckBounds(AData, AOffset, SizeOf(UInt16)); - Result := ReadUInt16LEInternal(AData, AOffset); + Result := ReadUInt16LEAt(PByte(AData), AOffset); end; class function TBinaryPrimitives.ReadUInt32LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt32; begin CheckBounds(AData, AOffset, SizeOf(UInt32)); - Result := ReadUInt32LEInternal(AData, AOffset); + Result := ReadUInt32LEAt(PByte(AData), AOffset); end; class function TBinaryPrimitives.ReadUInt64LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt64; begin CheckBounds(AData, AOffset, SizeOf(UInt64)); - Result := ReadUInt64LEInternal(AData, AOffset); + Result := ReadUInt64LEAt(PByte(AData), AOffset); end; class function TBinaryPrimitives.ReadInt16LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Int16; begin CheckBounds(AData, AOffset, SizeOf(Int16)); - Result := Int16(ReadUInt16LEInternal(AData, AOffset)); + Result := Int16(ReadUInt16LEAt(PByte(AData), AOffset)); end; class function TBinaryPrimitives.ReadInt32LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Int32; begin CheckBounds(AData, AOffset, SizeOf(Int32)); - Result := Int32(ReadUInt32LEInternal(AData, AOffset)); + Result := Int32(ReadUInt32LEAt(PByte(AData), AOffset)); end; class function TBinaryPrimitives.ReadInt64LittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Int64; begin CheckBounds(AData, AOffset, SizeOf(Int64)); - Result := Int64(ReadUInt64LEInternal(AData, AOffset)); + Result := Int64(ReadUInt64LEAt(PByte(AData), AOffset)); end; class function TBinaryPrimitives.ReadSingleLittleEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Single; @@ -362,7 +704,7 @@ class function TBinaryPrimitives.ReadSingleLittleEndian(const AData: TSimpleBase LBits: UInt32; begin CheckBounds(AData, AOffset, SizeOf(Single)); - LBits := ReadUInt32LEInternal(AData, AOffset); + LBits := ReadUInt32LEAt(PByte(AData), AOffset); Move(LBits, Result, SizeOf(Single)); end; @@ -371,48 +713,48 @@ class function TBinaryPrimitives.ReadDoubleLittleEndian(const AData: TSimpleBase LBits: UInt64; begin CheckBounds(AData, AOffset, SizeOf(Double)); - LBits := ReadUInt64LEInternal(AData, AOffset); + LBits := ReadUInt64LEAt(PByte(AData), AOffset); Move(LBits, Result, SizeOf(Double)); end; // ============================================================================ -// Public Read Methods - Big Endian +// Public Read Methods - Big Endian (TArray) // ============================================================================ class function TBinaryPrimitives.ReadUInt16BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt16; begin CheckBounds(AData, AOffset, SizeOf(UInt16)); - Result := ReadUInt16BEInternal(AData, AOffset); + Result := ReadUInt16BEAt(PByte(AData), AOffset); end; class function TBinaryPrimitives.ReadUInt32BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt32; begin CheckBounds(AData, AOffset, SizeOf(UInt32)); - Result := ReadUInt32BEInternal(AData, AOffset); + Result := ReadUInt32BEAt(PByte(AData), AOffset); end; class function TBinaryPrimitives.ReadUInt64BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): UInt64; begin CheckBounds(AData, AOffset, SizeOf(UInt64)); - Result := ReadUInt64BEInternal(AData, AOffset); + Result := ReadUInt64BEAt(PByte(AData), AOffset); end; class function TBinaryPrimitives.ReadInt16BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Int16; begin CheckBounds(AData, AOffset, SizeOf(Int16)); - Result := Int16(ReadUInt16BEInternal(AData, AOffset)); + Result := Int16(ReadUInt16BEAt(PByte(AData), AOffset)); end; class function TBinaryPrimitives.ReadInt32BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Int32; begin CheckBounds(AData, AOffset, SizeOf(Int32)); - Result := Int32(ReadUInt32BEInternal(AData, AOffset)); + Result := Int32(ReadUInt32BEAt(PByte(AData), AOffset)); end; class function TBinaryPrimitives.ReadInt64BigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Int64; begin CheckBounds(AData, AOffset, SizeOf(Int64)); - Result := Int64(ReadUInt64BEInternal(AData, AOffset)); + Result := Int64(ReadUInt64BEAt(PByte(AData), AOffset)); end; class function TBinaryPrimitives.ReadSingleBigEndian(const AData: TSimpleBaseLibByteArray; AOffset: Integer): Single; @@ -420,7 +762,7 @@ class function TBinaryPrimitives.ReadSingleBigEndian(const AData: TSimpleBaseLib LBits: UInt32; begin CheckBounds(AData, AOffset, SizeOf(Single)); - LBits := ReadUInt32BEInternal(AData, AOffset); + LBits := ReadUInt32BEAt(PByte(AData), AOffset); Move(LBits, Result, SizeOf(Single)); end; @@ -429,10 +771,8 @@ class function TBinaryPrimitives.ReadDoubleBigEndian(const AData: TSimpleBaseLib LBits: UInt64; begin CheckBounds(AData, AOffset, SizeOf(Double)); - LBits := ReadUInt64BEInternal(AData, AOffset); + LBits := ReadUInt64BEAt(PByte(AData), AOffset); Move(LBits, Result, SizeOf(Double)); end; end. - -