logo.png
mORMot2 API Reference

mormot.core.rtti.pas unit

Purpose: Framework Core Low-Level Cross-Compiler RTTI Definitions
- this unit is a part of the Open Source Synopse mORMot framework 2, licensed under a MPL/GPL/LGPL three license - see LICENSE.md

1.1. Units used in the mormot.core.rtti unit

Unit NameDescription
mormot.core.baseFramework Core Shared Types and RTL-like Functions
mormot.core.osFramework Core Low-Level Wrappers to the Operating-System API
mormot.core.textFramework Core Low-Level Text Processing
mormot.core.unicodeFramework Core Low-Level Unicode UTF-8 UTF-16 Ansi Conversion

1.2. mormot.core.rtti class hierarchy

TObjectTRttiPropsTRttiPropTRttiMapTRttiInterfaceTypeDataTRttiInfoTRttiEnumTypeTRttiCustomPropsTRttiCustomPropTRttiCustomListTRttiCustomTRttiClassTObjectWithCustomCreateTObjectWithIDESynExceptionERttiException
mormot.core.rtti class hierarchy

1.3. Objects implemented in the mormot.core.rtti unit

ObjectsDescription
ERttiExceptionThe kind of Exception raised by this unit
PropWrapUsed to map a TPropInfo.GetProc/SetProc and retrieve its kind
TArrayInfoRkArray RTTI not defined in Delphi 7/2007 TTypeData
TObjectWithCustomCreateAbstract parent class with published properties and a virtual constructor
TObjectWithIDRoot class of an object with a 64-bit ID primary key
TPropDataPPropData not defined in Delphi 7/2007 TypInfo
TPublishedMethodInfoInformation about one method, as returned by GetPublishedMethods
TRecordInfoRkRecord RTTI is not defined in Delphi 7/2007 TTypeData
TRttiCacheConvenient wrapper about PRttiInfo content and its more precise information
TRttiClassA wrapper to class type information, as defined by the compiler RTTI
TRttiCustomAllow to customize the process of a given TypeInfo/PRttiInfo
TRttiCustomListMaintain a thread-safe list of PRttiInfo/TRttiCustom/TRttiJson registration
TRttiCustomListPairsEfficient PRttiInfo/TRttiCustom pairs for TRttiCustomList hash table
TRttiCustomPropStore information about one property/field of a given TypeInfo/PRttIinfo
TRttiCustomPropsStore information about all properties/fields of a given TypeInfo/PRttIinfo
TRttiEnumTypeA wrapper to enumeration type information, as defined by the compiler RTTI and returned by PRttiInfo.EnumBaseType/SetEnumType
TRttiInfoMain entry-point wrapper to access RTTI for a given pascal type
TRttiInterfaceStore IInvokable methods information
TRttiInterfaceTypeDataA wrapper to interface type information, as defined by the the compiler RTTI
TRttiMapCustomizable field mapping between classes and records
TRttiMethodStore IInvokable method information
TRttiPropA wrapper containing a RTTI class property definition
TRttiPropsA wrapper to published properties of a class, as defined by compiler RTTI
TRttiRecordAllFieldEnhanced RTTI of a record/object type definition
TRttiRecordFieldRTTI of a record/object type definition (managed) field
TRttiRecordManagedFieldsRecord RTTI as returned by TRttiInfo.RecordManagedFields
TRttiVarDataVariant-like value as returned by TRttiCustomProp.GetRttiVarData

1.3.1. ERttiException

ERttiException = class(ESynException)

The kind of Exception raised by this unit


1.3.2. TRttiProps

TRttiProps = object(TObject)

A wrapper to published properties of a class, as defined by compiler RTTI
- access properties for only a given class level, not inherited properties
- start enumeration by getting a PRttiProps with PRttiInfo.RttiProps(), then use P := PropList to get the first PRttiProp, and iterate with P^.Next
- this enumeration is very fast and doesn't require any temporary memory, as in the TypInfo.GetPropInfos() PPropList usage
- for TOrm, you should better use the Properties.Fields[] array, which is faster and contains the properties published in parent classes


function FieldProp(const PropName: ShortString): PRttiProp;

Retrieve a Field property RTTI information from a Property Name


function PropCount: integer;

Number of published properties in this object


function PropList: PRttiProp;

Point to a TPropInfo packed array
- layout is as such, with variable TPropInfo storage size:

 PropList: array[1..PropCount] of TPropInfo

- use TPropInfo.Next to get the next one:

 P := PropList;
 for i := 1 to PropCount do
 begin
   // ... do something with P
   P := P^.Next;
 end;

1.3.3. TRttiClass

TRttiClass = object(TObject)

A wrapper to class type information, as defined by the compiler RTTI
- get a PRttiClass with PRttiInfo.RttiClass() or GetRttiClass()


function InheritsFrom(AClass: TClass): boolean;

Fast and easy find if this class inherits from a specific class type
- you should rather consider using TRttiInfo.InheritsFrom directly


function ParentInfo: PRttiInfo;

The parent class type information


function PropCount: integer;

The number of published properties of this class and all parents
- use RttiProps if you want to properties only published in this class


function RttiClass: TClass;

The class type


function RttiProps: PRttiProps;

Get the information about the published properties of this class
- stored after UnitName memory


function UnitName: PShortString;

The name (without .pas extension) of the unit were the class was defined
- then the PRttiProps information follows: use the method RttiProps to retrieve its address


1.3.4. TRttiEnumType

TRttiEnumType = object(TObject)

A wrapper to enumeration type information, as defined by the compiler RTTI and returned by PRttiInfo.EnumBaseType/SetEnumType
- we use this to store the enumeration values as integer, but easily provide a text equivalent, translated if necessary, from the enumeration type definition itself


function GetCaption(const Value): string;

Get the caption text corresponding to a enumeration name
- return the first one if Value is invalid (>MaxValue)
- Value will be converted to the matching ordinal value (byte or word)


function GetCaptionStrings(UsedValuesBits: pointer = nil): string;

Get all caption names, ready to be display, as lines separated by #13#10
- return "string" type, i.e. UnicodeString for Delphi 2009+
- if UsedValuesBits is not nil, only the corresponding bits set are added


function GetEnumName(const Value): PShortString;

Get the corresponding enumeration name
- return the first one if Value is invalid (>MaxValue)
- Value will be converted to the matching ordinal value (byte or word)


function GetEnumNameAllAsJsonArray(TrimLeftLowerCase: boolean; UnCamelCased: boolean = false): RawUtf8;

Get all enumeration names as a JSON array of strings


function GetEnumNameOrd(Value: cardinal): PShortString;

Get the corresponding enumeration name
- return a void '' ShortString if Value is invalid (>MaxValue)


function GetEnumNameTrimed(const Value): RawUtf8;

Get the corresponding enumeration name, without the first lowercase chars (otDone -> 'Done')
- Value will be converted to the matching ordinal value (byte or word)


function GetEnumNameTrimedValue(Value: PUtf8Char; ValueLen: integer = 0): integer; overload;

Get the corresponding enumeration ordinal value, from its name without its first lowercase chars ('Done' will find otDone e.g.)
- return -1 if not found, or if RTTI's MinValue is not 0


function GetEnumNameTrimedValue(const EnumName: ShortString): integer; overload;

Get the corresponding enumeration ordinal value, from its name without its first lowercase chars ('Done' will find otDone e.g.)
- return -1 if not found, or if RTTI's MinValue is not 0


function GetEnumNameValue(const EnumName: ShortString): integer; overload;

