
Purpose: Framework Core Shared Types and RTL-like Functions
- this unit is a part of the Open Source Synopse mORMot framework 2, licensed under a MPL/GPL/LGPL three license - see LICENSE.md
| Objects | Description | |
|---|---|---|
| TDiv100Rec | Small structure used as convenient result to Div100() procedure | |
| TDWordRec | Binary access to an unsigned 32-bit value (4 bytes in memory) | |
| TDynArrayRec | 32-bit longint with Delphi map the Delphi/FPC dynamic array header (stored before each instance) | |
| THash128Rec | Map a 128-bit hash as an array of lower bit size values | |
| THash256Rec | Map a 256-bit hash as an array of lower bit size values | |
| THash512Rec | Map a 512-bit hash as an array of lower bit size values | |
| TIntelAvx10Features | The AVX10 Converged Vector ISA features | |
| TLecuyer | 32-bit Pierre L'Ecuyer software (random) generator | |
| TQWordRec | Binary access to an unsigned 64-bit value (8 bytes in memory) | |
| TRawByteStringStream | TStream using a RawByteString as internal storage | |
| TSortedIntegerArray | Used to store and retrieve Integers in a sorted array | |
| TSortedWordArray | Used to store and retrieve Words in a sorted array | |
| TStreamWithPosition | TStream with a protected fPosition field | |
| TStreamWithPositionAndSize | TStream with two protected fPosition/fSize fields | |
| TStrRec | Map the Delphi/FPC string header (stored before each instance) | |
| TSynMemoryStream | TStream pointing to some existing in-memory data, for instance UTF-8 text | |
| TSynTempBuffer | Implements a 4KB stack-based storage of some (UTF-8 or binary) content | |
| TSynVarData | A variant/TVarData overlapped structure with a 32-bit VType field |
TStrRec = packed record
Map the Delphi/FPC string header (stored before each instance)
length: TStrLen;
32-bit longint with Delphi equals length(s) - i.e. size in AnsiChar/WideChar, not bytes
refCnt: TStrCnt;
String reference count (basic garbage memory mechanism)
TDynArrayRec = packed record
32-bit longint with Delphi map the Delphi/FPC dynamic array header (stored before each instance)
length: TDALen;
32-bit longint with Delphi length in element count
- size in bytes = length*ElemSize
refCnt: TDACnt;
Dynamic array reference count (basic garbage memory mechanism)
TDiv100Rec = packed record
Small structure used as convenient result to Div100() procedure
D: cardinal;
Contains V div 100 after Div100(V)
M: cardinal;
Contains V mod 100 after Div100(V)
TSortedWordArray = object(TObject)
Used to store and retrieve Words in a sorted array
- ensure Count=0 before use - if not defined as a private member of a class
Count: PtrInt;
How many items are currently in Values[]
Values: TWordDynArray;
The actual 16-bit word storage
function Add(aValue: Word): PtrInt;
Add a value into the sorted array
- return the index of the new inserted value into the Values[] array
- return -(foundindex+1) if this value is already in the Values[] array
function IndexOf(aValue: Word): PtrInt;
Return the index if the supplied value in the Values[] array
- return -1 if not found
procedure SetArray(out aValues: TWordDynArray);
Save the internal array into a TWordDynArray variable
TSortedIntegerArray = object(TObject)
Used to store and retrieve Integers in a sorted array
- ensure Count=0 before use - if not defined as a private member of a class
Count: PtrInt;
How many items are currently in Values[]
Values: TIntegerDynArray;
The actual 32-bit integers storage
function Add(aValue: integer): PtrInt;
Add a value into the sorted array
- return the index of the new inserted value into the Values[] array
- return -(foundindex+1) if this value is already in the Values[] array
function IndexOf(aValue: integer): PtrInt;
Return the index if the supplied value in the Values[] array
- return -1 if not found
procedure SetArray(out aValues: TIntegerDynArray);
Save the internal array into a TWordDynArray variable
TDWordRec = record
Binary access to an unsigned 32-bit value (4 bytes in memory)
TQWordRec = record
Binary access to an unsigned 64-bit value (8 bytes in memory)
THash128Rec = packed record
Map a 128-bit hash as an array of lower bit size values
- consumes 16 bytes of memory
THash256Rec = packed record
Map a 256-bit hash as an array of lower bit size values
- consumes 32 bytes of memory
THash512Rec = packed record
Map a 512-bit hash as an array of lower bit size values
- consumes 64 bytes of memory
TIntelAvx10Features = record
The AVX10 Converged Vector ISA features
MaxSubLeaf: cardinal;
Maximum supported sub-leaf
Vector: TIntelAvx10Vector;
Bit vector size support
Version: byte;
The ISA version (>= 1)
TLecuyer = object(TObject)
32-bit Pierre L'Ecuyer software (random) generator
- cross-compiler and cross-platform efficient randomness generator, very fast with a much better distribution than Delphi system's Random() function see https://www.gnu.org/software/gsl/doc/html/rng.html#c.gsl_rng_taus2
- used by thread-safe Random32/RandomBytes, storing 16 bytes per thread - a stronger algorithm like Mersenne Twister (as used by FPC RTL) requires 5KB
- SeedGenerator() makes it a sequence generator - or encryptor via Fill()
- when used as random generator (default when initialized with 0), Seed() will gather and hash some system entropy to initialize the internal state
function Next: cardinal; overload;
Compute the next 32-bit generated value
- will automatically reseed after around 2^32 generated values, which is huge but very conservative since this generator has a period of 2^88
function Next(max: cardinal): cardinal; overload;
Compute the next 32-bit generated value, in range [0..max-1]
function NextDouble: double;
Compute a 64-bit floating point value
function NextQWord: QWord;
Compute a 64-bit integer value
function RawNext: cardinal;
Compute the next 32-bit generated value with no Seed - internal call
procedure Fill(dest: pointer; bytes: integer);
XOR some memory buffer with random bytes
- when used as sequence generator after SeedGenerator(), dest buffer should be filled with zeros before the call if you want to use it as generator, but could be applied on any memory buffer for encryption
procedure FillShort(var dest: ShortString; size: PtrUInt = 255);
Fill some string[0..size] with 7-bit ASCII random text
procedure FillShort31(var dest: TShort31);
Fill some string[0..31] with 7-bit ASCII random text
procedure Seed(entropy: PByteArray = nil; entropylen: PtrInt = 0);
Force a random seed of the generator from current system state
- as executed by the Next method at thread startup, and after 2^32 values
- calls XorEntropy(), so RdRand32/Rdtsc opcodes on Intel/AMD CPUs
procedure SeedGenerator(fixedseed: QWord); overload;
Force a well-defined seed of the generator from a fixed initial point
- to be called before Next/Fill to generate the very same output
- will generate up to 16GB of predictable output, then switch to random
procedure SeedGenerator(fixedseed: pointer; fixedseedbytes: integer); overload;
Force a well-defined seed of the generator from a buffer initial point
- apply crc32c() over the fixedseed buffer to initialize the generator
TSynTempBuffer = object(TObject)
Implements a 4KB stack-based storage of some (UTF-8 or binary) content
- could be used e.g. to make a temporary copy when JSON is parsed in-place
- call one of the Init() overloaded methods, then Done to release its memory
- will avoid temporary memory allocation via the heap for up to 4KB of data
- all Init() methods will allocate 16 more bytes, for a trailing #0 and to ensure our fast JSON parsing won't trigger any GPF (since it may read up to 4 bytes ahead via its PInteger() trick) or any SSE4.2 function
buf: pointer;
Where the text/binary is available (and any Source has been copied)
- equals nil if len=0
len: PtrInt;
The text/binary length, in bytes, excluding the trailing #0
tmp: array[0..4095] of AnsiChar;
Default 4KB buffer allocated on stack - after the len/buf main fields
- 16 last bytes are reserved to prevent potential buffer overflow, so usable length is 4080 bytes
function BufEnd: pointer;
Inlined wrapper around buf + len
function Init(SourceLen: PtrInt): pointer; overload;
Initialize a new temporary buffer of a given number of bytes
- also include ending #0 at SourceLen position
function Init: integer; overload;
Initialize the buffer returning the internal buffer size (4080 bytes)
- also set len to the internal buffer size
- could be used e.g. for an API call, first trying with plain temp.Init and using temp.buf and temp.len safely in the call, only calling temp.Init(expectedsize) if the API returns an insufficient buffer error
function Init(Source: PUtf8Char): PUtf8Char; overload;
Initialize a temporary copy of the supplied text buffer, ending with #0
function InitIncreasing(Count: PtrInt; Start: PtrInt = 0): PIntegerArray;
Initialize a new temporary buffer filled with 32-bit integer increasing values
function InitOnStack: pointer;
Initialize a temporary buffer with the length of the internal stack
function InitRandom(RandomLen: integer): pointer;
Initialize a new temporary buffer of a given number of random bytes
- will fill the buffer via RandomBytes() call
function InitZero(ZeroLen: PtrInt): pointer;
Initialize a new temporary buffer of a given number of zero bytes
- if ZeroLen=0, will initialize the whole tmp[] stack buffer to 0
procedure Done; overload;
Finalize the temporary storage
procedure Done(EndBuf: pointer; var Dest: RawUtf8); overload;
Finalize the temporary storage, and create a RawUtf8 string from it
procedure Init(Source: pointer; SourceLen: PtrInt); overload;
Initialize a temporary copy of the supplied text buffer
- also include ending #0 at SourceLen position
procedure Init(const Source: RawByteString); overload;
Initialize a temporary copy of the content supplied as RawByteString
- will also allocate and copy the ending #0 (even for binary)
TSynVarData = packed record
A variant/TVarData overlapped structure with a 32-bit VType field
- 32-bit VType is faster for initialization than 16-bit TVarData.VType
- it is safe to transtype this as plain variant or TVarData
VInteger: integer
Access the most used TVarData value members
TStreamWithPosition = class(TStream)
TStream with a protected fPosition field
function Seek(Offset: Longint; Origin: Word): Longint; override;
Call the 64-bit Seek() overload
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;
Change the current Read/Write position, within current GetSize
TStreamWithPositionAndSize = class(TStreamWithPosition)
TStream with two protected fPosition/fSize fields
TRawByteStringStream = class(TStreamWithPosition)
TStream using a RawByteString as internal storage
- default TStringStream uses UTF-16 WideChars since Delphi 2009, so it is not compatible with previous versions or FPC, and it makes more sense to work with RawByteString/RawUtf8 in our UTF-8 oriented framework
- just like TStringStream, is designed for appending data, not modifying in-place, as requested e.g. by TJsonWriter or TBufferWriter classes
constructor Create(const aString: RawByteString); overload;
Initialize the storage, optionally with some RawByteString content
- to be used for Read() from this memory buffer
function Read(var Buffer; Count: Longint): Longint; override;
Read some bytes from the internal storage
- returns the number of bytes filled into Buffer (<=Count)
function Write(const Buffer; Count: Longint): Longint; override;
Append some data to the buffer
- will resize the buffer, i.e. will replace the end of the string from the current position with the supplied data
procedure Clear;
Reset the internal DataString content and the current position
procedure GetAsText(StartPos, Len: PtrInt; var Text: RawUtf8);
Retrieve the stored content from a given position, as UTF-8 text
- warning: may directly return DataString and reset its value to ''
property DataString: RawByteString read fDataString write fDataString;
Direct low-level access to the internal RawByteString storage
TSynMemoryStream = class(TCustomMemoryStream)
TStream pointing to some existing in-memory data, for instance UTF-8 text
- warning: there is no local copy of the supplied content: the source data must be available during all the TSynMemoryStream usage
constructor Create(Data: pointer; DataLen: PtrInt); overload;
Create a TStream with the supplied data buffer
- warning: there is no local copy of the supplied content: the Data/DataLen buffer must be available during all the TSynMemoryStream usage: don't release the source Data before calling TSynMemoryStream.Free
constructor Create(const aText: RawByteString); overload;
Create a TStream with the supplied text data
- warning: there is no local copy of the supplied content: the aText variable must be available during all the TSynMemoryStream usage: don't release aText before calling TSynMemoryStream.Free
- aText can be on any AnsiString format, e.g. RawUtf8 or RawByteString
function Write(const Buffer; Count: Longint): Longint; override;
This TStream is read-only: calling this method will raise an exception
HalfInt = smallint;
A CPU-dependent signed integer type cast of half a pointer
HalfUInt = word;
A CPU-dependent unsigned integer type cast of half a pointer
PBlock128 = ^TBlock128;
Pointer to a 128-bit buffer
PBooleanArray = ^TBooleanArray;
Redefine here with {$R-}
PDACnt = ^TDACnt;
Pointer to cross-compiler type used for dynarray reference counter
PDALen = ^TDALen;
Pointer to cross-compiler type used for dynamic array length
PDateTimeMSDynArray = ^TDateTimeMSDynArray;
Pointer to a dynamic array of TDateTimeMS values
PDWordRec = ^TDWordRec;
Points to the binary of an unsigned 32-bit value
PHalfInt = ^HalfInt;
A CPU-dependent signed integer type cast of a pointer to half a pointer
PHalfUInt = ^HalfUInt;
A CPU-dependent unsigned integer type cast of a pointer to half a pointer
PHash128 = ^THash128;
Pointer to a 128-bit hash value
PHash128Array = ^THash128Array;
Pointer to an infinite array of 128-bit hash values
PHash128Rec = ^THash128Rec;
Pointer to 128-bit hash map variable record
PHash160 = ^THash160;
Pointer to a 160-bit hash value
PHash192 = ^THash192;
Pointer to a 192-bit hash value
PHash224 = ^THash224;
Pointer to a 224-bit hash value
PHash256 = ^THash256;
Pointer to a 256-bit hash value
PHash256Array = ^THash256Array;
Pointer to an infinite array of 256-bit hash values
PHash256Rec = ^THash256Rec;
Pointer to 256-bit hash map variable record
PHash384 = ^THash384;
Pointer to a 384-bit hash value
PHash512 = ^THash512;
Pointer to a 512-bit hash value
PHash512Array = ^THash512Array;
Pointer to an infinite array of 512-bit hash values
PHash512Rec = ^THash512Rec;
Pointer to 512-bit hash map variable record
PID = ^TID;
A pointer to TOrm.ID, i.e. our ORM primary key
PIDDynArray = ^TIDDynArray;
Pointer to a dynamic array of ORM primary keys, i.e. TOrm.ID
PMethod = ^TMethod;
This pointer is not defined on older Delphi revisions
PPtrInt = ^PtrInt;
A CPU-dependent signed integer type cast of a pointer of pointer
- used for 64-bit compatibility, native under Free Pascal Compiler
PPtrUInt = ^PtrUInt;
A CPU-dependent unsigned integer type cast of a pointer of pointer
- used for 64-bit compatibility, native under Free Pascal Compiler
PQWord = ^QWord;
Points to an unsigned Int64
PQWordRec = ^TQWordRec;
Points to the binary of an unsigned 64-bit value
PRawByteString = ^RawByteString;
Pointer to a RawByteString
PSingle = System.PSingle;
Redefined here to not use the unexpected PSingle definition from Windows unit
PStrCnt = ^TStrCnt;
Pointer to cross-compiler type used for string reference counter
PStrLen = ^TStrLen;
Pointer to cross-compiler type used for string length
PStrRec = ^TStrRec;
PtrInt/NativeInt
PSynVarData = ^TSynVarData;
Access to all standard value members
PtrInt = integer;
A CPU-dependent signed integer type cast of a pointer / register
- used for 64-bit compatibility, native under Free Pascal Compiler
PtrUInt = cardinal;
A CPU-dependent unsigned integer type cast of a pointer / register
- used for 64-bit compatibility, native under Free Pascal Compiler
PUInt64 = ^UInt64;
Compatibility definition with FPC and newer Delphi
PUnixMSTime = ^TUnixMSTime;
Pointer to a timestamp stored as millisecond-based Unix Time
PUnixTime = ^TUnixTime;
Pointer to a timestamp stored as second-based Unix Time
PUtf8Char = type PAnsiChar;
A simple wrapper to UTF-8 encoded zero-terminated PAnsiChar
- PAnsiChar is used only for Win-Ansi encoded text
- the Synopse mORMot framework uses mostly this PUtf8Char type, because all data is internally stored and expected to be UTF-8 encoded
PWord = System.PWord;
Redefined here to not use the unexpected PWord definition from Windows unit
QWord = type Int64;
Unsigned Int64 doesn't exist under older Delphi, but is defined in FPC
- and UInt64 is buggy as hell under Delphi 2007 when inlining functions: older compilers will fallback to signed Int64 values
- anyway, consider using SortDynArrayQWord() to compare QWord values in a safe and efficient way, under a CPUX86
- use UInt64 explicitly in your computation (like in mormot.crypt.ecc), if you are sure that Delphi 6-2007 compiler handles your code as expected, but mORMot code will expect to use QWord for its internal process (e.g. ORM/SOA serialization)
RawBlob = type RawByteString;
A RawByteString sub-type used to store the BLOB content in our ORM
- equals RawByteString for byte storage
- TRttiInfo.AnsiStringCodePage will identify this type, and return CP_RAWBLOB fake codepage for such a published property, even if it is just an alias to CP_RAWBYTESTRING
- our ORM will therefore identify such properties as BLOB
- by default, the BLOB fields are not retrieved or updated with raw TRest.Retrieve() method, that is "Lazy loading" is enabled by default for blobs, unless TRestClientUri.ForceBlobTransfert property is TRUE (for all tables), or ForceBlobTransfertTable[] (for a particular table); so use RetrieveBlob() methods for handling BLOB fields
- could be defined as value in a TOrm property as such:
property Blob: RawBlob read fBlob write fBlob;
- is defined here for proper TRttiProp.WriteAsJson serialization
RawByteString = type AnsiString;
Define RawByteString, as it does exist in Delphi 2009+
- to be used for byte storage into an AnsiString
- use this type if you don't want the Delphi compiler not to do any code page conversions when you assign a typed AnsiString to a RawByteString, i.e. a RawUtf8 or a WinAnsiString
RawJson = type RawUtf8;
RawJson will indicate that this variable content would stay as raw JSON
- i.e. won't be serialized into values
- could be any JSON content: number, boolean, null, string, object or array
- e.g. interface-based service will use it for efficient and AJAX-ready transmission of TOrmTableJson result
RawUcs4 = TIntegerDynArray;
Low-level storage of UCS4 CodePoints, stored as 32-bit integers
RawUnicode = type AnsiString;
Low-level RawUnicode as an Unicode String stored in an AnsiString
- DEPRECATED TYPE, introduced in Delphi 7/2007 days: SynUnicode is to be used
- faster than WideString, which are allocated in Global heap (for COM)
- an AnsiChar(#0) is added at the end, for having a true WideChar(#0) at ending
- length(RawUnicode) returns memory bytes count: use (length(RawUnicode) shr 1) for WideChar count (that's why the definition of this type since Delphi 2009 is AnsiString(1200) and not UnicodeString)
- pointer(RawUnicode) is compatible with Win32 'Wide' API call
- mimic Delphi 2009 UnicodeString, without the WideString or Ansi conversion overhead
- all conversion to/from AnsiString or RawUtf8 must be explicit: the compiler may not be able to perform implicit conversions on CP_UTF16
RawUtf8 = System.UTF8String;
RawUtf8 is an UTF-8 String stored in an AnsiString, alias to System.UTF8String
- all conversion to/from string or WinAnsiString must be explicit on Delphi 7/2007, and it will be faster anyway to use our optimized functions from mormot.core.unicode.pas unit like StringToUtf8/Utf8ToString
SpiUtf8 = type RawUtf8;
CP_UTF8 Codepage a RawUtf8 value which may contain Sensitive Personal Information (e.g. a bank card number or a plain password)
- identified as a specific type e.g. to be hidden in the logs - when the woHideSensitivePersonalInformation TTextWriterWriteObjectOption is set
SynUnicode = WideString;
SynUnicode is the fastest available Unicode native string type, depending on the compiler used
- this type is native to the compiler, so you can use Length() Copy() and such functions with it (this is not possible with RawUnicodeString type)
- before Delphi 2009+, it uses slow OLE compatible WideString (with our Enhanced RTL, WideString allocation can be made faster by using an internal caching mechanism of allocation buffers - WideString allocation has been made much faster since Windows Vista/Seven)
- starting with Delphi 2009, it uses the faster UnicodeString type, which allow Copy On Write, Reference Counting and fast heap memory allocation
- on recent FPC, HASVARUSTRING is defined and native UnicodeString is set
TArm32HwCap = ( arm32SWP, arm32HALF, arm32THUMB, arm3226BIT, arm32FAST_MULT, arm32FPA, arm32VFP, arm32EDSP, arm32JAVA, arm32IWMMXT, arm32CRUNCH, arm32THUMBEE, arm32NEON, arm32VFPv3, arm32VFPv3D16, arm32TLS, arm32VFPv4, arm32IDIVA, arm32IDIVT, arm32VFPD32, arm32LPAE, arm32EVTSTRM, arm32_22, arm32_23, arm32_24, arm32_25, arm32_26, arm32_27, arm32_28, arm32_29, arm32_30, arm32_31, arm32AES, arm32PMULL, arm32SHA1, arm32SHA2, arm32CRC32 );
32-bit ARM Hardware capabilities
- merging AT_HWCAP and AT_HWCAP2 flags as reported by github.com/torvalds/linux/blob/master/arch/arm/include/uapi/asm/hwcap.h
- is defined on all platforms for cross-system use
TArm64HwCap = ( arm64FP, arm64ASIMD, arm64EVTSTRM, arm64AES, arm64PMULL, arm64SHA1, arm64SHA2, arm64CRC32, arm64ATOMICS, arm64FPHP, arm64ASIMDHP, arm64CPUID, arm64ASIMDRDM, arm64JSCVT, arm64FCMA, arm64LRCPC, arm64DCPOP, arm64SHA3, arm64SM3, arm64SM4, arm64ASIMDDP, arm64SHA512, arm64SVE, arm64ASIMDFHM, arm64DIT, arm64USCAT, arm64ILRCPC, arm64FLAGM, arm64SSBS, arm64SB, arm64PACA, arm64PACG, arm64DCPODP, arm64SVE2, arm64SVEAES, arm64SVEPMULL, arm64SVEBITPERM, arm64SVESHA3, arm64SVESM4, arm64FLAGM2, arm64FRINT, arm64SVEI8MM, arm64SVEF32MM, arm64SVEF64MM, arm64SVEBF16, arm64I8MM, arm64BF16, arm64DGH, arm64RNG, arm64BTI, arm64MTE );
64-bit AARCH64 Hardware capabilities
- merging AT_HWCAP and AT_HWCAP2 flags as reported by github.com/torvalds/linux/blob/master/arch/arm64/include/uapi/asm/ahccap.h
- is defined on all platforms for cross-system use
TBits32 = set of 0..31;
Fast access to 32-bit integer bits
- compiler will generate bt/btr/bts opcodes - note: they may be slow when applied on a memory location, but not on an integer value (register)
TBits64 = set of 0..63;
Fast access to 64-bit integer bits
- compiler will generate bt/btr/bts opcodes - note: they may be slow when applied on a memory location, but not on a Int64 value (register)
- as used by GetBit64/SetBit64/UnSetBit64
TBits8 = set of 0..7;
Fast access to 8-bit integer bits
- compiler will generate bt/btr/bts opcodes - note: they may be slow when applied on a memory location, but not on a byte value (register)
TBlock128 = array[0..3] of cardinal;
Store a 128-bit buffer
- e.g. an AES block
- consumes 16 bytes of memory
TCompareOperator = ( coEqualTo, coNotEqualTo, coLessThan, coLessThanOrEqualTo, coGreaterThan, coGreaterThanOrEqualTo );
The recognized operators for comparison functions results match
TDACnt = integer ;
Cross-compiler type used for dynarray reference counter
- FPC uses PtrInt/SizeInt, Delphi uses longint even on CPU64
TDALen = PtrInt;
Cross-compiler type used for dynamic array length
- both FPC and Delphi uses PtrInt/NativeInt for dynamic array high/length
TDateTimeMS = type TDateTime;
A type alias, which will be serialized as ISO-8601 with milliseconds
- i.e. 'YYYY-MM-DD hh:mm:ss.sss' or 'YYYYMMDD hhmmss.sss' format
TDateTimeMSDynArray = array of TDateTimeMS;
A dynamic array of TDateTimeMS values
TDynArraySortCompare = function(const A, B): integer;
Function prototype to be used for TDynArray Sort and Find method
- common functions exist for base types: see e.g. SortDynArrayBoolean, SortDynArrayByte, SortDynArrayWord, SortDynArrayInteger, SortDynArrayCardinal, SortDynArrayInt64, SortDynArrayQWord, SordDynArraySingle, SortDynArrayDouble, SortDynArrayAnsiString, SortDynArrayAnsiStringI, SortDynArrayUnicodeString, SortDynArrayUnicodeStringI, SortDynArrayString, SortDynArrayStringI
- any custom type (even records) can be compared then sort by defining such a custom function
- must return 0 if A=B, -1 if A<B, 1 if A>B
- simple types are compared within this unit (with proper optimized asm if possible), whereas more complex types are implemented in other units - e.g. SortDynArrayVariant/SortDynArrayVariantI are in mormot.core.variants and SortDynArrayPUtf8CharI/SortDynArrayStringI in mormot.core.text
TFloatNan = ( fnNumber, fnNan, fnInf, fnNegInf );
The non-number values potentially stored in an IEEE floating point
TGuidShortString = string[38];
Stack-allocated ASCII string, used by GuidToShort() function
THash128 = array[0..15] of byte;
Store a 128-bit hash value
- e.g. a MD5 digest, or array[0..3] of cardinal (TBlock128)
- consumes 16 bytes of memory
THash128Array = array[ 0 .. MaxInt div SizeOf(THash128) - 1 ] of THash128;
Map an infinite array of 128-bit hash values
- each item consumes 16 bytes of memory
THash128DynArray = array of THash128;
Store several 128-bit hash values
- e.g. MD5 digests
- consumes 16 bytes of memory per item
THash160 = array[0..19] of byte;
Store a 160-bit hash value
- e.g. a SHA-1 digest
- consumes 20 bytes of memory
THash192 = array[0..23] of byte;
Store a 192-bit hash value
- consumes 24 bytes of memory
THash224 = array[0..27] of byte;
Store a 224-bit hash value
- consumes 28 bytes of memory
THash256 = array[0..31] of byte;
Store a 256-bit hash value
- e.g. a SHA-256 digest, a TEccSignature result, or array[0..7] of cardinal
- consumes 32 bytes of memory
THash256Array = array[ 0 .. MaxInt div SizeOf(THash256) - 1 ] of THash256;
Map an infinite array of 256-bit hash values
- each item consumes 32 bytes of memory
THash256DynArray = array of THash256;
Store several 256-bit hash values
- e.g. SHA-256 digests, TEccSignature results, or array[0..7] of cardinal
- consumes 32 bytes of memory per item
THash256RecDynArray = array of THash256Rec;
Store several 256-bit hash map variable records
THash384 = array[0..47] of byte;
Store a 384-bit hash value
- e.g. a SHA-384 digest
- consumes 48 bytes of memory
THash384DynArray = array of THash384;
Store several 384-bit hash values
THash512 = array[0..63] of byte;
Store a 512-bit hash value
- e.g. a SHA-512 digest, a TEccSignature result, or array[0..15] of cardinal
- consumes 64 bytes of memory
THash512Array = array[ 0 .. MaxInt div SizeOf(THash512) - 1 ] of THash512;
Map an infinite array of 512-bit hash values
- each item consumes 64 bytes of memory
THash512DynArray = array of THash512;
Store several 512-bit hash values
- e.g. SHA-512 digests, or array[0..15] of cardinal
- consumes 64 bytes of memory per item
THash512RecDynArray = array of THash512Rec;
Store several 256-bit hash map variable records
THasher = function(crc: cardinal; buf: PAnsiChar; len: cardinal): cardinal;
Function prototype to be used for 32-bit hashing of an element
- it must return a cardinal hash, with as less collision as possible
- is the function signature of DefaultHasher and InterningHasher
THasher128 = procedure(hash: PHash128; buf: PAnsiChar; len: cardinal);
Function prototype to be used for 128-bit hashing of an element
- the input hash buffer is used as seed, and contains the 128-bit result
- is the function signature of DefaultHasher128
THasher64 = function(crc: QWord; buf: PAnsiChar; len: cardinal): QWord;
Function prototype to be used for 64-bit hashing of an element
- it must return a QWord hash, with as less collision as possible
- is the function signature of DefaultHasher64
TID = type Int64;
A 64-bit identifier, as used for our ORM primary key, i.e. TOrm.ID
- also maps the SQLite3 64-bit RowID definition
TIDDynArray = array of TID;
Used to store a dynamic array of ORM primary keys, i.e. TOrm.ID
TIntCnt = integer ;
Cross-compiler return type of IUnknown._AddRef/_Release methods
- used to reduce the $ifdef when implementing interfaces in Delphi and FPC
TIntelAvx10Vector = set of ( av128, av256, av512);
The supported AVX10 Converged Vector ISA bit sizes
TIntelCpuFeature = ( cfFPU, cfVME, cfDE, cfPSE, cfTSC, cfMSR, cfPAE, cfMCE, cfCX8, cfAPIC, cf_d10, cfSEP, cfMTRR, cfPGE, cfMCA, cfCMOV, cfPAT, cfPSE36, cfPSN, cfCLFSH, cf_d20, cfDS, cfACPI, cfMMX, cfFXSR, cfSSE, cfSSE2, cfSS, cfHTT, cfTM, cfIA64, cfPBE, cfSSE3, cfCLMUL, cfDS64, cfMON, cfDSCPL, cfVMX, cfSMX, cfEST, cfTM2, cfSSSE3, cfCID, cfSDBG, cfFMA, cfCX16, cfXTPR, cfPDCM, cf_c16, cfPCID, cfDCA, cfSSE41, cfSSE42, cfX2A, cfMOVBE, cfPOPCNT, cfTSC2, cfAESNI, cfXS, cfOSXS, cfAVX, cfF16C, cfRAND, cfHYP, cfFSGS, cfTSCADJ, cfSGX, cfBMI1, cfHLE, cfAVX2, cfFDPEO, cfSMEP, cfBMI2, cfERMS, cfINVPCID, cfRTM, cfPQM, cfFPUSEG, cfMPX, cfPQE, cfAVX512F, cfAVX512DQ, cfRDSEED, cfADX, cfSMAP, cfAVX512IFMA, cfPCOMMIT, cfCLFLUSH, cfCLWB, cfIPT, cfAVX512PF, cfAVX512ER, cfAVX512CD, cfSHA, cfAVX512BW, cfAVX512VL, cfPREFW1, cfAVX512VBMI, cfUMIP, cfPKU, cfOSPKE, cfWAITPKG, cfAVX512VBMI2, cfCETSS, cfGFNI, cfVAES, cfVCLMUL, cfAVX512NNI, cfAVX512BITALG, cfTMEEN, cfAVX512VPC, cf_c15, cfFLP, cfMPX0, cfMPX1, cfMPX2, cfMPX3, cfMPX4, cfRDPID, cfKL, cfBUSLOCK, cfCLDEMOTE, cf_c26, cfMOVDIRI, cfMOVDIR64B, cfENQCMD, cfSGXLC, cfPKS, cf_d0, cfSGXKEYS, cfAVX512NNIW, cfAVX512MAPS, cfFSRM, cfUINTR, cf_d6, cf_d7, cfAVX512VP2I, cfSRBDS, cfMDCLR, cfTSXABRT, cf_d12, cfTSXFA, cfSER, cfHYBRID, cfTSXLDTRK, cf_d17, cfPCFG, cfLBR, cfIBT, cf_d21, cfAMXBF16, cfAVX512FP16, cfAMXTILE, cfAMXINT8, cfIBRSPB, cfSTIBP, cfL1DFL, cfARCAB, cfCORCAB, cfSSBD, cfSHA512, cfSM3, cfSM4, cfRAOINT, cfAVXVNNI, cfAVX512BF16, cfLASS, cfCMPCCXADD, cfAPMEL, cf_a9, cfFZLREPM, cfFSREPS, cfFSREPC, cf_a13, cf_a14, cf_a15, cf_a16, cfFRED, cfLKGS, cfWRMSRNS, cf_a20, cfAMXFP16, cfHRESET, cfAVXIFMA, cf_a24, cf_a25, cfLAM, cfMSRLIST, cf_a28, cf_a29, cf_a30, cf_a31, cf__d0, cf_d1, cf_d2, cf_d3, cfAVXVNN8, cfAVXNECVT, cf__d6, cf__d7, cfAMXCPLX, cf_d9, cfAVXVNNI16, cf_d11, cf__d12, cf_d13, cfPREFETCHI, cf_d15, cf_d16, cfUIRETUIF, cfCETSSS, cfAVX10, cf__d20, cf_APXF, cf_d22, cf_d23, cf_d24, cf_d25, cf_d26, cf_d27, cf_d28, cf_d29, cf_d30, cf_d31 );
The potential features, retrieved from an Intel/AMD CPU
- cf https://en.wikipedia.org/wiki/CPUID#EAX.3D1:_Processor_Info_and_Feature_Bits
- is defined on all platforms, so that e.g. an ARM desktop may browse Intel-generated logs using TSynLogFile from mormot.core.log.pas
TIntelCpuFeatures = set of TIntelCpuFeature;
All CPU features flags, as retrieved from an Intel/AMD CPU
TIntQry = HRESULT ;
Cross-compiler return type of IUnknown.QueryInterface method
- used to reduce the $ifdef when implementing interfaces in Delphi and FPC
ToByte = byte;
Used as ToByte() to properly truncate any integer into 8-bit
- is defined as an inlined "and 255" function under ARM to work as expected
TPtrArrayKind = ( pakPointer, pakClass, pakClassSafe, pakInterface );
Used by PtrArrayDelete() to finalize an item
TPUtf8CharArray = array[ 0 .. MaxInt div SizeOf(PUtf8Char) - 1 ] of PUtf8Char;
A Row/Col array of PUtf8Char, for containing sqlite3_get_table() result
TPUtf8CharDynArray = array of PUtf8Char;
A dynamic array of PUtf8Char pointers
TRawUtf8DynArray = array of RawUtf8;
A dynamic array of UTF-8 encoded strings
TShort15 = string[15];
Used e.g. by TSynSystemTime.ToTextDateShort
TShort16 = string[16];
Used e.g. by PointerToHexShort/CardinalToHexShort/Int64ToHexShort/FormatShort16
- such result type would avoid a string allocation on heap, so are highly recommended e.g. when logging small pieces of information
TShort23 = string[23];
Used e.g. by Int64ToHttpEtag
TShort31 = string[31];
Used e.g. for SetThreadName/GetCurrentThreadName
TShort47 = string[47];
A shortstring which only takes 48 bytes of memory
TShort64 = string[64];
Not as good as ESynException used e.g. to serialize up to 256-bit as hexadecimal
TShort8 = string[8];
Used e.g. for TTextWriter.AddShorter small text constants
TSqlRawBlob = RawBlob;
Backward compatibility types redirections
TStrCnt = integer ;
Cross-compiler type used for string reference counter
- FPC and Delphi don't always use the same type
TStreamDynArray = array of TStream;
A dynamic array of TStream instances
TStrLen = longint ;
Cross-compiler type used for string length
- FPC uses PtrInt/SizeInt, Delphi uses longint even on CPU64
TSynExtended = extended;
The floating-point type to be used for best precision and speed
- will allow to fallback to double e.g. on x64 and ARM CPUs
TSynLogLevel = ( sllNone, sllInfo, sllDebug, sllTrace, sllWarning, sllError, sllEnter, sllLeave, sllLastError, sllException, sllExceptionOS, sllMemory, sllStackTrace, sllFail, sllSQL, sllCache, sllResult, sllDB, sllHTTP, sllClient, sllServer, sllServiceCall, sllServiceReturn, sllUserAuth, sllCustom1, sllCustom2, sllCustom3, sllCustom4, sllNewRun, sllDDDError, sllDDDInfo, sllMonitoring );
The available logging events, as handled by mormot.core.log
- defined in mormot.core.base so that it may be used by the core units, even if mormot.core.log is not explicitely linked
- limited to 32 items, to efficiently fit in a 32-bit set
- sllInfo will log general information events
- sllDebug will log detailed debugging information
- sllTrace will log low-level step by step debugging information
- sllWarning will log unexpected values (not an error)
- sllError will log errors
- sllEnter will log every method start
- sllLeave will log every method exit
- sllLastError will log the GetLastError OS message
- sllException will log all exception raised - available since Windows XP
- sllExceptionOS will log all OS low-level exceptions (EDivByZero, ERangeError, EAccessViolation...)
- sllMemory will log memory statistics (in MB units)
- sllStackTrace will log caller's stack trace (it's by default part of TSynLogFamily.LevelStackTrace like sllError, sllException, sllExceptionOS, sllLastError and sllFail)
- sllFail was defined for TSynTestsLogged.Failed method, and can be used to log some customer-side assertions (may be notifications, not errors)
- sllSQL is dedicated to trace the SQL statements
- sllCache should be used to trace the internal caching mechanism
- sllResult could trace the SQL results, JSON encoded
- sllDB is dedicated to trace low-level database engine features
- sllHTTP could be used to trace HTTP process
- sllClient/sllServer could be used to trace some Client or Server process
- sllServiceCall/sllServiceReturn to trace some remote service or library
- sllUserAuth to trace user authentication (e.g. for individual requests)
- sllCustom* items can be used for any purpose
- sllNewRun will be written when a process opens a rotated log
- sllDDDError will log any DDD-related low-level error information
- sllDDDInfo will log any DDD-related low-level debugging information
- sllMonitoring will log the statistics information (if available), or may be used for real-time chat among connected people to ToolsAdmin
TSynLogLevelDynArray = array of TSynLogLevel;
A dynamic array of logging event levels
TSynLogLevels = set of TSynLogLevel;
Used to define a set of logging level abilities
- i.e. a combination of none or several logging event - stored as 32-bit
- e.g. use LOG_VERBOSE constant to log all events, or LOG_STACKTRACE to log all errors and exceptions
TSynLogProc = procedure(Level: TSynLogLevel; const Fmt: RawUtf8; const Args: array of const; Instance: TObject = nil) of object;
Callback definition used to abstractly log some events
- defined as TMethod to avoid dependency with the mormot.core.log unit
- match class procedure TSynLog.DoLog
- used e.g. by global variables like WindowsServiceLog in mormot.core.os or TCrtSocket.OnLog in mormot.net.sock
TThreadID = cardinal;
Used to store the handle of a system Thread
TTimeLog = type Int64;
Fast bit-encoded date and time value
- see TTimeLog helper functions and types in mormot.core.datetime
- faster than Iso-8601 text and TDateTime, e.g. can be used as published property field in mORMot's TOrm (see also TModTime and TCreateTime)
- use internally for computation an abstract "year" of 16 months of 32 days of 32 hours of 64 minutes of 64 seconds - same as Iso8601ToTimeLog()
- use TimeLogFromDateTime/TimeLogToDateTime/TimeLogNow functions, or type-cast any TTimeLog value with the TTimeLogBits memory structure for direct access to its bit-oriented content (or via PTimeLogBits pointer)
- since TTimeLog type is bit-oriented, you can't just add or substract two TTimeLog values when doing date/time computation: use a TDateTime temporary conversion in such case:
aTimestamp := TimeLogFromDateTime(IncDay(TimeLogToDateTime(aTimestamp)));
TTimeLogDynArray = array of TTimeLog;
Dynamic array of TTimeLog
- recognized e.g. by TDynArray JSON serialization
TTVarRecDynArray = array of TVarRec;
A dynamic array of TVarRec, i.e. could match an "array of const" parameter
TUnixMSTime = type Int64;
Timestamp stored as millisecond-based Unix Time
- see Unix Time helper functions and types in mormot.core.datetime
- i.e. the number of milliseconds since 1970-01-01 00:00:00 UTC
- see TUnixTime for a second resolution Unix Timestamp
- use UnixMSTimeToDateTime/DateTimeToUnixMSTime functions to convert it to/from a regular TDateTime
- also one of the JavaScript date encodings
TUnixMSTimeDynArray = array of TUnixMSTime;
Dynamic array of timestamps stored as millisecond-based Unix Time
TUnixTime = type Int64;
Timestamp stored as second-based Unix Time
- see Unix Time helper functions and types in mormot.core.datetime
- i.e. the number of seconds since 1970-01-01 00:00:00 UTC
- is stored as 64-bit value, so that it won't be affected by the "Year 2038" overflow issue
- see TUnixMSTime for a millisecond resolution Unix Timestamp
- use UnixTimeToDateTime/DateTimeToUnixTime functions to convert it to/from a regular TDateTime
- use UnixTimeUtc to return the current timestamp, using fast OS API call
- also one of the encodings supported by SQLite3 date/time functions
TUnixTimeDynArray = array of TUnixTime;
Dynamic array of timestamps stored as second-based Unix Time
TVarDataStaticArray = array[ 0 .. MaxInt div SizeOf(TVarData) - 1 ] of TVarData;
A TVarData values array
- is not called TVarDataArray to avoid confusion with the corresponding type already defined in RTL Variants.pas, and used for custom late-binding
Ucs4CodePoint = cardinal;
Store one 32-bit UCS4 CodePoint (with a better naming than UCS4 "Char")
- RTL's Ucs4Char is buggy, especially on oldest Delphi
unaligned = Double;
Unaligned() will be defined and useful only on FPC ARM/Aarch64 plaforms
WinAnsiString = type AnsiString;
WinAnsiString is a WinAnsi-encoded AnsiString (code page 1252)
- use this type instead of System.String, which behavior changed between Delphi 2009 compiler and previous versions: our implementation is consistent and compatible with all versions of Delphi compiler
- all conversion to/from string or RawUtf8/UTF8String must be explicit on Delphi 7/2007, and it will be faster anyway to use our optimized functions from mormot.core.unicode.pas unit like StringToUtf8/Utf8ToString
ALLBITS_CARDINAL: array[1..32] of cardinal = ( 1 shl 1 - 1, 1 shl 2 - 1, 1 shl 3 - 1, 1 shl 4 - 1, 1 shl 5 - 1, 1 shl 6 - 1, 1 shl 7 - 1, 1 shl 8 - 1, 1 shl 9 - 1, 1 shl 10 - 1, 1 shl 11 - 1, 1 shl 12 - 1, 1 shl 13 - 1, 1 shl 14 - 1, 1 shl 15 - 1, 1 shl 16 - 1, 1 shl 17 - 1, 1 shl 18 - 1, 1 shl 19 - 1, 1 shl 20 - 1, 1 shl 21 - 1, 1 shl 22 - 1, 1 shl 23 - 1, 1 shl 24 - 1, 1 shl 25 - 1, 1 shl 26 - 1, 1 shl 27 - 1, 1 shl 28 - 1, 1 shl 29 - 1, 1 shl 30 - 1, $7fffffff, $ffffffff);
Constant array used by GetAllBits() function (when inlined)
CODEPAGE_LATIN1 = CP_LATIN1;
Use rather CP_LATIN1 with mORMot 2
CODEPAGE_US = CP_WINANSI;
Use rather CP_WINANSI with mORMot 2
CP_ACP = 0;
Internal Code Page for System AnsiString encoding
CP_LATIN1 = 819;
Latin-1 ISO/IEC 8859-1 Code Page
- map low 8-bit Unicode CodePoints
CP_OEM = 1;
Internal Code Page for System Console encoding
CP_RAWBLOB = 65534;
Fake code page used to recognize RawBlob
- RawBlob internal code page will be CP_RAWBYTESTRING = 65535, but our ORM will identify the RawBlob type and unserialize it using CP_RAWBLOB instead
- TJsonWriter.AddAnyAnsiBuffer will recognize it and use Base-64 encoding
CP_RAWBYTESTRING = 65535;
Internal Code Page for RawByteString undefined string
CP_UTF16 = 1200;
Internal Code Page for UTF-16 Unicode encoding
- used e.g. for Delphi 2009+ UnicodeString=String type
CP_UTF8 = 65001;
Internal Code Page for UTF-8 Unicode encoding
- as used by RawUtf8 and all our internal framework text process
CP_WINANSI = 1252;
US English Windows Code Page, i.e. WinAnsi standard character encoding
CURR_RES = 10000;
Used e.g. to convert a currency (via PInt64) into a double
- warning: FPC Win64 to Win32 cross-compiler doesn't support currency values properly -> use FPC Win32 compiler only on Windows
DOUBLE_SAME = 1E-11;
A typical error allowed when working with double floating-point values
- 1E-12 is too small, and triggers sometimes some unexpected errors; FPC RTL uses 1E-4 so we are paranoid enough
FindNonVoid: array[boolean] of TFindNonVoid = ( FindNonVoidRawUtf8I, FindNonVoidRawUtf8);
Raw internal methods for case sensitive (or not) search for a RawUtf8
- expects non-void RawUtf8 values, with ASCII-7 encoding, e.g. as with TDocVariantData.GetValueIndex() property names
GUID_NULL: TGuid = ();
A TGuid containing '{00000000-0000-0000-0000-00000000000}'
KNUTH_HASH32_MUL = $9E3779B1;
Knuth's magic number for hashing a 32-bit value, using the golden ratio
- then use the result high bits, i.e. via "shr" not via "and"
- for instance, mormot.core.log uses it to hash the TThreadID:
hash := cardinal(cardinal(id) * KNUTH_HASH32_MUL) shr (32 - MAXLOGTHREADBITS);
KNUTH_HASH64_MUL = $9E3779B97F4A7C15;
Knuth's magic number for hashing a 64-bit value, using the golden ratio
KNUTH_HASHPTR_MUL = KNUTH_HASH32_MUL;
Knuth's magic number for hashing a PtrUInt, using the golden ratio
LOG_TRACEWARNING: array[boolean] of TSynLogLevel = ( sllTrace, sllWarning);
May be used to log as Trace or Warning event, depending on an Error: boolean
NULCHAR: AnsiChar = #0;
Used to mark the end of ASCIIZ buffer, or return a void ShortString
NullVarData: TVarData = (VType: varNull);
A slightly faster alternative to Variants.Null function with TVarData
POINTERAND = 3 ;
Could be used to compute the bitmask of a pointer integer
POINTERBITS = 32 ;
Could be used to check all bits on a pointer
POINTERBYTES = 4 ;
Could be used to check all bytes on a pointer
POINTERSHR = 2 ;
Could be used to compute the index in a pointer list from its byte position
POINTERSHRBITS = 5 ;
Could be used to compute the index in a pointer list from its bits position
POW10: TPow10 = ( 1E-31, 1E-30, 1E-29, 1E-28, 1E-27, 1E-26, 1E-25, 1E-24, 1E-23, 1E-22, 1E-21, 1E-20, 1E-19, 1E-18, 1E-17, 1E-16, 1E-15, 1E-14, 1E-13, 1E-12, 1E-11, 1E-10, 1E-9, 1E-8, 1E-7, 1E-6, 1E-5, 1E-4, 1E-3, 1E-2, 1E-1, 1E0, 1E1, 1E2, 1E3, 1E4, 1E5, 1E6, 1E7, 1E8, 1E9, 1E10, 1E11, 1E12, 1E13, 1E14, 1E15, 1E16, 1E17, 1E18, 1E19, 1E20, 1E21, 1E22, 1E23, 1E24, 1E25, 1E26, 1E27, 1E28, 1E29, 1E30, 1E31, 0, -1, 1E0, 1E32, 1E64, 1E96, 1E128, 1E160, 1E192, 1E224, 1E256, 1E288, 1E320, 1E-0, 1E-32, 1E-64, 1E-96, 1E-128, 1E-160, 1E-192, 1E-224, 1E-256, 1E-288, 1E-320);
Most common 10 ^ exponent constants, ending with values for HugePower10*()
SYNOPSE_FRAMEWORK_FULLVERSION = SYNOPSE_FRAMEWORK_VERSION ;
A text including the version and the main active conditional options
- usefull for low-level debugging purpose
SYNOPSE_FRAMEWORK_NAME = 'mORMot';
The full text of the Synopse mORMot framework
- note: we don't supply full version number with build revision for HTTP servers, to reduce potential attack surface
SYNOPSE_FRAMEWORK_VERSION = '2.2.7976' ;
The corresponding version of the mORMot framework, as '2.#.#'
- 2nd digit is minor version, increased at each framework release, when adding functionality in a stable enough manner
- 3rd digit is a globally increasing git commit number (as generated by the commit.sh script) - so won't be reset when minor is up
TwoDigitLookup: packed array[0..99] of array[1..2] of AnsiChar = ('00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99');
Fast lookup table for converting any decimal number from 0 to 99 into their ASCII equivalence
varNativeString = varString;
This variant type will map the current string type
- depending on the compiler string definition (UnicodeString or AnsiString)
varOleClsid = 72;
Map the Windows VT_CLSID extended VARENUM, i.e. a by-reference PGuid
varOleFileTime = 64;
Map the Windows VT_FILETIME extended VARENUM, i.e. a 64-bit TFileTime
- also detected and handled by VariantToDateTime
varOleInt = 22;
Map the Windows VT_INT extended VARENUM, i.e. a 32-bit signed integer
- also detected and handled by VariantToInteger/VariantToInt64
varOlePAnsiChar = 30;
Map the Windows VT_LPSTR extended VARENUM, i.e. a PAnsiChar
- also detected and handled by VariantToUtf8
varOlePWideChar = 31;
Map the Windows VT_LPWSTR extended VARENUM, i.e. a PWideChar
- also detected and handled by VariantToUtf8
varOleUInt = 23;
Map the Windows VT_UINT extended VARENUM, i.e. a 32-bit unsigned integer
- also detected and handled by VariantToInteger/VariantToInt64
varSynUnicode = varOleStr;
This variant type will map the current SynUnicode type
- depending on the compiler version
varWord64 = 21;
Unsigned 64bit integer variant type
- currently called varUInt64 in Delphi (not defined in older versions), and varQWord in FPC
VTYPE_NUMERIC = [varSmallInt .. varDouble, varCurrency, varBoolean .. varOleUInt];
Those TVarData.VType values are meant to be number values and need no escape
VTYPE_SIMPLE = [varEmpty..varDate, varBoolean, varShortInt..varWord64, varOleInt, varOleUInt, varOlePAnsiChar, varOlePWideChar, varOleFileTime, varUnknown];
Those TVarData.VType values are meant to be direct values
VTYPE_STATIC = $BFE8;
Bitmask used by our inlined VarClear() to avoid unneeded VarClearProc()
_DACNT = SizeOf(TDACnt) + _DALEN;
Cross-compiler negative offset to TDynArrayRec.refCnt field
- to be used inlined e.g. as PDACnt(PAnsiChar(Values) - _DACNT)^
_DALEN = SizeOf(TDALen);
Cross-compiler negative offset to TDynArrayRec.high/length field
- to be used inlined e.g. as
PDALen(PAnsiChar(Values) - _DALEN)^ + _DAOFF
- both FPC and Delphi uses PtrInt/NativeInt for dynamic array high/length
_DAMAXSIZE = $5fffffff;
In-memory TBytes process will allow up to 800 MB
- used as high limit e.g. for TBufferWriter.FlushToBytes
- even if a dynamic array can handle PtrInt length, consider other patterns
_DAOFF = 0 ;
Cross-compiler adjuster to get length from TDynArrayRec.high/length field
_DARECSIZE = SizeOf(TDynArrayRec);
Used to calc the beginning of memory allocation of a dynamic array
_STRCNT = SizeOf(TStrCnt) + _STRLEN;
Cross-compiler negative offset to TStrRec.refCnt field
- to be used inlined e.g. as PStrCnt(p - _STRCNT)^
_STRLEN = SizeOf(TStrLen);
Cross-compiler negative offset to TStrRec.length field
- to be used inlined e.g. as PStrLen(p - _STRLEN)^
_STRMAXSIZE = $5fffffff;
In-memory string process will allow up to 800 MB
- used as high limit e.g. for TBufferWriter over a TRawByteStringStream
- Delphi strings have a 32-bit length so you should change your algorithm
- even if FPC on CPU64 can handle bigger strings, consider other patterns
_STRRECSIZE = SizeOf(TStrRec);
CodePage offset = string header size
- used to calc the beginning of memory allocation of a string
| Functions or procedures | Description | |
|---|---|---|
| AddGuid | Append one TGuid item to a TGuid dynamic array | |
| AddHash128 | Add a 128-bit item in an array of such values | |
| AddInt64 | Add a 64-bit integer value at the end of a dynamic array | |
| AddInt64 | Add a 64-bit integer value at the end of a dynamic array of integers | |
| AddInt64 | Add a 64-bit integer array at the end of a dynamic array | |
| AddInt64Once | If not already existing, add a 64-bit integer value to a dynamic array | |
| AddInt64Sorted | If not already existing, add a 64-bit integer value to a sorted dynamic array | |
| AddInteger | Add an integer array at the end of a dynamic array of integer | |
| AddInteger | Add an integer value at the end of a dynamic array of integers | |
| AddInteger | Add an integer value at the end of a dynamic array of integers | |
| AddInteger | Add an integer value at the end of a dynamic array of integers | |
| AddPtrUInt | Add a pointer-sized integer array at the end of a dynamic array | |
| AddSortedInteger | Add an integer value in a sorted dynamic array of integers | |
| AddSortedInteger | Add an integer value in a sorted dynamic array of integers | |
| AddWord | Add a 16-bit integer value at the end of a dynamic array of integers | |
| AndMemory | Logical AND of two memory buffers | |
| Ansi7StringToShortString | Direct conversion of an ANSI-7 AnsiString into an ShortString | |
| AppendShort | Simple concatenation of a ShortString text into a shorstring | |
| AppendShortAnsi7String | Simple concatenation of an ANSI-7 AnsiString into a shorstring | |
| AppendShortBuffer | Simple concatenation of a #0 ending text into a shorstring | |
| AppendShortByteHex | Simple concatenation of a byte as hexadecimal into a shorstring | |
| AppendShortCardinal | Simple concatenation of a 32-bit unsigned integer as text into a shorstring | |
| AppendShortChar | Simple concatenation of a character into a shorstring | |
| AppendShortInt64 | Simple concatenation of a 64-bit integer as text into a shorstring | |
| BitsToBytes | Compute how many bytes are needed to store a given number of bits | |
| BSRdword | Return the position of the leftmost set bit in a 32-bit value | |
| BSRqword | Return the position of the leftmost set bit in a 64-bit value | |
| bswap32 | Convert the endianness of a given unsigned 32-bit integer into BigEndian | |
| bswap64 | Convert the endianness of a given unsigned 64-bit integer into BigEndian | |
| bswap64array | Convert the endianness of an array of unsigned 64-bit integer into BigEndian | |
| BufferLineLength | Compute the line length from a size-delimited source array of chars | |
| ByteScanIndex | Fast search of an unsigned byte value position in a byte array | |
| ClassNameShort | Just a wrapper around vmtClassName to avoid a string conversion | |
| ClassNameShort | Just a wrapper around vmtClassName to avoid a string conversion | |
| ClassToText | Just a wrapper around vmtClassName to avoid a string conversion | |
| ClearVariantForString | Internal efficient wrapper of VarClear() + set VType=varString and VAny=nil | |
| CompareBuf | Overload wrapper of MemCmp() to compare a RawByteString vs a memory buffer | |
| CompareBuf | Overload wrapper to SortDynArrayRawByteString(P1, P2) | |
| CompareCardinal | A comparison function for sorting 32-bit unsigned integer values | |
| CompareFloat | A comparison function for sorting IEEE 754 double precision values | |
| CompareInt64 | A comparison function for sorting 64-bit signed integer values | |
| CompareInteger | A comparison function for sorting 32-bit signed integer values | |
| CompareMem | Our fast version of CompareMem() | |
| CompareMemSmall | A CompareMem()-like function designed for small (a few bytes) content | |
| ComparePointer | A comparison function for sorting 32/64-bit pointers as unsigned values | |
| ComparePtrInt | A comparison function for sorting 32/64-bit signed integer values | |
| CompareQWord | A comparison function for sorting 64-bit unsigned integer values | |
| CompressSynLZ | Compress a data content using the SynLZ algorithm | |
| CompressSynLZGetHash32 | Return the Hash32() 32-bit CRC of CompressSynLZ() uncompressed data | |
| crc128c | Compute a 128-bit checksum on the supplied buffer, cascading two crc32c | |
| crc16 | Compute CRC16-CCITT checkum on the supplied buffer | |
| crc256c | Compute a 256-bit checksum on the supplied buffer using crc32c | |
| crc32c128 | Compute a 128-bit CRC of any binary buffers | |
| crc32cBy4fast | Pure pascal function implementing crc32cBy4() | |
| crc32cfast | Compute CRC32C checksum on the supplied buffer on processor-neutral code | |
| crc32cHash | Compute a 32-bit hash of any array of bytes using the CRC32C checksum | |
| crc32cHash | Compute a 32-bit hash of any string using the CRC32C checksum | |
| crc32cinlined | Compute CRC32C checksum on the supplied buffer using inlined code | |
| crc32csse42 | Defined here for mormot.test.base only | |
| crc32ctwice | Expand a CRC32C checksum on the supplied buffer for 64-bit hashing | |
| crc32fast | Compute CRC32 checksum on the supplied buffer on processor-neutral code | |
| crc63c | Compute CRC63C checksum on the supplied buffer, cascading two crc32c | |
| crc64c | Compute CRC64C checksum on the supplied buffer, cascading two crc32c | |
| crcblockfast | Computation of our 128-bit CRC of a 128-bit binary buffer without SSE4.2 | |
| crcblocksfast | Compute a proprietary 128-bit CRC of 128-bit binary buffers | |
| CurrencyToDouble | Convert a currency value pointer into a double | |
| CurrencyToDouble | Convert a currency value pointer into a double | |
| CurrencyToDouble | Convert a currency value into a double | |
| CurrencyToInt64 | Convert a currency value into a Int64 | |
| CurrencyToVariant | Fill a variant value from a currency value | |
| DACntAdd | Low-level dynarray reference counter process | |
| DACntDecFree | Low-level dynarray reference counter unprocess | |
| DateTimeToIsoString | Use the RTL to return a date/time as ISO-8601 text | |
| DefaultHash | Compute a 32-bit hash of any string using DefaultHasher() | |
| DefaultHash | Compute a 32-bit hash of any array of bytes using DefaultHasher() | |
| DeleteInt64 | Delete any 64-bit integer in Values[] | |
| DeleteInt64 | Delete any 64-bit integer in Values[] | |
| DeleteInteger | Delete any 32-bit integer in Values[] | |
| DeleteInteger | Delete any 32-bit integer in Values[] | |
| DeleteWord | Delete any 16-bit integer in Values[] | |
| Div100 | Simple wrapper to efficiently compute both division and modulo per 100 | |
| DoubleToCurrency | Convert a double value into a currency | |
| DoubleToCurrency | Convert a double value into a currency | |
| DoubleToCurrency | Convert a double value into a currency | |
| DynArrayFakeLength | Like SetLength() but without any memory resize - WARNING: len should be > 0 | |
| DynArrayHashTableAdjust | Internal hash table adjustment as called from TDynArrayHasher.HashDelete | |
| DynArrayHashTableAdjust16 | DynArrayHashTableAdjust() version for 16-bit HashTable[] - SSE2 asm on x86_64 | |
| EnsureRawUtf8 | Ensure the supplied variable will have a CP_UTF8 - making it unique if needed | |
| EnsureRawUtf8 | Ensure the supplied variable will have a CP_UTF8 - making it unique if needed | |
| EqualBuf | Overload wrapper to SortDynArrayRawByteString(P1, P2) = 0 | |
| EventEquals | Compare two TMethod instances | |
| Exchg | Low-level inlined function for exchanging two memory buffers | |
| ExchgPointer | Low-level inlined function for exchanging two pointers | |
| ExchgPointers | Low-level inlined function for exchanging two sets of pointers | |
| ExchgVariant | Low-level inlined function for exchanging two variants | |
| FakeCodePage | Internal function which could be used instead of SetCodePage() if RefCnt = 1 | |
| FakeLength | Internal function which could be used instead of SetLength() if RefCnt = 1 | |
| FakeLength | Internal function which could be used instead of SetLength() if RefCnt = 1 | |
| FakeLength | Internal function which could be used instead of SetLength() if RefCnt = 1 | |
| FakeSetLength | Internal function which could be used instead of SetLength() if RefCnt = 1 | |
| FakeSetLength | Internal function which could be used instead of SetLength() if RefCnt = 1 | |
| FastAssignNew | Assign any constant or already ref-counted AnsiString/RawUtf8 | |
| FastAssignNewNotVoid | Internal function to assign any constant or ref-counted AnsiString/RawUtf8 | |
| FastAssignUtf8 | Internal function which assign src to dest, force CP_UTF8 and set src to '' | |
| FastFindInt64Sorted | Fast O(log(n)) binary search of a 64-bit signed integer value in a sorted array | |
| FastFindIntegerSorted | Fast O(log(n)) binary search of an integer value in a sorted integer array | |
| FastFindIntegerSorted | Fast O(log(n)) binary search of an integer value in a sorted integer array | |
| FastFindPointerSorted | Fast O(log(n)) binary search of a pointer value in a sorted array | |
| FastFindPtrIntSorted | Fast O(log(n)) binary search of a PtrInt value in a sorted array | |
| FastFindQWordSorted | Fast O(log(n)) binary search of a 64-bit unsigned integer value in a sorted array | |
| FastFindWordSorted | Fast O(log(n)) binary search of a 16-bit unsigned integer value in a sorted array | |
| FastLocateIntegerSorted | Retrieve the index where to insert an integer value in a sorted integer array | |
| FastLocateWordSorted | Retrieve the index where to insert a word value in a sorted word array | |
| FastNewRawByteString | Equivalence to SetString(s,nil,len) function to allocate a new RawByteString | |
| FastNewString | Internal function used by FastSetString/FastSetStringCP | |
| FastSearchIntegerSorted | Retrieve the matching index or where to insert an integer value | |
| FastSetRawByteString | Equivalence to SetString(s,pansichar,len) function but from a raw pointer | |
| FastSetString | Equivalence to SetString(s,pansichar,len) function but from a raw pointer | |
| FastSetString | Faster equivalence to SetString(s,nil,len) function | |
| FastSetStringCP | Equivalence to SetString(s,pansichar,len) function with a specific code page | |
| FillAnsiStringFromRandom | Internal function used e.g. by TLecuyer.FillShort/FillShort31 | |
| FillcharFast | Our fast version of FillChar() on Intel/AMD | |
| FillIncreasing | Fill some values with i,i+1,i+2...i+Count-1 | |
| FillRandom | Fill some 32-bit memory buffer with values from the gsl_rng_taus2 generator | |
| FillZero | Fill all 64 bytes of this 512-bit buffer with zero | |
| FillZero | Fill all 32 bytes of this 256-bit buffer with zero | |
| FillZero | Fill a TGuid with 0 | |
| FillZero | Fill all 20 bytes of this 160-bit buffer with zero | |
| FillZero | Fill all 16 bytes of this 128-bit buffer with zero | |
| FillZero | Fill all entries of a supplied array of 64-bit integers with 0 | |
| FillZero | Fill all bytes of a memory buffer with zero | |
| FillZero | Fill all 32 bytes of this 384-bit buffer with zero | |
| FillZero | Fill all entries of a supplied array of 32-bit integers with 0 | |
| FillZeroSmall | Fill first bytes of a memory buffer with zero | |
| FindNonVoidRawUtf8 | Raw internal method as published by FindNonVoid[false] | |
| FindNonVoidRawUtf8I | Raw internal method as published by FindNonVoid[true] | |
| FindPropName | Return the case-insensitive ASCII 7-bit index of Value in non-void Values[] | |
| FindPropName | Return the index of Value in Values[], -1 if not found | |
| fnv32 | Simple FNV-1a hashing function | |
| FreeAndNilSafe | Same as FreeAndNil() but catching and ignoring any exception | |
| FromI32 | Initializes a dynamic array from a set of 32-bit integer signed values | |
| FromI64 | Initializes a dynamic array from a set of 64-bit integer signed values | |
| FromU32 | Initializes a dynamic array from a set of 32-bit integer unsigned values | |
| FromU64 | Initializes a dynamic array from a set of 64-bit integer unsigned values | |
| gcd | Compute GCD of two integers using modulo-based Euclidean algorithm | |
| GetAllBits | Returns TRUE if all BitCount bits are set in the input 32-bit cardinal | |
| GetBit | Retrieve a particular bit status from a bit array | |
| GetBit64 | Retrieve a particular bit status from a 64-bit integer bits (max aIndex is 63) | |
| GetBitPtr | Retrieve a particular bit status from a bit array | |
| GetBitsCount | Compute the number of bits set in a bit array | |
| GetBitsCountPas | Pure pascal version of GetBitsCountPtrInt() | |
| GetBitsCountSSE42 | Defined here for mormot.test.base only | |
| GetBoolean | Get a boolean value stored as 'true'/'false' text in input variable | |
| GetBoolean | Get a boolean value stored as 'true'/'false' text in P^ | |
| GetCardinal | Get the unsigned 32-bit integer value stored in P^ | |
| GetCardinal | Get the unsigned 32-bit integer value stored in P^ | |
| GetCardinalDef | Get the unsigned 32-bit integer value stored in P^ | |
| GetCardinalW | Get the unsigned 32-bit integer value stored as Unicode string in P^ | |
| GetClassParent | Just a wrapper around vmtParent to avoid a function call | |
| GetExtended | Get the extended floating point value stored in P^ | |
| GetExtended | Get the extended floating point value stored in P^ | |
| GetInt64 | Get the 64-bit integer value stored in P^ | |
| GetInt64 | Get the 64-bit signed integer value stored in P^ | |
| GetInt64Bool | Get the 64-bit integer value from P^, recognizing true/false/yes/no input | |
| GetInt64Def | Get the 64-bit integer value stored in P^ | |
| GetInteger | Get the signed 32-bit integer value stored in P^..PEnd^ | |
| GetInteger | Get the signed 32-bit integer value stored in P^ | |
| GetInteger | Get the signed 32-bit integer value stored in P^ | |
| GetIntegerDef | Get the signed 32-bit integer value stored in P^ | |
| GetMemAligned | Initialize a RawByteString, ensuring returned "aligned" pointer is 16-bytes aligned | |
| GetQWord | Get the 64-bit unsigned integer value stored in P^ | |
| GetTrue | Return 1 if 'TRUE' or 'YES', or 0 otherwise | |
| GotoNextControlChar | Fast go to the first char <= #13 | |
| GotoNextLine | Fast go to next text line, ended by #13 or #13#10 | |
| Hash128Index | Fast O(n) search of a 128-bit item in an array of such values | |
| Hash128To64 | Combine/reduce a 128-bit hash into a 64-bit hash | |
| Hash256Index | Fast O(n) search of a 256-bit item in an array of such values | |
| Hash32 | Our custom efficient 32-bit hash/checksum function | |
| Hash32 | Our custom efficient 32-bit hash/checksum function | |
| HasHWAes | Cross-platform wrapper function to check AES HW support on Intel or ARM | |
| HugePower10Neg | Low-level computation of 10 ^ negative exponent, if POW10[] is not enough | |
| HugePower10Pos | Low-level computation of 10 ^ positive exponent, if POW10[] is not enough | |
| InsertInteger | Insert an integer value at the specified index position of a dynamic array of integers | |
| Int64Scan | Fast search of an integer position in a 64-bit integer array | |
| Int64ScanExists | Fast search of an integer value in a 64-bit integer array | |
| Int64ScanIndex | Fast search of an integer position in a signed 64-bit integer array | |
| Int64ToCurrency | Convert a Int64 value into a currency | |
| Int64ToCurrency | Convert a Int64 value into a currency | |
| IntegerScan | Fast search of an unsigned integer item in a 32-bit integer array | |
| IntegerScanExists | Fast search of an unsigned integer in a 32-bit integer array | |
| IntegerScanIndex | Fast search of an unsigned integer position in a 32-bit integer array | |
| InterfaceArrayAdd | Wrapper to add an item to a T*InterfaceArray dynamic array storage | |
| InterfaceArrayAddCount | Wrapper to add an item to a T*InterfaceArray dynamic array storage | |
| InterfaceArrayAddOnce | Wrapper to add once an item to a T*InterfaceArray dynamic array storage | |
| InterfaceArrayDelete | Wrapper to delete an item in a T*InterfaceArray dynamic array storage | |
| InterfaceArrayDelete | Wrapper to delete an item in a T*InterfaceArray dynamic array storage | |
| InterfaceArrayFind | Wrapper to search an item in a T*InterfaceArray dynamic array storage | |
| InterfaceNilSafe | Same as aInterface := nil but ignoring any exception | |
| InterfacesNilSafe | Same as aInterface := nil but ignoring any exception | |
| InterlockedDecrement | Compatibility function, to be implemented according to the running CPU | |
| InterlockedIncrement | Compatibility function, to be implemented according to the running CPU | |
| IsAnsiCompatible | Return TRUE if the supplied text only contains 7-bits Ansi characters | |
| IsAnsiCompatible | Return TRUE if the supplied buffer only contains 7-bits Ansi characters | |
| IsAnsiCompatible | Return TRUE if the supplied buffer only contains 7-bits Ansi characters | |
| IsAnsiCompatibleW | Return TRUE if the supplied UTF-16 buffer only contains 7-bits Ansi characters | |
| IsAnsiCompatibleW | Return TRUE if the supplied UTF-16 buffer only contains 7-bits Ansi characters | |
| IsEqual | Returns TRUE if all 20 bytes of both 160-bit buffers do match | |
| IsEqual | Returns TRUE if all 16 bytes of both 128-bit buffers do match | |
| IsEqual | Returns TRUE if all 48 bytes of both 384-bit buffers do match | |
| IsEqual | Returns TRUE if all 64 bytes of both 512-bit buffers do match | |
| IsEqual | Returns TRUE if all bytes of both buffers do match | |
| IsEqual | Returns TRUE if all 32 bytes of both 256-bit buffers do match | |
| IsEqualGuid | Compare two TGuid values | |
| IsEqualGuid | Compare two TGuid values | |
| IsEqualGuidArray | Returns the index of a matching TGuid in an array | |
| IsNullGuid | Check if a TGuid value contains only 0 bytes | |
| IsZero | Returns TRUE if all 16 bytes of this 128-bit buffer equal zero | |
| IsZero | Returns TRUE if all 48 bytes of this 384-bit buffer equal zero | |
| IsZero | Returns TRUE if Value is nil or all supplied Values[] equal 0 | |
| IsZero | Returns TRUE if all 64 bytes of this 512-bit buffer equal zero | |
| IsZero | Returns TRUE if all bytes equal zero | |
| IsZero | Returns TRUE if all 20 bytes of this 160-bit buffer equal zero | |
| IsZero | Returns TRUE if Value is nil or all supplied Values[] equal 0 | |
| IsZero | Returns TRUE if all 32 bytes of this 256-bit buffer equal zero | |
| IsZeroSmall | Returns TRUE if all of a few bytes equal zero | |
| KahanSum | Compute the sum of values, using a running compensation for lost low-order bits | |
| kr32 | Standard Kernighan & Ritchie hash from "The C programming Language", 3rd edition | |
| Lecuyer | Return the 32-bit Pierre L'Ecuyer software generator for the current thread | |
| LecuyerEncrypt | Cipher/uncipher some memory buffer using a 64-bit seed and Pierre L'Ecuyer's algorithm, and its gsl_rng_taus2 generator | |
| LockedAdd | Fast atomic addition operation on a pointer-sized integer value | |
| LockedAdd32 | Fast atomic addition operation on a 32-bit integer value | |
| LockedDec | Fast atomic substraction operation on a pointer-sized integer value | |
| LockedDec32 | Slightly faster than InterlockedDecrement() when you don't need the result | |
| LockedExc | Fast atomic compare-and-swap operation on a pointer-sized integer value | |
| LockedInc32 | Slightly faster than InterlockedIncrement() when you don't need the result | |
| LockedInc64 | Slightly faster than InterlockedIncrement64() | |
| MemCmp | Binary comparison of buffers, returning <0, 0 or >0 results | |
| MoveAndZero | Perform a MoveFast then fill the Source buffer with zeros | |
| MoveByOne | Move() with one-by-one byte copy | |
| MoveFast | Our fast version of move() on Intel/AMD | |
| MoveSwap | Copy one memory buffer to another, swapping the bytes order | |
| mul64x64 | Fast computation of two 64-bit unsigned integers into a 128-bit value | |
| MultiEventAdd | Low-level wrapper to add a callback to a dynamic list of events | |
| MultiEventFind | Low-level wrapper to check if a callback is in a dynamic list of events | |
| MultiEventMerge | Low-level wrapper to add one or several callbacks from another list of events | |
| MultiEventRemove | Low-level wrapper to remove a callback from a dynamic list of events | |
| MultiEventRemove | Low-level wrapper to remove a callback from a dynamic list of events | |
| NextGrow | Compute the new capacity when expanding an array of items | |
| ObjArrayAdd | Wrapper to add an item to a T*ObjArray dynamic array storage | |
| ObjArrayAddCount | Wrapper to add an item to a T*ObjArray dynamic array storage | |
| ObjArrayAddFrom | Wrapper to add items to a T*ObjArray dynamic array storage | |
| ObjArrayAddOnce | Wrapper to add once an item to a T*ObjArray dynamic array storage | |
| ObjArrayAddOnce | Wrapper to add once an item to a T*ObjArray dynamic array storage and Count | |
| ObjArrayAddOnceFrom | ||
| ObjArrayAppend | Wrapper to add and move items to a T*ObjArray dynamic array storage | |
| ObjArrayClear | Wrapper to release all items stored in a T*ObjArray dynamic array | |
| ObjArrayClear | Wrapper to release all items stored in a T*ObjArray dynamic array | |
| ObjArrayClear | Wrapper to release all items stored in a T*ObjArray dynamic array | |
| ObjArrayDelete | Wrapper to delete an item in a T*ObjArray dynamic array storage | |
| ObjArrayDelete | Wrapper to delete an item in a T*ObjArray dynamic array storage | |
| ObjArrayDelete | Wrapper to delete an item in a T*ObjArray dynamic array storage | |
| ObjArrayFind | Wrapper to search an item in a T*ObjArray dynamic array storage | |
| ObjArrayFind | Wrapper to search an item in a T*ObjArray dynamic array storage | |
| ObjArrayNotNilCount | Wrapper to count all not nil items in a T*ObjArray dynamic array storage | |
| ObjArrayObjArrayClear | Wrapper to release all items stored in an array of T*ObjArray dynamic array | |
| ObjArraysClear | Wrapper to release all items stored in several T*ObjArray dynamic arrays | |
| ObjArraySetLength | Wrapper to set the length of a T*ObjArray dynamic array storage | |
| OrMemory | Logical OR of two memory buffers | |
| PosChar | Fast retrieve the position of a given character in a #0 ended buffer | |
| PosChar | Fast retrieve the position of a given character in a #0 ended buffer | |
| PosEx | Faster RawUtf8 Equivalent of standard StrUtils.PosEx | |
| PosExChar | Optimized version of PosEx() with search text as one AnsiChar | |
| PosExString | Our own PosEx() function dedicated to RTL string process | |
| PropNameEquals | Case-insensitive comparison of two shortstrings only containing ASCII 7-bit | |
| PropNameEquals | Delphi has troubles inlining goto/label case-insensitive comparison of two RawUtf8 only containing ASCII 7-bit | |
| PtrArrayAdd | Wrapper to add an item to a array of pointer dynamic array storage | |
| PtrArrayAdd | Wrapper to add an item to a array of pointer dynamic array storage | |
| PtrArrayAddOnce | Wrapper to add once an item to a array of pointer dynamic array storage | |
| PtrArrayAddOnce | Wrapper to add once an item to a array of pointer dynamic array storage | |
| PtrArrayDelete | Wrapper to delete an item from a array of pointer dynamic array storage | |
| PtrArrayDelete | Wrapper to delete an item from a array of pointer dynamic array storage | |
| PtrArrayFind | Wrapper to find an item to a array of pointer dynamic array storage | |
| PtrArrayInsert | Wrapper to insert an item to a array of pointer dynamic array storage | |
| PtrUIntScan | Fast search of a pointer-sized unsigned integer in an pointer-sized integer array | |
| PtrUIntScanExists | Fast search of a pointer-sized unsigned integer position in an pointer-sized integer array | |
| PtrUIntScanIndex | Fast search of a pointer-sized unsigned integer position in an pointer-sized integer array | |
| QuickSortDouble | Sort a double array, low values first | |
| QuickSortInt64 | Sort a 64-bit integer array, low values first | |
| QuickSortInt64 | Sort a 64-bit signed integer array, low values first | |
| QuickSortInteger | Sort an integer array, low values first | |
| QuickSortInteger | Sort an integer array, low values first | |
| QuickSortInteger | Sort an integer array, low values first | |
| QuickSortPointer | Sort a pointer array, low values first | |
| QuickSortPtrInt | Sort a PtrInt array, low values first | |
| QuickSortQWord | Sort a 64-bit unsigned integer array, low values first | |
| QuickSortWord | Sort a 16-bit unsigned integer array, low values first | |
| QWordScanIndex | Fast search of an integer position in an unsigned 64-bit integer array | |
| RaiseStreamError | Raise a EStreamError exception - e.g. from TSynMemoryStream.Write | |
| Random31 | Fast compute of some 31-bit random value, using the gsl_rng_taus2 generator | |
| Random31Not0 | Compute of a 31-bit random value <> 0, using the gsl_rng_taus2 generator | |
| Random32 | Fast compute of some 32-bit random value, using the gsl_rng_taus2 generator | |
| Random32 | Fast compute of bounded 32-bit random value, using the gsl_rng_taus2 generator | |
| Random32Seed | Seed the thread-specific gsl_rng_taus2 Random32 generator | |
| Random64 | Fast compute of a 64-bit random value, using the gsl_rng_taus2 generator | |
| RandomBytes | Fill a memory buffer with random bytes from the gsl_rng_taus2 generator | |
| RandomDouble | Fast compute of a 64-bit random floating point, using the gsl_rng_taus2 generator | |
| RandomGuid | Compute a random UUid value from the RandomBytes() generator and RFC 4122 | |
| RandomGuid | Compute a random UUid value from the RandomBytes() generator and RFC 4122 | |
| RandomShort31 | Fill some string[31] with 7-bit ASCII random text | |
| RawByteStringToVariant | Convert a RawByteString content into a variant varString | |
| RawByteStringToVariant | Convert a raw binary buffer into a variant RawByteString varString | |
| RawObjectsClear | Low-level function calling FreeAndNil(o^) successively n times | |
| RawUtf8ToVariant | Convert an UTF-8 encoded string into a variant RawUtf8 varString | |
| RawUtf8ToVariant | Convert an UTF-8 encoded string into a variant RawUtf8 varString | |
| RawUtf8ToVariant | Convert an UTF-8 encoded text buffer into a variant RawUtf8 varString | |
| Rcu | Thread-safe move of a memory buffer using a simple Read-Copy-Update pattern | |
| Rcu128 | Thread-safe move of a 128-bit value using a simple Read-Copy-Update pattern | |
| Rcu32 | Thread-safe move of a 32-bit value using a simple Read-Copy-Update pattern | |
| Rcu64 | Thread-safe move of a 64-bit value using a simple Read-Copy-Update pattern | |
| RcuPtr | Thread-safe move of a pointer value using a simple Read-Copy-Update pattern | |
| RdRand32 | Compute 32-bit random number generated by modern Intel CPU hardware | |
| RdRand32 | XOR a memory buffer with some random generated by modern Intel CPU | |
| Rdtsc | Returns the 64-bit Intel Time Stamp Counter (TSC) | |
| ReadBarrier | This function is an intrinsic in FPC | |
| RleCompress | Simple Run-Length-Encoding compression of a memory buffer | |
| RleUnCompress | Simple Run-Length-Encoding uncompression of a memory buffer | |
| RleUnCompressPartial | Partial Run-Length-Encoding uncompression of a memory buffer | |
| SameValue | Compare to floating point values, with IEEE 754 double precision | |
| SameValueFloat | Compare to floating point values, with IEEE 754 double precision | |
| SetBit | Set a particular bit into a bit array | |
| SetBit64 | Set a particular bit into a 64-bit integer bits (max aIndex is 63) | |
| SetBitPtr | Set a particular bit into a bit array | |
| SetInt64 | Get the 64-bit signed integer value stored in P^ | |
| SetQWord | Get the 64-bit unsigned integer value stored in P^ | |
| SetQWord | Get the 64-bit unsigned integer value stored in P^ | |
| SetVariantNull | Same as Value := Null, but slightly faster | |
| SetVariantUnRefSimpleValue | Same as Dest := TVarData(Source) for simple values | |
| ShortStringToAnsi7String | Direct conversion of an ANSI-7 ShortString into an AnsiString | |
| ShortStringToAnsi7String | Direct conversion of an ANSI-7 ShortString into an AnsiString | |
| SimpleRoundTo2Digits | No banker rounding into two digits after the decimal point | |
| SimpleRoundTo2DigitsCurr64 | Simple, no banker rounding of a Currency value, stored as Int64, to only 2 digits | |
| SortDynArray128 | Compare two "array of THash128" 128-bit elements | |
| SortDynArray256 | Compare two "array of THash256" 256-bit elements | |
| SortDynArray512 | Compare two "array of THash512" 512-bit elements | |
| SortDynArrayAnsiString | Compare two "array of AnsiString" elements, with case sensitivity | |
| SortDynArrayBoolean | Compare two "array of boolean" 8-bit elements | |
| SortDynArrayByte | Compare two "array of byte" 8-bit elements | |
| SortDynArrayCardinal | Compare two "array of cardinal" 32-bit elements | |
| SortDynArrayDouble | Compare two "array of double" 64-bit elements | |
| SortDynArrayExtended | Compare two "array of TSynExtended" 64/80-bit elements | |
| SortDynArrayInt64 | Compare two "array of Int64" or "array of Currency" 64-bit elements | |
| SortDynArrayInteger | Compare two "array of integer" 32-bit elements | |
| SortDynArrayPointer | Compare two "array of TObject/pointer" elements | |
| SortDynArrayPUtf8Char | Compare two "array of PUtf8Char/PAnsiChar" elements, with case sensitivity | |
| SortDynArrayQWord | Compare two "array of QWord" 64-bit elements | |
| SortDynArrayShortint | Compare two "array of shortint" 8-bit elements | |
| SortDynArrayShortString | Compare two "array of shortstring" elements, with case sensitivity | |
| SortDynArraySingle | Compare two "array of single" 32-bit elements | |
| SortDynArraySmallint | Compare two "array of smallint" 16-bit elements | |
| SortDynArrayString | Compare two "array of RTL string" elements, with case sensitivity | |
| SortDynArrayUnicodeString | Compare two "array of WideString/UnicodeString" elements, with case sensitivity | |
| SortDynArrayVariant | Compare two "array of variant" elements, with case sensitivity | |
| SortDynArrayVariantI | Compare two "array of variant" elements, with no case sensitivity | |
| SortDynArrayWord | Compare two "array of word" 16-bit elements | |
| SortMatch | Fast search if a comparison function result (<0,0,>0) match an operator | |
| Split | Returns the left part of a RawUtf8 string, according to SepStr separator | |
| StrCntAdd | Low-level string reference counter process | |
| StrCntDecFree | Low-level string reference counter unprocess | |
| StrComp | Buffer-overflow safe version of StrComp(), to be used with PUtf8Char/PAnsiChar | |
| StrCompW | Our fast version of StrComp(), to be used with PWideChar | |
| StrInt32 | Internal fast integer val to text conversion | |
| StrInt64 | Internal fast Int64 val to text conversion | |
| StrLenSafe | Simple version of StrLen(), but which will never read beyond the string | |
| StrLenW | Our fast version of StrLen(), to be used with PWideChar | |
| StrUInt32 | Internal fast unsigned integer val to text conversion | |
| StrUInt64 | Internal fast unsigned Int64 val to text conversion | |
| SynLZcompress1 | Raw SynLZ compression algorithm | |
| SynLZcompress1pas | Raw SynLZ compression algorithm implemented in pascal | |
| SynLZcompressdestlen | Get maximum possible (worse) SynLZ compressed size | |
| SynLZdecompress1 | Raw SynLZ decompression algorithm | |
| SynLZdecompress1partial | SynLZ decompression algorithm with memory boundaries check | |
| SynLZdecompress1pas | Raw SynLZ decompression algorithm implemented in pascal | |
| SynLZdecompressdestlen | Get exact uncompressed size from SynLZ-compressed buffer (to reserve memory, e.g.) | |
| TInt64DynArrayFrom | Quick helper to initialize a dynamic array of 64-bit integers from 32-bit values | |
| TIntegerDynArrayFrom | Quick helper to initialize a dynamic array of integer from some constants | |
| TIntegerDynArrayFrom64 | Quick helper to initialize a dynamic array of integer from 64-bit integers | |
| ToCardinal | Get the unsigned 32-bit cardinal value stored in a RawUtf8 string | |
| ToDouble | Get a 64-bit floating-point value stored in a RawUtf8 string | |
| ToHumanHex | Convert a binary into its human-friendly per-byte hexadecimal lowercase text | |
| ToHumanHexReverse | Convert a binary into its human-friendly hexadecimal in reverse order | |
| ToInt64 | Get the signed 64-bit integer value stored in a RawUtf8 string | |
| ToInteger | Get the signed 32-bit integer value stored in a RawUtf8 string | |
| ToText | Just a wrapper around ClassToText() to avoid a string conversion | |
| TQWordDynArrayFrom | Quick helper to initialize a dynamic array of 64-bit integers from 32-bit values | |
| Trim | Fast dedicated RawUtf8 version of Trim() | |
| TrimCopy | Single-allocation (therefore faster) alternative to Trim(copy()) | |
| TrimSelf | Fast dedicated RawUtf8 version of s := Trim(s) | |
| TrimU | Fast dedicated RawUtf8 version of Trim() | |
| TruncTo2Digits | Truncate a currency value to only 2 digits | |
| TruncTo2Digits64 | Truncate a Currency value, stored as Int64, to only 2 digits | |
| TruncTo2DigitsCurr64 | Truncate a currency value, stored as Int64, to only 2 digits | |
| TwoDigits | No banker rounding into text, with two digits after the decimal point | |
| UniqueRawUtf8 | Equivalence to @u[1] expression to ensure a RawUtf8 variable is unique | |
| UnSetBit | Unset/clear a particular bit into a bit array | |
| UnSetBit64 | Unset/clear a particular bit into a 64-bit integer bits (max aIndex is 63) | |
| UnSetBitPtr | Unset/clear a particular bit into a bit array | |
| Utf8ToInt64 | Get the signed 64-bit integer value stored in a RawUtf8 string | |
| Utf8ToInteger | Get the signed 32-bit integer value stored in a RawUtf8 string | |
| Utf8ToInteger | Get and check range of a signed 32-bit integer stored in a RawUtf8 string | |
| VarClearAndSetType | Overloaded function which can be properly inlined to clear a variant | |
| VarDataFromVariant | Get the root PVarData of a variant, redirecting any varByRef | |
| VarDataIsEmptyOrNull | Same as VarIsEmpty(PVariant(V)^) or VarIsNull(PVariant(V)^), but faster | |
| VariantCompSimple | Basic default case-sensitive variant comparison function | |
| VariantStringToUtf8 | Convert Variant string values into RawUtf8 encoded String | |
| VariantStringToUtf8 | Convert a Variant varString value into RawUtf8 encoded String | |
| VariantToBoolean | Convert any numerical Variant into a boolean value | |
| VariantToCurrency | Convert any numerical Variant into a fixed decimals floating point value | |
| VariantToDouble | Convert any numerical Variant into a floating point value | |
| VariantToDoubleDef | Convert any numerical Variant into a floating point value | |
| VariantToInt64 | Convert any numerical Variant into a 64-bit integer | |
| VariantToInt64Def | Convert any numerical Variant into a 64-bit integer | |
| VariantToInteger | Convert any numerical Variant into a 32-bit integer | |
| VariantToIntegerDef | Convert any numerical Variant into an integer | |
| VariantToRawByteString | Convert back a RawByteString from a variant | |
| VarIsEmptyOrNull | Same as VarIsEmpty(V) or VarIsNull(V), but faster | |
| WordScanIndex | Fast search of an unsigned Word value position in a Word array | |
| XorEntropy | Retrieve 512-bit of entropy, from system time and current execution state | |
| XorMemory | Logical XOR of two memory buffers into a third | |
| XorMemory | Logical XOR of two memory buffers | |
| xxHash32 | Perform very fast xxHash hashing in 32-bit mode | |
| xxHash32Mixup | Shuffle a 32-bit value using the last stage of xxHash32 algorithm | |
| YearToPChar | Add the 4 digits of integer Y to P^ as '0000'..'9999' |
function AddGuid(var guids: TGuidDynArray; const guid: TGuid; NoDuplicates: boolean = false): integer;
Append one TGuid item to a TGuid dynamic array
- returning the newly inserted index in guids[], or an existing index in guids[] if NoDuplicates is TRUE and TGuid already exists
function AddHash128(var Arr: THash128DynArray; const V: THash128; var Count: integer): PtrInt;
Add a 128-bit item in an array of such values
function AddInt64(var Values: TInt64DynArray; const Another: TInt64DynArray): PtrInt; overload;
Add a 64-bit integer array at the end of a dynamic array
function AddInt64(var Values: TInt64DynArray; var ValuesCount: integer; Value: Int64): PtrInt; overload;
Add a 64-bit integer value at the end of a dynamic array of integers
function AddInt64(var Values: TInt64DynArray; Value: Int64): PtrInt; overload;
Add a 64-bit integer value at the end of a dynamic array
function AddInt64Once(var Values: TInt64DynArray; Value: Int64): PtrInt;
If not already existing, add a 64-bit integer value to a dynamic array
procedure AddInt64Sorted(var Values: TInt64DynArray; Value: Int64);
If not already existing, add a 64-bit integer value to a sorted dynamic array
function AddInteger(var Values: TIntegerDynArray; Value: integer; NoDuplicates: boolean = false): boolean; overload;
Add an integer value at the end of a dynamic array of integers
- returns TRUE if Value was added successfully in Values[], in this case length(Values) will be increased
function AddInteger(var Values: TIntegerDynArray; var ValuesCount: integer; Value: integer; NoDuplicates: boolean): boolean; overload;
Add an integer value at the end of a dynamic array of integers
- this overloaded function will use a separate Count variable (faster), and would allow to search for duplicates
- returns TRUE if Value was added successfully in Values[], in this case ValuesCount will be increased, but length(Values) would stay fixed most of the time (since it stores the Values[] array capacity)
function AddInteger(var Values: TIntegerDynArray; const Another: TIntegerDynArray): PtrInt; overload;
Add an integer array at the end of a dynamic array of integer
procedure AddInteger(var Values: TIntegerDynArray; var ValuesCount: integer; Value: integer); overload;
Add an integer value at the end of a dynamic array of integers
- this overloaded function will use a separate Count variable (faster)
- it won't search for any existing duplicate
function AddPtrUInt(var Values: TPtrUIntDynArray; var ValuesCount: integer; Value: PtrUInt): PtrInt;
Add a pointer-sized integer array at the end of a dynamic array
function AddSortedInteger(var Values: TIntegerDynArray; Value: integer; CoValues: PIntegerDynArray = nil): PtrInt; overload;
Add an integer value in a sorted dynamic array of integers
- overloaded function which do not expect an external Count variable
function AddSortedInteger(var Values: TIntegerDynArray; var ValuesCount: integer; Value: integer; CoValues: PIntegerDynArray = nil): PtrInt; overload;
Add an integer value in a sorted dynamic array of integers
- returns the index where the Value was added successfully in Values[]
- returns -(foundindex+1) i.e. <0 if the specified Value was already present
- if CoValues is set, its content will be moved to allow inserting a new value at CoValues[result] position
function AddWord(var Values: TWordDynArray; var ValuesCount: integer; Value: Word): PtrInt;
Add a 16-bit integer value at the end of a dynamic array of integers
procedure AndMemory(Dest, Source: PByteArray; size: PtrInt);
Logical AND of two memory buffers
- will perform on all buffer bytes:
Dest[i] := Dest[i] and Source[i];
procedure Ansi7StringToShortString(const source: RawUtf8; var result: ShortString);
Direct conversion of an ANSI-7 AnsiString into an ShortString
- can be used e.g. for names retrieved from RTTI
procedure AppendShort(const src: ShortString; var dest: ShortString);
Simple concatenation of a ShortString text into a shorstring
procedure AppendShortAnsi7String(const buf: RawByteString; var dest: ShortString);
Simple concatenation of an ANSI-7 AnsiString into a shorstring
- if Len is < 0, will use StrLen(buf)
procedure AppendShortBuffer(buf: PAnsiChar; len: integer; var dest: ShortString);
Simple concatenation of a #0 ending text into a shorstring
- if Len is < 0, will use StrLen(buf)
procedure AppendShortByteHex(value: byte; var dest: ShortString);
Simple concatenation of a byte as hexadecimal into a shorstring
procedure AppendShortCardinal(value: cardinal; var dest: ShortString);
Simple concatenation of a 32-bit unsigned integer as text into a shorstring
procedure AppendShortChar(chr: AnsiChar; var dest: ShortString);
Simple concatenation of a character into a shorstring
procedure AppendShortInt64(value: Int64; var dest: ShortString);
Simple concatenation of a 64-bit integer as text into a shorstring
function BitsToBytes(bits: byte): byte;
Compute how many bytes are needed to store a given number of bits
- e.g. 0 returns 0, 1..8 returns 1, 9..16 returns 2, and so on
function BSRdword(c: cardinal): cardinal;
Return the position of the leftmost set bit in a 32-bit value
- returns 255 if c equals 0
- this function is an intrinsic on FPC
function BSRqword(const q: Qword): cardinal;
Return the position of the leftmost set bit in a 64-bit value
- returns 255 if q equals 0
- this function is an intrinsic on FPC
function bswap32(a: cardinal): cardinal;
Convert the endianness of a given unsigned 32-bit integer into BigEndian
function bswap64(const a: QWord): QWord;
Convert the endianness of a given unsigned 64-bit integer into BigEndian
procedure bswap64array(a, b: PQWordArray; n: PtrInt);
Convert the endianness of an array of unsigned 64-bit integer into BigEndian
- n is required to be > 0
- warning: on x86, a should be <> b
function BufferLineLength(Text, TextEnd: PUtf8Char): PtrInt;
Compute the line length from a size-delimited source array of chars
- will use fast SSE2 assembly on x86-64 CPU
- is likely to read some bytes after the TextEnd buffer, so GetLineSize() from mormot.core.text may be preferred, e.g. on memory mapped files
- expects Text and TextEnd to be not nil - see GetLineSize() instead
function ByteScanIndex(P: PByteArray; Count: PtrInt; Value: byte): PtrInt;
Fast search of an unsigned byte value position in a byte array
- Count is the number of byte entries in P^
- return index of P^[index]=Value, -1 if Value was not found
- is implemented with SSE2 asm on i386 and x86_64
function ClassNameShort(Instance: TObject): PShortString; overload;
Just a wrapper around vmtClassName to avoid a string conversion
function ClassNameShort(C: TClass): PShortString; overload;
Just a wrapper around vmtClassName to avoid a string conversion
procedure ClassToText(C: TClass; var result: RawUtf8);
Just a wrapper around vmtClassName to avoid a string conversion
procedure ClearVariantForString(var Value: variant);
Internal efficient wrapper of VarClear() + set VType=varString and VAny=nil
- used e.g. by RawUtf8ToVariant() functions
- could also be used as a faster alternative to Value := ''
function CompareBuf(const P1, P2: RawByteString): integer; overload;
Overload wrapper to SortDynArrayRawByteString(P1, P2)
- won't involve any code page - so may be safer e.g. on FPC
function CompareBuf(const P1: RawByteString; P2: pointer; P2Len: PtrInt): integer; overload;
Overload wrapper of MemCmp() to compare a RawByteString vs a memory buffer
- will first check length(P1)=P2Len then call MemCmp()
function CompareCardinal(const A, B: cardinal): integer;
A comparison function for sorting 32-bit unsigned integer values
function CompareFloat(const A, B: double): integer;
A comparison function for sorting IEEE 754 double precision values
function CompareInt64(const A, B: Int64): integer;
A comparison function for sorting 64-bit signed integer values
function CompareInteger(const A, B: integer): integer;
A comparison function for sorting 32-bit signed integer values
function CompareMem(P1, P2: pointer; Length: PtrInt): boolean;
Our fast version of CompareMem()
- tuned asm for x86, call MemCmpSse2 for x64, or fallback to tuned pascal
function CompareMemSmall(P1, P2: pointer; Length: PtrInt): boolean;
A CompareMem()-like function designed for small (a few bytes) content
- to be efficiently inlined in processing code
function ComparePointer(const A, B: pointer): integer;
A comparison function for sorting 32/64-bit pointers as unsigned values
function ComparePtrInt(const A, B: PtrInt): integer;
A comparison function for sorting 32/64-bit signed integer values
function CompareQWord(const A, B: QWord): integer;
A comparison function for sorting 64-bit unsigned integer values
- note that QWord(A)>QWord(B) is wrong on older versions of Delphi, so you should better use this function or SortDynArrayQWord() to properly compare two QWord values over CPUX86 on Delphi 7-2007
function CompressSynLZ(var Data: RawByteString; Compress: boolean): RawUtf8;
Compress a data content using the SynLZ algorithm
- as expected by THttpSocket.RegisterCompress
- will return 'synlz' as ACCEPT-ENCODING: header parameter
- will store a hash of both compressed and uncompressed stream: if the data is corrupted during transmission, will instantly return ''
function CompressSynLZGetHash32(const Data: RawByteString): cardinal;
Return the Hash32() 32-bit CRC of CompressSynLZ() uncompressed data
- will first check the CRC of the supplied compressed Data
- returns 0 if the CRC of the compressed Data is not correct
procedure crc128c(buf: PAnsiChar; len: cardinal; out crc: THash128);
Compute a 128-bit checksum on the supplied buffer, cascading two crc32c
- will use SSE 4.2 or ARMv8 hardware accelerated instruction, if available
- will combine two crc32c() calls into a single TAesBlock result
- by design, such combined hashes cannot be cascaded
function crc16(Data: PAnsiChar; Len: integer): cardinal;
Compute CRC16-CCITT checkum on the supplied buffer
- i.e. 16-bit CRC-CCITT, with polynomial x^16 + x^12 + x^5 + 1 ($1021) and $ffff as initial value
- this version is not optimized for speed, but for correctness
procedure crc256c(buf: PAnsiChar; len: cardinal; out crc: THash256);
Compute a 256-bit checksum on the supplied buffer using crc32c
- will use SSE 4.2 or ARMv8 hardware accelerated instruction, if available
- will combine two crc32c() calls into a single THash256 result
- by design, such combined hashes cannot be cascaded
procedure crc32c128(hash: PHash128; buf: PAnsiChar; len: cardinal);
Compute a 128-bit CRC of any binary buffers
- combine crcblocks() with 4 parallel crc32c() for 1..15 trailing bytes
function crc32cBy4fast(crc, value: cardinal): cardinal;
Pure pascal function implementing crc32cBy4()
function crc32cfast(crc: cardinal; buf: PAnsiChar; len: cardinal): cardinal;
Compute CRC32C checksum on the supplied buffer on processor-neutral code
- result is compatible with SSE 4.2 based hardware accelerated instruction
- will use fast x86/x64 asm or efficient pure pascal implementation on ARM
- result is not compatible with zlib's crc32() - not the same polynom
- crc32cfast() is 1.7 GB/s, crc32csse42() is 4.3 GB/s
- you should use crc32c() function instead of crc32cfast() or crc32csse42()
function crc32cHash(const s: RawByteString): cardinal; overload;
Compute a 32-bit hash of any string using the CRC32C checksum
- the returned hash value will be stable on all platforms, and use HW opcodes if available on the current CPU
function crc32cHash(const b: TBytes): cardinal; overload;
Compute a 32-bit hash of any array of bytes using the CRC32C checksum
- the returned hash value will be stable on all platforms, and use HW opcodes if available on the current CPU
function crc32cinlined(crc: cardinal; buf: PAnsiChar; len: cardinal): cardinal;
Compute CRC32C checksum on the supplied buffer using inlined code
- if the compiler supports inlining, will compute a slow but safe crc32c checksum of the binary buffer, without calling the main crc32c() function
- may be used e.g. to identify patched executable at runtime, for a licensing protection system, or if you don't want to pollute the CPU L1 cache with crc32cfast() bigger lookup tables
function crc32csse42(crc: cardinal; buf: PAnsiChar; len: cardinal): cardinal;
Defined here for mormot.test.base only
- use instead global crc32c() variable
function crc32ctwice(seed: QWord; buf: PAnsiChar; len: cardinal): QWord;
Expand a CRC32C checksum on the supplied buffer for 64-bit hashing
- will use SSE 4.2 or ARMv8 hardware accelerated instruction, if available
- is the default implementation of DefaultHasher64
function crc32fast(crc: cardinal; buf: PAnsiChar; len: cardinal): cardinal;
Compute CRC32 checksum on the supplied buffer on processor-neutral code
- result is compatible with zlib's crc32() but not with crc32c/crc32cfast()
function crc63c(buf: PAnsiChar; len: cardinal): Int64;
Compute CRC63C checksum on the supplied buffer, cascading two crc32c
- similar to crc64c, but with 63-bit, so no negative value: may be used safely e.g. as mORMot's TID source
- will use SSE 4.2 or ARMv8 hardware accelerated instruction, if available
- will combine two crc32c() calls into an unsigned 63-bit Int64 result
- by design, such combined hashes cannot be cascaded
function crc64c(buf: PAnsiChar; len: cardinal): Int64;
Compute CRC64C checksum on the supplied buffer, cascading two crc32c
- will use SSE 4.2 or ARMv8 hardware accelerated instruction, if available
- will combine two crc32c() calls into a single Int64 result
- by design, such combined hashes cannot be cascaded
procedure crcblockfast(crc128, data128: PBlock128);
Computation of our 128-bit CRC of a 128-bit binary buffer without SSE4.2
- to be used for regression tests only: crcblock will use the fastest implementation available on the current CPU (e.g. with SSE 4.2 or ARMv8)
procedure crcblocksfast(crc128, data128: PBlock128; count: integer);
Compute a proprietary 128-bit CRC of 128-bit binary buffers
- to be used for regression tests only: crcblocks will use the fastest implementation available on the current CPU (e.g. with SSE 4.2 or ARMv8)
procedure CurrencyToDouble(const c: currency; out d: double); overload;
Convert a currency value into a double
- using PInt64() division by CURR_RES (=10000)
- warning: FPC Win64 to Win32 cross-compiler doesn't support currency values properly -> use FPC Win32 compiler only on Windows
procedure CurrencyToDouble(c: PCurrency; out d: double); overload;
Convert a currency value pointer into a double
- using PInt64() division by CURR_RES (=10000)
- warning: FPC Win64 to Win32 cross-compiler doesn't support currency values properly -> use FPC Win32 compiler only on Windows
function CurrencyToDouble(c: PCurrency): double; overload;
Convert a currency value pointer into a double
- using PInt64() division by CURR_RES (=10000)
- warning: FPC Win64 to Win32 cross-compiler doesn't support currency values properly -> use FPC Win32 compiler only on Windows
procedure CurrencyToInt64(c: PCurrency; var i: Int64); overload;
Convert a currency value into a Int64
- using PInt64() division by CURR_RES (=10000)
- warning: FPC Win64 to Win32 cross-compiler doesn't support currency values properly -> use FPC Win32 compiler only on Windows
procedure CurrencyToVariant(const c: currency; var v: variant);
Fill a variant value from a currency value
- as compatible with VariantToCurrency/VariantToDouble
- warning: FPC Win64 to Win32 cross-compiler doesn't support currency values properly -> use FPC Win32 compiler only on Windows
procedure DACntAdd(var refcnt: TDACnt; increment: TDACnt);
Low-level dynarray reference counter process
function DACntDecFree(var refcnt: TDACnt): boolean;
Low-level dynarray reference counter unprocess
- caller should have tested that refcnt>=0
function DateTimeToIsoString(dt: TDateTime): string;
Use the RTL to return a date/time as ISO-8601 text
- slow function, here to avoid linking mormot.core.datetime
function DefaultHash(const b: TBytes): cardinal; overload;
Compute a 32-bit hash of any array of bytes using DefaultHasher()
- so the hash value may change on another computer or after program restart
function DefaultHash(const s: RawByteString): cardinal; overload;
Compute a 32-bit hash of any string using DefaultHasher()
- so the hash value may change on another computer or after program restart
procedure DeleteInt64(var Values: TInt64DynArray; var ValuesCount: integer; Index: PtrInt); overload;
Delete any 64-bit integer in Values[]
procedure DeleteInt64(var Values: TInt64DynArray; Index: PtrInt); overload;
Delete any 64-bit integer in Values[]
procedure DeleteInteger(var Values: TIntegerDynArray; var ValuesCount: integer; Index: PtrInt); overload;
Delete any 32-bit integer in Values[]
procedure DeleteInteger(var Values: TIntegerDynArray; Index: PtrInt); overload;
Delete any 32-bit integer in Values[]
procedure DeleteWord(var Values: TWordDynArray; Index: PtrInt);
Delete any 16-bit integer in Values[]
procedure Div100(Y: cardinal; var res: TDiv100Rec);
Simple wrapper to efficiently compute both division and modulo per 100
- compute result.D = Y div 100 and result.M = Y mod 100
- under FPC, will use fast multiplication by reciprocal so can be inlined
- under Delphi, we use our own optimized asm version (which can't be inlined)
procedure DoubleToCurrency(const d: double; c: PCurrency); overload;
Convert a double value into a currency
- using truncated multiplication by CURR_RES (=10000)
- warning: FPC Win64 to Win32 cross-compiler doesn't support currency values properly -> use FPC Win32 compiler only on Windows
procedure DoubleToCurrency(const d: double; out c: currency); overload;
Convert a double value into a currency
- using truncated multiplication by CURR_RES (=10000)
- warning: FPC Win64 to Win32 cross-compiler doesn't support currency values properly -> use FPC Win32 compiler only on Windows
function DoubleToCurrency(const d: double): currency; overload;
Convert a double value into a currency
- using truncated multiplication by CURR_RES (=10000)
- warning: FPC Win64 to Win32 cross-compiler doesn't support currency values properly -> use FPC Win32 compiler only on Windows
procedure DynArrayFakeLength(arr: pointer; len: TDALen);
Like SetLength() but without any memory resize - WARNING: len should be > 0
procedure DynArrayHashTableAdjust(P: PIntegerArray; deleted: integer; count: PtrInt);
Internal hash table adjustment as called from TDynArrayHasher.HashDelete
- decrement any integer greater or equal to a deleted value
- brute force O(n) indexes fix after deletion (much faster than full ReHash)
- we offer very optimized SSE2 and AVX2 versions on x86_64 - therefore is defined in this unit to put this asm code in mormot.core.base.asmx64.inc
procedure DynArrayHashTableAdjust16(P: PWordArray; deleted: cardinal; count: PtrInt);
DynArrayHashTableAdjust() version for 16-bit HashTable[] - SSE2 asm on x86_64
procedure EnsureRawUtf8(var s: RawByteString); overload;
Ensure the supplied variable will have a CP_UTF8 - making it unique if needed
procedure EnsureRawUtf8(var s: RawUtf8); overload;
Ensure the supplied variable will have a CP_UTF8 - making it unique if needed
function EqualBuf(const P1, P2: RawByteString): boolean; overload;
Overload wrapper to SortDynArrayRawByteString(P1, P2) = 0
- won't involve any code page - so may be safer e.g. on FPC
function EventEquals(const eventA, eventB): boolean;
Compare two TMethod instances
procedure Exchg(P1, P2: PAnsiChar; count: PtrInt);
Low-level inlined function for exchanging two memory buffers
- used e.g. during sorting process
procedure ExchgPointer(n1, n2: PPointer);
Low-level inlined function for exchanging two pointers
- used e.g. during sorting process
procedure ExchgPointers(n1, n2: PPointer; count: PtrInt);
Low-level inlined function for exchanging two sets of pointers
- used e.g. during sorting process
procedure ExchgVariant(v1, v2: PPtrIntArray);
Low-level inlined function for exchanging two variants
- used e.g. during sorting process
procedure FakeCodePage(var s: RawByteString; cp: cardinal);
Internal function which could be used instead of SetCodePage() if RefCnt = 1
- do nothing if HASCODEPAGE is not defined, e.g. on Delphi 7-2007
- warning: s should NOT be read-only (i.e. assigned from a constant), but a just-allocated string with RefCnt <> -1
procedure FakeLength(var s: RawUtf8; endChar: PUtf8Char); overload;
Internal function which could be used instead of SetLength() if RefCnt = 1
procedure FakeLength(var s: RawUtf8; len: PtrInt); overload;
Internal function which could be used instead of SetLength() if RefCnt = 1
procedure FakeLength(var s: RawByteString; len: PtrInt); overload;
Internal function which could be used instead of SetLength() if RefCnt = 1
procedure FakeSetLength(var s: RawUtf8; len: PtrInt); overload;
Internal function which could be used instead of SetLength() if RefCnt = 1
- FakeLength() don't handle len = 0, whereas this function will
procedure FakeSetLength(var s: RawByteString; len: PtrInt); overload;
Internal function which could be used instead of SetLength() if RefCnt = 1
- FakeLength() don't handle len = 0, whereas this function will
procedure FastAssignNew(var d; s: pointer = nil);
Assign any constant or already ref-counted AnsiString/RawUtf8
- by default, called with s = nil, is an equivalence to Finalize(d) or d := ''
- is also called by FastSetString/FastSetStringCP to setup its allocated value
- faster especially under FPC
procedure FastAssignNewNotVoid(var d; s: pointer); overload;
Internal function to assign any constant or ref-counted AnsiString/RawUtf8
- caller should have tested that pointer(d) <> nil
procedure FastAssignUtf8(var dest: RawUtf8; var src: RawByteString);
Internal function which assign src to dest, force CP_UTF8 and set src to ''
- warning: calls FakeCodePage(CP_UTF8) so requires src to have a RefCnt of 1
function FastFindInt64Sorted(P: PInt64Array; R: PtrInt; const Value: Int64): PtrInt; overload;
Fast O(log(n)) binary search of a 64-bit signed integer value in a sorted array
- R is the last index of available integer entries in P^ (i.e. Count-1)
- return index of P^[result]=Value
- return -1 if Value was not found
- use branchless asm on x86_64
function FastFindIntegerSorted(const Values: TIntegerDynArray; Value: integer): PtrInt; overload;
Fast O(log(n)) binary search of an integer value in a sorted integer array
- return index of Values[result]=Value
- return -1 if Value was not found
function FastFindIntegerSorted(P: PIntegerArray; R: PtrInt; Value: integer): PtrInt; overload;
Fast O(log(n)) binary search of an integer value in a sorted integer array
- R is the last index of available integer entries in P^ (i.e. Count-1)
- return index of P^[result]=Value
- return -1 if Value was not found
- use branchless asm on x86_64
function FastFindPointerSorted(P: PPointerArray; R: PtrInt; Value: pointer): PtrInt; overload;
Fast O(log(n)) binary search of a pointer value in a sorted array
function FastFindPtrIntSorted(P: PPtrIntArray; R: PtrInt; Value: PtrInt): PtrInt; overload;
Fast O(log(n)) binary search of a PtrInt value in a sorted array
function FastFindQWordSorted(P: PQWordArray; R: PtrInt; const Value: QWord): PtrInt; overload;
Fast O(log(n)) binary search of a 64-bit unsigned integer value in a sorted array
- R is the last index of available integer entries in P^ (i.e. Count-1)
- return index of P^[result]=Value
- return -1 if Value was not found
- QWord comparison are implemented correctly under FPC or Delphi 2009+ - older compilers will fast and exact SortDynArrayQWord()
function FastFindWordSorted(P: PWordArray; R: PtrInt; Value: Word): PtrInt;
Fast O(log(n)) binary search of a 16-bit unsigned integer value in a sorted array
- use branchless asm on x86_64
function FastLocateIntegerSorted(P: PIntegerArray; R: PtrInt; Value: integer): PtrInt;
Retrieve the index where to insert an integer value in a sorted integer array
- R is the last index of available integer entries in P^ (i.e. Count-1)
- returns -(foundindex+1) i.e. <0 if the specified Value was found
function FastLocateWordSorted(P: PWordArray; R: integer; Value: word): PtrInt;
Retrieve the index where to insert a word value in a sorted word array
- R is the last index of available integer entries in P^ (i.e. Count-1)
- returns -(foundindex+1) i.e. <0 if the specified Value was found
procedure FastNewRawByteString(var s: RawByteString; len: PtrInt);
Equivalence to SetString(s,nil,len) function to allocate a new RawByteString
- faster especially under FPC
function FastNewString(len, codepage: PtrInt): PAnsiChar;
Internal function used by FastSetString/FastSetStringCP
function FastSearchIntegerSorted(P: PIntegerArray; R: PtrInt; Value: integer): PtrInt;
Retrieve the matching index or where to insert an integer value
procedure FastSetRawByteString(var s: RawByteString; p: pointer; len: PtrInt);
Equivalence to SetString(s,pansichar,len) function but from a raw pointer
- so works with both PAnsiChar and PUtf8Char input buffer (or even PByteArray)
- faster especially under FPC
procedure FastSetString(var s: RawUtf8; len: PtrInt); overload;
Faster equivalence to SetString(s,nil,len) function
procedure FastSetString(var s: RawUtf8; p: pointer; len: PtrInt); overload;
Equivalence to SetString(s,pansichar,len) function but from a raw pointer
- so works with both PAnsiChar and PUtf8Char input buffer (or even PByteArray)
- faster especially under FPC
procedure FastSetStringCP(var s; p: pointer; len, codepage: PtrInt);
Equivalence to SetString(s,pansichar,len) function with a specific code page
- faster especially under FPC
procedure FillAnsiStringFromRandom(dest: PByteArray; size: PtrUInt);
Internal function used e.g. by TLecuyer.FillShort/FillShort31
procedure FillcharFast(var dst; cnt: PtrInt; value: byte);
Our fast version of FillChar() on Intel/AMD
- on Intel i386/x86_64, will use fast SSE2/AVX instructions (if available)
- on non-Intel CPUs, it will fallback to the default RTL FillChar()
- note: Delphi RTL is far from efficient: on i386 the FPU is slower/unsafe, and on x86_64, ERMS is wrongly used even for small blocks
- on ARM/AARCH64 POSIX, mormot.core.os would redirect to optimized libc
procedure FillIncreasing(Values: PIntegerArray; StartValue: integer; Count: PtrUInt);
Fill some values with i,i+1,i+2...i+Count-1
procedure FillRandom(Dest: PCardinal; CardinalCount: integer);
Fill some 32-bit memory buffer with values from the gsl_rng_taus2 generator
- the destination buffer is expected to be allocated as 32-bit items
procedure FillZero(var dest; count: PtrInt); overload;
Fill all bytes of a memory buffer with zero
- just redirect to FillCharFast(..,...,0)
procedure FillZero(var Values: TInt64DynArray); overload;
Fill all entries of a supplied array of 64-bit integers with 0
procedure FillZero(var Values: TIntegerDynArray); overload;
Fill all entries of a supplied array of 32-bit integers with 0
procedure FillZero(out dig: THash384); overload;
Fill all 32 bytes of this 384-bit buffer with zero
- may be used to cleanup stack-allocated content
... finally FillZero(digest); end;
procedure FillZero(out dig: THash128); overload;
Fill all 16 bytes of this 128-bit buffer with zero
- may be used to cleanup stack-allocated content
... finally FillZero(digest); end;
procedure FillZero(out dig: THash256); overload;
Fill all 32 bytes of this 256-bit buffer with zero
- may be used to cleanup stack-allocated content
... finally FillZero(digest); end;
procedure FillZero(out dig: THash512); overload;
Fill all 64 bytes of this 512-bit buffer with zero
- may be used to cleanup stack-allocated content
... finally FillZero(digest); end;
procedure FillZero(out dig: THash160); overload;
Fill all 20 bytes of this 160-bit buffer with zero
- may be used to cleanup stack-allocated content
... finally FillZero(digest); end;
procedure FillZero(var result: TGuid); overload;
Fill a TGuid with 0
procedure FillZeroSmall(P: pointer; Length: PtrInt);
Fill first bytes of a memory buffer with zero
- Length is expected to be not 0, typically in 1..8 range
- when inlined, is slightly more efficient than regular FillZero/FillCharFast
function FindNonVoidRawUtf8(n: PPointerArray; name: pointer; len: TStrLen; count: PtrInt): PtrInt;
Raw internal method as published by FindNonVoid[false]
function FindNonVoidRawUtf8I(n: PPointerArray; name: pointer; len: TStrLen; count: PtrInt): PtrInt;
Raw internal method as published by FindNonVoid[true]
function FindPropName(const Names: array of RawUtf8; const Name: RawUtf8): integer; overload;
Return the index of Value in Values[], -1 if not found
- here name search would use fast IdemPropNameU() function
function FindPropName(Values: PRawUtf8Array; const Value: RawUtf8; ValuesCount: PtrInt): PtrInt; overload;
Return the case-insensitive ASCII 7-bit index of Value in non-void Values[]
- typical use with a TRawUtf8DynArray is like this:
index := FindPropName(pointer(aDynArray), aValue, length(aDynArray));
- by design, this function expects Values[] to not contain any void ''
function fnv32(crc: cardinal; buf: PAnsiChar; len: PtrInt): cardinal;
Simple FNV-1a hashing function
- when run over our regression suite, is similar to crc32c() about collisions, and 4 times better than kr32(), but also slower than the others
- fnv32() is 715.5 MB/s - kr32() 898.8 MB/s
- this hash function should not be usefull, unless you need several hashing algorithms at once (e.g. if crc32c with diverse seeds is not enough)
procedure FreeAndNilSafe(var aObj);
Same as FreeAndNil() but catching and ignoring any exception
- only difference is that aObj is set to nil AFTER being destroyed
function FromI32(const Values: array of integer): TIntegerDynArray;
Initializes a dynamic array from a set of 32-bit integer signed values
function FromI64(const Values: array of Int64): TInt64DynArray;
Initializes a dynamic array from a set of 64-bit integer signed values
function FromU32(const Values: array of cardinal): TCardinalDynArray;
Initializes a dynamic array from a set of 32-bit integer unsigned values
function FromU64(const Values: array of QWord): TQWordDynArray;
Initializes a dynamic array from a set of 64-bit integer unsigned values
function gcd(a, b: PtrUInt): PtrUInt;
Compute GCD of two integers using modulo-based Euclidean algorithm
function GetAllBits(Bits, BitCount: cardinal): boolean;
Returns TRUE if all BitCount bits are set in the input 32-bit cardinal
function GetBit(const Bits; aIndex: PtrInt): boolean;
Retrieve a particular bit status from a bit array
- this function can't be inlined, whereas GetBitPtr() function can
function GetBit64(const Bits: Int64; aIndex: PtrInt): boolean;
Retrieve a particular bit status from a 64-bit integer bits (max aIndex is 63)
function GetBitPtr(Bits: pointer; aIndex: PtrInt): boolean;
Retrieve a particular bit status from a bit array
- GetBit() can't be inlined, whereas this pointer-oriented function can
function GetBitsCount(const Bits; Count: PtrInt): PtrInt;
Compute the number of bits set in a bit array
- Count is the number of BITS to check, not the byte size
- will use fast SSE4.2 popcnt instruction if available on the CPU
function GetBitsCountPas(value: PtrInt): PtrInt;
Pure pascal version of GetBitsCountPtrInt()
- defined just for regression tests - call GetBitsCountPtrInt() instead
- has optimized asm on x86_64 and i386
function GetBitsCountSSE42(value: PtrInt): PtrInt;
Defined here for mormot.test.base only
function GetBoolean(P: PUtf8Char): boolean; overload;
Get a boolean value stored as 'true'/'false' text in P^
- would also recognize any non '0' integer as true, or false if P = nil
- see relaxed GetInt64Bool() to recognize e.g. 'TRUE' or 'yes'/'YES'
function GetBoolean(const value: RawUtf8): boolean; overload;
Get a boolean value stored as 'true'/'false' text in input variable
- would also recognize any non '0' integer as true, or false if P is ''
function GetCardinal(P: PUtf8Char): PtrUInt; overload;
Get the unsigned 32-bit integer value stored in P^
- we use the PtrUInt result type, even if expected to be 32-bit, to use native CPU register size (don't want any 32-bit overflow here)
function GetCardinal(P, PEnd: PUtf8Char): PtrUInt; overload;
Get the unsigned 32-bit integer value stored in P^
- we use the PtrUInt result type, even if expected to be 32-bit, to use native CPU register size (don't want any 32-bit overflow here)
function GetCardinalDef(P: PUtf8Char; Default: PtrUInt): PtrUInt;
Get the unsigned 32-bit integer value stored in P^
- if P if nil or not start with a valid numerical value, returns Default
function GetCardinalW(P: PWideChar): PtrUInt;
Get the unsigned 32-bit integer value stored as Unicode string in P^
function GetClassParent(C: TClass): TClass;
Just a wrapper around vmtParent to avoid a function call
- slightly faster than TClass.ClassParent thanks to proper inlining
function GetExtended(P: PUtf8Char): TSynExtended; overload;
Get the extended floating point value stored in P^
- this overloaded version returns 0 as a result if the content of P is invalid
function GetExtended(P: PUtf8Char; out err: integer): TSynExtended; overload;
Get the extended floating point value stored in P^
- set the err content to the index of any faulty character, 0 if conversion was successful (same as the standard val function)
- this optimized function is consistent on all platforms/compilers and return the decoded value even if err is not 0 (e.g. if P^ is not #0 ended)
function GetInt64(P: PUtf8Char; var err: integer): Int64; overload;
Get the 64-bit signed integer value stored in P^
- set the err content to the index of any faulty character, 0 if conversion was successful (same as the standard val function)
function GetInt64(P: PUtf8Char): Int64; overload;
Get the 64-bit integer value stored in P^
function GetInt64Bool(P: PUtf8Char; out V: Int64): boolean;
Get the 64-bit integer value from P^, recognizing true/false/yes/no input
- return true on correct parsing, false if P is no number or boolean
function GetInt64Def(P: PUtf8Char; const Default: Int64): Int64;
Get the 64-bit integer value stored in P^
- if P if nil or not start with a valid numerical value, returns Default
function GetInteger(P: PUtf8Char): PtrInt; overload;
Get the signed 32-bit integer value stored in P^
- we use the PtrInt result type, even if expected to be 32-bit, to use native CPU register size (don't want any 32-bit overflow here)
- will end parsing when P^ does not contain any number (e.g. it reaches any ending #0 char)
function GetInteger(P: PUtf8Char; var err: integer): PtrInt; overload;
Get the signed 32-bit integer value stored in P^
- this version return 0 in err if no error occurred, and 1 if an invalid character was found, not its exact index as for the val() function
function GetInteger(P, PEnd: PUtf8Char): PtrInt; overload;
Get the signed 32-bit integer value stored in P^..PEnd^
- will end parsing when P^ does not contain any number (e.g. it reaches any ending #0 char), or when P reached PEnd (avoiding any buffer overflow)
function GetIntegerDef(P: PUtf8Char; Default: PtrInt): PtrInt;
Get the signed 32-bit integer value stored in P^
- if P if nil or not start with a valid numerical value, returns Default
procedure GetMemAligned(var holder: RawByteString; fillwith: pointer; len: PtrUInt; out aligned: pointer; alignment: PtrUInt = 16);
Initialize a RawByteString, ensuring returned "aligned" pointer is 16-bytes aligned
- to be used e.g. for proper SIMD process
- you can specify an alternate alignment, but it should be a power of two
function GetQWord(P: PUtf8Char; var err: integer): QWord;
Get the 64-bit unsigned integer value stored in P^
- set the err content to the index of any faulty character, 0 if conversion was successful (same as the standard val function)
function GetTrue(P: PUtf8Char): integer;
Return 1 if 'TRUE' or 'YES', or 0 otherwise
function GotoNextControlChar(source: PUtf8Char): PUtf8Char;
Fast go to the first char <= #13
- source is expected to be not nil
function GotoNextLine(source: PUtf8Char): PUtf8Char;
Fast go to next text line, ended by #13 or #13#10
- source is expected to be not nil
- returns the beginning of next line, or nil if source^=#0 was reached
function Hash128Index(P: PHash128Rec; Count: integer; h: PHash128Rec): integer;
Fast O(n) search of a 128-bit item in an array of such values
function Hash128To64(const b: THash128): QWord;
Combine/reduce a 128-bit hash into a 64-bit hash
- e.g. from non cryptographic 128-bit hashers with linked lower/higher 64-bit
function Hash256Index(P: PHash256Rec; Count: integer; h: PHash256Rec): integer;
Fast O(n) search of a 256-bit item in an array of such values
function Hash32(Data: PCardinalArray; Len: integer): cardinal; overload;
Our custom efficient 32-bit hash/checksum function
- a Fletcher-like checksum algorithm, not a hash function: has less colisions than Adler32 for short strings, but more than xxhash32 or crc32/crc32c
- written in simple plain pascal, with no L1 CPU cache pollution, but we also provide optimized x86/x64 assembly versions, since the algorithm is used heavily e.g. for TDynArray binary serialization, TRestStorageInMemory binary persistence, or CompressSynLZ/StreamSynLZ/FileSynLZ
- some numbers on Linux x86_64:
2500 xxhash32 in 1.34ms i.e. 1861504/s or 3.8 GB/s 2500 crc32c in 943us i.e. 2651113/s or 5.5 GB/s (SSE4.2 disabled) 2500 hash32 in 707us i.e. 3536067/s or 7.3 GB/s 2500 crc32c in 387us i.e. 6459948/s or 13.4 GB/s (SSE4.2 enabled)
function Hash32(const Text: RawByteString): cardinal; overload;
Our custom efficient 32-bit hash/checksum function
- a Fletcher-like checksum algorithm, not a hash function: has less colisions than Adler32 for short strings, but more than xxhash32 or crc32/crc32c
- overloaded function using RawByteString for binary content hashing, whatever the codepage is
function HasHWAes: boolean;
Cross-platform wrapper function to check AES HW support on Intel or ARM
function HugePower10Neg(exponent: PtrInt; pow10: PPow10): TSynExtended;
Low-level computation of 10 ^ negative exponent, if POW10[] is not enough
function HugePower10Pos(exponent: PtrInt; pow10: PPow10): TSynExtended;
Low-level computation of 10 ^ positive exponent, if POW10[] is not enough
function InsertInteger(var Values: TIntegerDynArray; var ValuesCount: integer; Value: integer; Index: PtrInt; CoValues: PIntegerDynArray = nil): PtrInt;
Insert an integer value at the specified index position of a dynamic array of integers
- if Index is invalid, the Value is inserted at the end of the array
function Int64Scan(P: PInt64Array; Count: PtrInt; const Value: Int64): PInt64;
Fast search of an integer position in a 64-bit integer array
- Count is the number of Int64 entries in P^
- returns P where P^=Value
- returns nil if Value was not found
function Int64ScanExists(P: PInt64Array; Count: PtrInt; const Value: Int64): boolean;
Fast search of an integer value in a 64-bit integer array
- returns true if P^=Value within Count entries
- returns false if Value was not found
function Int64ScanIndex(P: PInt64Array; Count: PtrInt; const Value: Int64): PtrInt;
Fast search of an integer position in a signed 64-bit integer array
- Count is the number of Int64 entries in P^
- returns index of P^[index]=Value
- returns -1 if Value was not found
procedure Int64ToCurrency(const i: Int64; out c: currency); overload;
Convert a Int64 value into a currency
- using multiplication by CURR_RES (=10000)
- warning: FPC Win64 to Win32 cross-compiler doesn't support currency values properly -> use FPC Win32 compiler only on Windows
procedure Int64ToCurrency(const i: Int64; c: PCurrency); overload;
Convert a Int64 value into a currency
- using multiplication by CURR_RES (=10000)
- warning: FPC Win64 to Win32 cross-compiler doesn't support currency values properly -> use FPC Win32 compiler only on Windows
function IntegerScan(P: PCardinalArray; Count: PtrInt; Value: cardinal): PCardinal;
Fast search of an unsigned integer item in a 32-bit integer array
- Count is the number of cardinal entries in P^
- returns P where P^=Value
- returns nil if Value was not found
- is implemented via IntegerScanIndex() SSE2 asm on i386 and x86_64
function IntegerScanExists(P: PCardinalArray; Count: PtrInt; Value: cardinal): boolean;
Fast search of an unsigned integer in a 32-bit integer array
- returns true if P^=Value within Count entries
- returns false if Value was not found
- is implemented via IntegerScanIndex() SSE2 asm on i386 and x86_64
function IntegerScanIndex(P: PCardinalArray; Count: PtrInt; Value: cardinal): PtrInt;
Fast search of an unsigned integer position in a 32-bit integer array
- Count is the number of integer entries in P^
- return index of P^[index]=Value
- return -1 if Value was not found
- is implemented with SSE2 asm on i386 and x86_64
function InterfaceArrayAdd(var aInterfaceArray; const aItem: IUnknown): PtrInt;
Wrapper to add an item to a T*InterfaceArray dynamic array storage
function InterfaceArrayAddCount(var aInterfaceArray; var aCount: integer; const aItem: IUnknown): PtrInt;
Wrapper to add an item to a T*InterfaceArray dynamic array storage
procedure InterfaceArrayAddOnce(var aInterfaceArray; const aItem: IUnknown);
Wrapper to add once an item to a T*InterfaceArray dynamic array storage
procedure InterfaceArrayDelete(var aInterfaceArray; aItemIndex: PtrInt); overload;
Wrapper to delete an item in a T*InterfaceArray dynamic array storage
- do nothing if the item is not found in the dynamic array
function InterfaceArrayDelete(var aInterfaceArray; const aItem: IUnknown): PtrInt; overload;
Wrapper to delete an item in a T*InterfaceArray dynamic array storage
- search is performed by address/reference, not by content
- do nothing if the item is not found in the dynamic array
function InterfaceArrayFind(const aInterfaceArray; const aItem: IUnknown): PtrInt;
Wrapper to search an item in a T*InterfaceArray dynamic array storage
- search is performed by address/reference, not by content
- return -1 if the item is not found in the dynamic array, or the index of the matching entry otherwise
procedure InterfaceNilSafe(var aInterface);
Same as aInterface := nil but ignoring any exception
procedure InterfacesNilSafe(const aInterfaces: array of pointer);
Same as aInterface := nil but ignoring any exception
function InterlockedDecrement(var I: integer): integer;
Compatibility function, to be implemented according to the running CPU
- expect the same result as the homonymous Win32 API function, i.e. returns I - 1, and store I - 1 within I in an atomic/tread-safe way
- FPC will define this function as intrinsic for non-Intel CPUs
function InterlockedIncrement(var I: integer): integer;
Compatibility function, to be implemented according to the running CPU
- expect the same result as the homonymous Win32 API function, i.e. returns I + 1, and store I + 1 within I in an atomic/tread-safe way
- FPC will define this function as intrinsic for non-Intel CPUs
function IsAnsiCompatible(PC: PAnsiChar): boolean; overload;
Return TRUE if the supplied buffer only contains 7-bits Ansi characters
function IsAnsiCompatible(PC: PAnsiChar; Len: PtrUInt): boolean; overload;
Return TRUE if the supplied buffer only contains 7-bits Ansi characters
function IsAnsiCompatible(const Text: RawByteString): boolean; overload;
Return TRUE if the supplied text only contains 7-bits Ansi characters
function IsAnsiCompatibleW(PW: PWideChar; Len: PtrInt): boolean; overload;
Return TRUE if the supplied UTF-16 buffer only contains 7-bits Ansi characters
function IsAnsiCompatibleW(PW: PWideChar): boolean; overload;
Return TRUE if the supplied UTF-16 buffer only contains 7-bits Ansi characters
function IsEqual(const A, B: THash512): boolean; overload;
Returns TRUE if all 64 bytes of both 512-bit buffers do match
- e.g. two SHA-512 digests
- this function is not sensitive to any timing attack, so is designed for cryptographic purpose
function IsEqual(const A, B; count: PtrInt): boolean; overload;
Returns TRUE if all bytes of both buffers do match
- this function is not sensitive to any timing attack, so is designed for cryptographic purposes - use CompareMem/CompareMemSmall/CompareMemFixed as faster alternatives for general-purpose code
function IsEqual(const A, B: THash256): boolean; overload;
Returns TRUE if all 32 bytes of both 256-bit buffers do match
- e.g. a SHA-256 digest, or a TEccSignature result
- this function is not sensitive to any timing attack, so is designed for cryptographic purpose
function IsEqual(const A, B: THash160): boolean; overload;
Returns TRUE if all 20 bytes of both 160-bit buffers do match
- e.g. a SHA-1 digest
- this function is not sensitive to any timing attack, so is designed for cryptographic purpose
function IsEqual(const A, B: THash128): boolean; overload;
Returns TRUE if all 16 bytes of both 128-bit buffers do match
- e.g. a MD5 digest, or an AES block
- this function is not sensitive to any timing attack, so is designed for cryptographic purpose - and it is also branchless therefore fast
function IsEqual(const A, B: THash384): boolean; overload;
Returns TRUE if all 48 bytes of both 384-bit buffers do match
- e.g. a SHA-384 digest
- this function is not sensitive to any timing attack, so is designed for cryptographic purpose
function IsEqualGuid(const guid1, guid2: TGuid): boolean; overload;
Compare two TGuid values
- this version is faster than the one supplied by SysUtils
function IsEqualGuid(guid1, guid2: PGuid): boolean; overload;
Compare two TGuid values
- this version is faster than the one supplied by SysUtils
function IsEqualGuidArray(const guid: TGuid; const guids: array of TGuid): integer;
Returns the index of a matching TGuid in an array
- returns -1 if no item matched
function IsNullGuid(const guid: TGuid): boolean;
Check if a TGuid value contains only 0 bytes
- this version is faster than the one supplied by SysUtils
function IsZero(const dig: THash160): boolean; overload;
Returns TRUE if all 20 bytes of this 160-bit buffer equal zero
- e.g. a SHA-1 digest
function IsZero(P: pointer; Length: integer): boolean; overload;
Returns TRUE if all bytes equal zero
function IsZero(const dig: THash256): boolean; overload;
Returns TRUE if all 32 bytes of this 256-bit buffer equal zero
- e.g. a SHA-256 digest, or a TEccSignature result
function IsZero(const Values: TInt64DynArray): boolean; overload;
Returns TRUE if Value is nil or all supplied Values[] equal 0
function IsZero(const dig: THash384): boolean; overload;
Returns TRUE if all 48 bytes of this 384-bit buffer equal zero
- e.g. a SHA-384 digest
function IsZero(const dig: THash128): boolean; overload;
Returns TRUE if all 16 bytes of this 128-bit buffer equal zero
- e.g. a MD5 digest, or an AES block
function IsZero(const dig: THash512): boolean; overload;
Returns TRUE if all 64 bytes of this 512-bit buffer equal zero
- e.g. a SHA-512 digest
function IsZero(const Values: TIntegerDynArray): boolean; overload;
Returns TRUE if Value is nil or all supplied Values[] equal 0
function IsZeroSmall(P: pointer; Length: PtrInt): boolean;
Returns TRUE if all of a few bytes equal zero
- to be called instead of IsZero() e.g. for 1..8 bytes
procedure KahanSum(const Data: double; var Sum, Carry: double);
Compute the sum of values, using a running compensation for lost low-order bits
- a naive "Sum := Sum + Data" will be restricted to 53 bits of resolution, so will eventually result in an incorrect number
- Kahan algorithm keeps track of the accumulated error in integer operations, to achieve a precision of more than 100 bits
- see https://en.wikipedia.org/wiki/Kahan_summation_algorithm
function kr32(crc: cardinal; buf: PAnsiChar; len: PtrInt): cardinal;
Standard Kernighan & Ritchie hash from "The C programming Language", 3rd edition
- simple and efficient code, but too much collisions for THasher
- kr32() is 898.8 MB/s - crc32cfast() 1.7 GB/s, crc32csse42() 4.3 GB/s
function Lecuyer: PLecuyer;
Return the 32-bit Pierre L'Ecuyer software generator for the current thread
- can be used as an alternative to several Random32 function calls
procedure LecuyerEncrypt(key: Qword; var data: RawByteString);
Cipher/uncipher some memory buffer using a 64-bit seed and Pierre L'Ecuyer's algorithm, and its gsl_rng_taus2 generator
procedure LockedAdd(var Target: PtrUInt; Increment: PtrUInt);
Fast atomic addition operation on a pointer-sized integer value
- via Intel/AMD custom asm or FPC RTL InterlockedExchangeAdd(pointer)
- Target should be aligned, which is the case when defined as a class field
procedure LockedAdd32(var Target: cardinal; Increment: cardinal);
Fast atomic addition operation on a 32-bit integer value
- via Intel/AMD custom asm or FPC RTL InterlockedExchangeAdd(pointer)
- Target should be aligned, which is the case when defined as a class field
procedure LockedDec(var Target: PtrUInt; Decrement: PtrUInt);
Fast atomic substraction operation on a pointer-sized integer value
- via Intel/AMD custom asm or FPC RTL InterlockedExchangeAdd(-pointer)
- Target should be aligned, which is the case when defined as a class field
procedure LockedDec32(int32: PInteger);
Slightly faster than InterlockedDecrement() when you don't need the result
function LockedExc(var Target: PtrUInt; NewValue, Comperand: PtrUInt): boolean;
Fast atomic compare-and-swap operation on a pointer-sized integer value
- via Intel/AMD custom asm or FPC RTL InterlockedCompareExchange(pointer)
- true if Target was equal to Comparand, and Target set to NewValue
- used e.g. as thread-safe atomic operation for TLightLock/TRWLock
- Target should be aligned, which is the case when defined as a class field
procedure LockedInc32(int32: PInteger);
Slightly faster than InterlockedIncrement() when you don't need the result
procedure LockedInc64(int64: PInt64);
Slightly faster than InterlockedIncrement64()
function MemCmp(P1, P2: PByteArray; L: PtrInt): integer;
Binary comparison of buffers, returning <0, 0 or >0 results
- caller should ensure that P1<>nil, P2<>nil and L>0
- on x86_64, will use a fast SSE2 asm version of the C function memcmp() (which is also used by CompareMem and CompareBuf)
- on other platforms, run a simple but efficient per-byte comparison
procedure MoveAndZero(Source, Dest: pointer; Count: PtrUInt);
Perform a MoveFast then fill the Source buffer with zeros
- could be used e.g. to quickly move a managed record content into a newly allocated stack variable with no reference counting
procedure MoveByOne(Source, Dest: pointer; Count: PtrUInt);
Move() with one-by-one byte copy
- never redirect to MoveFast() so could be used when data overlaps
procedure MoveFast(const src; var dst; cnt: PtrInt);
Our fast version of move() on Intel/AMD
- on Delphi Intel i386/x86_64, will use fast SSE2 instructions (if available)
- FPC i386 has fastmove.inc which is faster than our SSE2/ERMS version
- FPC x86_64 RTL is slower than our SSE2/AVX asm
- on non-Intel CPUs, it will fallback to the default RTL Move()
- on ARM/AARCH64 POSIX, mormot.core.os would redirect to optimized libc
procedure MoveSwap(dst, src: PByte; n: PtrInt);
Copy one memory buffer to another, swapping the bytes order
- used e.g. by TBigInt.Load/Save to follow DER big-endian encoding
- warning: src and dst should not overlap
procedure mul64x64(const left, right: QWord; out product: THash128Rec);
Fast computation of two 64-bit unsigned integers into a 128-bit value
function MultiEventAdd(var EventList; const Event: TMethod): boolean;
Low-level wrapper to add a callback to a dynamic list of events
- by default, you can assign only one callback to an Event: but by storing it as a dynamic array of events, you can use this wrapper to add one callback to this list of events
- if the event was already registered, do nothing (i.e. won't call it twice)
- since this function uses an unsafe typeless EventList parameter, you should not use it in high-level code, but only as wrapper within dedicated methods
- will add Event to EventList[] unless Event is already registered
- is used e.g. by TJsonWriter as such:
... fEchos: array of TOnTextWriterEcho; ... procedure EchoAdd(const aEcho: TOnTextWriterEcho); ... procedure TEchoWriter.EchoAdd(const aEcho: TOnTextWriterEcho); begin MultiEventAdd(fEchos,TMethod(aEcho)); end;
then callbacks are then executed as such:
if fEchos<>nil then
for i := 0 to length(fEchos) - 1 do
fEchos[i](self,fEchoBuf);- use MultiEventRemove() to un-register a callback from the list
function MultiEventFind(const EventList; const Event: TMethod): PtrInt;
Low-level wrapper to check if a callback is in a dynamic list of events
- by default, you can assign only one callback to an Event: but by storing it as a dynamic array of events, you can use this wrapper to check if a callback has already been registered to this list of events
- used internally by MultiEventAdd() and MultiEventRemove() functions
procedure MultiEventMerge(var DestList; const ToBeAddedList);
Low-level wrapper to add one or several callbacks from another list of events
- all events of the ToBeAddedList would be added to DestList
- the list is not checked for duplicates
procedure MultiEventRemove(var EventList; const Event: TMethod); overload;
Low-level wrapper to remove a callback from a dynamic list of events
- by default, you can assign only one callback to an Event: but by storing it as a dynamic array of events, you can use this wrapper to remove one callback already registered by MultiEventAdd() to this list of events
- since this function uses an unsafe typeless EventList parameter, you should not use it in high-level code, but only as wrapper within dedicated methods
- is used e.g. by TJsonWriter as such:
... fEchos: array of TOnTextWriterEcho; ... procedure EchoRemove(const aEcho: TOnTextWriterEcho); ... procedure TJsonWriter.EchoRemove(const aEcho: TOnTextWriterEcho); begin MultiEventRemove(fEchos,TMethod(aEcho)); end;
procedure MultiEventRemove(var EventList; Index: PtrInt); overload;
Low-level wrapper to remove a callback from a dynamic list of events
- same as the same overloaded procedure, but accepting an EventList[] index to identify the Event to be suppressed
function NextGrow(capacity: integer): integer;
Compute the new capacity when expanding an array of items
- handle tiny, small, medium, large and huge sizes properly to reduce memory usage and maximize performance
- initial steps are 4, 8, 12, 28, 40, 56, 72, 88, 104, 120, 136, 170, 212, 265, 331, 413, 516, 645, 806, 1007, 1258, 1572, ...
function ObjArrayAdd(var aObjArray; aItem: TObject): PtrInt; overload;
Wrapper to add an item to a T*ObjArray dynamic array storage
- for proper serialization on Delphi 7-2009, use Rtti.RegisterObjArray()
- could be used as such (note the T*ObjArray type naming convention):
TUserObjArray = array of TUser;
...
var arr: TUserObjArray;
user: TUser;
..
try
user := TUser.Create;
user.Name := 'Name';
index := ObjArrayAdd(arr,user);
...
finally
ObjArrayClear(arr); // release all items
end;- return the index of the item in the dynamic array
function ObjArrayAddCount(var aObjArray; aItem: TObject; var aObjArrayCount: integer): PtrInt;
Wrapper to add an item to a T*ObjArray dynamic array storage
- this overloaded function will use a separated variable to store the items count, so will be slightly faster: but you should call SetLength() when done, to have a stand-alone array as expected by our ORM/SOA serialziation
- return the index of the item in the dynamic array
function ObjArrayAddFrom(var aDestObjArray; const aSourceObjArray): PtrInt;
Wrapper to add items to a T*ObjArray dynamic array storage
- aSourceObjArray[] items are just copied to aDestObjArray, which remains untouched
- return the new number of the items in aDestObjArray
function ObjArrayAddOnce(var aObjArray; aItem: TObject; var aObjArrayCount: integer): PtrInt; overload;
Wrapper to add once an item to a T*ObjArray dynamic array storage and Count
function ObjArrayAddOnce(var aObjArray; aItem: TObject): PtrInt; overload;
Wrapper to add once an item to a T*ObjArray dynamic array storage
- for proper serialization on Delphi 7-2009, use Rtti.RegisterObjArray()
- if the object is already in the array (searching by address/reference, not by content), return its current index in the dynamic array
- if the object does not appear in the array, add it at the end
function ObjArrayAddOnceFrom(var aDestObjArray; const aSourceObjArray): PtrInt;
- aSourceObjArray[] items are just copied to aDestObjArray, which remains untouched
- will first check if aSourceObjArray[] items are not already in aDestObjArray
- return the new number of the items in aDestObjArray
function ObjArrayAppend(var aDestObjArray, aSourceObjArray): PtrInt;
Wrapper to add and move items to a T*ObjArray dynamic array storage
- aSourceObjArray[] items will be owned by aDestObjArray[], therefore aSourceObjArray is set to nil
- return the new number of the items in aDestObjArray
procedure ObjArrayClear(var aObjArray); overload;
Wrapper to release all items stored in a T*ObjArray dynamic array
- for proper serialization on Delphi 7-2009, use Rtti.RegisterObjArray()
- you should always use ObjArrayClear() before the array storage is released, e.g. in the owner class destructor
- when T*ObjArray are used as SOA parameters, no need to release the values
- will also set the dynamic array length to 0, so could be used to re-use an existing T*ObjArray
procedure ObjArrayClear(var aObjArray; aCount: integer); overload;
Wrapper to release all items stored in a T*ObjArray dynamic array
- this overloaded function will use the supplied array length as parameter
- you should always use ObjArrayClear() before the array storage is released, e.g. in the owner class destructor
- will also set the dynamic array length to 0, so could be used to re-use an existing T*ObjArray
procedure ObjArrayClear(var aObjArray; aContinueOnException: boolean; aCount: PInteger = nil); overload;
Wrapper to release all items stored in a T*ObjArray dynamic array
- for proper serialization on Delphi 7-2009, use Rtti.RegisterObjArray()
- you should always use ObjArrayClear() before the array storage is released, e.g. in the owner class destructor
- will also set the dynamic array length to 0, so could be used to re-use an existing T*ObjArray
function ObjArrayDelete(var aObjArray; var aCount: integer; aItem: TObject): PtrInt; overload;
Wrapper to delete an item in a T*ObjArray dynamic array storage
- for proper serialization on Delphi 7-2009, use Rtti.RegisterObjArray()
- search is performed by address/reference, not by content
- do nothing if the item is not found in the dynamic array
procedure ObjArrayDelete(var aObjArray; aItemIndex: PtrInt; const aContinueOnException: boolean = false; aCount: PInteger = nil); overload;
Wrapper to delete an item in a T*ObjArray dynamic array storage
- for proper serialization on Delphi 7-2009, use Rtti.RegisterObjArray()
- do nothing if the index is out of range in the dynamic array
function ObjArrayDelete(var aObjArray; aItem: TObject): PtrInt; overload;
Wrapper to delete an item in a T*ObjArray dynamic array storage
- for proper serialization on Delphi 7-2009, use Rtti.RegisterObjArray()
- search is performed by address/reference, not by content
- do nothing if the item is not found in the dynamic array
function ObjArrayFind(const aObjArray; aCount: integer; aItem: TObject): PtrInt; overload;
Wrapper to search an item in a T*ObjArray dynamic array storage
- for proper serialization on Delphi 7-2009, use Rtti.RegisterObjArray()
- search is performed by address/reference, not by content
- returns -1 if the item is not found in the dynamic array
function ObjArrayFind(const aObjArray; aItem: TObject): PtrInt; overload;
Wrapper to search an item in a T*ObjArray dynamic array storage
- for proper serialization on Delphi 7-2009, use Rtti.RegisterObjArray()
- search is performed by address/reference, not by content
- returns -1 if the item is not found in the dynamic array
function ObjArrayNotNilCount(const aObjArray): integer;
Wrapper to count all not nil items in a T*ObjArray dynamic array storage
- for proper serialization on Delphi 7-2009, use Rtti.RegisterObjArray()
procedure ObjArrayObjArrayClear(var aObjArray);
Wrapper to release all items stored in an array of T*ObjArray dynamic array
- e.g. aObjArray may be defined as "array of array of TSynFilter"
procedure ObjArraysClear(const aObjArray: array of pointer);
Wrapper to release all items stored in several T*ObjArray dynamic arrays
- for proper serialization on Delphi 7-2009, use Rtti.RegisterObjArray()
procedure ObjArraySetLength(var aObjArray; aLength: integer);
Wrapper to set the length of a T*ObjArray dynamic array storage
- could be used as an alternative to SetLength() when you do not know the exact T*ObjArray type
procedure OrMemory(Dest, Source: PByteArray; size: PtrInt);
Logical OR of two memory buffers
- will perform on all buffer bytes:
Dest[i] := Dest[i] or Source[i];
function PosChar(Str: PUtf8Char; Chr: AnsiChar): PUtf8Char; overload;
Fast retrieve the position of a given character in a #0 ended buffer
- will use fast SSE2 asm on i386 and x86_64
function PosChar(Str: PUtf8Char; StrLen: PtrInt; Chr: AnsiChar): PUtf8Char; overload;
Fast retrieve the position of a given character in a #0 ended buffer
- will use fast SSE2 asm on i386 and x86_64
function PosEx(const SubStr, S: RawUtf8; Offset: PtrUInt = 1): PtrInt;
Faster RawUtf8 Equivalent of standard StrUtils.PosEx
function PosExChar(Chr: AnsiChar; const Str: RawUtf8): PtrInt;
Optimized version of PosEx() with search text as one AnsiChar
- will use fast SSE2 asm on i386 and x86_64
function PosExString(const SubStr, S: string; Offset: PtrUInt = 1): PtrInt;
Our own PosEx() function dedicated to RTL string process
- Delphi XE or older don't support Pos() with an Offset
function PropNameEquals(const P1, P2: RawUtf8): boolean; overload;
Delphi has troubles inlining goto/label case-insensitive comparison of two RawUtf8 only containing ASCII 7-bit
- use e.g. with RTTI property names values only including A..Z,0..9,_ chars
- will make the "XOR AND $DF" trick to quickly test A-Z / a-z characters
- behavior is undefined with UTF-8 encoding (some false positive may occur)
- see IdemPropName/IdemPropNameU functions in mormot.core.text for a similar comparison with other kind of input variables
function PropNameEquals(P1, P2: PShortString): boolean; overload;
Case-insensitive comparison of two shortstrings only containing ASCII 7-bit
- use e.g. with RTTI property names values only including A..Z,0..9,_ chars
- will make the "XOR AND $DF" trick to quickly test A-Z / a-z characters
- behavior is undefined with UTF-8 encoding (some false positive may occur)
- see IdemPropName/IdemPropNameU functions in mormot.core.text for a similar comparison with other kind of input variables
function PtrArrayAdd(var aPtrArray; aItem: pointer): integer; overload;
Wrapper to add an item to a array of pointer dynamic array storage
function PtrArrayAdd(var aPtrArray; aItem: pointer; var aPtrArrayCount: integer): PtrInt; overload;
Wrapper to add an item to a array of pointer dynamic array storage
function PtrArrayAddOnce(var aPtrArray; aItem: pointer; var aPtrArrayCount: integer): PtrInt; overload;
Wrapper to add once an item to a array of pointer dynamic array storage
function PtrArrayAddOnce(var aPtrArray; aItem: pointer): PtrInt; overload;
Wrapper to add once an item to a array of pointer dynamic array storage
procedure PtrArrayDelete(var aPtrArray; aIndex: PtrInt; aCount: PInteger = nil; aKind: TPtrArrayKind = pakPointer); overload;
Wrapper to delete an item from a array of pointer dynamic array storage
function PtrArrayDelete(var aPtrArray; aItem: pointer; aCount: PInteger = nil; aKind: TPtrArrayKind = pakPointer): PtrInt; overload;
Wrapper to delete an item from a array of pointer dynamic array storage
function PtrArrayFind(var aPtrArray; aItem: pointer): integer;
Wrapper to find an item to a array of pointer dynamic array storage
function PtrArrayInsert(var aPtrArray; aItem: pointer; aIndex: PtrInt; var aPtrArrayCount: integer): PtrInt; overload;
Wrapper to insert an item to a array of pointer dynamic array storage
function PtrUIntScan(P: PPtrUIntArray; Count: PtrInt; Value: PtrUInt): pointer;
Fast search of a pointer-sized unsigned integer in an pointer-sized integer array
- Count is the number of pointer-sized integer entries in P^
- returns true if P^=Value within Count entries
- returns false if Value was not found
function PtrUIntScanExists(P: PPtrUIntArray; Count: PtrInt; Value: PtrUInt): boolean;
Fast search of a pointer-sized unsigned integer position in an pointer-sized integer array
- Count is the number of pointer-sized integer entries in P^
- returns true if P^=Value within Count entries
- returns false if Value was not found
function PtrUIntScanIndex(P: PPtrUIntArray; Count: PtrInt; Value: PtrUInt): PtrInt;
Fast search of a pointer-sized unsigned integer position in an pointer-sized integer array
- Count is the number of pointer-sized integer entries in P^
- return index of P^[index]=Value
- return -1 if Value was not found
procedure QuickSortDouble(ID: PDoubleArray; L, R: PtrInt);
Sort a double array, low values first
procedure QuickSortInt64(ID: PInt64Array; L, R: PtrInt); overload;
Sort a 64-bit signed integer array, low values first
procedure QuickSortInt64(ID, CoValues: PInt64Array; L, R: PtrInt); overload;
Sort a 64-bit integer array, low values first
procedure QuickSortInteger(var ID: TIntegerDynArray); overload;
Sort an integer array, low values first
procedure QuickSortInteger(ID: PIntegerArray; L, R: PtrInt); overload;
Sort an integer array, low values first
procedure QuickSortInteger(ID, CoValues: PIntegerArray; L, R: PtrInt); overload;
Sort an integer array, low values first
procedure QuickSortPointer(P: PPointerArray; L, R: PtrInt);
Sort a pointer array, low values first
procedure QuickSortPtrInt(P: PPtrIntArray; L, R: PtrInt);
Sort a PtrInt array, low values first
procedure QuickSortQWord(ID: PQWordArray; L, R: PtrInt); overload;
Sort a 64-bit unsigned integer array, low values first
- QWord comparison are implemented correctly under FPC or Delphi 2009+ - older compilers will use fast and exact SortDynArrayQWord()
procedure QuickSortWord(ID: PWordArray; L, R: PtrInt);
Sort a 16-bit unsigned integer array, low values first
function QWordScanIndex(P: PQWordArray; Count: PtrInt; const Value: QWord): PtrInt;
Fast search of an integer position in an unsigned 64-bit integer array
- Count is the number of QWord entries in P^
- returns index of P^[index]=Value
- returns -1 if Value was not found
function RaiseStreamError(Caller: TObject; const Context: shortstring): PtrInt;
Raise a EStreamError exception - e.g. from TSynMemoryStream.Write
function Random31: integer;
Fast compute of some 31-bit random value, using the gsl_rng_taus2 generator
- thread-safe function: each thread will maintain its own TLecuyer table
function Random31Not0: integer;
Compute of a 31-bit random value <> 0, using the gsl_rng_taus2 generator
- thread-safe function: each thread will maintain its own TLecuyer table
function Random32(max: cardinal): cardinal; overload;
Fast compute of bounded 32-bit random value, using the gsl_rng_taus2 generator
- calls internally the overloaded Random32 function, ensuring Random32(max)<max
- consider using TAesPrng.Main.Random32(), which offers cryptographic-level randomness, but is twice slower (even with AES-NI)
- thread-safe and non-blocking function using a per-thread TLecuyer engine
function Random32: cardinal; overload;
Fast compute of some 32-bit random value, using the gsl_rng_taus2 generator
- this function will use well documented and proven Pierre L'Ecuyer software generator - which happens to be faster (and safer) than RDRAND opcode (which is used for seeding anyway)
- consider using TAesPrng.Main.Random32(), which offers cryptographic-level randomness, but is twice slower (even with AES-NI)
- thread-safe and non-blocking function: each thread will maintain its own TLecuyer table (note that RTL's system.Random function is not thread-safe)
procedure Random32Seed(entropy: pointer = nil; entropylen: PtrInt = 0);
Seed the thread-specific gsl_rng_taus2 Random32 generator
- by default, gsl_rng_taus2 generator is re-seeded every 2^32 values, which is very conservative against the Pierre L'Ecuyer's algorithm period of 2^88
- you can specify some additional entropy buffer; note that calling this function with the same entropy again WON'T seed the generator with the same sequence (as with RTL's RandomSeed function), but initiate a new one
- calls XorEntropy(), so RdRand32/Rdtsc opcodes on Intel/AMD CPUs
- thread-safe and non-blocking function using a per-thread TLecuyer engine
function Random64: QWord;
Fast compute of a 64-bit random value, using the gsl_rng_taus2 generator
- thread-safe function: each thread will maintain its own TLecuyer table
procedure RandomBytes(Dest: PByte; Count: integer);
Fill a memory buffer with random bytes from the gsl_rng_taus2 generator
- will actually XOR the Dest buffer with Lecuyer numbers
- consider also the cryptographic-level TAesPrng.Main.FillRandom() method
- thread-safe and non-blocking function using a per-thread TLecuyer engine
function RandomDouble: double;
Fast compute of a 64-bit random floating point, using the gsl_rng_taus2 generator
- thread-safe and non-blocking function using a per-thread TLecuyer engine
procedure RandomGuid(out result: TGuid); overload;
Compute a random UUid value from the RandomBytes() generator and RFC 4122
function RandomGuid: TGuid; overload;
Compute a random UUid value from the RandomBytes() generator and RFC 4122
procedure RandomShort31(var dest: TShort31);
Fill some string[31] with 7-bit ASCII random text
- thread-safe and non-blocking function using a per-thread TLecuyer engine
procedure RawByteStringToVariant(Data: PByte; DataLen: integer; var Value: variant); overload;
Convert a raw binary buffer into a variant RawByteString varString
- you can then use VariantToRawByteString() to retrieve the binary content
procedure RawByteStringToVariant(const Data: RawByteString; var Value: variant); overload;
Convert a RawByteString content into a variant varString
- you can then use VariantToRawByteString() to retrieve the binary content
procedure RawObjectsClear(o: PObject; n: integer);
Low-level function calling FreeAndNil(o^) successively n times
procedure RawUtf8ToVariant(Txt: PUtf8Char; TxtLen: integer; var Value: variant); overload;
Convert an UTF-8 encoded text buffer into a variant RawUtf8 varString
procedure RawUtf8ToVariant(const Txt: RawUtf8; var Value: variant); overload;
Convert an UTF-8 encoded string into a variant RawUtf8 varString
function RawUtf8ToVariant(const Txt: RawUtf8): variant; overload;
Convert an UTF-8 encoded string into a variant RawUtf8 varString
procedure Rcu(var src, dst; len: integer);
Thread-safe move of a memory buffer using a simple Read-Copy-Update pattern
procedure Rcu128(var src, dst);
Thread-safe move of a 128-bit value using a simple Read-Copy-Update pattern
procedure Rcu32(var src, dst);
Thread-safe move of a 32-bit value using a simple Read-Copy-Update pattern
procedure Rcu64(var src, dst);
Thread-safe move of a 64-bit value using a simple Read-Copy-Update pattern
procedure RcuPtr(var src, dst);
Thread-safe move of a pointer value using a simple Read-Copy-Update pattern
procedure RdRand32(buffer: PCardinal; n: integer); overload;
XOR a memory buffer with some random generated by modern Intel CPU
- n is the number of 32-bit slots in the supplied buffer to fill
- will do nothing if cfSSE42 is not available on this CPU
function RdRand32: cardinal; overload;
Compute 32-bit random number generated by modern Intel CPU hardware
- using NIST SP 800-90A and FIPS 140-2 compliant RDRAND Intel x86/x64 opcode
- caller should ensure that cfSSE42 is included in CpuFeatures flags
- you should rather call XorEntropy() which offers additional sources
function Rdtsc: Int64;
Returns the 64-bit Intel Time Stamp Counter (TSC)
- could be used as entropy source for randomness - use TPrecisionTimer if you expect a cross-platform and cross-CPU high resolution performance counter
procedure ReadBarrier;
This function is an intrinsic in FPC
function RleCompress(src, dst: PByteArray; srcsize, dstsize: PtrUInt): PtrInt;
Simple Run-Length-Encoding compression of a memory buffer
- SynLZ is not good with input of a lot of redundant bytes, e.g. chunks of zeros: you could pre-process RleCompress/RleUnCompress such data before SynLZ
- see AlgoRleLZ as such a RLE + SynLZ algorithm
- returns the number of bytes written to dst, or -1 on dstsize overflow
function RleUnCompress(src, dst: PByteArray; size: PtrUInt): PtrUInt;
Simple Run-Length-Encoding uncompression of a memory buffer
- SynLZ is not good with input of a lot of redundant bytes, e.g. chunks of zeros: you could pre-process RleCompress/RleUnCompress such data before SynLZ
- see AlgoRleLZ as such a RLE + SynLZ algorithm
function RleUnCompressPartial(src, dst: PByteArray; size, max: PtrUInt): PtrUInt;
Partial Run-Length-Encoding uncompression of a memory buffer
function SameValue(const A, B: Double; DoublePrec: double = DOUBLE_SAME): boolean;
Compare to floating point values, with IEEE 754 double precision
- use this function instead of raw = operator
- the precision is calculated from the A and B value range
- faster equivalent than SameValue() in Math unit
- if you know the precision range of A and B, it's faster to check abs(A-B)<range
function SameValueFloat(const A, B: TSynExtended; DoublePrec: TSynExtended = DOUBLE_SAME): boolean;
Compare to floating point values, with IEEE 754 double precision
- use this function instead of raw = operator
- the precision is calculated from the A and B value range
- faster equivalent than SameValue() in Math unit
- if you know the precision range of A and B, it's faster to check abs(A-B)<range
procedure SetBit(var Bits; aIndex: PtrInt);
Set a particular bit into a bit array
- this function can't be inlined, whereas SetBitPtr() function can
procedure SetBit64(var Bits: Int64; aIndex: PtrInt);
Set a particular bit into a 64-bit integer bits (max aIndex is 63)
procedure SetBitPtr(Bits: pointer; aIndex: PtrInt);
Set a particular bit into a bit array
- SetBit() can't be inlined, whereas this pointer-oriented function can
procedure SetInt64(P: PUtf8Char; var result: Int64);
Get the 64-bit signed integer value stored in P^
procedure SetQWord(P: PUtf8Char; var result: QWord); overload;
Get the 64-bit unsigned integer value stored in P^
procedure SetQWord(P, PEnd: PUtf8Char; var result: QWord); overload;
Get the 64-bit unsigned integer value stored in P^
procedure SetVariantNull(var Value: variant);
Same as Value := Null, but slightly faster
function SetVariantUnRefSimpleValue(const Source: variant; var Dest: TVarData): boolean;
Same as Dest := TVarData(Source) for simple values
- will return TRUE for all simple values after varByRef unreference, and copying the unreferenced Source value into Dest raw storage
- will return FALSE for not varByRef values, or complex values (e.g. string)
function ShortStringToAnsi7String(const source: ShortString): RawByteString; overload;
Direct conversion of an ANSI-7 ShortString into an AnsiString
- can be used e.g. for names retrieved from RTTI to convert them into RawUtf8
procedure ShortStringToAnsi7String(const source: ShortString; var result: RawUtf8); overload;
Direct conversion of an ANSI-7 ShortString into an AnsiString
- can be used e.g. for names retrieved from RTTI to convert them into RawUtf8
function SimpleRoundTo2Digits(Value: Currency): Currency;
No banker rounding into two digits after the decimal point
- #.##51 will round to #.##+0.01 and #.##50 will be truncated to #.##
- implementation will use fast Int64 math to avoid any precision loss due to temporary floating-point conversion
procedure SimpleRoundTo2DigitsCurr64(var Value: Int64);
Simple, no banker rounding of a Currency value, stored as Int64, to only 2 digits
- #.##51 will round to #.##+0.01 and #.##50 will be truncated to #.##
- implementation will use fast Int64 math to avoid any precision loss due to temporary floating-point conversion
function SortDynArray128(const A, B): integer;
Compare two "array of THash128" 128-bit elements
function SortDynArray256(const A, B): integer;
Compare two "array of THash256" 256-bit elements
function SortDynArray512(const A, B): integer;
Compare two "array of THash512" 512-bit elements
function SortDynArrayAnsiString(const A, B): integer;
Compare two "array of AnsiString" elements, with case sensitivity
- on Intel/AMD will use efficient i386/x86_64 assembly using length
- on other CPU, will redirect to inlined StrComp() using #0 trailing char
function SortDynArrayBoolean(const A, B): integer;
Compare two "array of boolean" 8-bit elements
function SortDynArrayByte(const A, B): integer;
Compare two "array of byte" 8-bit elements
function SortDynArrayCardinal(const A, B): integer;
Compare two "array of cardinal" 32-bit elements
function SortDynArrayDouble(const A, B): integer;
Compare two "array of double" 64-bit elements
function SortDynArrayExtended(const A, B): integer;
Compare two "array of TSynExtended" 64/80-bit elements
function SortDynArrayInt64(const A, B): integer;
Compare two "array of Int64" or "array of Currency" 64-bit elements
function SortDynArrayInteger(const A, B): integer;
Compare two "array of integer" 32-bit elements
function SortDynArrayPointer(const A, B): integer;
Compare two "array of TObject/pointer" elements
function SortDynArrayPUtf8Char(const A, B): integer;
Compare two "array of PUtf8Char/PAnsiChar" elements, with case sensitivity
function SortDynArrayQWord(const A, B): integer;
Compare two "array of QWord" 64-bit elements
- note that QWord(A)>QWord(B) is wrong on older versions of Delphi, so you should better use this function or CompareQWord() to properly compare two QWord values over CPUX86
function SortDynArrayShortint(const A, B): integer;
Compare two "array of shortint" 8-bit elements
function SortDynArrayShortString(const A, B): integer;
Compare two "array of shortstring" elements, with case sensitivity
function SortDynArraySingle(const A, B): integer;
Compare two "array of single" 32-bit elements
function SortDynArraySmallint(const A, B): integer;
Compare two "array of smallint" 16-bit elements
function SortDynArrayString(const A, B): integer;
Compare two "array of RTL string" elements, with case sensitivity
- the expected string type is the RTL string
function SortDynArrayUnicodeString(const A, B): integer;
Compare two "array of WideString/UnicodeString" elements, with case sensitivity
function SortDynArrayVariant(const A, B): integer;
Compare two "array of variant" elements, with case sensitivity
- just a wrapper around SortDynArrayVariantComp(A,B,false)
function SortDynArrayVariantI(const A, B): integer;
Compare two "array of variant" elements, with no case sensitivity
- just a wrapper around SortDynArrayVariantComp(A,B,true)
function SortDynArrayWord(const A, B): integer;
Compare two "array of word" 16-bit elements
function SortMatch(CompareResult: integer; CompareOperator: TCompareOperator): boolean;
Fast search if a comparison function result (<0,0,>0) match an operator
function Split(const Str, SepStr: RawUtf8; StartPos: PtrInt = 1): RawUtf8; overload;
Returns the left part of a RawUtf8 string, according to SepStr separator
- if SepStr is found, returns Str first chars until (and excluding) SepStr
- if SepStr is not found, returns Str
procedure StrCntAdd(var refcnt: TStrCnt; increment: TStrCnt);
Low-level string reference counter process
function StrCntDecFree(var refcnt: TStrCnt): boolean;
Low-level string reference counter unprocess
- caller should have tested that refcnt>=0
- returns true if the managed variable should be released (i.e. refcnt was 1)
function StrComp(Str1, Str2: pointer): PtrInt;
Buffer-overflow safe version of StrComp(), to be used with PUtf8Char/PAnsiChar
function StrCompW(Str1, Str2: PWideChar): PtrInt;
Our fast version of StrComp(), to be used with PWideChar
function StrInt32(P: PAnsiChar; val: PtrInt): PAnsiChar;
Internal fast integer val to text conversion
- expect the last available temporary char position in P
- return the last written char position (write in reverse order in P^)
- typical use:
function Int32ToUtf8(Value: PtrInt): RawUtf8; var tmp: array[0..23] of AnsiChar; P: PAnsiChar; begin P := StrInt32(@tmp[23],Value); SetString(result,P,@tmp[23]-P); end;
- convert the input value as PtrInt, so work with Int64 on 64-bit CPUs
- not to be called directly: use IntToStr() or Int32ToUtf8() instead
function StrInt64(P: PAnsiChar; const val: Int64): PAnsiChar;
Internal fast Int64 val to text conversion
- same calling convention as with StrInt32() above
function StrLenSafe(S: pointer): PtrInt;
Simple version of StrLen(), but which will never read beyond the string
- this version won't access the memory beyond the string, so may be preferred e.g. with valgrid
- SSE2 StrLen() versions would never read outside a memory page boundary, so are safe to use in practice, but may read outside the string buffer itself, so may not please paranoid tools like valgrid
function StrLenW(S: PWideChar): PtrInt;
Our fast version of StrLen(), to be used with PWideChar
function StrUInt32(P: PAnsiChar; val: PtrUInt): PAnsiChar;
Internal fast unsigned integer val to text conversion
- expect the last available temporary char position in P
- return the last written char position (write in reverse order in P^)
- convert the input value as PtrUInt, so work with QWord on 64-bit CPUs
function StrUInt64(P: PAnsiChar; const val: QWord): PAnsiChar;
Internal fast unsigned Int64 val to text conversion
- same calling convention as with StrInt32() above
function SynLZcompress1(src: PAnsiChar; size: integer; dst: PAnsiChar): integer;
Raw SynLZ compression algorithm
- includes optimized x86/x64 asm version on Intel/AMD
- just redirects to SynLZcompress1pas on other CPUs
- note that SynLZ is not very good at compressing a lot of zeros: it excels with somewhat already pre-encoded data like text, JSON or our mormot.core.data binary serialization
function SynLZcompress1pas(src: PAnsiChar; size: integer; dst: PAnsiChar): integer;
Raw SynLZ compression algorithm implemented in pascal
- you should rather call SynLZcompress1() which is likely to be much faster
function SynLZcompressdestlen(in_len: integer): integer;
Get maximum possible (worse) SynLZ compressed size
function SynLZdecompress1(src: PAnsiChar; size: integer; dst: PAnsiChar): integer;
Raw SynLZ decompression algorithm
- includes optimized x86/x64 asm version on Intel/AMD
- just redirects to SynLZcompress1pas on other CPUs
function SynLZdecompress1partial(src: PAnsiChar; size: integer; dst: PAnsiChar; maxDst: integer): integer;
SynLZ decompression algorithm with memory boundaries check
- this function is slower, but will allow to uncompress only the start of the content (e.g. to read some metadata header)
- it will also check for dst buffer overflow, so will be more secure than other functions, which expect the content to be verified (e.g. via CRC)
function SynLZdecompress1pas(src: PAnsiChar; size: integer; dst: PAnsiChar): integer;
Raw SynLZ decompression algorithm implemented in pascal
- you should rather call SynLZdecompress1() which is likely to be much faster
function SynLZdecompressdestlen(in_p: PAnsiChar): integer;
Get exact uncompressed size from SynLZ-compressed buffer (to reserve memory, e.g.)
function TInt64DynArrayFrom(const Values: TIntegerDynArray): TInt64DynArray;
Quick helper to initialize a dynamic array of 64-bit integers from 32-bit values
- see also FromI64() for 64-bit signed integer values input
function TIntegerDynArrayFrom(const Values: array of integer): TIntegerDynArray;
Quick helper to initialize a dynamic array of integer from some constants
- can be used e.g. as:
MyArray := TIntegerDynArrayFrom([1,2,3]);
- see also FromI32()
function TIntegerDynArrayFrom64(const Values: TInt64DynArray; raiseExceptionOnOverflow: boolean = true): TIntegerDynArray;
Quick helper to initialize a dynamic array of integer from 64-bit integers
- will raise an Exception if any Value[] can not fit into 32-bit, unless raiseExceptionOnOverflow is FALSE and the returned array slot is filled with maxInt/minInt
function ToCardinal(const text: RawUtf8; out value: cardinal; minimal: cardinal = 0): boolean;
Get the unsigned 32-bit cardinal value stored in a RawUtf8 string
- returns TRUE if the supplied text was successfully converted into a cardinal
function ToDouble(const text: RawUtf8; out value: double): boolean;
Get a 64-bit floating-point value stored in a RawUtf8 string
- returns TRUE if the supplied text was successfully converted into a double
procedure ToHumanHex(var result: RawUtf8; bin: PByteArray; len: PtrInt);
Convert a binary into its human-friendly per-byte hexadecimal lowercase text
- returns e.g. '12:50:b6:1e:c6:aa', i.e. the DN/MAC format
- used e.g. in mormot.lib.openssl11 and mormot.net.sock
procedure ToHumanHexReverse(var result: RawUtf8; bin: PByteArray; len: PtrInt);
Convert a binary into its human-friendly hexadecimal in reverse order
function ToInt64(const text: RawUtf8; out value: Int64): boolean;
Get the signed 64-bit integer value stored in a RawUtf8 string
- returns TRUE if the supplied text was successfully converted into an Int64
function ToInteger(const text: RawUtf8; out value: integer): boolean;
Get the signed 32-bit integer value stored in a RawUtf8 string
- returns TRUE if the supplied text was successfully converted into an integer
function ToText(C: TClass): RawUtf8; overload;
Just a wrapper around ClassToText() to avoid a string conversion
function TQWordDynArrayFrom(const Values: TCardinalDynArray): TQWordDynArray;
Quick helper to initialize a dynamic array of 64-bit integers from 32-bit values
- see also FromU64() for 64-bit unsigned integer values input
function Trim(const S: RawUtf8): RawUtf8;
Fast dedicated RawUtf8 version of Trim()
- in the middle of UI code, consider using TrimU() which won't have name collision ambiguity as with SysUtils' homonymous function
procedure TrimCopy(const S: RawUtf8; start, count: PtrInt; var result: RawUtf8);
Single-allocation (therefore faster) alternative to Trim(copy())
procedure TrimSelf(var S: RawUtf8);
Fast dedicated RawUtf8 version of s := Trim(s)
function TrimU(const S: RawUtf8): RawUtf8;
Fast dedicated RawUtf8 version of Trim()
- should be used for RawUtf8 instead of SysUtils' Trim() which is ambiguous with the main String/UnicodeString type of Delphi 2009+
- in mORMot 1.18, there was a Trim() function but it was confusing
function TruncTo2Digits(Value: currency): currency;
Truncate a currency value to only 2 digits
- implementation will use fast Int64 math to avoid any precision loss due to temporary floating-point conversion
function TruncTo2Digits64(Value: Int64): Int64;
Truncate a Currency value, stored as Int64, to only 2 digits
- implementation will use fast Int64 math to avoid any precision loss due to temporary floating-point conversion
procedure TruncTo2DigitsCurr64(var Value: Int64);
Truncate a currency value, stored as Int64, to only 2 digits
- implementation will use fast Int64 math to avoid any precision loss due to temporary floating-point conversion
function TwoDigits(const d: double): TShort23;
No banker rounding into text, with two digits after the decimal point
- #.##51 will round to #.##+0.01 and #.##50 will be truncated to #.##
- this function will only allow 2 digits in the returned text
function UniqueRawUtf8(var u: RawUtf8): pointer;
Equivalence to @u[1] expression to ensure a RawUtf8 variable is unique
- will ensure that the string refcount is 1, and return a pointer to the text
- under FPC, @u[1] does not call UniqueString() as it does with Delphi
- if u is a constant (refcount=-1), will allocate a temporary copy in heap
procedure UnSetBit(var Bits; aIndex: PtrInt);
Unset/clear a particular bit into a bit array
- this function can't be inlined, whereas UnSetBitPtr() function can
procedure UnSetBit64(var Bits: Int64; aIndex: PtrInt);
Unset/clear a particular bit into a 64-bit integer bits (max aIndex is 63)
procedure UnSetBitPtr(Bits: pointer; aIndex: PtrInt);
Unset/clear a particular bit into a bit array
- UnSetBit() can't be inlined, whereas this pointer-oriented function can
function Utf8ToInt64(const text: RawUtf8; const default: Int64 = 0): Int64;
Get the signed 64-bit integer value stored in a RawUtf8 string
- returns the default value if the supplied text was not successfully converted into an Int64
function Utf8ToInteger(const value: RawUtf8; min, max: PtrInt; default: PtrInt = 0): PtrInt; overload;
Get and check range of a signed 32-bit integer stored in a RawUtf8 string
- we use the PtrInt result type, even if expected to be 32-bit, to use native CPU register size (don't want any 32-bit overflow here)
function Utf8ToInteger(const value: RawUtf8; Default: PtrInt = 0): PtrInt; overload;
Get the signed 32-bit integer value stored in a RawUtf8 string
- we use the PtrInt result type, even if expected to be 32-bit, to use native CPU register size (don't want any 32-bit overflow here)
procedure VarClearAndSetType(var v: variant; vtype: integer);
Overloaded function which can be properly inlined to clear a variant
function VarDataFromVariant(const Value: variant): PVarData;
Get the root PVarData of a variant, redirecting any varByRef
- if result^.VPointer=nil, returns varEmpty
function VarDataIsEmptyOrNull(VarData: pointer): boolean;
Same as VarIsEmpty(PVariant(V)^) or VarIsNull(PVariant(V)^), but faster
- we also discovered some issues with FPC's Variants unit, so this function may be used even in end-user cross-compiler code
function VariantCompSimple(const A, B: variant): integer;
Basic default case-sensitive variant comparison function
- try as VariantToInt64/VariantToDouble, then RTL VarCompareValue()
procedure VariantStringToUtf8(const V: Variant; var result: RawUtf8); overload;
Convert a Variant varString value into RawUtf8 encoded String
- works as the exact reverse of RawUtf8ToVariant() function
- non varString variants (e.g. UnicodeString, WideString, numbers, empty and null) will be returned as ''
- use VariantToUtf8() instead if you need to convert numbers or other strings
- use VariantSaveJson() instead if you need a conversion to JSON with custom parameters
function VariantStringToUtf8(const V: Variant): RawUtf8; overload;
Convert Variant string values into RawUtf8 encoded String
- works as the exact reverse of RawUtf8ToVariant() function
- non varString variants (e.g. UnicodeString, WideString, numbers, empty and null) will be returned as ''
function VariantToBoolean(const V: Variant; var Value: boolean): boolean;
Convert any numerical Variant into a boolean value
- text content will return true after case-sensitive 'true' comparison
function VariantToCurrency(const V: Variant; var Value: currency): boolean;
Convert any numerical Variant into a fixed decimals floating point value
function VariantToDouble(const V: Variant; var Value: double): boolean;
Convert any numerical Variant into a floating point value
function VariantToDoubleDef(const V: Variant; const default: double = 0): double;
Convert any numerical Variant into a floating point value
function VariantToInt64(const V: Variant; var Value: Int64): boolean;
Convert any numerical Variant into a 64-bit integer
- it will expect true numerical Variant and won't convert any string nor floating-pointer Variant, which will return FALSE and won't change the Value variable content
function VariantToInt64Def(const V: Variant; DefaultValue: Int64): Int64;
Convert any numerical Variant into a 64-bit integer
- it will expect true numerical Variant and won't convert any string nor floating-pointer Variant, which will return the supplied DefaultValue
function VariantToInteger(const V: Variant; var Value: integer): boolean;
Convert any numerical Variant into a 32-bit integer
- it will expect true numerical Variant and won't convert any string nor floating-pointer Variant, which will return FALSE and won't change the Value variable content
function VariantToIntegerDef(const V: Variant; DefaultValue: integer): integer; overload;
Convert any numerical Variant into an integer
- it will expect true numerical Variant and won't convert any string nor floating-pointer Variant, which will return the supplied DefaultValue
procedure VariantToRawByteString(const Value: variant; var Dest: RawByteString);
Convert back a RawByteString from a variant
- the supplied variant should have been created via a RawByteStringToVariant() function call
function VarIsEmptyOrNull(const V: Variant): boolean;
Same as VarIsEmpty(V) or VarIsNull(V), but faster
- we also discovered some issues with FPC's Variants unit, so this function may be used even in end-user cross-compiler code
function WordScanIndex(P: PWordArray; Count: PtrInt; Value: word): PtrInt;
Fast search of an unsigned Word value position in a Word array
- Count is the number of Word entries in P^
- return index of P^[index]=Value, -1 if Value was not found
- is implemented with SSE2 asm on i386 and x86_64
procedure XorEntropy(var e: THash512Rec);
Retrieve 512-bit of entropy, from system time and current execution state
- entropy is gathered over several sources like RTL Now(), CreateGuid(), current gsl_rng_taus2 Lecuyer state, and RdRand32/Rdtsc low-level Intel opcodes
- the resulting output is to be hashed - e.g. with DefaultHasher128
- execution is fast, but not enough as unique seed for a cryptographic PRNG: TAesPrng.GetEntropy will call it as one of its entropy sources, in addition to system-retrieved randomness from mormot.core.os.pas' XorOSEntropy()
procedure XorMemory(Dest, Source: PByteArray; size: PtrInt); overload;
Logical XOR of two memory buffers
- will perform on all buffer bytes:
Dest[i] := Dest[i] xor Source[i];
procedure XorMemory(Dest, Source1, Source2: PByteArray; size: PtrInt); overload;
Logical XOR of two memory buffers into a third
- will perform on all buffer bytes:
Dest[i] := Source1[i] xor Source2[i];
function xxHash32(crc: cardinal; P: PAnsiChar; len: cardinal): cardinal;
Perform very fast xxHash hashing in 32-bit mode
- will use optimized asm for x86/x64, or a pascal version on other CPUs
function xxHash32Mixup(crc: cardinal): cardinal;
Shuffle a 32-bit value using the last stage of xxHash32 algorithm
- is a cascade of binary shifts and multiplications by prime numbers
- see also (c * KNUTH_HASH32_MUL) shr (32 - bits) as weaker alternative
procedure YearToPChar(Y: PtrUInt; P: PUtf8Char);
Add the 4 digits of integer Y to P^ as '0000'..'9999'
adler32: THasher;
Compute ADLER32 checksum on the supplied buffer
- is only available if mormot.lib.z.pas unit is included in the project
ClassUnit: function(C: TClass): PShortString;
Retrieve the unit name where a given class is implemented
- is implemented in mormot.core.rtti.pas; so may be nil otherwise
- is needed since Delphi 7-2009 do not define TObject.UnitName (because there is no such information available in RTTI)
CompareMemFixed: function(P1, P2: pointer; Length: PtrInt): boolean = CompareMem;
A CompareMem()-like function designed for small and fixed-sized content
- here, Length is expected to be a constant value - typically from SizeOf() - so that inlining has better performance than calling the CompareMem() function
CpuAvx10: TIntelAvx10Features;
The detected AVX10 Converged Vector ISA features
- only set if cfAVX10 is part of CpuFeatures
CpuFeatures: TIntelCpuFeatures;
The available Intel/AMD CPU features, as recognized at program startup
- on LINUX, consider CpuInfoArm or the textual CpuInfoFeatures from mormot.core.os.pas
crc32: THasher = crc32fast;
Compute CRC32 checksum on the supplied buffer
- mormot.lib.z.pas will replace with its official (may be faster) version
crc32c: THasher = crc32cfast;
Compute CRC32C checksum on the supplied buffer
- result is not compatible with zlib's crc32() - Intel/SCSI CRC32C has not same polynom - but will use the fastest mean available, e.g. SSE 4.2 or ARMv8, achieve up to 16GB/s with the optimized implementation from mormot.crypt.core
- you should use this function instead of crc32cfast() or crc32csse42()
crc32cBy4: function(crc, value: cardinal): cardinal = crc32cBy4fast;
Compute CRC32C checksum on one 32-bit unsigned integer
- can be used instead of crc32c() for inlined process during data acquisition
- doesn't make "crc := not crc" before and after the computation: caller has to start with "crc := cardinal(not 0)" and make "crc := not crc" at the end, to compute the very same hash value than regular crc32c()
- this variable will use the fastest mean available, e.g. SSE 4.2 or ARMv8
crc32ctab: TCrc32tab;
8KB tables used by crc32cfast() function
- created with a polynom diverse from zlib's crc32() algorithm, but compatible with SSE 4.2 crc32 instruction
- tables content is created from code in initialization section below
- will also be used internally by SymmetricEncrypt and TSynUniqueIdentifierGenerator as 1KB master/reference key tables
crc32tab: TCrc32tab;
8KB tables used by crc32fast() function
crcblock: procedure(crc128, data128: PBlock128) = crcblockfast;
Compute a proprietary 128-bit CRC of a 128-bit binary buffer
- apply four crc32c() calls on the 128-bit input chunk, into a 128-bit crc
- its output won't match crc128c() value, which works on 8-bit input
- will use SSE 4.2 or ARMv8 hardware accelerated instruction, if available
- is used e.g. by mormot.crypt.core's TAesCfc/TAesOfc/TAesCtc to check for data integrity
crcblocks: procedure(crc128, data128: PBlock128; count: integer) = crcblocksfast;
Compute a proprietary 128-bit CRC of 128-bit binary buffers
- apply four crc32c() calls on the 128-bit input chunks, into a 128-bit crc
- its output won't match crc128c() value, which works on 8-bit input
- will use SSE 4.2 or ARMv8 hardware accelerated instruction, if available
- is used e.g. by crc32c128 or mormot.crypt.ecc's TEcdheProtocol.ComputeMAC for macCrc128c or TAesAbstractAead.MacCheckError
DefaultHasher: THasher = xxHash32;
The 32-bit default hasher used by TDynArrayHashed
- set to crc32csse42() if SSE4.2 or ARMv8 are available on this CPU, or fallback to xxHash32() which is faster than crc32cfast() e.g. on ARM
- mormot.crypt.core may assign safer and faster AesNiHash32() if available
- so the hash value may change on another computer or after program restart
DefaultHasher128: THasher128 = crc32c128;
A 128-bit hasher function
- crc32c128() by default, but mormot.crypt.core may assign AesNiHash128()
- so the hash value may change on another computer or after program restart
DefaultHasher64: THasher64 = crc32cTwice;
A 64-bit hasher function
- crc32cTwice() by default, but mormot.crypt.core may assign AesNiHash64()
- so the hash value may change on another computer or after program restart
DOUBLE_PRECISION: integer = 15;
Best possible precision when rendering a "double" kind of float
- can be used as parameter for ExtendedToShort/ExtendedToStr
- is defined as a var, so that you may be able to override the default settings, for the whole process
EXTENDED_PRECISION: integer = 18;
Best possible precision when rendering a "extended" kind of float
- can be used as parameter for ExtendedToShort/ExtendedToStr
- is defined as a var, so that you may be able to override the default settings, for the whole process
GetBitsCountPtrInt: function(value: PtrInt): PtrInt = GetBitsCountPas;
Compute how many bits are set in a given pointer-sized integer
- the PopCnt() intrinsic under FPC doesn't have any fallback on older CPUs, and default implementation is 5 times slower than our GetBitsCountPas() on x64
- this redirected function will use fast SSE4.2 "popcnt" opcode, if available
InterningHasher: THasher = xxHash32;
The 32-bit hash function used by TRawUtf8Interning
- set to crc32csse42() if SSE4.2 or ARMv8 are available on this CPU, or fallback to xxHash32() which performs better than crc32cfast()
- mormot.crypt.core may assign safer and faster AesNiHash32() if available
- so the hash value may change on another computer or after program restart
Null: variant absolute NullVarData;
A slightly faster alternative to Variants.Null function
SINGLE_PRECISION: integer = 8;
Best possible precision when rendering a "single" kind of float
- can be used as parameter for ExtendedToShort/ExtendedToStr
- is defined as a var, so that you may be able to override the default settings, for the whole process
SortDynArrayRawByteString: TDynArraySortCompare = SortDynArrayAnsiString;
Compare two "array of RawByteString" elements, with case sensitivity
- can't use StrComp() or similar functions since RawByteString may contain #0
- on Intel/AMD, the more efficient SortDynArrayAnsiString asm is used instead
SortDynArrayVariantComp: function( const A, B: TVarData; caseInsensitive: boolean): integer;
Compare two variant/TVarData values, with or without case sensitivity
- this unit registers the basic VariantCompSimple() case-sensitive comparer
- mormot.core.variants will assign the much better FastVarDataComp()
- called e.g. by SortDynArrayVariant/SortDynArrayVariantI functions
StrLen: function(S: pointer): PtrInt = StrLenSafe;
Our fast version of StrLen(), to be used with PUtf8Char/PAnsiChar
- under x86, will detect SSE2 and use it if available, reaching e.g. 37.5 GB/s on a Core i5-13500 under Linux x86_64
- on ARM/AARCH64 POSIX, mormot.core.os would redirect to optimized libc
TwoDigitLookupW: packed[0..99] of word absolute TwoDigitLookup;
Fast lookup table for converting any decimal number from 0 to 99 into their ASCII equivalence
VarFalse: variant absolute FalseVarData;
A slightly faster alternative to false constant when assigned to a variant
VariantClearSeveral: procedure(V: PVarData; n: integer);
Efficient finalization of successive variant items from a (dynamic) array
- this unit will include a basic version calling VarClear()
- mormot.core.variants will assign a more efficient implementation
VarTrue: variant absolute TrueVarData;
A slightly faster alternative to true constant when assigned to a variant