Get the corresponding enumeration ordinal value, from its name
- if EnumName does start with lowercases 'a'..'z', they will be searched: e.g. GetEnumNameValue('sllWarning') will find sllWarning item
- if Value does not start with lowercases 'a'..'z', they will be ignored: e.g. GetEnumNameValue('Warning') will find sllWarning item
- return -1 if not found (don't use directly this value to avoid any GPF)


function GetEnumNameValue(Value: PUtf8Char): integer; overload;

Get the corresponding enumeration ordinal value, from its name
- if Value does start with lowercases 'a'..'z', they will be searched: e.g. GetEnumNameValue('sllWarning') will find sllWarning item
- if Value does not start with lowercases 'a'..'z', they will be ignored: e.g. GetEnumNameValue('Warning') will find sllWarning item
- return -1 if not found (don't use directly this value to avoid any GPF)


function GetEnumNameValue(Value: PUtf8Char; ValueLen: integer; AlsoTrimLowerCase: boolean = true): integer; overload;

Get the corresponding enumeration ordinal value, from its name
- if Value does start with lowercases 'a'..'z', they will be searched: e.g. GetEnumNameValue('sllWarning') will find sllWarning item
- if AlsoTrimLowerCase is TRUE, and EnumName does not start with lowercases 'a'..'z', they will be ignored: e.g. GetEnumNameValue('Warning') will find sllWarning item
- return -1 if not found, or if RTTI's MinValue is not 0


function GetEnumNameValueTrimmed(Value: PUtf8Char; ValueLen: integer; CaseSensitive: boolean): integer;

Get the corresponding enumeration ordinal value, from its trimmed name


function GetSetName(const value; trimmed: boolean = false; const sep: RawUtf8 = ','): RawUtf8;

Get the enumeration names corresponding to a set value as CSV


function GetSetNameJsonArray(Value: cardinal; SepChar: AnsiChar = ','; FullSetsAsStar: boolean = false): RawUtf8; overload;

Get the enumeration names corresponding to a set value as JSON array


function MaxValue: PtrInt;

Same as ord(high(type)): not the enumeration count, but the highest index


function MinValue: PtrInt;

First value of enumeration type, typicaly 0
- may be < 0 e.g. for boolean


function NameList: PShortString;

A concatenation of shortstrings, containing the enumeration names
- those shortstrings are not aligned whatsoever (even if FPC_REQUIRES_PROPER_ALIGNMENT is set)


function RttiOrd: TRttiOrd;

Specify ordinal storage size and sign
- is prefered to MaxValue to identify the number of stored bytes


function SizeInStorageAsEnum: integer;

Compute how many bytes this type will use to be stored as a enumerate


function SizeInStorageAsSet: integer;

Compute how many bytes (1, 2, 4) this type will use to be stored as a set
- consider using TRttiInfo.SetEnumSize if ISFPC32 conditional is defined


procedure AddCaptionStrings(Strings: TStrings; UsedValuesBits: pointer = nil);

Add caption names, ready to be display, to a TStrings class
- add pointer(ord(element)) as Objects[] value
- if UsedValuesBits is not nil, only the corresponding bits set are added
- can be used e.g. to populate a combo box as such:

 PTypeInfo(TypeInfo(TMyEnum))^.EnumBaseType^.AddCaptionStrings(ComboBox.Items);

procedure GetEnumNameAll(out result: RawUtf8; const Prefix: RawUtf8 = ''; quotedValues: boolean = false; const Suffix: RawUtf8 = ''; trimedValues: boolean = false; unCamelCased: boolean = false); overload;

Retrieve all element names as CSV, with optional quotes


procedure GetEnumNameAll(var result: TRawUtf8DynArray; TrimLeftLowerCase: boolean); overload;

Retrieve all element names as a dynamic array of RawUtf8
- names could be optionally trimmed left from their initial lower chars


procedure GetEnumNameTrimedAll(var result: RawUtf8; const Prefix: RawUtf8 = ''; quotedValues: boolean = false; const Suffix: RawUtf8 = '');

Retrieve all trimed element names as CSV


procedure GetSetNameJsonArray(W: TTextWriter; Value: cardinal; SepChar: AnsiChar = ','; QuoteChar: AnsiChar = #0; FullSetsAsStar: boolean = false; ForceTrim: boolean = false); overload;

Write the enumeration names corresponding to a set value as a JSON array


procedure SetEnumFromOrdinal(out Value; Ordinal: PtrUInt);

Store an enumeration value from its ordinal representation


1.3.5. TRttiRecordField

TRttiRecordField = record

RTTI of a record/object type definition (managed) field
- defined here since this structure is not available in oldest Delphi's TypInfo.pas
- maps TRecordElement in FPC rtti.inc or TManagedField in TypInfo


Offset: PtrUInt;

Where this managed field starts in the record memory layout


TypeInfoRef: PPRttiInfo;

The RTTI of this managed field


1.3.6. TRttiInterfaceTypeData

TRttiInterfaceTypeData = object(TObject)

A wrapper to interface type information, as defined by the the compiler RTTI


function IntfFlags: TRttiIntfFlags;

Interface abilities - not inlined to avoid random trouble on FPC trunk


function IntfGuid: PGuid;

Interface 128-bit Guid


function IntfParent: PRttiInfo;

Ancestor interface type


function IntfUnit: PShortString;

Where the interface has been defined


1.3.7. TRttiRecordManagedFields

TRttiRecordManagedFields = record

Record RTTI as returned by TRttiInfo.RecordManagedFields


Count: PtrInt;

How many managed Fields[] are defined in this record


Fields: PRttiRecordField;

Points to the first field RTTI
- use inc(Fields) to go to the next one


Size: PtrInt;

The record size in bytes


1.3.8. TRttiRecordAllField

TRttiRecordAllField = record

Enhanced RTTI of a record/object type definition
- as returned by TRttiInfo.RecordAllFields on Delphi 2010+


Name: PShortString;

The field property name


Offset: PtrUInt;

The field offset in the record


TypeInfo: PRttiInfo;

The field RTTI definition


1.3.9. TRttiCache

TRttiCache = record

Convenient wrapper about PRttiInfo content and its more precise information
- is cached within TRttiCustom instances for more efficient process


BinarySize: byte;

If > 0, this type should be serialized as hexadecimal string


CodePage: cardinal;

From TypeInfo() on older Delphi with no CP RTTI


Engine: TSynAnsiConvert

RawBlob=CP_RAWBYTESTRING not CP_RAWBLOB


Flags: TRttiCacheFlags;

Quick identification of specific types, e.g. rkOrdinalTypes


Info: PRttiInfo;

The associated RTTI TypeInfo()


InterfaceGuid: PGuid;

= TRttiCustom of the rkInterface


ItemInfoRaw: PRttiInfo;

= nil for unmanaged types


ItemSize: integer;

From RTTI, likely <> nil for unmanaged types


Kind: TRttiKind;

Equals Info^.Kind


RttiFloat: TRttiFloat;

Type-specific information


RttiOrd: TRttiOrd;

For rkHasRttiOrdTypes/rcfHasRttiOrd, equals Info^.RttiOrd


RttiVarDataVType: word;

Pre-computed TRttiVarData.VType for TRttiCustomProp.GetRttiVarData
- rkEnumeration,rkSet,rkDynArray,rkClass,rkInterface,rkRecord,rkArray are identified as varAny with TVarData.VAny pointing to the actual value, and will be handled as expected by TJsonWriter.AddRttiVarData


SerializableInterface: pointer;

RkArray only


SerializableInterfaceEntryOffset: integer;

= TInterfacedSerializable


Size: integer;

The size in bytes of a value of this type - equals Info^.RttiSize


VarDataVType: word;

Corresponding TVarData.VType
- in respect to RttiVarDataVType, rkEnumeration and rkSet are varInt64 since we don't need the RTTI information as for TRttiVarData


1.3.10. TRttiInfo

TRttiInfo = object(TObject)

Main entry-point wrapper to access RTTI for a given pascal type
- as returned by the TypeInfo() low-level compiler function
- other RTTI objects can be computed from a pointer to this structure
- user types defined as an alias don't have this type information:

 type
   TNewType = TOldType;

here TypeInfo(TNewType) = TypeInfo(TOldType)
- user types defined as new types have this type information:

 type
   TNewType = type TOldType;

here TypeInfo(TNewType) <> TypeInfo(TOldType)


Kind: TRttiKind;

The value type family
- not defined as an inlined function, since first field is always aligned


RawName: ShortString;

The declared name of the type ('String','Word','RawUnicode'...)
- won't adjust internal/cardinal names on FPC as with Name method


function AnsiStringCodePage: integer;

Recognize most used string types, returning their code page
- will return the exact code page on FPC and since Delphi 2009, from RTTI
- for non Unicode versions of Delphi, will recognize WinAnsiString as CP_WINANSI, RawUnicode as CP_UTF16, RawByteString/RawBlob as CP_RAWBYTESTRING, AnsiString as CP_ACP=0, and any other type as RawUtf8
- it will also recognize RawBlob as the fake CP_RAWBLOB codepage


function ArrayItemType(out aDataCount, aDataSize: PtrInt): PRttiInfo;

For rkArray: get the static array type information of the stored item
- same as ArrayItemTypeExtended() but, always returns nil if the array type is unmanaged (i.e. like old Delphi)
- used e.g. for static array binary-level process in mormot.core.data


function ArrayItemTypeExtended(out aDataCount, aDataSize: PtrInt): PRttiInfo;

For rkArray: get the static array type information of the stored item
- may returns nil if the array type is unmanaged on old Delphi revisions
- aDataSize is the size in bytes of all aDataCount static items (not the size of each item)
- caller should ensure the type is indeed a static array


function ArraySize: PtrInt;

For rkArray: get the size in bytes of all the static array items
- caller should ensure the type is indeed a static array


function ClassFieldCount(onlyWithoutGetter: boolean): integer;

For rkClass: return the number of published properties in this class
- you can count the plain fields without any getter function, if you do need only the published properties corresponding to some value actually stored, and ignore e.g. any textual conversion


function DynArrayItemSize: PtrInt;

For rkDynArray: get the dynamic array size (in bytes) of the stored item


function DynArrayItemType(out aDataSize: PtrInt): PRttiInfo; overload;

For rkDynArray: get the dynamic array type information of the stored item
- returns nil if the item has no managed field
- this overloaded method will also return the item size in bytes
- caller should ensure the type is indeed a dynamic array


function DynArrayItemType: PRttiInfo; overload;

For rkDynArray: get the dynamic array standard RTTI of the stored item
- returns nil if the item has no managed field
- caller should ensure the type is indeed a dynamic array


function DynArrayItemTypeExtended: PRttiInfo;

For rkDynArray: get the dynamic array deep RTTI of the stored item
- works for both managed and unmanaged types, on FPC and Delphi 2010+
- caller should ensure the type is indeed a dynamic array


function EnumBaseType: PRttiEnumType; overload;

For rkEnumeration: get the enumeration type information


function EnumBaseType(out NameList: PShortString; out Min, Max: integer): PRttiEnumType; overload;

For rkEnumeration: get the enumeration values information


function InheritsFrom(AClass: TClass): boolean;

For rkClass: fast and easy check if a class inherits from this RTTI


function InterfaceAncestor: PRttiInfo;

For rkInterface: get the ancestor/parent of a given interface type information
- returns nil if this type has no parent


function InterfaceGuid: PGuid;

For rkInterface: get the TGuid of a given interface type information
- returns nil if this type is not an interface


function InterfaceImplements(const AGuid: TGuid): boolean;

For rkInterface: check if this type (or ancestor) implements a TGuid


function InterfaceType: PRttiInterfaceTypeData;

For rkInterface: get the interface type information


function InterfaceUnitName: PShortString;

For rkInterface: get the unit name of a given interface type information
- returns '' if this type is not an interface


function IsBoolean: boolean;

Return TRUE if the property is a boolean field


function IsCurrency: boolean;

Return TRUE if the property is a currency field


function IsDate: boolean;

Return TRUE if the property is a TDateTime/TDateTimeMS/TDate


function IsManaged: boolean;

Check if this type is a managed type, or has any managed field
- will also check for the nested fields e.g. for rkRecordTypes


function IsQWord: boolean;

Return TRUE if the property is an unsigned 64-bit field (QWord/UInt64)


function IsRawBlob: boolean;

Return true if this property is a BLOB (RawBlob)


function Name: PShortString;

The declared name of the type ('String','Word','RawUnicode'...)
- will return '' if @self is nil
- on FPC, will adjust 'integer'/'cardinal' from 'longint'/'longword' RTTI
- on Delphi and FPC, will adjust weak RawUtf8 = UTF8String as 'RawUtf8'


function RecordAllFields(out RecSize: PtrInt): TRttiRecordAllFields;

For rkRecordTypes: retrieve enhanced RTTI information about all fields of this record, for JSON serialization without text definition
- this information is currently only available since Delphi 2010
- if any field has no RTTI (e.g. a static array of unmanaged type), then it will ignore this uncomplete, therefore non-useful RTTI
- in practice, it may be a good habit to always define the records used within the SOA (e.g. as DTOs) calling RegisterFromText, and don't rely on this RTTI, since it will be more cross-platform, and more customizable


function RecordManagedFieldsCount: integer;

For rkRecordTypes: check if this record as any managed fields


function RecordSize: PtrInt;

For rkRecordTypes: get the record size
- returns 0 if the type is not a record/object


function RttiClass: PRttiClass;

For rkClass: get the class type information


function RttiFloat: TRttiFloat;

For rkFloat: get the storage size and precision
- will also properly detect our currency internal type as rfCurr


function RttiNonVoidClass: PRttiClass;

For rkClass: get the class type information


function RttiOrd: TRttiOrd;

For ordinal types, get the storage size and sign


function RttiSize: PtrInt;

Compute in how many bytes this type is stored
- will use Kind (and RttiOrd/RttiFloat) to return the exact value


function SetEnumSize: PtrInt;

For rkSet: in how many bytes this type is stored
- is very efficient on latest FPC only - i.e. ifdef ISFPC32


function SetEnumType: PRttiEnumType; overload;

For rkSet: get the type information of its associated enumeration


function SetEnumType(out NameList: PShortString; out Min, Max: integer): PRttiEnumType; overload;

For rkSet: get the associated enumeration values information


procedure Clear(Data: pointer);

Efficiently finalize any (managed) type value
- do nothing for unmanaged types (e.g. integer)
- if you are sure that your type is managed, you may call directly

 RTTI_FINALIZE[Info^.Kind](Data, Info);

procedure ComputeCache(var Cache: TRttiCache);

Compute extended information about this RTTI type


procedure Copy(Dest, Source: pointer);

Efficiently copy any (managed) type value
- do nothing for unmanaged types (e.g. integer)
- if you are sure that your type is managed, you may call directly

 RTTI_MANAGEDCOPY[Info^.Kind](Dest, Source, Info);

procedure InterfaceAncestors(out Ancestors: PRttiInfoDynArray; OnlyImplementedBy: TInterfacedObjectClass; out AncestorsImplementedEntry: TPointerDynArray);

For rkInterface: get all ancestors/parents of a given interface type information
- only ancestors with an associated TGuid will be added
- if OnlyImplementedBy is not nil, only the interface explicitly implemented by this class will be added, and AncestorsImplementedEntry[] will contain the corresponding PInterfaceEntry values


procedure RecordManagedFields(out Fields: TRttiRecordManagedFields);

For rkRecordTypes: retrieve RTTI information about all managed fields of this record
- non managed fields (e.g. integers, double...) are not listed here
- also includes the total record size in bytes
- caller should ensure the type is indeed a record/object
- note: if FPC_OLDRTTI is defined, unmanaged fields are included


procedure StringToUtf8(Data: pointer; var Value: RawUtf8);

Retrieve rkLString, rkSString, rkUString, rkWString, rkChar, rkWChar values as RawUtf8, from a pointer to its memory storage
- makes heap allocations and encoding conversion, so may be slow


1.3.11. TRttiProp

TRttiProp = object(TObject)

A wrapper containing a RTTI class property definition
- used for direct Delphi / UTF-8 SQL type mapping/conversion
- doesn't depend on RTL's TypInfo unit, to enhance cross-compiler support


function Default: integer;

Contains the default value for an ordinal or set property
- NO_DEFAULT=$80000000 indicates none was defined in source code
- see also TPropInfo.DefaultOr0


function DefaultOr0: integer;

Return the Default RTTI value defined for this property, or 0 if not set


function FieldSize: PtrInt;

Compute in how many bytes this property is stored


function GetAsString(Instance: TObject): RawUtf8; overload;

Retrieve rkLString, rkSString, rkUString, rkWString, rkChar, rkWChar as RawUtf8
- just a wrapper around the overloaded GetAsString() function


function GetAsString(Instance: TObject; var Value: RawUtf8): boolean; overload;

Retrieve rkLString, rkSString, rkUString, rkWString, rkChar, rkWChar as RawUtf8
- this would make heap allocations and encoding conversion, so may be slow


function GetDoubleProp(Instance: TObject): double;

Raw retrieval of rkFloat/double


function GetDoubleValue(Instance: TObject): double;

Low-level getter of the floating-point property value of a given instance
- this method will check if the corresponding property is floating-point
- return 0 on any error


function GetDynArrayPropGetter(Instance: TObject): pointer;

Raw retrieval of rkDynArray getter as a pointer
- caller should then release the instance using e.g. FastDynArrayClear()
- do nothing if the property is a field with no getter


function GetFieldAddr(Instance: TObject): pointer;

Low-level getter of the field value memory pointer
- return NIL if both getter and setter are methods


function GetFloatProp(Instance: TObject): double;

Raw retrieval of rkFloat - with conversion to 64-bit double
- use instead GetDoubleProp if you know the property is a rkFloat/double


function GetInt64Prop(Instance: TObject): Int64;

Raw retrieval of rkInt64, rkQWord
- rather call GetInt64Value


function GetInt64Value(Instance: TObject): Int64;

Low-level getter of the ordinal property value of a given instance
- this method will check if the corresponding property is ordinal
- ordinal properties smaller than rkInt64 will return an Int64-converted value (e.g. rkInteger)
- return 0 on any error


function GetObjProp(Instance: TObject): TObject;

Raw retrieval of rkClass


function GetOrdProp(Instance: TObject): Int64;

Raw retrieval of rkInteger,rkEnumeration,rkSet,rkChar,rkWChar,rkBool
- rather call GetOrdValue/GetInt64Value
- returns an Int64 to properly support cardinal values


function GetOrdValue(Instance: TObject): Int64;

Low-level getter of the ordinal property value of a given instance
- this method will check if the corresponding property is ordinal
- returns an Int64 to properly support cardinal values
- return -1 on any error


function Getter(Instance: TObject; Call: PMethod): TRttiPropCall;

Raw retrieval of the property read access definition
- note: 'var Call' generated incorrect code on Delphi XE4 -> use PMethod


function GetterAddr(Instance: pointer): pointer;

Returns the low-level field read address, if GetterIsField is TRUE


function GetterCall: TRttiPropCall;

Returns how a property should be retrieved
- no "read" attribute specified will return rpcField if "write" is a direct field access - just like any Get*() method would do


function GetterIsField: boolean;

Return TRUE if the property has no getter but direct field read
- returns FALSE if no "read" attribute was specified: use GetterCall if you want to mimic how Get*() methods could use the "write" field


function GetValueText(Instance: TObject): RawUtf8;

Get a property value into text
- handle all kind of fields, e.g. converting ordinal or floats into text


function Index: integer;

Contains the index value of an indexed class data property
- outside SQLite3, this can be used to define a VARCHAR() length value for the textual field definition (sftUtf8Text/sftAnsiText); e.g. the following will create a NAME VARCHAR(40) field:

 Name: RawUtf8 index 40 read fName write fName;

- is used by a dynamic array property for fast usage of the TOrm.DynArray(DynArrayFieldIndex) method


function IsRawBlob: boolean;

Return true if this property is a BLOB (RawBlob)


function IsStored(Instance: TObject): boolean;

Return the "stored true/false/method/field" value for a class property
- not used internally: for backward compatibility only


function IsStoredGetter(Instance: TObject): boolean;

Raw retrieval of the 'stored' flag using getter
- called by IsStored or for TRttiPropStored = rpsGetter


function IsStoredKind: TRttiPropStored;

Returns rpsTrue/rpsFalse if was marked as "stored true/false" or rpsGetter if IsStoredGetter(Instance) is to be called at runtime


function Name: PShortString;

The property Name, directly returned from RTTI


function NameIndex: integer;

Index of the property in the current inherited class definition
- first name index at a given class level is 0
- index is reset to 0 at every inherited class level


function NameUtf8: RawUtf8;

The property Name, converted as a RawUtf8


function Next: PRttiProp;

Get the next property information
- no range check: use RttiProps()^.PropCount to determine the properties count
- get the first PRttiProp with RttiProps()^.PropList


function SetAsString(Instance: TObject; const Value: RawUtf8): boolean;

Set rkLString, rkSString, rkUString, rkWString, rkChar, rkWChar from a RawUtf8 value
- this would make heap allocations and encoding conversion, so may be slow


function Setter(Instance: TObject; Call: PMethod): TRttiPropCall;

Raw retrieval of the property access definition


function SetterAddr(Instance: pointer): pointer;

Returns the low-level field write address, if SetterIsField is TRUE


function SetterCall: TRttiPropCall;

Returns how a property should be set
- no "write" attribute specified will return rpcField if "read" is a direct field access - just like any Set*() method would do


function SetterIsField: boolean;

Return TRUE if the property has no setter but direct field write
- returns FALSE if no "write" attribute is specified: use SetterCall if you want to mimic how Set*() methods could use the "read" field


function SetValue(Instance: TObject; const Value: variant): boolean;

Set a property value from a variant value
- to be called when a setter is involved - not very fast, but safe


function SetValueText(Instance: TObject; const Value: RawUtf8): boolean;

Set a property value from a text value
- handle simple kind of fields, e.g. converting from text into ordinals or floats, and also enumerates or sets; but won't support complex types like class instances, dynamic arrays or variants


function TypeInfo: PRttiInfo;

The type information of this property
- will de-reference the PropType pointer on Delphi and newer FPC compilers


function WriteIsDefined: boolean;

Return TRUE if the property has a write setter or direct field


procedure CopyLongStrProp(Source, Dest: TObject);

Raw copy of rkLString


procedure GetCurrencyProp(Instance: TObject; var Value: currency);

Raw retrieval of rkFloat/currency
- use instead GetCurrencyValue


procedure GetCurrencyValue(Instance: TObject; var Value: currency);

Low-level getter of the currency property value of a given instance
- this method will check if the corresponding property is exactly currency
- return 0 on any error


procedure GetLongStrProp(Instance: TObject; var Value: RawByteString);

Raw retrieval of rkLString


procedure GetRawByteStringValue(Instance: TObject; var Value: RawByteString);

Low-level getter of the long string property content of a given instance
- just a wrapper around low-level GetLongStrProp() function
- call GetLongStrValue() method if you want a conversion into RawUtf8
- will work only for Kind=rkLString


procedure GetShortStrProp(Instance: TObject; var Value: RawUtf8);

Raw retrieval of rkString into an Ansi7String


procedure GetVariantProp(Instance: TObject; var Result: Variant; SetByRef: boolean);

Raw retrieval of rkVariant
- will use varByRef from the field address if SetByRef is true


procedure GetWideStrProp(Instance: TObject; var Value: WideString);

Raw retrieval of rkWString


procedure SetCurrencyProp(Instance: TObject; const Value: currency);

Raw assignment of rkFloat/currency


procedure SetDoubleProp(Instance: TObject; Value: Double);

Raw assignment of rkFloat/double


procedure SetDoubleValue(Instance: TObject; const Value: double);

Low-level setter of the floating-point property value of a given instance
- this method will check if the corresponding property is floating-point


procedure SetFloatProp(Instance: TObject; Value: TSynExtended);

Raw assignment of rkFloat
- use instead SetDoubleProp if you know the property is a rkFloat/double


procedure SetInt64Prop(Instance: TObject; const Value: Int64);

Raw assignment of rkInt64, rkQWord
- rather call SetInt64Value


procedure SetInt64Value(Instance: TObject; Value: Int64);

Low-level setter of the ordinal property value of a given instance
- this method will check if the corresponding property is ordinal


procedure SetLongStrProp(Instance: TObject; const Value: RawByteString);

Raw assignment of rkLString


procedure SetOrdProp(Instance: TObject; Value: PtrInt);

Raw assignment of rkInteger,rkEnumeration,rkSet,rkChar,rkWChar,rkBool
- rather call SetOrdValue/SetInt64Value


procedure SetOrdValue(Instance: TObject; Value: PtrInt);

Low-level setter of the ordinal property value of a given instance
- this method will check if the corresponding property is ordinal


procedure SetVariantProp(Instance: TObject; const Value: Variant);

Raw assignment of rkVariant


procedure SetWideStrProp(Instance: TObject; const Value: WideString);

Raw assignment of rkWString


1.3.12. PropWrap

PropWrap = packed record

Used to map a TPropInfo.GetProc/SetProc and retrieve its kind
- defined here for proper Delphi inlining


Kind: byte;

=$ff for a ptField address, or =$fe for a ptVirtual method


1.3.13. TPropData

TPropData = packed record

PPropData not defined in Delphi 7/2007 TypInfo
- defined here for proper Delphi inlining


1.3.14. TRecordInfo

TRecordInfo = packed record

RkRecord RTTI is not defined in Delphi 7/2007 TTypeData
- defined here for proper Delphi inlining


1.3.15. TArrayInfo

TArrayInfo = packed record

RkArray RTTI not defined in Delphi 7/2007 TTypeData
- defined here for proper Delphi inlining


1.3.16. TPublishedMethodInfo

TPublishedMethodInfo = record

Information about one method, as returned by GetPublishedMethods


Method: TMethod;

A callback to the method, for the given class instance


Name: RawUtf8;

The method name


1.3.17. TRttiMethod

TRttiMethod = record

Store IInvokable method information


Args: array of TRttiMethodArg;

The method arguments


HierarchyLevel: integer;

0 for the root interface, >0 for inherited interfaces


IsFunction: boolean;

If this method is a function, i.e. expects a result


Name: RawUtf8;

The method name, e.g. 'Add' for ICalculator.Add


1.3.18. TRttiInterface

TRttiInterface = record

Store IInvokable methods information


Guid: TGuid;

The associated GUID of this interface


Methods: array of TRttiMethod;

The interface methods


Name: RawUtf8;

The interface name, e.g. 'ICalculator'


UnitName: RawUtf8;

The unit where the interface was defined


1.3.19. TRttiVarData

TRttiVarData = packed record

Variant-like value as returned by TRttiCustomProp.GetRttiVarData
- used internally by TRttiCustomProp.AddValueJson/CompareValueComplex (handled in TJsonWriter.AddVariant/AddRttiVarData methods)
- simple values (integers, floats, strings or variant) are set into Data
- rkEnumeration, rkSet, rkDynArray, rkClass, rkInterface, rkRecord and rkObject are stored as varAny/PropValue pointer to the field value (for GetRttiVarDataDirect) or Instance (for GetRttiVarDataGetter if PropValueIsInstance is true), and Prop to the corresponding property RTTI
- varAny is NON-STANDARD, so should NOT be used as a plain variant, e.g. calling Prop.SetValueVariant(RVD.Data) or transtyping variant(RVD)
- use TSynVarData if you want a TVarData exact wrapper with 32-bit VType
- for varAny, Prop contains additional RTTI and NeedsClear should be checked:

 if RVD.NeedsClear then VarClearProc(RVD.Data);

Data: TVarData

Maps DataType + NeedsClear + PropValueIsInstance


NeedsClear: boolean;

Matches TVarData.VType


Prop: PRttiCustomProp;

Assert(@PropValue=@VAny) is done in initialization section below


1.3.20. TRttiCustomProp

TRttiCustomProp = object(TObject)

Store information about one property/field of a given TypeInfo/PRttIinfo
- used by both rkClass for published properties, and rkRecord/rkObject for nested fields


Name: RawUtf8;

Contains Prop^.Name or a customized field/property name
- equals '' if Props.NameChange() was set to New='', meaning this field should not be part of the serialized JSON object


OffsetGet: PtrInt;

Read field/property offset in the record/class instance memory
- equals -1 if Prop has a getter


OffsetSet: PtrInt;

Write field/property offset in the record/class instance memory
- equals -1 if Prop has a setter


OrdinalDefault: integer;

Equals NO_DEFAULT or the default integer value of this property


Prop: PRttiProp;

Store standard RTTI of this published property
- equals nil for rkRecord/rkObject nested field


Stored: TRttiPropStored;

Reflect the "stored" property attribute as defined in the source


Value: TRttiCustom;

Contains standard TypeInfo/PRttiInfo of this field/property
- for instance, Value.Size contains its memory size in bytes


function CompareValue(Data, Other: pointer; const OtherRtti: TRttiCustomProp; CaseInsensitive: boolean): integer;

Compare two properties values with proper getter method call
- is likely to call Value.ValueCompare() which requires mormot.core.json


function NameMatch(P: PUtf8Char; Len: PtrInt): boolean;

Case-insensitive compare the supplied name/len with the Name property


function SetValueText(Data: pointer; const Text: RawUtf8): boolean;

Set a field value from its UTF-8 text
- will convert the Text into proper ordinal or float if needed
- also implemented for Prop = nil (i.e. rkRecord/rkObject nested field)
- use Prop^.SetValueText() if you want to support enumerates and sets


function ValueIsDefault(Data: pointer): boolean;

Check if the Value equals the default property set in source code
- caller should have checked that PropDefault <> NO_DEFAULT


function ValueIsVoid(Data: pointer): boolean;

Check if the Value is void (0 / '' / null)
- less restrictive function than VarIsVoid() from mormot.core.variants


procedure AddValueJson(W: TTextWriter; Data: pointer; Options: TTextWriterWriteObjectOptions; K: TTextWriterKind = twNone);

Append the field value as JSON with proper getter method call
- wrap GetRttiVarData() + AddVariant() over a temp TRttiVarData


procedure ClearValue(Data: pointer; FreeAndNilNestedObjects: boolean);

Low-level initialization of one property value


procedure CopyValue(Dest, Source: PAnsiChar; DestRtti: PRttiCustomProp);

Low-level copy of two properties values


procedure GetValueJson(Data: pointer; out Result: RawUtf8);

A wrapper calling AddValueJson()


procedure GetValueVariant(Data: pointer; out Dest: TVarData; Options: pointer = nil);

Retrieve any field value as a variant instance
- will generate a stand-alone variant value, not an internal TRttiVarData
- complex values can be returned as TDocVariant after JSON conversion, using e.g. @JSON_[mFastFloat] as optional Options parameter


procedure SetValueVariant(Data: pointer; var Source: TVarData);

Set a field value to a given variant content
- use a temporary text conversion for a record field (Prop=nil)
- Source is eventually cleared via VarClearProc()
- typical usage is from GetValueVariant() output
- do not use the output of GetRttiVarData() as Source


1.3.21. TRttiCustomProps

TRttiCustomProps = object(TObject)

Store information about all properties/fields of a given TypeInfo/PRttIinfo
- includes parent properties when filled by AddFromClass(IncludeParents=true)


Count: integer;

How many properties/fields are in List[]


CountNonVoid: integer;

How many properties/fields with Name <> '' are in List[]


List: TRttiCustomPropDynArray;

One List[] item per property/field


Managed: PRttiCustomPropDynArray;

Points to List[] items which are managed


NamesAsJsonArray: RawUtf8;

Contains List[].Name as a JSON array including a trailing ,
- as used by _JS_DynArray() for efficient twoNonExpandedArrays generation


NotInheritedIndex: integer;

List[NotInheritedIndex]..List[Count-1] store the last level of properties


Size: integer;

Total size, in bytes, of all properties/fields
- equals the sum of List[].Value.Size


function AdjustAfterAdded: TRttiCustomFlags;

Called once List[] and Size have been defined
- compute the Managed[] internal list and return the matching flags


function Find(PropName: PUtf8Char; PropNameLen: PtrInt): PRttiCustomProp; overload;

Locate a property/field by name
- just redirect to FindCustomProp() low-level function


function Find(const PropName: RawUtf8): PRttiCustomProp; overload;

Locate a property/field by name
- just redirect to FindCustomProp() low-level function


function FindIndex(const PropName: RawUtf8): PtrInt; overload;

Locate a property/field index by name


function FindIndex(PropName: PUtf8Char; PropNameLen: PtrInt): PtrInt; overload;

Locate a property/field index by name


function FromTextPrepare(const PropName: RawUtf8): integer;

Prepare List[result].Name from TRttiCustom.SetPropsFromText


function NameChange(const Old, New: RawUtf8): PRttiCustomProp;

Customize a property/field name
- New is expected to be only plain pascal identifier, i.e. A-Z a-z 0-9 and _ characters, up to 63 in length
- if New equals '', this published property will be excluded from the JSON serialized object


procedure AsText(out Result: RawUtf8; IncludePropType: boolean; const Prefix, Suffix: RawUtf8);

Retrieve all List[] items as text


procedure CopyProperties(Dest, Source: PAnsiChar);

Copy the properties of a rkClass instance
- called e.g. when no RTTI is available, i.e. text serialization
- will copy all published properties one-by-one


procedure CopyRecord(Dest, Source: PAnsiChar);

Copy the fields of a rkRecordTypes instance
- called e.g. when no RTTI is available, i.e. text serialization
- will move() all bytes between managed fields


procedure FinalizeAndClearPublishedProperties(Instance: TObject);

Finalize and fill with zero all properties of this class instance
- it will individually fill the properties, not the whole memory as TRttiCustom.FinalizeAndClear would on a record


procedure FinalizeManaged(Data: PAnsiChar);

Finalize the managed properties of this instance
- called e.g. when no RTTI is available, i.e. text serialization


procedure InternalAdd(Info: PRttiInfo; Offset: PtrInt; const PropName: RawUtf8; AddFirst: boolean = false);

Manual adding of a property/field definition
- append as last field, unless AddFirst is set to true


procedure InternalAddFromClass(ClassInfo: PRttiInfo; IncludeParents: boolean);

Register the published properties of a given class
- is called recursively if IncludeParents is true


procedure InternalClear;

Reset all properties


procedure NameChanges(const Old, New: array of RawUtf8);

Customize property/field name, specified as old/new pairs
- will first restore all field names from RTTI, then each Old[] field name will be replaced by the corresponding New[] name
- so setting both Old=New=[] just set back the default names from RTTI
- New[] is expected to be only plain pascal identifier, i.e. A-Z a-z 0-9 and _ characters, up to 63 in length
- if any New[] equals '', this published property will be excluded from the JSON serialized object
- Rtti.ByClass[TMyClass].Props.NameChanges() replaces deprecated TJsonSerializer.RegisterCustomSerializerFieldNames(TMyClass, ...)


procedure SetFromRecordExtendedRtti(RecordInfo: PRttiInfo);

Register the properties specified from extended RTTI (Delphi 2010+ only)
- do nothing on FPC or Delphi 2009 and older


1.3.22. TRttiCustom

TRttiCustom = class(TObject)

Allow to customize the process of a given TypeInfo/PRttiInfo
- a global list of TRttiCustom instances mapping TypeInfo() is maintained in Rtti: TRttiCustomList
- never instantiate this class directly, but call RttiCustom methods


constructor CreateFromText(const RttiDefinition: RawUtf8);

Initialize abstract custom serialization for a given record
- not registered in the main TRttiCustomList: caller should free it
- in practice, is used only by test.core.data.pas regression tests


destructor Destroy; override;

Finalize this instance


function ClassNewInstance: pointer;

Create a new TObject instance of this rkClass
- not implemented here (raise an ERttiException) but in TRttiJson, so that mormot.core.rtti has no dependency to TSynPersistent and such


function ComputeFakeObjArrayRtti(aItemClass: TClass): TBytes;

Create a fake TRttiCustom clone with an overloaded ArrayRtti/ObjArrayClass


function GetPrivateSlot(aClass: TClass): pointer;

Retrieve an instance of a given class per RTTI
- previously registered by SetPrivateSlot


function HasClassNewInstance: boolean;

Check if this type has ClassNewInstance information


function PropFindByPath(var Data: pointer; FullName: PUtf8Char; PathDelim: AnsiChar = '.'): PRttiCustomProp;

Recursively search for 'one.two.three' nested properties
- returns nil if not found
- returns the property information and let Data point to its associated rkClass or rkRecord/rkObject owner


function SetPrivateSlot(aObject: TObject): pointer;

Register once an instance of a given class per RTTI
- thread-safe returns aObject, or an existing object (freeing aObject)
- just like PrivateSlot property, but for as many class as needed


function ValueByPath(var Data: pointer; Path: PUtf8Char; var Temp: TVarData; PathDelim: AnsiChar = '.'): TRttiCustom; virtual;

Lookup a value by a path name e.g. 'one.two.three' nested values
- for a record/class, will search for a property name
- for a TDocVariant/TBsonVariant, calls TSynInvokeableVariantType.IntGet
- for an enumeration or set, will return true/false about the enum name
- for a string, Data^ will be compared to the name
- implemented in TRttiJson for proper knowledge of our variants


function ValueCompare(Data, Other: pointer; CaseInsensitive: boolean): integer; virtual;

{$ifdef HASINLINE}inline;{$endif} compare two stored values of this type
- not implemented in this class (raise an ERttiException) but in TRttiJson, so that it will use mormot.core.data comparison


function ValueIsVoid(Data: PAnsiChar): boolean;

Return TRUE if the Value is 0 / nil / '' / null
- less restrictive function than VarIsVoid() from mormot.core.variants


function ValueIterate(Data: pointer; Index: PtrUInt; out ResultRtti: TRttiCustom): pointer; virtual;

Iterate over one sub-item of a given value
- returns nil if the value is not iterable or Index is out of range
- returns a pointer to the value, rkClass/rkLString kinds being already resolved (as the TList/TSynList/TRawUtf8List items are returned), so you can directly trans-type the result to TObject() or RawUtf8()
- ResultRtti holds the type of the resolved result pointer
- note that TStrings values are not supported, because they require a temporary string variable for their getter method
- implemented in TRttiJson for proper knowledge of TSynList/TRawUtf8List


function ValueIterateCount(Data: pointer): integer; virtual;

How many iterations could be done one a given value
- returns -1 if the value is not iterable, or length(DynArray) or TRawUtf8List.Count or TList.Count or TSynList.Count
- implemented in TRttiJson for proper knowledge of TSynList/TRawUtf8List


function ValueSetText(Data: pointer; const Text: RawUtf8): boolean;

Set a property value from a text value
- handle most kind of fields, e.g. converting from text into ordinal or floats


function ValueToVariant(Data: pointer; out Dest: TVarData; Options: pointer = nil): PtrInt; virtual;

Fill a variant with a stored value of this type
- not implemented in this class (raise an ERttiException) but in TRttiJson, so that it will use mormot.core.variants process
- complex values can be returned as TDocVariant after JSON conversion, using e.g. @JSON_[mFast] as optional Options parameter
- returns the size of the Data in bytes, i.e. Cache.ItemSize


procedure FromRtti(aInfo: PRttiInfo); virtual;

Initialize the customizer class from known RTTI
- is called just after Create


procedure PropsClear;

Reset all stored Props[] and associated flags


procedure SetClassNewInstance(FactoryMethod: TRttiCustomNewInstance);

Allow low-level customization of the fNewInstance pointer


procedure ValueCopy(Dest, Source: pointer);

Efficiently copy of a stored value of this type
- same behavior as Dest := Source for all types


procedure ValueFinalize(Data: pointer);

Efficiently finalize a stored value of this type
- if rcfObjArray is defined in Flags, will release all nested TObject


procedure ValueFinalizeAndClear(Data: pointer);

Efficiently finalize a stored value of this type, and fill it with zeros
- if rcfObjArray is defined in Flags, will release all nested TObject


procedure ValueRandom(Data: pointer);

Fill a value from random - including strings and nested types


procedure ValueWriteText(Data: pointer; W: TTextWriter; HtmlEscape: boolean); virtual;

Serialize a value into (HTML) text
- implemented in TRttiJson for proper knowledge of complex types
- warning: supplied W instance should be a TJsonWriter


property ArrayFirstField: TRttiParserType read fArrayFirstField;

Best guess of first field type for a rkDynArray
- equals ArrayRtti.Parser if ArrayRtti.Kind is not rkRecordTypes


property ArrayFirstFieldSort: TRttiParserType read fArrayFirstFieldSort;

Best guess of first field type for a rkDynArray
- equals ArrayFirstField or an ordinal type matching the enum/set type


property ArrayRtti: TRttiCustom read fArrayRtti;

Shortcut to the TRttiCustom of the item of a (dynamic) array
- only set for rkArray and rkDynArray
- may be set also for unmanaged types - use Cache.ItemInfo if you want the raw PRttiInfo TypeInfo() pointer for rkManagedTypes only


property BinarySize: byte read fCache.BinarySize;

Store the number of bytes for hexadecimal serialization for rcfBinary
- used when rcfBinary is defined in Flags; equals 0 if disabled (default)


property Cache: TRttiCache read fCache;

Direct access to the ready-to-use RTTI


property CollectionItem: TCollectionItemClass read fCollectionItem;

Store the Item class for a given TCollection
- as previously registered by Rtti.RegisterCollection()


property Copy: TRttiCopier read fCopy;

Redirect to the low-level value copy - use rather ValueCopy()


property CopyObject: TRttiClassCopier read fCopyObject write fCopyObject;

Redirect to the low-level class instance copy
- nil by default, to use Props.CopyProperties()
- is overwritten e.g. by TOrm.RttiCustomSetParser


property Flags: TRttiCustomFlags read fFlags write fFlags;

Define specific behavior for this type


property Info: PRttiInfo read fCache.Info;

Direct access to the low-level RTTI TypeInfo() pointer, from Rtti property


property JsonLoad: pointer read fJsonLoad write fJsonLoad;

Opaque TRttiJsonLoad callback used by mormot.core.json.pas


property JsonReader: TMethod read fJsonReader write fJsonReader;

Opaque TOnRttiJsonRead callback used by mormot.core.json.pas


property JsonSave: pointer read fJsonSave write fJsonSave;

Opaque TRttiJsonSave callback used by mormot.core.json.pas


property JsonWriter: TMethod read fJsonWriter write fJsonWriter;

Opaque TOnRttiJsonWrite callback used by mormot.core.json.pas


property Kind: TRttiKind read fCache.Kind;

Low-level RTTI kind, taken from Rtti property


property Name: RawUtf8 read fName;

The known type name
- may be an hexadecimal value of self, if rcfWithoutRtti is in Flags


property ObjArrayClass: TClass read fObjArrayClass;

Store the class of a T*ObjArray dynamic array
- shortcut to ArrayRtti.Info.RttiClass.RttiClass
- used when rcfObjArray is defined in Flags


property Parser: TRttiParserType read fParser;

High-level Parser kind


property ParserComplex: TRttiParserComplexType read fParserComplex;

High-level Parser Complex kind


property PrivateSlot: pointer read fPrivateSlot write fPrivateSlot;

Opaque private instance used by mormot.orm.base.pas or mormot.core.log.pas
- stores e.g. the TOrmProperties ORM information of a TOrm, or the TSynLogFamily of a TSynLog instance
- is owned, as TObject, by this TRttiCustom
- assignment is usually protected by the Rtti.RegisterSafe


property Props: TRttiCustomProps read fProps;

Store information about the properties/fields of this type
- only set for rkClass and rkRecord/rkObject


property Size: integer read fCache.Size;

Direct access to the low-level size in bytes used to store a value of this type, as taken from Rtti property
- warning: for rkArray/rkDynArray, equals SizeOf(pointer), not the item size, which is hold in Cache.ItemSize


property ValueClass: TClass read fValueClass;

Store the class of this type, i.e. contains Cache.Info.RttiClass.RttiClass


property ValueRtlClass: TRttiValueClass read fValueRtlClass;

Identify most common RTL inherited classes for special handling
- recognize TCollection TStrings TObjectList TList parents
- TRttiValueClass enumerate is faster than InheritsFrom() call


1.3.23. TRttiCustomListPairs

TRttiCustomListPairs = record

Efficient PRttiInfo/TRttiCustom pairs for TRttiCustomList hash table
- as stored in TRttiCustomList.fHashTable[RK_TOSLOT[TRttiKind]]
- contains hash tables by TypeInfo() and by case-insensitive name


HashInfo: array[0..RTTIHASH_MAX] of TPointerDynArray;

CPU L1 cache efficient PRttiInfo/TRttiCustom pairs hashed by PRttiInfo


HashName: array[0..RTTIHASH_MAX] of TPointerDynArray;

CPU L1 cache efficient PRttiInfo/TRttiCustom pairs hashed by Name


LastHash: array[0..RTTIHASH_MAX] of TRttiCustom;

Thread-safe speedup search by PRttiInfo e.g. from a loop


LastInfo: TRttiCustom;

Thread-safe speedup search by PRttiInfo e.g. from a loop


LastName: TRttiCustom;

Speedup search by name e.g. from a loop


Safe: TRWLightLock;

Efficient HashInfo/HashName[] pairs thread-safety during Find/AddToPairs


1.3.24. TRttiCustomList

TRttiCustomList = class(TObject)

Maintain a thread-safe list of PRttiInfo/TRttiCustom/TRttiJson registration


Count: integer;

Ensure Count=0 how many TRttiCustom instances have been registered


Counts: array[TRttiKind] of integer;

How many TRttiCustom instances have been registered for a given type
- we include rkUnknown for safety


RegisterSafe: TOSLock;

A global lock shared for high-level RTTI registration process
- is used e.g. to protect DoRegister() or TRttiCustom.PrivateSlot
- should be a reentrant lock, even if seldom called


constructor Create;

Initialize the RTTI list


destructor Destroy; override;

Finalize the RTTI list


function DoRegister(ObjectClass: TClass): TRttiCustom; overload;

Low-level registration function called from RegisterClass()
- is sometimes called after manual vmtAutoTable slot lookup


function FindByArrayRtti(ElemInfo: PRttiInfo): TRttiCustom;

Manual search of any matching TRttiCustom.ArrayRtti type
- currently not called: IList<T> and IKeyValue<T> just use TypeInfo(T)


class function FindClass(ObjectClass: TClass): TRttiCustom;

Efficient search of TRttiCustom from a given TObject class
- returns nil if Info is not known
- will use the ObjectClass vmtAutoTable slot for very fast O(1) lookup, or use our "hash table of the poor" (tm) if NOPATCHVMT conditional is set


function FindName(const Name: ShortString; Kinds: TRttiKinds = []): TRttiCustom; overload;

Efficient search of TRttiCustom from a given type name


function FindName(Name: PUtf8Char; NameLen: PtrInt; Kind: TRttiKind): TRttiCustom; overload;

Efficient search of TRttiCustom from a given type name


function FindName(Name: PUtf8Char; NameLen: PtrInt; Kinds: TRttiKinds = []): TRttiCustom; overload;

Efficient search of TRttiCustom from a given type name


function FindType(Info: PRttiInfo): TRttiCustom;

Efficient search of TRttiCustom from a given RTTI TypeInfo()
- returns nil if Info is not known
- call RegisterType() if you want to initialize the type via its RTTI
- not inlined since less efficient code is generated


function RegisterAutoCreateFieldsClass(ObjectClass: TClass): TRttiCustom;

Register a given class type, using its RTTI, to auto-create/free its class and dynamic array published fields


function RegisterBinaryType(Info: PRttiInfo; BinarySize: integer = 0): TRttiCustom;

Register one RTTI TypeInfo() to be serialized as hexadecimal
- data will be serialized as BinToHexDisplayLower() JSON hexadecimal string, using BinarySize bytes of the value, i.e. BinarySize*2 hexa chars
- you can truncate the original data size (e.g. if all bits of an integer are not used) by specifying the aFieldSize optional parameter
- will also ensure that those types will be recognized by text definition
- leave BinarySize=0 to write all bytes as hexadecimal
- set BinarySize=-1 to unregister the binary serialization for the type
- not thread-safe: should be called once from the main thread, at startup, e.g. in the initialization section of your types definition unit
- match mORMot 1.18 TTextWriter.RegisterCustomJSONSerializerFromTextBinaryType


function RegisterClass(aObject: TObject): TRttiCustom; overload;

Register a given class type, using its RTTI
- returns existing or new TRttiCustom
- please call RegisterCollection for TCollection


function RegisterClass(ObjectClass: TClass): TRttiCustom; overload;

Register a given class type, using its RTTI
- returns existing or new TRttiCustom
- please call RegisterCollection for TCollection


function RegisterCollection(Collection: TCollectionClass; CollectionItem: TCollectionItemClass): TRttiCustom;

Define how a given TCollectionClass should instantiate its items
- we need to know the CollectionItem to propertly initialize a TCollection
- not thread-safe: should be called once from the main thread, at startup, e.g. in the initialization section of your collection definition unit


function RegisterFromText(DynArrayOrRecord: PRttiInfo; const RttiDefinition: RawUtf8): TRttiCustom; overload;

Register TypeInfo() custom serialization for a given dynamic array or record
- DynArrayOrRecord should be valid TypeInfo() - use overloaded RegisterFromText(TypeName) if the record has no TypeInfo()
- the RTTI information will here be defined as plain text
- since Delphi 2010, you can call directly RegisterType()
- the record where the data will be stored should be defined as PACKED:

 type TMyRecord = packed record
   A,B,C: integer;
   D: RawUtf8;
   E: record; // or array of record/integer/string/...
     E1,E2: double;
   end;
 end;

- call this method with RttiDefinition='' to return back to the default serialization, i.e. binary + Base64 or Delphi 2010+ extended RTTI
- RTTI textual information shall be supplied as text, with the same format as any pascal record:

 'A,B,C: integer; D: RawUtf8; E: record E1,E2: double;'
 'A,B,C: integer; D: RawUtf8; E: array of record E1,E2: double;'
 'A,B,C: integer; D: RawUtf8; E: array of SynUnicode; F: array of TGuid'

or a shorter alternative syntax for records and arrays:

 'A,B,C: integer; D: RawUtf8; E: {E1,E2: double}'
 'A,B,C: integer; D: RawUtf8; E: [E1,E2: double]'

in fact ; could be ignored:

 'A,B,C:integer D:RawUtf8 E:{E1,E2:double}'
 'A,B,C:integer D:RawUtf8 E:[E1,E2:double]'

or even : could be ignored:

 'A,B,C integer D RawUtf8 E{E1,E2 double}'
 'A,B,C integer D RawUtf8 E[E1,E2 double]'

- it will return the cached TRttiCustom instance corresponding to the supplied RTTI text definition - i.e. the rkRecord if TypeInfo(SomeArray)
- match mORMot 1.18 TTextWriter.RegisterCustomJSONSerializerFromText()


function RegisterFromText(const TypeName: RawUtf8; const RttiDefinition: RawUtf8): TRttiCustom; overload;

Register by name a custom serialization for a given dynamic array or record
- use overloaded RegisterFromText(TypeName) if the record has TypeInfo()
- the RTTI information will here be defined as plain text


function RegisterObjArray(DynArray: PRttiInfo; Item: TClass): TRttiCustom;

Register one dynamic array RTTI TypeInfo() to be serialized as T*ObjArray
- not needed on FPC and Delphi 2010+ since "array of TSomeClass" will be recognized directly - see HASDYNARRAYTYPE conditional
- allow JSON serialization and unserialization of the registered dynamic array property defined in any TPersistent or TOrm for oldest Delphi
- could be used as such (note the T*ObjArray type naming convention):

 TUserObjArray = array of TUser;
 ...
 Rtti.RegisterObjArray(TypeInfo(TUserObjArray), TUser);

- then you can use ObjArrayAdd/ObjArrayFind/ObjArrayDelete to manage the stored items, and never forget to call ObjArrayClear to release the memory
- set Item=nil to unregister the type as a T*ObjArray - may be needed to bypass the FPC and Delphi 2010+ automatic recognition
- may return nil if DynArray is not a rkDynArray
- replace deprecated TJsonSerializer.RegisterObjArrayForJson() method
- not thread-safe: should be called once from the main thread, at startup, e.g. in the initialization section of your T*ObjArray definition unit


function RegisterType(Info: PRttiInfo): TRttiCustom;

Register a given RTTI TypeInfo()
- returns a new (or existing if it was already registered) TRttiCustom
- if Info.Kind is rkDynArray, it will also register the nested rkRecord
- match mORMot 1.18 TTextWriter.RegisterCustomJSONSerializerFromTextSimpleType


function RegisterTypeFromName(Name: PUtf8Char; NameLen: PtrInt; ParserType: PRttiParserType = nil): TRttiCustom; overload;

Recognize (and register if needed) a standard simple type
- calls Find() to return already registered TRttiCustom instance, and also recognize "array" or "record" keywords as expected by our parser
- returns nil if nothing was found
- will truncate any 'unitname.typename' into plain 'typename' before Find()


function RegisterTypeFromName(const Name: RawUtf8; ParserType: PRttiParserType = nil): TRttiCustom; overload;

Recognize (and register if needed) a standard simple type
- calls Find() to return already registered TRttiCustom instance, and also recognize "array" or "record" keywords as expected by our parser
- returns nil if nothing was found
- will truncate any 'unitname.typename' into plain 'typename' before Find()


procedure RegisterBinaryTypes(const InfoBinarySize: array of const);

Register one or several RTTI TypeInfo() to be serialized as hexadecimal
- TypeInfo() and associated size information will here be defined by pairs: ([TypeInfo(TType1),TYPE1_BYTES,TypeInfo(TType2),TYPE2_BYTES])
- a wrapper around the RegisterBinaryType() method
- not thread-safe: should be called once from the main thread, at startup, e.g. in the initialization section of your types definition unit
- match mORMot 1.18 TTextWriter.RegisterCustomJSONSerializerFromTextBinaryType


procedure RegisterClasses(const ObjectClass: array of TClass);

Register one or several RTTI TypeInfo()
- to ensure that those classes will be recognized by text definition
- will just call RegisterClass() for each ObjectClass[]


procedure RegisterFromText( const TypeInfoTextDefinitionPairs: array of const); overload;

Define a custom serialization for several dynamic arrays or records
- the TypeInfo() and textual RTTI information will here be defined as ([TypeInfo(TType1),_TType1, TypeInfo(TType2),_TType2]) pairs
- a wrapper around the overloaded RegisterFromText() method
- match mORMot 1.18 TTextWriter.RegisterCustomJSONSerializerFromText()


procedure RegisterObjArrays(const DynArrayItem: array of const);

Register one or several dynamic array RTTI TypeInfo() to be serialized as T*ObjArray
- not needed on FPC and Delphi 2010+ since "array of TSomeClass" will be recognized directly - see HASDYNARRAYTYPE conditional
- will call the RegisterObjArray() class method by pair:

 Rtti.RegisterObjArrays([
   TypeInfo(TAddressObjArray), TAddress,
   TypeInfo(TUserObjArray), TUser]);

- not thread-safe: should be called once from the main thread, at startup, e.g. in the initialization section of your T*ObjArray definition unit


procedure RegisterTypes(const Info: array of PRttiInfo);

Register one or several RTTI TypeInfo()
- to ensure that those types will be recognized by text definition
- will just call RegisterType() for each Info[]
- match mORMot 1.18 TTextWriter.RegisterCustomJSONSerializerFromTextSimpleType


procedure RegisterUnsafeSpiType(const Types: array of PRttiInfo);

Register some TypeInfo() containing unsafe parameter values
- i.e. any RTTI type containing Sensitive Personal Information, e.g. a bank card number or a plain password
- such values will force associated values to be ignored during loging, as a more tuned alternative to optNoLogInput or optNoLogOutput
- not thread-safe: should be called once from the main thread, at startup, e.g. in the initialization section of your types definition unit


property ByClass[C: TClass]: TRttiCustom read GetByClass;

Default property to access a given RTTI customization of a class
- you can access or register one type by using this default property:

 Rtti.ByClass[TMyClass].Props.NameChanges(['old', 'new'])

property ByTypeInfo[P: PRttiInfo]: TRttiCustom read RegisterType;

Default property to access a given RTTI TypeInfo() customization
- you can access or register one type by using this default property:

 Rtti[TypeInfo(TMyClass)].Props.NameChange('old', 'new')

property GlobalClass: TRttiCustomClass read fGlobalClass write SetGlobalClass;

Which kind of TRttiCustom class is to be used for registration
- properly set e.g. by mormot.core.json.pas to TRttiJson for JSON support


1.3.25. TRttiMap

TRttiMap = object(TObject)

Customizable field mapping between classes and records
- Init/Map overloaded methods return self to allow proper fluid-calling
- records should have field-level extended RTTI (since Delphi 2010), or have been properly defined with Rtti.RegisterFromText() on FPC or oldest Delphi
- allow RTTI or custom mapping, e.g. with Data Transfer Objects (DTO)


function AutoMap: PRttiMap;

Use RTTI field names to map the content


function Init(A, B: PRttiInfo): PRttiMap; overload;

Initialize fields mapping between two record instances


function Init(A, B: TClass): PRttiMap; overload;

Initialize fields mapping between two class instances


function Init(A: TClass; B: PRttiInfo): PRttiMap; overload;

Initialize fields mapping between a class instance and a record


function Map(const ABPairs: array of RawUtf8): PRttiMap; overload;

Map fields by A,B pairs of names


function Map(const A, B: RawUtf8): PRttiMap; overload;

Map two fields by name
- if any field A or B name is '', this field will be ignored


function ToA(B: pointer): pointer; overload;

Create a new A class instance, copying field values from B
- returned A is a newly allocated instance of the TClass specified to Init()
- B is either a TObject instance or a @record pointer, depending on Init()


function ToB(A: pointer): pointer; overload;

Create a new B class instance, copying field values from A
- A is either a TObject instance or a @record pointer, depending on Init()
- returned B is a newly allocated instance of the TClass specified to Init()


procedure ToA(A, B: pointer); overload;

Copy B fields values into A
- A and B are either a TObject instance or a @record pointer, depending on Init()


procedure ToB(A, B: pointer); overload;

Copy A fields values into B
- A and B are either a TObject instance or a @record pointer, depending on Init()


1.3.26. TObjectWithCustomCreate

TObjectWithCustomCreate = class(TObject)

Abstract parent class with published properties and a virtual constructor
- is the parent of both TSynPersistent and TOrm classes
- will ensure the class type is registered to the Rtti global list
- also features some protected virtual methods for custom RTTI/JSON process


constructor Create; virtual;

Virtual constructor called at instance creation
- is declared as virtual so that inherited classes may have a root constructor to override
- is recognized by our RTTI serialization/initialization process


class function NewInstance: TObject; override;

Optimized initialization code
- will also register the class type to the Rtti global list
- somewhat faster than the regular RTL implementation
- warning: this optimized version won't initialize the vmtIntfTable for this class hierarchy: as a result, you would NOT be able to implement an interface with a TSynPersistent descendent (but you should not need to, but inherit from TInterfacedObject)
- warning: under FPC, it won't initialize fields management operators


class function RttiCustom: TRttiCustom;

Very efficiently retrieve the TRttiCustom associated with this class
- since Create did register it, just return the first vmtAutoTable slot


1.3.27. TObjectWithID

TObjectWithID = class(TObjectWithCustomCreate)

Root class of an object with a 64-bit ID primary key
- is the parent of mormot.orm.core's TOrm, but you could use it e.g. on client side to avoid a dependency to all ORM process, but still have the proper published fields and use it in SOA - with a single conditional over your class definition to inherit either from TOrm or from TObjectWithID


constructor CreateWithID(aID: TID);

This constructor initializes the instance with a given ID


property IDValue: TID read fID write fID;

This property gives direct access to the class instance ID
- not defined as "published" since RttiCustomSetParser did register it


1.4. Types implemented in the mormot.core.rtti unit

1.4.1. PPRttiInfo

PPRttiInfo = ^PRttiInfo;

Double-reference to RTTI type definition
- Delphi and newer FPC do store all nested TTypeInfo as pointer to pointer, to ease linking of the executable


1.4.2. PRttiCache

PRttiCache = ^TRttiCache;

Resolve once map extended PRttiInfo content


1.4.3. PRttiClass

PRttiClass = ^TRttiClass;

Pointer to TClassType, as returned by PRttiInfo.RttiClass()
- as returned by PRttiInfo.RttiClass() or GetRttiClass()
- equivalency to PClassData/PClassType as defined in old mORMot.pas


1.4.4. PRttiEnumType

PRttiEnumType = ^TRttiEnumType;

Pointer to TEnumType, as returned by PRttiInfo.EnumBaseType/SetEnumType
- equivalency to PEnumType as defined in old mORMot.pas


1.4.5. PRttiInfo

PRttiInfo = ^TRttiInfo;

Pointer to low-level RTTI of a type definition, as returned by TypeInfo() compiler function over a type
- equivalency to PTypeInfo as defined in TypInfo RTL unit and old mORMot.pas
- this is the main entry point of all the information exposed by this unit


1.4.6. PRttiInfoDynArray

PRttiInfoDynArray = array of PRttiInfo;

Dynamic array of low-level RTTI type definitions


1.4.7. PRttiInterfaceTypeData

PRttiInterfaceTypeData = ^TRttiInterfaceTypeData;

Pointer to a wrapper to interface type information


1.4.8. PRttiKind

PRttiKind = ^TRttiKind;

RfSingle rfDouble rfExtended rfComp rfCurr


1.4.9. PRttiMap

PRttiMap = ^TRttiMap;

Pointer to a TRttiMap reference, for fluid-interface initialization


1.4.10. PRttiProp

PRttiProp = ^TRttiProp;

Pointer to a RTTI class property definition as stored in PRttiProps.PropList
- equivalency to PPropInfo as defined in TypInfo RTL unit and old mORMot.pas


1.4.11. PRttiPropDynArray

PRttiPropDynArray = array of PRttiProp;

Used to store a chain of properties RTTI
- could be used e.g. by TOrmPropInfo to handled flattened properties


1.4.12. PRttiProps

PRttiProps = ^TRttiProps;

Pointer to all RTTI class properties definitions
- as returned by PRttiInfo.RttiProps() or GetRttiProps()


1.4.13. PRttiRecordField

PRttiRecordField = ^TRttiRecordField;

Pointer to the RTTI of a record/object type definition (managed) field


1.4.14. PRttiVarData

PRttiVarData = ^TRttiVarData;

TObject if PropValueIsInstance=true, or field addr


1.4.15. TObjectWithCustomCreateClass

TObjectWithCustomCreateClass = class of TObjectWithCustomCreate;

Used to determine the exact class type of a TObjectWithCustomCreate
- allow to create instances using its virtual constructor


1.4.16. TObjectWithIDClass

TObjectWithIDClass = class of TObjectWithID;

Used to determine the exact class type of a TObjectWithID


1.4.17. TPublishedMethodInfoDynArray

TPublishedMethodInfoDynArray = array of TPublishedMethodInfo;

Information about all methods, as returned by GetPublishedMethods


1.4.18. TRttiCacheFlag

TRttiCacheFlag = ( rcfQWord, rcfBoolean, rcfHasRttiOrd, rcfGetOrdProp, rcfGetInt64Prop, rcfIsRawBlob, rcfIsNumber );

Quick identification of some RTTI value types


1.4.19. TRttiCacheFlags

TRttiCacheFlags = set of TRttiCacheFlag;

As used by TRttiCache.Flags
- rcfQWord/rcfBoolean map Info^.IsQWord/IsBoolean
- rcfIsRawBlob maps Info^.IsRawBlob
- rcfIsNumber is set if Info^.Kind is in rkNumberTypes
- set rcfHasRttiOrd/rcfGetOrdProp/rcfGetInt64Prop to access the value


1.4.20. TRttiClassCopier

TRttiClassCopier = procedure(Dest, Source: TObject);

Internal function handler for copying a class instance
- use TRttiCustom.Props.CopyProperties but may be overriden e.g. for TOrm


1.4.21. TRttiCopier

TRttiCopier = function(Dest, Source: pointer; Info: PRttiInfo): PtrInt;

Internal function handler for copying a managed type value
- i.e. the kind of functions called via RTTI_MANAGEDCOPY[] lookup table


1.4.22. TRttiCopiers

TRttiCopiers = array[TRttiKind] of TRttiCopier;

The type of RTTI_MANAGEDCOPY[] efficient lookup table


1.4.23. TRttiCustomClass

TRttiCustomClass = class of TRttiCustom;

Meta-class of TRttiCustom
- is usually a TRttiJson class type once mormot.core.json.pas is linked


1.4.24. TRttiCustomFlag

TRttiCustomFlag = ( rcfIsManaged, rcfObjArray, rcfBinary, rcfJsonString, rcfWithoutRtti, rcfSpi, rcfHookWrite, rcfHookWriteProperty, rcfHookRead, rcfHookReadProperty, rcfHasNestedProperties, rcfHasNestedManagedProperties, rcfHasOffsetSetJsonLoadProperties, rcfArrayItemManaged, rcfReadIgnoreUnknownFields, rcfAutoCreateFields, rcfDisableStored, rcfClassMayBeID );

Define specific behavior for a given TypeInfo/PRttIinfo
- rcfIsManaged is set if a value of this type expects finalization
- rcfObjArray is for T*ObjArray dynamic arrays
- rcfBinary is for hexadecimal serialization of integers
- rcfJsonString when is to be serialized as text and properly JSON-escaped (ptStringTypes or rcfBinary, but excluding ptRawJson)
- rcfWithoutRtti is set if was created purely by text, and uses fake RTTI
- rcfSpi identifies types containing Sensitive Personal Information (e.g. a bank card number or a plain password) which should be hidden
- rcfHookWrite, rcfHookWriteProperty, rcfHookRead, rcfHookReadProperty for TObjectWithCustomCreate kind of class, to customize JSON serialization calling the set of TObjectWithCustomCreate protected virtual methods - disabled by default not to slow down the serialization process
- rcfHasNestedProperties is set e.g. for rkClass or rcfWithoutRtti records, rcfHasNestedManagedProperties if any of the property/field is rcfIsManaged
- rcfHasOffsetSetJsonLoadProperties is set if all nested properties can be directly written, i.e. have OffsetSet >= 0 and Assigned(JsonLoad)
- rcfArrayItemManaged maps rcfIsManaged flag in ArrayRtti.Flags
- rcfReadIgnoreUnknownFields will let JSON unserialization ignore unknown fields for this class/record
- rcfAutoCreateFields is defined when AutoCreateFields() has been called
- rcfDisableStored is set for TOrm, where "stored AS_UNIQUE" does not mean "not stored" for serialization but "UNIQUE SQL"
- rcfClassMayBeID is set e.g. for TOrm classes, which may be storing not instances but IDs in published properties PtrInt


1.4.25. TRttiCustomFlags

TRttiCustomFlags = set of TRttiCustomFlag;

Define specific behaviors for a given TypeInfo/PRttIinfo
- as stored in TRttiCustom.Flags


1.4.26. TRttiCustomFromTextExpectedEnd

TRttiCustomFromTextExpectedEnd = ( eeNothing, eeSquare, eeCurly, eeEndKeyWord );

Used internally by our RTTI text definition


1.4.27. TRttiCustomNewInstance

TRttiCustomNewInstance = function(Rtti: TRttiCustom): pointer;

Used internally for fast allocation of a rkClass/rkInterface instance
- member is properly initialized by TRttiJson from mormot.core.json.pas


1.4.28. TRttiCustomPropDynArray

TRttiCustomPropDynArray = array of TRttiCustomProp;

Store information about the properties/fields of a given TypeInfo/PRttiInfo


1.4.29. TRttiCustomRandom

TRttiCustomRandom = procedure(Data: pointer; Rtti: TRttiCustom);

Internal function handler for filling a value with some randomness


1.4.30. TRttiFinalizer

TRttiFinalizer = function(Data: pointer; Info: PRttiInfo): PtrInt;

Internal function handler for finalizing a managed type value
- i.e. the kind of functions called via RTTI_FINALIZE[] lookup table
- as used by TRttiInfo.Clear() inlined method


1.4.31. TRttiFinalizers

TRttiFinalizers = array[TRttiKind] of TRttiFinalizer;

The type of RTTI_FINALIZE[] efficient lookup table


1.4.32. TRttiFloat

TRttiFloat = ( rfSingle, rfDouble, rfExtended, rfComp, rfCurr );

Map TFloatType, to specify floating point (ftFloat) storage size and precision


1.4.33. TRttiIntfFlag

TRttiIntfFlag = ( ifHasGuid, ifDispInterface, ifDispatch );

Define the interface abilities


1.4.34. TRttiIntfFlags

TRttiIntfFlags = set of TRttiIntfFlag;

Define the set of interface abilities


1.4.35. TRttiKind

TRttiKind = ( rkUnknown, rkInteger, rkChar, rkEnumeration, rkFloat, rkSString, rkSet, rkClass, rkMethod, rkWChar, rkLString, rkWString, rkVariant, rkArray, rkRecord, rkInterface, rkInt64, rkDynArray );

Available type families for Delphi 6 and up, similar to typinfo.pas
- redefined here to leverage FPC and Delphi compatibility as much as possible


1.4.36. TRttiMethodArgDirection

TRttiMethodArgDirection = ( rmdConst, rmdVar, rmdOut, rmdResult );

Handled kind of parameters direction for an interface method
- IN, IN/OUT, OUT directions can be applied to arguments, e.g. to be available through our JSON-serialized remote access: rmdVar and rmdOut kind of parameters will be returned within the "result": JSON array
- rmdResult is used for a function method, to handle the returned value


1.4.37. TRttiMethodArgDirections

TRttiMethodArgDirections = set of TRttiMethodArgDirection;

Set of parameter directions e.g. for an interface-based service method


1.4.38. TRttiOrd

TRttiOrd = ( roSByte, roUByte, roSWord, roUWord, roSLong, roULong );

Map TOrdType, to specify ordinal (rkInteger and rkEnumeration) storage size and sign
- note: on FPC, Int64 is stored as its own TRttiKind, not as rkInteger


1.4.39. TRttiParserComplexType

TRttiParserComplexType = ( pctNone, pctTimeLog, pctCreateTime, pctModTime, pctID, pctSpecificClassID, pctRecordReference, pctRecordReferenceToBeDeleted, pctRecordVersion );

The complex kind of variables for ptTimeLog and ptOrm TRttiParserType


1.4.40. TRttiParserType

TRttiParserType = ( ptNone, ptArray, ptBoolean, ptByte, ptCardinal, ptCurrency, ptDouble, ptExtended, ptInt64, ptInteger, ptQWord, ptRawByteString, ptRawJson, ptRawUtf8, ptRecord, ptSingle, ptString, ptSynUnicode, ptDateTime, ptDateTimeMS, ptGuid, ptHash128, ptHash256, ptHash512, ptOrm, ptTimeLog, ptUnicodeString, ptUnixTime, ptUnixMSTime, ptVariant, ptWideString, ptWinAnsi, ptWord, ptEnumeration, ptSet, ptClass, ptDynArray, ptInterface, ptPUtf8Char, ptCustom );

The kind of variables handled by our RTTI/JSON parser
- the last item should be ptCustom, for non simple types
- ptOrm is recognized from TID, T*ID, TRecordReference, TRecordReferenceToBeDeleted and TRecordVersion type names
- ptTimeLog is recognized from TTimeLog, TCreateTime and TModTime
- other types (not ptComplexTypes) are recognized by their genuine type name
- ptUnicodeString is defined even if not available prior to Delphi 2009
- replace deprecated TJsonCustomParserRTTIType type from old mORMot 1.18
- TDynArrayKind is now an alias to this genuine enumerate


1.4.41. TRttiPropCall

TRttiPropCall = ( rpcNone, rpcField, rpcMethod, rpcIndexed );

How a RTTI property definition access its value
- as returned by TPropInfo.Getter/Setter/GetterIs/SetterIs methods


1.4.42. TRttiPropStored

TRttiPropStored = ( rpsTrue, rpsFalse, rpsGetter );

TRttiProp.IsStoredKind response - default is "stored true"


1.4.43. TRttiRecordAllFields

TRttiRecordAllFields = array of TRttiRecordAllField;

As returned by TRttiInfo.RecordAllFields


1.4.44. TRttiValueClass

TRttiValueClass = ( vcNone, vcCollection, vcStrings, vcObjectList, vcList, vcSynList, vcRawUtf8List, vcESynException, vcException, vcObjectWithID );

The recognized raw RTL classes as identified in TRttiCustom.ValueRtlClass


1.5. Constants implemented in the mormot.core.rtti unit

1.5.1. FLOATTYPE_SIZE

FLOATTYPE_SIZE: array[TRttiFloat] of byte = ( 4, 8, 10 , 8, 8 );

RoSByte roUByte roSWord roUWord roSLong roULong roSQWord, roUQWord quick retrieve how many bytes a floating-point consist in


1.5.2. NO_INDEX

NO_INDEX = integer($80000000);

Delphi requires those definitions for proper inlining


1.5.3. ORDTYPE_SIZE

ORDTYPE_SIZE: array[TRttiOrd] of byte = ( 1, 1, 2, 2, 4, 4 );

Quick retrieve how many bytes an ordinal consist in


1.5.4. ptComplexTypes

ptComplexTypes = [ptArray, ptRecord, ptCustom, ptTimeLog, ptOrm, ptDynArray, ptEnumeration, ptSet, ptClass, ptInterface];

Which TRttiParserType are not simple types
- ptTimeLog and ptOrm are complex, since more than one TypeInfo() may map to their TRttiParserType - see also TRttiParserComplexType


1.5.5. PTC_NAME

PTC_NAME: array[TRttiParserComplexType] of RawUtf8 = ( '', 'TTimeLog', 'TCreateTime', 'TModTime', 'TID', '', 'TRecordReference', 'TRecordReferenceToBeDeleted', 'TRecordVersion');

PtNone ptArray ptBoolean ptByte ptCardinal ptCurrency ptDouble ptExtended ptInt64 ptInteger ptQWord ptRawByteString ptRawJson ptRawUtf8 ptRecord ptSingle ptString ptSynUnicode ptDateTime ptDateTimeMS ptGuid ptHash128 ptHash256 ptHash512 ptOrm ptTimeLog ptUnicodeString ptUnixTime ptUnixMSTime ptVariant ptWideString ptWinAnsi ptWord ptEnumeration ptSet ptClass ptDynArray ptInterface ptPUtf8Char ptCustom type definition name lookup to the TRttiParserComplexType values
- for ptComplexTypes types, with PT_NAME[]=''
- ptcSpecificClassID returns '' since T....ID types are variable


1.5.6. PTC_PT

PTC_PT: array[TRttiParserComplexType] of TRttiParserType = ( ptNone, ptTimeLog, ptTimeLog, ptTimeLog, ptOrm, ptNone, ptOrm, ptOrm, ptOrm );

Simple lookup to the TRttiParserType of a complex type


1.5.7. ptMultiLineStringTypes

ptMultiLineStringTypes = [ptRawUtf8, ptString, ptSynUnicode, ptUnicodeString, ptWideString, ptWinAnsi];

Which TRttiParserType types could be serialized as multi-line JSON "text"
- e.g. plain RawUtf8 which may include \n line feeds but not RawByteString, TTimeLog or THash128, which never include line breaks within their "value"


1.5.8. ptPtrInt

ptPtrInt = ptInteger ;

Map a PtrInt type to the TRttiParserType set


1.5.9. ptPtrUInt

ptPtrUInt = ptCardinal ;

Map a PtrUInt type to the TRttiParserType set


1.5.10. ptStringTypes

ptStringTypes = [ptRawByteString .. ptRawUtf8, ptString .. ptHash512, ptTimeLog, ptUnicodeString, ptWideString, ptWinAnsi, ptPUtf8Char];

Which TRttiParserType types are (usually) serialized as JSON "text"
- actual serialization may depend e.g. on TTextWriterWriteObjectOptions


1.5.11. ptUnmanagedTypes

ptUnmanagedTypes = [ptBoolean..ptQWord, ptSingle, ptDateTime..ptTimeLog, ptUnixTime, ptUnixMSTime, ptWord..ptClass];

Which TRttiParserType types don't need memory management


1.5.12. PT_NAME

PT_NAME: array[TRttiParserType] of RawUtf8 = ( '', '', 'boolean', 'byte', 'cardinal', 'currency', 'double', 'extended', 'Int64', 'integer', 'QWord', 'RawByteString', 'RawJson', 'RawUtf8', '', 'single', 'string', 'SynUnicode', 'TDateTime', 'TDateTimeMS', 'TGuid', 'THash128', 'THash256', 'THash512', '', '', 'UnicodeString', 'TUnixTime', 'TUnixMSTime', 'variant', 'WideString', 'WinAnsi', 'word', '', '', '', '', '', 'PUtf8Char', '');

PtNone ptArray ptBoolean ptByte ptCardinal ptCurrency ptDouble ptExtended ptInt64 ptInteger ptQWord ptRawByteString ptRawJson ptRawUtf8 ptRecord ptSingle ptString ptSynUnicode ptDateTime ptDateTimeMS ptGuid ptHash128 ptHash256 ptHash512 ptOrm ptTimeLog ptUnicodeString ptUnixTime ptUnixMSTime ptVariant ptWideString ptWinAnsi ptWord ptEnumeration ptSet ptClass ptDynArray ptInterface ptPUtf8Char ptCustom type definition name lookup to the TRttiParserType values
- ptComplexTypes types should see PTC_NAME[] constant


1.5.13. PT_SIZE

PT_SIZE: array[TRttiParserType] of byte = ( 0, 0, 1, 1, 4, 8, 8, 8, 8, 4, 8, SizeOf(pointer), SizeOf(pointer), SizeOf(pointer), 0, 4, SizeOf(pointer), SizeOf(pointer), 8, 8, 16, 16, 32, 64, 8, 8, SizeOf(pointer), 8, 8, SizeOf(variant), SizeOf(pointer), SizeOf(pointer), 2, 0, 0, SizeOf(pointer), SizeOf(pointer), SizeOf(pointer), SizeOf(pointer), 0 );

PctNone pctTimeLog pctCreateTime pctModTime pctID pctSpecificClassID pctRecordReference pctRecordReferenceToBeDeleted pctRecordVersion simple lookup to the size in bytes of TRttiParserType values


1.5.14. rkAllTypes

rkAllTypes = [succ(low(TRttiKind))..high(TRttiKind)];

All recognized TRttiKind enumerates, i.e. all but rkUnknown


1.5.15. rkComplexTypes

rkComplexTypes = [rkClass, rkDynArray, rkInterface];

Types which are considerated as non-simple values


1.5.16. rkEnumerationTypes

rkEnumerationTypes = [rkEnumeration ];

Maps enumeration types in TRttiKind RTTI


1.5.17. rkGetInt64PropTypes

rkGetInt64PropTypes = [rkInt64 ];

Maps ordinal values which expect TRttiProp.GetInt64Prop/SetInt64Prop
- includes 64-bit ordinals


1.5.18. rkGetIntegerPropTypes

rkGetIntegerPropTypes = rkGetInt64PropTypes + [rkInteger];

Maps value which are integer or Int64/QWord, but not ordinal char/enum/set


1.5.19. rkGetOrdPropTypes

rkGetOrdPropTypes = rkHasRttiOrdTypes + rkComplexTypes;

Maps values which expect TRttiProp.GetOrdProp/SetOrdProp
- includes 32-bit ordinals and pointers


1.5.20. rkHasRttiOrdTypes

rkHasRttiOrdTypes = [rkInteger, rkChar, rkWChar, rkEnumeration, rkSet ];

Maps types with proper TRttiProp.RttiOrd field
- i.e. rkOrdinalTypes excluding the 64-bit values


1.5.21. rkManagedTypes

rkManagedTypes = [rkLString, rkWstring, rkArray, rkRecord, rkDynArray, rkInterface, rkVariant ];

Potentially managed types in TRttiKind enumerates


1.5.22. rkNumberTypes

rkNumberTypes = rkOrdinalTypes + [ rkFloat ];

Maps integer and floating point types in TRttiKind RTTI enumerates


1.5.23. rkOrdinalTypes

rkOrdinalTypes = rkHasRttiOrdTypes + [ rkInt64 ];

Maps 1, 8, 16, 32 and 64-bit ordinal in TRttiKind RTTI enumerates


1.5.24. rkPerReference

rkPerReference = rkStringTypes + rkComplexTypes;

Types which are stored as pointers so are always accessed by reference


1.5.25. rkRecordOrArrayTypes

rkRecordOrArrayTypes = rkRecordTypes + [rkArray];

Maps records or static arrays


1.5.26. rkRecordOrDynArrayTypes

rkRecordOrDynArrayTypes = rkRecordTypes + [rkDynArray];

Maps records or dynamic arrays


1.5.27. rkRecordTypes

rkRecordTypes = [rkRecord ];

Maps record or object in TTypeKind RTTI enumerates


1.5.28. rkStringTypes

rkStringTypes = [rkLString, rkWString ];

Maps string/text types in TRttiKind RTTI enumerates, excluding shortstring


1.5.29. rkWideStringTypes

rkWideStringTypes = [ rkWString ];

Maps UTF-16 string in TRttiKind RTTI enumerates


1.5.30. RTTIHASH_MAX

RTTIHASH_MAX = 31 ;

TRttiCustomList stores its TypeInfo() by Kind + PRttiInfo/Name
- optimized "hash table of the poor" (tm) for FindType() and Find(Name)
- should be a bit mask (i.e. power of two minus 1)


1.6. Functions or procedures implemented in the mormot.core.rtti unit

Functions or proceduresDescription
ClassFieldAllPropsRetrieve the PRttiProp values of all published properties of a class
ClassFieldCountWithParentsRetrieve the total number of properties for a class, including its parents
ClassFieldInstanceRetrieve a class Field property instance from a Property class type
ClassFieldInstanceRetrieve a class Field property instance from a Property Name
ClassFieldInstancesRetrieve all class Field property instances from a Property class type
ClassFieldInt64Retrieve an integer/Int64 Field propery value from a Property Name
ClassFieldNamesAllPropsRetrieve the field names of all published properties of a class
ClassFieldNamesAllPropsAsTextRetrieve the field names of all published properties of a class
ClassFieldPropRetrieve a Field property RTTI information from a Property Name
ClassFieldPropInstanceMatchingClassRetrieve a class instance property value matching a class type
ClassFieldPropWithParentsRetrieve a Field property RTTI information from a Property Name
ClassFieldPropWithParentsFromClassOffsetRetrieve a Field property RTTI information searching for an exact Property offset address
ClassFieldPropWithParentsFromClassTypeRetrieve a Field property RTTI information searching for an exact Property class type
ClassFieldPropWithParentsFromUtf8Retrieve a Field property RTTI information from a Property Name
ClassFieldPropWithParentsInheritsFromClassTypeRetrieve a Field property RTTI information searching for an inherited Property class type
ClassHasPublishedFieldsReturns TRUE if the class has some published fields, including its parents
ClassHierarchyWithFieldRetrieve all class hierachy types which have some published properties
ClearObjectWill reset all the object properties to their default
CopyCollectionCopy two TCollection instances
CopyObjectCreate a new object instance, from an existing one
CopyObjectCopy class published properties via names using RTTI
CopySeveralEfficiently copy several (dynamic) array items
CopyStringsCopy two TStrings instances
DynArrayCopyCreate a dynamic array from another one
DynArrayEnsureUniqueSame as Value := copy(Value) but faster and with no temporary variable
DynArrayGrowLow-level size up of a dynamic array
DynArrayNewLow-level initialization of a dynamic array
EnsureUniqueSame as Value := copy(Value) but faster and with no temporary variable
EnsureUniqueSame as Value := copy(Value) but faster and with no temporary variable
EnsureUniqueSame as Value := copy(Value) but faster and with no temporary variable
FastDynArrayClearLow-level finalization of a dynamic array of any kind
FastFinalizeArrayLow-level finalization of all dynamic array items of any kind
FastRecordClearClear the managed fields of a record content
FillZeroRttiFill all sensitive fields of this class or record with zeros
FinalizeObjectRelease all low-level managed fields of this instance
FindCustomPropLow-level internal function use when inlining TRttiCustomProps.Find()
FindPrivateSlotLow-level internal function used e.g. by TRttiCustom.GetPrivateSlot()
GetCaptionFromClassUnCamelCase and translate the class name, triming any left 'T' 'TSyn' 'TOrm'
GetCaptionFromEnumUnCamelCase and translate the enumeration item
GetCaptionFromTrimmedLow-level helper to retrieve a (translated) caption from a PShortString
GetDisplayNameFromClassWill get a class name as UTF-8
GetEnumCaptionsHelper to retrieve all (translated) caption texts of an enumerate
GetEnumNameHelper to retrieve the text of an enumerate item
GetEnumNamesHelper to retrieve all texts of an enumerate
GetEnumNameTrimedGet the corresponding enumeration name, without the first lowercase chars
GetEnumNameUnCamelCaseGet the enumeration name, without the first lowercase chars, and uncamelcased
GetEnumNameValueHelper to retrieve the index of an enumerate item from its text
GetEnumNameValueHelper to retrieve the index of an enumerate item from its text
GetEnumNameValueTrimmedRetrieve the index of an enumerate item from its left-trimmed text
GetEnumNameValueTrimmedExactRetrieve the index of an enumerate item from its left-trimmed text
GetEnumTrimmedNamesHelper to retrieve all trimmed texts of an enumerate as UTF-8 strings
GetEnumTrimmedNamesHelper to retrieve all trimmed texts of an enumerate
GetEnumTypeHelper to retrieve low-level RTTI information of an enumeration type
GetInstanceByPathRetrieve a (possibly nested) class property RTTI and instance by path
GetInterfaceFromEntryExecute an instance method from its RTTI per-interface information
GetPublishedMethodsRetrieve published methods information about any class instance
GetRttiClassRetrieve the class RTTI information for a specific class
GetRttiClassGuidReturns all TGuid implemented by a given class
GetRttiInterfaceRetrieve methods information of a given IInvokable
GetRttiPropRetrieve the class property RTTI information for a specific class
GetRttiPropsRetrieve the class property RTTI information for a specific class
GetSetCsvValueHelper to parse some CSV values into a set, returned as 64-bit
GetSetNameHelper to retrieve the CSV text of all enumerate items defined in a set
GetSetNameShortHelper to retrieve the CSV text of all enumerate items defined in a set
InterfaceEntryIsStandardCheck if a pre-computed PInterfaceEntry has a direct IOffset information
IsObjectDefaultOrVoidReturns TRUE on a nil instance or if all its published properties are default/0
IsRawUtf8DynArrayCheck if the TypeInfo() points to an "array of RawUtf8"
ItemSizeToDynArrayKindInternal function used e.g. for enumerations and sets
ObjectToRecordCopy an object instance properties into a record
ParserTypeToTypeInfoRetrieve the TypeInfo() from PT_INFO[] PTC_INFO[] constant arrays
RawUtf8DynArrayClearLow-level finalization of a dynamic array of RawUtf8
RecordClearSeveralEfficient finalization of successive record items from a (dynamic) array
RecordCopyCopy a record content from source to Dest
RecordToObjectCopy record properties into an object instance
RecordZeroInitialize a record content
SetDefaultValuesObjectSet any default integer or enumerates (including boolean) published properties values for a TPersistent/TSynPersistent
SetEnumFromOrdinalStore an enumeration value from its ordinal representation
SetNamesValueLow-level function parsing Value/ValueLen into a set, returned as 64-bit
SetObjectFromExecutableCommandLineFill a class instance properties from command line switches
SetValueObjectSet any (potentially nested) object property by path
StringClearSeveralEfficient finalization of successive RawUtf8 items from a (dynamic) array
TObjectWithCustomCreateRttiCustomSetParserInternal wrapper to protected TObjectWithCustomCreate.RttiCustomSetParser()
TObjectWithIDDynArrayCompareTDynArraySortCompare compatible function, sorting by TObjectWithID/TOrm.ID
TObjectWithIDDynArrayHashOneTDynArrayHashOne compatible function, hashing TObjectWithID/TOrm.ID
ToTextDefined here to avoid circular dependency in mormot.core.os.pas
ToTextRetrieve the text name of one TRttiKind enumerate
ToTextDefined here to avoid circular dependency in mormot.core.os.pas
ToTextPctNone pctTimeLog pctCreateTime pctModTime pctID pctSpecificClassID pctRecordReference pctRecordReferenceToBeDeleted pctRecordVersion retrieve the text name of one TRttiParserType enumerate
TypeInfoToDynArrayTypeInfoRecognize most simple types and return their known dynamic array RTTI
VariantDynArrayClearFaster alternative to Finalize(aVariantDynArray)

1.6.1. ClassFieldAllProps

function ClassFieldAllProps(ClassType: TClass; Types: TRttiKinds = [low(TRttiKind)..high(TRttiKind)]): PRttiPropDynArray;

Retrieve the PRttiProp values of all published properties of a class
- you could select which property types should be included in the list


1.6.2. ClassFieldCountWithParents

function ClassFieldCountWithParents(ClassType: TClass; onlyWithoutGetter: boolean = false): integer;

Retrieve the total number of properties for a class, including its parents


1.6.3. ClassFieldInstance

function ClassFieldInstance(Instance: TObject; const PropName: ShortString; PropClassType: TClass; out PropInstance): boolean; overload;

Retrieve a class Field property instance from a Property Name
- this special version also searches into parent properties (TRttiProp search scope is only inside the current class level)
- returns TRUE and set PropInstance if a matching property was found


1.6.4. ClassFieldInstance

function ClassFieldInstance(Instance: TObject; PropClassType: TClass; out PropInstance): boolean; overload;

Retrieve a class Field property instance from a Property class type
- this version also searches into parent properties
- returns TRUE and set PropInstance if a matching property was found


1.6.5. ClassFieldInstances

function ClassFieldInstances(Instance: TObject; PropClassType: TClass): TObjectDynArray;

Retrieve all class Field property instances from a Property class type
- this version also searches into parent properties
- returns all matching property instances found


1.6.6. ClassFieldInt64

function ClassFieldInt64(Instance: TObject; const PropName: ShortString; out PropValue: Int64): boolean;

Retrieve an integer/Int64 Field propery value from a Property Name
- this special version also searches into parent properties (TRttiProp search scope is only inside the current class level)
- returns TRUE and set PropValue if a matching property was found


1.6.7. ClassFieldNamesAllProps

function ClassFieldNamesAllProps( ClassType: TClass; IncludePropType: boolean = false; Types: TRttiKinds = [low(TRttiKind)..high(TRttiKind)]): TRawUtf8DynArray;

Retrieve the field names of all published properties of a class
- will optionally append the property type to the name, e.g 'Age: integer'
- you could select which property types should be included in the list


1.6.8. ClassFieldNamesAllPropsAsText

function ClassFieldNamesAllPropsAsText( ClassType: TClass; IncludePropType: boolean = false; Types: TRttiKinds = [low(TRttiKind)..high(TRttiKind)]): RawUtf8;

Retrieve the field names of all published properties of a class
- will optionally append the property type to the name, e.g 'Age: integer'
- you could select which property types should be included in the list


1.6.9. ClassFieldProp

function ClassFieldProp(ClassType: TClass; const PropName: ShortString): PRttiProp;

Retrieve a Field property RTTI information from a Property Name


1.6.10. ClassFieldPropInstanceMatchingClass

function ClassFieldPropInstanceMatchingClass(aSearchedInstance: TObject; aSearchedClassType: TClass): TObject;

Retrieve a class instance property value matching a class type
- if aSearchedInstance is aSearchedClassType, will return aSearchedInstance
- if aSearchedInstance is not aSearchedClassType, it will try all nested properties of aSearchedInstance for a matching aSearchedClassType: if no exact match is found, will return aSearchedInstance


1.6.11. ClassFieldPropWithParents

function ClassFieldPropWithParents(aClassType: TClass; const aPropName: ShortString; aCaseSensitive: boolean = false): PRttiProp;

Retrieve a Field property RTTI information from a Property Name
- this special version also searches into parent properties (TRttiProp search scope is only inside the current class level)


1.6.12. ClassFieldPropWithParentsFromClassOffset

function ClassFieldPropWithParentsFromClassOffset(aClassType: TClass; aSearchedOffset: pointer): PRttiProp;

Retrieve a Field property RTTI information searching for an exact Property offset address
- this special version also searches into parent properties


1.6.13. ClassFieldPropWithParentsFromClassType

function ClassFieldPropWithParentsFromClassType(aClassType, aSearchedClassType: TClass): PRttiProp;

Retrieve a Field property RTTI information searching for an exact Property class type
- this special version also searches into parent properties


1.6.14. ClassFieldPropWithParentsFromUtf8

function ClassFieldPropWithParentsFromUtf8(aClassType: TClass; PropName: PUtf8Char; PropNameLen: integer; aCaseSensitive: boolean = false): PRttiProp;

Retrieve a Field property RTTI information from a Property Name
- this special version also searches into parent properties (TRttiProp search scope is only inside the current class level)


1.6.15. ClassFieldPropWithParentsInheritsFromClassType

function ClassFieldPropWithParentsInheritsFromClassType(aClassType, aSearchedClassType: TClass): PRttiProp;

Retrieve a Field property RTTI information searching for an inherited Property class type
- this special version also searches into parent properties


1.6.16. ClassHasPublishedFields

function ClassHasPublishedFields(ClassType: TClass): boolean;

Returns TRUE if the class has some published fields, including its parents


1.6.17. ClassHierarchyWithField

function ClassHierarchyWithField(ClassType: TClass): TClassDynArray;

Retrieve all class hierachy types which have some published properties


1.6.18. ClearObject

procedure ClearObject(Value: TObject; FreeAndNilNestedObjects: boolean = false);

Will reset all the object properties to their default
- strings will be set to '', numbers to 0
- if FreeAndNilNestedObjects is the default FALSE, will recursively reset all nested class properties values
- if FreeAndNilNestedObjects is TRUE, will FreeAndNil() all the nested class properties
- for a TOrm, use its ClearProperties method instead, which will handle the ID property, and any nested JOINed instances


1.6.19. CopyCollection

procedure CopyCollection(Source, Dest: TCollection);

Copy two TCollection instances
- will call CopyObject() in loop to repopulate the Dest collection, which will work even if Assign() method was not overriden


1.6.20. CopyObject

procedure CopyObject(aFrom, aTo: TObject); overload;

Copy class published properties via names using RTTI
- copy integer, Int64, enumerates (including boolean), variant, records, dynamic arrays, classes and any string properties (excluding ShortString)
- TCollection items can be copied also, if they are of the same exact class
- object properties instances are created in aTo if the objects are not TOrm children (in this case, these are not class instances, but INTEGER reference to records, so only the integer value is copied), that is for regular classes
- see also TRttiMap for custom mapping between classes


1.6.21. CopyObject

function CopyObject(aFrom: TObject): TObject; overload;

Create a new object instance, from an existing one
- will create a new instance of the same class, then call the overloaded CopyObject() procedure to copy its values
- caller should use "CopyObject(...) as TDestClass" for safety
- see also TRttiMap for custom mapping between classes


1.6.22. CopySeveral

procedure CopySeveral(Dest, Source: PByte; SourceCount: PtrInt; ItemInfo: PRttiInfo; ItemSize: PtrInt);

Efficiently copy several (dynamic) array items
- faster than the RTL CopyArray() function


1.6.23. CopyStrings

procedure CopyStrings(Source, Dest: TStrings);

Copy two TStrings instances
- will just call Dest.Assign(Source) in practice


1.6.24. DynArrayCopy

procedure DynArrayCopy(Dest, Source: PPointer; Info: PRttiInfo; SourceExtCount: PInteger = nil);

Create a dynamic array from another one
- same as RTTI_MANAGEDCOPY[rkDynArray] but with an optional external source count


1.6.25. DynArrayEnsureUnique

procedure DynArrayEnsureUnique(Value: PPointer; Info: PRttiInfo);

Same as Value := copy(Value) but faster and with no temporary variable


1.6.26. DynArrayGrow

function DynArrayGrow(Dest: PPointer; Count, ItemSize: PtrInt): PAnsiChar;

Low-level size up of a dynamic array
- faster than System.DynArraySetLength() function dynamic array with RefCnt=1
- caller should ensure that Dest is not nil
- DataBytes is expected to be Count * ItemSize


1.6.27. DynArrayNew

function DynArrayNew(Dest: PPointer; Count, ItemSize: PtrInt): pointer;

Low-level initialization of a dynamic array
- faster than System.DynArraySetLength() function on a void dynamic array, when the RTTI is known
- caller should ensure that Dest is not nil, but Dest^ = nil (i.e. a clear/void dynamic array)


1.6.28. EnsureUnique

procedure EnsureUnique(var Value: TRawUtf8DynArray); overload;

Same as Value := copy(Value) but faster and with no temporary variable


1.6.29. EnsureUnique

procedure EnsureUnique(var Value: TVariantDynArray); overload;

Same as Value := copy(Value) but faster and with no temporary variable


1.6.30. EnsureUnique

procedure EnsureUnique(var Value: TIntegerDynArray); overload;

Same as Value := copy(Value) but faster and with no temporary variable


1.6.31. FastDynArrayClear

procedure FastDynArrayClear(Value: PPointer; ElemInfo: PRttiInfo);

Low-level finalization of a dynamic array of any kind
- faster than RTL Finalize() or setting nil, when you know ElemInfo
- see also TRttiInfo.Clear if you want to finalize any type


1.6.32. FastFinalizeArray

procedure FastFinalizeArray(Value: PPointer; ElemTypeInfo: PRttiInfo; Count: integer);

Low-level finalization of all dynamic array items of any kind
- as called by FastDynArrayClear(), after dec(RefCnt) reached 0


1.6.33. FastRecordClear

function FastRecordClear(Value: pointer; Info: PRttiInfo): PtrInt;

Clear the managed fields of a record content
- won't reset all values to zero, only managed fields - see RecordZero()
- caller should ensure the type is indeed a record/object
- see also TRttiInfo.Clear if you want to finalize any type
- same as RTTI_FINALIZE[rkRecord]()


1.6.34. FillZeroRtti

procedure FillZeroRtti(Info: PRttiInfo; var Value);

Fill all sensitive fields of this class or record with zeros
- RawByteString/TBytes with refcount=1 will be zeroed before freed


1.6.35. FinalizeObject

procedure FinalizeObject(Value: TObject);

Release all low-level managed fields of this instance
- just a wrapper around Value.CleanupInstance


1.6.36. FindCustomProp

function FindCustomProp(p: PRttiCustomProp; name: pointer; namelen: TStrLen; count: integer): PRttiCustomProp;

Low-level internal function use when inlining TRttiCustomProps.Find()
- caller should ensure that namelen <> 0


1.6.37. FindPrivateSlot

function FindPrivateSlot(c: TClass; slot: PPointer): pointer;

Low-level internal function used e.g. by TRttiCustom.GetPrivateSlot()
- caller should ensure that slot <> nil


1.6.38. GetCaptionFromClass

function GetCaptionFromClass(C: TClass): string;

UnCamelCase and translate the class name, triming any left 'T' 'TSyn' 'TOrm'
- return RTL string type, i.e. UnicodeString for Delphi 2009+


1.6.39. GetCaptionFromEnum

function GetCaptionFromEnum(aTypeInfo: PRttiInfo; aIndex: integer): string;

UnCamelCase and translate the enumeration item


1.6.40. GetCaptionFromTrimmed

procedure GetCaptionFromTrimmed(PS: PShortString; var result: string);

Low-level helper to retrieve a (translated) caption from a PShortString
- as used e.g. by GetEnumCaptions or GetCaptionFromEnum


1.6.41. GetDisplayNameFromClass

function GetDisplayNameFromClass(C: TClass): RawUtf8;

Will get a class name as UTF-8
- will trim 'T', 'TSyn' or 'TOrm' left side of the class name
- will encode the class name as UTF-8 (for Unicode Delphi versions)
- is used e.g. to extract the SQL table name for a TOrm class


1.6.42. GetEnumCaptions

procedure GetEnumCaptions(aTypeInfo: PRttiInfo; aDest: PString);

Helper to retrieve all (translated) caption texts of an enumerate
- may be used as cache for overloaded ToCaption() content


1.6.43. GetEnumName

function GetEnumName(aTypeInfo: PRttiInfo; aIndex: integer): PShortString;

Helper to retrieve the text of an enumerate item
- just a wrapper around

 aTypeInfo^.EnumBaseType.GetEnumNameOrd(aIndex)

1.6.44. GetEnumNames

procedure GetEnumNames(aTypeInfo: PRttiInfo; aDest: PPShortString);

Helper to retrieve all texts of an enumerate
- may be used as cache for overloaded ToText() content


1.6.45. GetEnumNameTrimed

function GetEnumNameTrimed(aTypeInfo: PRttiInfo; aIndex: integer): RawUtf8;

Get the corresponding enumeration name, without the first lowercase chars
- e.g. otDone -> 'Done'
- this will return the code-based English text; use GetEnumCaption() to retrieve the enumeration display text


1.6.46. GetEnumNameUnCamelCase

function GetEnumNameUnCamelCase(aTypeInfo: PRttiInfo; aIndex: integer): RawUtf8;

Get the enumeration name, without the first lowercase chars, and uncamelcased
- e.g. otProcessDone -> 'Process done'


1.6.47. GetEnumNameValue

function GetEnumNameValue(aTypeInfo: PRttiInfo; const aValue: RawUtf8; AlsoTrimLowerCase: boolean = false): integer; overload;

Helper to retrieve the index of an enumerate item from its text


1.6.48. GetEnumNameValue

function GetEnumNameValue(aTypeInfo: PRttiInfo; aValue: PUtf8Char; aValueLen: PtrInt; AlsoTrimLowerCase: boolean = false): integer; overload;

Helper to retrieve the index of an enumerate item from its text
- returns -1 if aValue was not found
- will search for the exact text and also trim the lowercase 'a'..'z' chars on left side of the text if no exact match is found and AlsoTrimLowerCase is TRUE


1.6.49. GetEnumNameValueTrimmed

function GetEnumNameValueTrimmed(aTypeInfo: PRttiInfo; aValue: PUtf8Char; aValueLen: PtrInt): integer;

Retrieve the index of an enumerate item from its left-trimmed text
- text comparison is case-insensitive for A-Z characters
- will trim the lowercase 'a'..'z' chars on left side of the supplied aValue text
- returns -1 if aValue was not found


1.6.50. GetEnumNameValueTrimmedExact

function GetEnumNameValueTrimmedExact(aTypeInfo: PRttiInfo; aValue: PUtf8Char; aValueLen: PtrInt): integer;

Retrieve the index of an enumerate item from its left-trimmed text
- text comparison is case-sensitive for A-Z characters
- will trim the lowercase 'a'..'z' chars on left side of the supplied aValue text
- returns -1 if aValue was not found


1.6.51. GetEnumTrimmedNames

procedure GetEnumTrimmedNames(aTypeInfo: PRttiInfo; aDest: PRawUtf8); overload;

Helper to retrieve all trimmed texts of an enumerate
- may be used as cache to retrieve UTF-8 text without lowercase 'a'..'z' chars


1.6.52. GetEnumTrimmedNames

function GetEnumTrimmedNames(aTypeInfo: PRttiInfo): TRawUtf8DynArray; overload;

Helper to retrieve all trimmed texts of an enumerate as UTF-8 strings
- typical usage is the following:

 var
   TXT: array[TBenchmark] of RawUtf8;
 ...
   GetEnumTrimmedNames(TypeInfo(TBenchmark), @TXT);

1.6.53. GetEnumType

function GetEnumType(aTypeInfo: PRttiInfo; out List: PShortString): integer;

Helper to retrieve low-level RTTI information of an enumeration type
- just a wrapper around

 aTypeInfo^.EnumBaseType(List, result);

1.6.54. GetInstanceByPath

function GetInstanceByPath(var Instance: TObject; const Path: RawUtf8; out Prop: PRttiCustomProp; PathDelim: AnsiChar = '.'): boolean;

Retrieve a (possibly nested) class property RTTI and instance by path
- as used e.g. by GetValueObject/SetValueObject wrapper functions


1.6.55. GetInterfaceFromEntry

function GetInterfaceFromEntry(Instance: TObject; Entry: PInterfaceEntry; out Obj): boolean;

Execute an instance method from its RTTI per-interface information
- calling this function with a pre-computed PInterfaceEntry value is faster than calling the TObject.GetInterface() method, especially when the class implements several interfaces, since it avoid a slow GUID lookup
- if the interface is retrieved using a getter, will fallback to the regular TObject.GetInterface RTL method


1.6.56. GetPublishedMethods

function GetPublishedMethods(Instance: TObject; out Methods: TPublishedMethodInfoDynArray; aClass: TClass = nil): integer;

Retrieve published methods information about any class instance
- will optionaly accept a Class, in this case Instance is ignored
- will work with FPC and Delphi RTTI


1.6.57. GetRttiClass

function GetRttiClass(RttiClass: TClass): PRttiClass;

Retrieve the class RTTI information for a specific class


1.6.58. GetRttiClassGuid

function GetRttiClassGuid(aClass: TClass): PGuidDynArray;

Returns all TGuid implemented by a given class
- TObject.GetInterfaceTable is not consistent on Delphi and FPC


1.6.59. GetRttiInterface

function GetRttiInterface(aTypeInfo: PRttiInfo; out aDefinition: TRttiInterface): integer;

Retrieve methods information of a given IInvokable
- all methods will be added, also from inherited interface definitions
- returns the number of methods detected


1.6.60. GetRttiProp

function GetRttiProp(C: TClass; out PropInfo: PRttiProp): integer;

Retrieve the class property RTTI information for a specific class
- will return the number of published properties
- and set the PropInfo variable to point to the first property
- typical use to enumerate all published properties could be:

  var i: integer;
      CT: TClass;
      P: PRttiProp;
  begin
    CT := ..;
    repeat
      for i := 1 to GetRttiProp(CT,P) do
       begin
        // use P^
        P := P^.Next;
      end;
      CT := GetClassParent(CT);
    until CT=nil;
  end;

such a loop is much faster than using the RTL's TypeInfo or RTTI units


1.6.61. GetRttiProps

function GetRttiProps(RttiClass: TClass): PRttiProps;

Retrieve the class property RTTI information for a specific class


1.6.62. GetSetCsvValue

function GetSetCsvValue(aTypeInfo: PRttiInfo; Csv: PUtf8Char): QWord;

Helper to parse some CSV values into a set, returned as 64-bit
- CSV could be separated by any non identifier char, e.g. ',' ';' or '|'
- see also GetSetNameValue() in mormot.core.json.pas for parsing a JSON array


1.6.63. GetSetName

function GetSetName(aTypeInfo: PRttiInfo; const value; trimmed: boolean = false): RawUtf8;

Helper to retrieve the CSV text of all enumerate items defined in a set


1.6.64. GetSetNameShort

procedure GetSetNameShort(aTypeInfo: PRttiInfo; const value; out result: ShortString; trimlowercase: boolean = false);

Helper to retrieve the CSV text of all enumerate items defined in a set


1.6.65. InterfaceEntryIsStandard

function InterfaceEntryIsStandard(Entry: PInterfaceEntry): boolean;

Check if a pre-computed PInterfaceEntry has a direct IOffset information


1.6.66. IsObjectDefaultOrVoid

function IsObjectDefaultOrVoid(Value: TObject): boolean;

Returns TRUE on a nil instance or if all its published properties are default/0
- check nested TRttiCustom.Props and TRttiCustom.ValueIterateCount


1.6.67. IsRawUtf8DynArray

function IsRawUtf8DynArray(Info: PRttiInfo): boolean;

Check if the TypeInfo() points to an "array of RawUtf8"
- e.g. returns true for TypeInfo(TRawUtf8DynArray) or other sub-types defined as "type aNewType = type TRawUtf8DynArray"


1.6.68. ItemSizeToDynArrayKind

function ItemSizeToDynArrayKind(size: integer): TRttiParserType;

Internal function used e.g. for enumerations and sets


1.6.69. ObjectToRecord

procedure ObjectToRecord(aFrom: TObject; var aTo; aToType: PRttiInfo);

Copy an object instance properties into a record
- handle properties of the same exact type, searched by name
- copy integer, Int64, enumerates (including boolean), variant, records, dynamic arrays, classes and any string properties (excluding ShortString)
- see also TRttiMap for custom mapping between class and record


1.6.70. ParserTypeToTypeInfo

function ParserTypeToTypeInfo(pt: TRttiParserType; pct: TRttiParserComplexType): PRttiInfo;

Retrieve the TypeInfo() from PT_INFO[] PTC_INFO[] constant arrays


1.6.71. RawUtf8DynArrayClear

procedure RawUtf8DynArrayClear(var Value: TRawUtf8DynArray);

Low-level finalization of a dynamic array of RawUtf8
- faster than RTL Finalize() or setting nil


1.6.72. RecordClearSeveral

procedure RecordClearSeveral(v: PAnsiChar; info: PRttiInfo; n: integer);

Efficient finalization of successive record items from a (dynamic) array


1.6.73. RecordCopy

procedure RecordCopy(var Dest; const Source; Info: PRttiInfo);

Copy a record content from source to Dest


1.6.74. RecordToObject

procedure RecordToObject(const aFrom; aTo: TObject; aFromType: PRttiInfo);

Copy record properties into an object instance
- handle properties of the same exact type, searched by name
- copy integer, Int64, enumerates (including boolean), variant, records, dynamic arrays, classes and any string properties (excluding ShortString)
- see also TRttiMap for custom mapping between class and record


1.6.75. RecordZero

procedure RecordZero(Dest: pointer; Info: PRttiInfo);

Initialize a record content
- calls FastRecordClear() and FillCharFast() with 0
- do nothing if the TypeInfo is not from a record/object


1.6.76. SetDefaultValuesObject

procedure SetDefaultValuesObject(Instance: TObject);

Set any default integer or enumerates (including boolean) published properties values for a TPersistent/TSynPersistent
- set only the values set as "property ... default ..." at class type level
- will also reset the published properties of the nested classes


1.6.77. SetEnumFromOrdinal

procedure SetEnumFromOrdinal(aTypeInfo: PRttiInfo; out Value; Ordinal: PtrUInt);

Store an enumeration value from its ordinal representation


1.6.78. SetNamesValue

procedure SetNamesValue(SetNames: PShortString; MinValue, MaxValue: integer; Value: PUtf8Char; ValueLen: PtrInt; var Result: QWord);

Low-level function parsing Value/ValueLen into a set, returned as 64-bit


1.6.79. SetObjectFromExecutableCommandLine

function SetObjectFromExecutableCommandLine(Value: TObject; const SwitchPrefix, DescriptionSuffix: RawUtf8; CommandLine: TExecutableCommandLine = nil): boolean;

Fill a class instance properties from command line switches
- SwitchPrefix + property name will be searched in CommandLine.Names[]
- is typically used to fill a settings class instance
- won't include any nested class or dynamic array properties


1.6.80. SetValueObject

function SetValueObject(Instance: TObject; const Path: RawUtf8; const Value: variant): boolean;

Set any (potentially nested) object property by path
- see also GetValueObject() from mormot.core.json


1.6.81. StringClearSeveral

procedure StringClearSeveral(v: PPointer; n: PtrInt);

Efficient finalization of successive RawUtf8 items from a (dynamic) array


1.6.82. TObjectWithCustomCreateRttiCustomSetParser

procedure TObjectWithCustomCreateRttiCustomSetParser( O: TObjectWithCustomCreateClass; Rtti: TRttiCustom);

Internal wrapper to protected TObjectWithCustomCreate.RttiCustomSetParser()
- a local TCCHook was reported to have issues on FPC with class methods


1.6.83. TObjectWithIDDynArrayCompare

function TObjectWithIDDynArrayCompare(const Item1, Item2): integer;

TDynArraySortCompare compatible function, sorting by TObjectWithID/TOrm.ID


1.6.84. TObjectWithIDDynArrayHashOne

function TObjectWithIDDynArrayHashOne(const Elem; Hasher: THasher): cardinal;

TDynArrayHashOne compatible function, hashing TObjectWithID/TOrm.ID


1.6.85. ToText

function ToText(w: TWellKnownSid): PShortString; overload;

Defined here to avoid circular dependency in mormot.core.os.pas


1.6.86. ToText

function ToText(t: TRttiParserType): PShortString; overload;

PctNone pctTimeLog pctCreateTime pctModTime pctID pctSpecificClassID pctRecordReference pctRecordReferenceToBeDeleted pctRecordVersion retrieve the text name of one TRttiParserType enumerate


1.6.87. ToText

function ToText(cmd: TParseCommands): ShortString; overload;

Defined here to avoid circular dependency in mormot.core.os.pas


1.6.88. ToText

function ToText(k: TRttiKind): PShortString; overload;

Retrieve the text name of one TRttiKind enumerate


1.6.89. TypeInfoToDynArrayTypeInfo

function TypeInfoToDynArrayTypeInfo(ElemInfo: PRttiInfo; ExpectExactElemInfo: boolean; ParserType: PRttiParserType = nil): PRttiInfo;

Recognize most simple types and return their known dynamic array RTTI
- returns nil if we don't know any dynamic array for this type
- ExpectExactElemInfo=true ensure that result's ArrayRtti.Info = ElemInfo
- currently not called: IList<T> and IKeyValue<T> just use TypeInfo(T)


1.6.90. VariantDynArrayClear

procedure VariantDynArrayClear(var Value: TVariantDynArray);

Faster alternative to Finalize(aVariantDynArray)
- this function will take account and optimize the release of a dynamic array of custom variant types values
- for instance, an array of TDocVariant will be optimized for speed


1.7. Variables implemented in the mormot.core.rtti unit

1.7.1. PTC_INFO

PTC_INFO: array[TRttiParserComplexType] of PRttiInfo;

Simple lookup to the plain RTTI type of most simple managed types
- nil if the complex type is not known
- mormot.orm.base may set the exact TypeInfo(TRecordReference) value - this unit set plain TypeInfo(QWord) which is enough for JSON Serialization


1.7.2. PTC_RTTI

PTC_RTTI: array[TRttiParserComplexType] of TRttiCustom;

Direct lookup to the TRttiCustom of TRttiParserComplexType values


1.7.3. PT_INFO

PT_INFO: array[TRttiParserType] of PRttiInfo;

Simple lookup to the plain RTTI type of most simple managed types
- nil for unmanaged types (e.g. rkOrdinals) or for more complex types requering additional PRttiInfo (rkRecord, rkDynArray, rkArray...)
- you can use PT_INFO[] for types with no RTTI before Delphi 2010, for instance PT_INFO[ptGuid], PT_INFO[ptHash128], PT_INFO[ptHash256] and PT_INFO[ptHash512] since oldest compilers refuse to compile TypeInfo(TGuid), TypeInfo(THash128), TypeInfo(THash256) and TypeInfo(THash512)


1.7.4. PT_RTTI

PT_RTTI: array[TRttiParserType] of TRttiCustom;

Direct lookup to the TRttiCustom of TRttiParserType values


1.7.5. Rtti

Rtti: TRttiCustomList;

Low-level access to the list of registered PRttiInfo/TRttiCustom/TRttiJson


1.7.6. RTTI_FINALIZE

RTTI_FINALIZE: TRttiFinalizers;

Lookup table of finalization functions for managed types
- as used by TRttiInfo.Clear() inlined method
- RTTI_FINALIZE[...]=nil for unmanaged types (e.g. rkOrdinalTypes)


1.7.7. RTTI_FROM_ORD

RTTI_FROM_ORD: array[TRttiOrd] of function(P: pointer): Int64;

Convert an ordinal value from its (signed) pointer-sized integer representation


1.7.8. RTTI_MANAGEDCOPY

RTTI_MANAGEDCOPY: TRttiCopiers;

Lookup table of copy function for managed types
- as used by TRttiInfo.Copy() inlined method
- RTTI_MANAGEDCOPY[...]=nil for unmanaged types (e.g. rkOrdinalTypes)


1.7.9. RTTI_TO_FLOAT

RTTI_TO_FLOAT: array[TRttiFloat] of procedure(P: pointer; Value: TSynExtended);

Convert a float value into its RTTI-defined binary buffer


1.7.10. RTTI_TO_ORD

RTTI_TO_ORD: array[TRttiOrd] of procedure(P: pointer; Value: PtrInt);

Convert an ordinal value into its RTTI-defined binary buffer