typinfo.pp 112 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Florian Klaempfl
  4. member of the Free Pascal development team
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. { This unit provides the same Functionality as the TypInfo Unit }
  12. { of Delphi }
  13. unit TypInfo;
  14. interface
  15. {$MODE objfpc}
  16. {$MODESWITCH AdvancedRecords}
  17. {$inline on}
  18. {$macro on}
  19. {$h+}
  20. uses SysUtils;
  21. // temporary types:
  22. type
  23. {$MINENUMSIZE 1 this saves a lot of memory }
  24. {$ifdef FPC_RTTI_PACKSET1}
  25. { for Delphi compatibility }
  26. {$packset 1}
  27. {$endif}
  28. { this alias and the following constant aliases are for backwards
  29. compatibility before TTypeKind was moved to System unit }
  30. TTypeKind = System.TTypeKind;
  31. const
  32. tkUnknown = System.tkUnknown;
  33. tkInteger = System.tkInteger;
  34. tkChar = System.tkChar;
  35. tkEnumeration = System.tkEnumeration;
  36. tkFloat = System.tkFloat;
  37. tkSet = System.tkSet;
  38. tkMethod = System.tkMethod;
  39. tkSString = System.tkSString;
  40. tkLString = System.tkLString;
  41. tkAString = System.tkAString;
  42. tkWString = System.tkWString;
  43. tkVariant = System.tkVariant;
  44. tkArray = System.tkArray;
  45. tkRecord = System.tkRecord;
  46. tkInterface = System.tkInterface;
  47. tkClass = System.tkClass;
  48. tkObject = System.tkObject;
  49. tkWChar = System.tkWChar;
  50. tkBool = System.tkBool;
  51. tkInt64 = System.tkInt64;
  52. tkQWord = System.tkQWord;
  53. tkDynArray = System.tkDynArray;
  54. tkInterfaceRaw = System.tkInterfaceRaw;
  55. tkProcVar = System.tkProcVar;
  56. tkUString = System.tkUString;
  57. tkUChar = System.tkUChar;
  58. tkHelper = System.tkHelper;
  59. tkFile = System.tkFile;
  60. tkClassRef = System.tkClassRef;
  61. tkPointer = System.tkPointer;
  62. type
  63. TOrdType = (otSByte,otUByte,otSWord,otUWord,otSLong,otULong,otSQWord,otUQWord);
  64. {$ifndef FPUNONE}
  65. TFloatType = (ftSingle,ftDouble,ftExtended,ftComp,ftCurr);
  66. {$endif}
  67. TMethodKind = (mkProcedure,mkFunction,mkConstructor,mkDestructor,
  68. mkClassProcedure,mkClassFunction,mkClassConstructor,
  69. mkClassDestructor,mkOperatorOverload);
  70. TParamFlag = (pfVar,pfConst,pfArray,pfAddress,pfReference,pfOut,pfConstRef
  71. {$ifndef VER3_0},pfHidden,pfHigh,pfSelf,pfVmt,pfResult{$endif VER3_0}
  72. );
  73. TParamFlags = set of TParamFlag;
  74. TIntfFlag = (ifHasGuid,ifDispInterface,ifDispatch,ifHasStrGUID);
  75. TIntfFlags = set of TIntfFlag;
  76. TIntfFlagsBase = set of TIntfFlag;
  77. // don't rely on integer values of TCallConv since it includes all conventions
  78. // which both Delphi and FPC support. In the future Delphi can support more and
  79. // FPC's own conventions will be shifted/reordered accordingly
  80. TCallConv = (ccReg, ccCdecl, ccPascal, ccStdCall, ccSafeCall,
  81. ccCppdecl, ccFar16, ccOldFPCCall, ccInternProc,
  82. ccSysCall, ccSoftFloat, ccMWPascal);
  83. {$push}
  84. {$scopedenums on}
  85. TSubRegister = (
  86. None,
  87. Lo,
  88. Hi,
  89. Word,
  90. DWord,
  91. QWord,
  92. FloatSingle,
  93. FloatDouble,
  94. FloatQuad,
  95. MultiMediaSingle,
  96. MultiMediaDouble,
  97. MultiMediaWhole,
  98. MultiMediaX,
  99. MultiMediaY
  100. );
  101. TRegisterType = (
  102. Invalid,
  103. Int,
  104. FP,
  105. MMX,
  106. MultiMedia,
  107. Special,
  108. Address
  109. );
  110. {$pop}
  111. {$MINENUMSIZE DEFAULT}
  112. const
  113. ptField = 0;
  114. ptStatic = 1;
  115. ptVirtual = 2;
  116. ptConst = 3;
  117. type
  118. TTypeKinds = set of TTypeKind;
  119. ShortStringBase = string[255];
  120. PParameterLocation = ^TParameterLocation;
  121. TParameterLocation =
  122. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  123. packed
  124. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  125. record
  126. private
  127. LocType: Byte;
  128. function GetRegType: TRegisterType; inline;
  129. function GetReference: Boolean; inline;
  130. function GetShiftVal: Int8; inline;
  131. public
  132. RegSub: TSubRegister;
  133. RegNumber: Word;
  134. { Stack offset if Reference, ShiftVal if not }
  135. Offset: SizeInt;
  136. { if Reference then the register is the index register otherwise the
  137. register in wihch (part of) the parameter resides }
  138. property Reference: Boolean read GetReference;
  139. property RegType: TRegisterType read GetRegType;
  140. { if Reference, otherwise 0 }
  141. property ShiftVal: Int8 read GetShiftVal;
  142. end;
  143. PParameterLocations = ^TParameterLocations;
  144. TParameterLocations =
  145. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  146. packed
  147. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  148. record
  149. private
  150. function GetLocation(aIndex: Byte): PParameterLocation; inline;
  151. function GetTail: Pointer; inline;
  152. public
  153. Count: Byte;
  154. property Location[Index: Byte]: PParameterLocation read GetLocation;
  155. property Tail: Pointer read GetTail;
  156. end;
  157. PVmtFieldClassTab = ^TVmtFieldClassTab;
  158. TVmtFieldClassTab =
  159. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  160. packed
  161. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  162. record
  163. Count: Word;
  164. ClassRef: array[0..0] of PClass;
  165. end;
  166. PVmtFieldEntry = ^TVmtFieldEntry;
  167. TVmtFieldEntry =
  168. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  169. packed
  170. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  171. record
  172. private
  173. function GetNext: PVmtFieldEntry; inline;
  174. function GetTail: Pointer; inline;
  175. public
  176. FieldOffset: PtrUInt;
  177. TypeIndex: Word;
  178. Name: ShortString;
  179. property Tail: Pointer read GetTail;
  180. property Next: PVmtFieldEntry read GetNext;
  181. end;
  182. PVmtFieldTable = ^TVmtFieldTable;
  183. TVmtFieldTable =
  184. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  185. packed
  186. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  187. record
  188. private
  189. function GetField(aIndex: Word): PVmtFieldEntry;
  190. public
  191. Count: Word;
  192. ClassTab: PVmtFieldClassTab;
  193. { should be array[Word] of TFieldInfo; but
  194. Elements have variant size! force at least proper alignment }
  195. Fields: array[0..0] of TVmtFieldEntry;
  196. property Field[aIndex: Word]: PVmtFieldEntry read GetField;
  197. end;
  198. {$PACKRECORDS 1}
  199. TTypeInfo = record
  200. Kind : TTypeKind;
  201. Name : ShortString;
  202. // here the type data follows as TTypeData record
  203. end;
  204. PTypeInfo = ^TTypeInfo;
  205. PPTypeInfo = ^PTypeInfo;
  206. PPropData = ^TPropData;
  207. { Note: these are only for backwards compatibility. New type references should
  208. only use PPTypeInfo directly! }
  209. {$ifdef ver3_0}
  210. {$define TypeInfoPtr := PTypeInfo}
  211. {$else}
  212. {$define TypeInfoPtr := PPTypeInfo}
  213. {$endif}
  214. {$PACKRECORDS C}
  215. {$if not defined(VER3_0) and not defined(VER3_2)}
  216. {$define PROVIDE_ATTR_TABLE}
  217. {$endif}
  218. TAttributeProc = function : TCustomAttribute;
  219. TAttributeEntry =
  220. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  221. packed
  222. {$endif}
  223. record
  224. AttrType: PPTypeInfo;
  225. AttrCtor: CodePointer;
  226. AttrProc: TAttributeProc;
  227. ArgLen: Word;
  228. ArgData: Pointer;
  229. end;
  230. {$ifdef CPU16}
  231. TAttributeEntryList = array[0..(High(SizeUInt) div SizeOf(TAttributeEntry))-1] of TAttributeEntry;
  232. {$else CPU16}
  233. TAttributeEntryList = array[0..$ffff] of TAttributeEntry;
  234. {$endif CPU16}
  235. TAttributeTable =
  236. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  237. packed
  238. {$endif}
  239. record
  240. AttributeCount: word;
  241. AttributesList: TAttributeEntryList;
  242. end;
  243. PAttributeTable = ^TAttributeTable;
  244. // members of TTypeData
  245. TArrayTypeData =
  246. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  247. packed
  248. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  249. record
  250. private
  251. function GetElType: PTypeInfo; inline;
  252. function GetDims(aIndex: Byte): PTypeInfo; inline;
  253. public
  254. property ElType: PTypeInfo read GetElType;
  255. property Dims[Index: Byte]: PTypeInfo read GetDims;
  256. public
  257. Size: SizeInt;
  258. ElCount: SizeInt;
  259. ElTypeRef: TypeInfoPtr;
  260. DimCount: Byte;
  261. DimsRef: array[0..255] of TypeInfoPtr;
  262. end;
  263. PManagedField = ^TManagedField;
  264. TManagedField =
  265. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  266. packed
  267. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  268. record
  269. private
  270. function GetTypeRef: PTypeInfo; inline;
  271. public
  272. property TypeRef: PTypeInfo read GetTypeRef;
  273. public
  274. TypeRefRef: TypeInfoPtr;
  275. FldOffset: SizeInt;
  276. end;
  277. PInitManagedField = ^TInitManagedField;
  278. TInitManagedField = TManagedField;
  279. PProcedureParam = ^TProcedureParam;
  280. TProcedureParam =
  281. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  282. packed
  283. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  284. record
  285. private
  286. function GetParamType: PTypeInfo; inline;
  287. function GetFlags: Byte; inline;
  288. public
  289. property ParamType: PTypeInfo read GetParamType;
  290. property Flags: Byte read GetFlags;
  291. public
  292. ParamFlags: TParamFlags;
  293. ParamTypeRef: TypeInfoPtr;
  294. Name: ShortString;
  295. end;
  296. PProcedureSignature = ^TProcedureSignature;
  297. TProcedureSignature =
  298. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  299. packed
  300. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  301. record
  302. private
  303. function GetResultType: PTypeInfo; inline;
  304. public
  305. property ResultType: PTypeInfo read GetResultType;
  306. public
  307. Flags: Byte;
  308. CC: TCallConv;
  309. ResultTypeRef: TypeInfoPtr;
  310. ParamCount: Byte;
  311. {Params: array[0..ParamCount - 1] of TProcedureParam;}
  312. function GetParam(ParamIndex: Integer): PProcedureParam;
  313. end;
  314. PVmtMethodParam = ^TVmtMethodParam;
  315. TVmtMethodParam =
  316. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  317. packed
  318. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  319. record
  320. private
  321. function GetTail: Pointer; inline;
  322. function GetNext: PVmtMethodParam; inline;
  323. function GetName: ShortString; inline;
  324. public
  325. ParamType: PPTypeInfo;
  326. Flags: TParamFlags;
  327. NamePtr: PShortString;
  328. ParaLocs: PParameterLocations;
  329. property Name: ShortString read GetName;
  330. property Tail: Pointer read GetTail;
  331. property Next: PVmtMethodParam read GetNext;
  332. end;
  333. PIntfMethodEntry = ^TIntfMethodEntry;
  334. TIntfMethodEntry =
  335. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  336. packed
  337. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  338. record
  339. private
  340. function GetParam(Index: Word): PVmtMethodParam;
  341. function GetResultLocs: PParameterLocations; inline;
  342. function GetTail: Pointer; inline;
  343. function GetNext: PIntfMethodEntry; inline;
  344. function GetName: ShortString; inline;
  345. public
  346. ResultType: PPTypeInfo;
  347. CC: TCallConv;
  348. Kind: TMethodKind;
  349. ParamCount: Word;
  350. StackSize: SizeInt;
  351. NamePtr: PShortString;
  352. { Params: array[0..ParamCount - 1] of TVmtMethodParam }
  353. { ResultLocs: PParameterLocations (if ResultType != Nil) }
  354. property Name: ShortString read GetName;
  355. property Param[Index: Word]: PVmtMethodParam read GetParam;
  356. property ResultLocs: PParameterLocations read GetResultLocs;
  357. property Tail: Pointer read GetTail;
  358. property Next: PIntfMethodEntry read GetNext;
  359. end;
  360. PIntfMethodTable = ^TIntfMethodTable;
  361. TIntfMethodTable =
  362. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  363. packed
  364. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  365. record
  366. private
  367. function GetMethod(Index: Word): PIntfMethodEntry;
  368. public
  369. Count: Word;
  370. { $FFFF if there is no further info, or the value of Count }
  371. RTTICount: Word;
  372. { Entry: array[0..Count - 1] of TIntfMethodEntry }
  373. property Method[Index: Word]: PIntfMethodEntry read GetMethod;
  374. end;
  375. PVmtMethodEntry = ^TVmtMethodEntry;
  376. TVmtMethodEntry =
  377. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  378. packed
  379. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  380. record
  381. Name: PShortString;
  382. CodeAddress: CodePointer;
  383. end;
  384. PVmtMethodTable = ^TVmtMethodTable;
  385. TVmtMethodTable =
  386. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  387. packed
  388. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  389. record
  390. private
  391. function GetEntry(Index: LongWord): PVmtMethodEntry; inline;
  392. public
  393. Count: LongWord;
  394. property Entry[Index: LongWord]: PVmtMethodEntry read GetEntry;
  395. private
  396. Entries: array[0..0] of TVmtMethodEntry;
  397. end;
  398. TRecOpOffsetEntry =
  399. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  400. packed
  401. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  402. record
  403. ManagementOperator: CodePointer;
  404. FieldOffset: SizeUInt;
  405. end;
  406. TRecOpOffsetTable =
  407. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  408. packed
  409. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  410. record
  411. Count: LongWord;
  412. Entries: array[0..0] of TRecOpOffsetEntry;
  413. end;
  414. PRecOpOffsetTable = ^TRecOpOffsetTable;
  415. PRecInitData = ^TRecInitData;
  416. TRecInitData =
  417. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  418. packed
  419. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  420. record
  421. {$ifdef PROVIDE_ATTR_TABLE}
  422. AttributeTable : PAttributeTable;
  423. {$endif}
  424. case TTypeKind of
  425. tkRecord: (
  426. Terminator: Pointer;
  427. Size: Longint;
  428. {$ifndef VER3_0}
  429. InitOffsetOp: PRecOpOffsetTable;
  430. ManagementOp: Pointer;
  431. {$endif}
  432. ManagedFieldCount: Longint;
  433. { ManagedFields: array[0..ManagedFieldCount - 1] of TInitManagedField ; }
  434. );
  435. { include for proper alignment }
  436. tkInt64: (
  437. dummy : Int64
  438. );
  439. end;
  440. PInterfaceData = ^TInterfaceData;
  441. TInterfaceData =
  442. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  443. packed
  444. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  445. record
  446. private
  447. function GetUnitName: ShortString; inline;
  448. function GetPropertyTable: PPropData; inline;
  449. function GetMethodTable: PIntfMethodTable; inline;
  450. public
  451. property UnitName: ShortString read GetUnitName;
  452. property PropertyTable: PPropData read GetPropertyTable;
  453. property MethodTable: PIntfMethodTable read GetMethodTable;
  454. public
  455. {$ifdef PROVIDE_ATTR_TABLE}
  456. AttributeTable : PAttributeTable;
  457. {$endif}
  458. case TTypeKind of
  459. tkInterface: (
  460. Parent: PPTypeInfo;
  461. Flags: TIntfFlagsBase;
  462. GUID: TGUID;
  463. ThunkClass : PPTypeInfo;
  464. UnitNameField: ShortString;
  465. { PropertyTable: TPropData }
  466. { MethodTable: TIntfMethodTable }
  467. );
  468. { include for proper alignment }
  469. tkInt64: (
  470. dummy : Int64
  471. );
  472. {$ifndef FPUNONE}
  473. tkFloat:
  474. (FloatType : TFloatType
  475. );
  476. {$endif}
  477. end;
  478. PInterfaceRawData = ^TInterfaceRawData;
  479. TInterfaceRawData =
  480. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  481. packed
  482. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  483. record
  484. private
  485. function GetUnitName: ShortString; inline;
  486. function GetIIDStr: ShortString; inline;
  487. function GetPropertyTable: PPropData; inline;
  488. function GetMethodTable: PIntfMethodTable; inline;
  489. public
  490. property UnitName: ShortString read GetUnitName;
  491. property IIDStr: ShortString read GetIIDStr;
  492. property PropertyTable: PPropData read GetPropertyTable;
  493. property MethodTable: PIntfMethodTable read GetMethodTable;
  494. public
  495. {$ifdef PROVIDE_ATTR_TABLE}
  496. AttributeTable : PAttributeTable;
  497. {$endif}
  498. case TTypeKind of
  499. tkInterface: (
  500. Parent: PPTypeInfo;
  501. Flags : TIntfFlagsBase;
  502. IID: TGUID;
  503. ThunkClass : PPTypeInfo;
  504. UnitNameField: ShortString;
  505. { IIDStr: ShortString; }
  506. { PropertyTable: TPropData }
  507. );
  508. { include for proper alignment }
  509. tkInt64: (
  510. dummy : Int64
  511. );
  512. {$ifndef FPUNONE}
  513. tkFloat:
  514. (FloatType : TFloatType
  515. );
  516. {$endif}
  517. end;
  518. PClassData = ^TClassData;
  519. TClassData =
  520. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  521. packed
  522. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  523. record
  524. private
  525. function GetUnitName: ShortString; inline;
  526. function GetPropertyTable: PPropData; inline;
  527. public
  528. property UnitName: ShortString read GetUnitName;
  529. property PropertyTable: PPropData read GetPropertyTable;
  530. public
  531. {$ifdef PROVIDE_ATTR_TABLE}
  532. AttributeTable : PAttributeTable;
  533. {$endif}
  534. case TTypeKind of
  535. tkClass: (
  536. ClassType : TClass;
  537. Parent : PPTypeInfo;
  538. PropCount : SmallInt;
  539. UnitNameField : ShortString;
  540. { PropertyTable: TPropData }
  541. );
  542. { include for proper alignment }
  543. tkInt64: (
  544. dummy: Int64;
  545. );
  546. {$ifndef FPUNONE}
  547. tkFloat: (
  548. FloatType : TFloatType
  549. );
  550. {$endif}
  551. end;
  552. PTypeData = ^TTypeData;
  553. TTypeData =
  554. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  555. packed
  556. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  557. record
  558. private
  559. function GetBaseType: PTypeInfo; inline;
  560. function GetCompType: PTypeInfo; inline;
  561. function GetParentInfo: PTypeInfo; inline;
  562. {$ifndef VER3_0}
  563. function GetRecInitData: PRecInitData; inline;
  564. {$endif}
  565. function GetHelperParent: PTypeInfo; inline;
  566. function GetExtendedInfo: PTypeInfo; inline;
  567. function GetIntfParent: PTypeInfo; inline;
  568. function GetRawIntfParent: PTypeInfo; inline;
  569. function GetIIDStr: ShortString; inline;
  570. function GetElType: PTypeInfo; inline;
  571. function GetElType2: PTypeInfo; inline;
  572. function GetInstanceType: PTypeInfo; inline;
  573. function GetRefType: PTypeInfo; inline;
  574. public
  575. { tkEnumeration }
  576. property BaseType: PTypeInfo read GetBaseType;
  577. { tkSet }
  578. property CompType: PTypeInfo read GetCompType;
  579. { tkClass }
  580. property ParentInfo: PTypeInfo read GetParentInfo;
  581. { tkRecord }
  582. {$ifndef VER3_0}
  583. property RecInitData: PRecInitData read GetRecInitData;
  584. {$endif}
  585. { tkHelper }
  586. property HelperParent: PTypeInfo read GetHelperParent;
  587. property ExtendedInfo: PTypeInfo read GetExtendedInfo;
  588. { tkInterface }
  589. property IntfParent: PTypeInfo read GetIntfParent;
  590. { tkInterfaceRaw }
  591. property RawIntfParent: PTypeInfo read GetRawIntfParent;
  592. property IIDStr: ShortString read GetIIDStr;
  593. { tkDynArray }
  594. property ElType2: PTypeInfo read GetElType2;
  595. property ElType: PTypeInfo read GetElType;
  596. { tkClassRef }
  597. property InstanceType: PTypeInfo read GetInstanceType;
  598. { tkPointer }
  599. property RefType: PTypeInfo read GetRefType;
  600. public
  601. {$ifdef PROVIDE_ATTR_TABLE}
  602. AttributeTable : PAttributeTable;
  603. {$endif}
  604. case TTypeKind of
  605. tkUnKnown,tkLString,tkWString,tkVariant,tkUString:
  606. ();
  607. tkAString:
  608. (CodePage: Word);
  609. {$ifndef VER3_0}
  610. tkInt64,tkQWord,
  611. {$endif VER3_0}
  612. tkInteger,tkChar,tkEnumeration,tkBool,tkWChar,tkSet:
  613. (OrdType : TOrdType;
  614. case TTypeKind of
  615. tkInteger,tkChar,tkEnumeration,tkBool,tkWChar : (
  616. MinValue,MaxValue : Longint;
  617. case TTypeKind of
  618. tkEnumeration:
  619. (
  620. BaseTypeRef : TypeInfoPtr;
  621. NameList : ShortString;
  622. {EnumUnitName: ShortString;})
  623. );
  624. {$ifndef VER3_0}
  625. {tkBool with OrdType=otSQWord }
  626. tkInt64:
  627. (MinInt64Value, MaxInt64Value: Int64);
  628. {tkBool with OrdType=otUQWord }
  629. tkQWord:
  630. (MinQWordValue, MaxQWordValue: QWord);
  631. {$endif VER3_0}
  632. tkSet:
  633. (
  634. {$ifndef VER3_0}
  635. SetSize : SizeInt;
  636. {$endif VER3_0}
  637. CompTypeRef : TypeInfoPtr
  638. )
  639. );
  640. {$ifndef FPUNONE}
  641. tkFloat:
  642. (FloatType : TFloatType);
  643. {$endif}
  644. tkSString:
  645. (MaxLength : Byte);
  646. tkClass:
  647. (ClassType : TClass;
  648. ParentInfoRef : TypeInfoPtr;
  649. PropCount : SmallInt;
  650. UnitName : ShortString;
  651. // here the properties follow as array of TPropInfo
  652. );
  653. tkRecord:
  654. (
  655. {$ifndef VER3_0}
  656. RecInitInfo: Pointer; { points to TTypeInfo followed by init table }
  657. {$endif VER3_0}
  658. RecSize: Longint;
  659. case Boolean of
  660. False: (ManagedFldCount: Longint deprecated 'Use RecInitData^.ManagedFieldCount or TotalFieldCount depending on your use case');
  661. True: (TotalFieldCount: Longint);
  662. {ManagedFields: array[1..TotalFieldCount] of TManagedField}
  663. );
  664. tkHelper:
  665. (HelperParentRef : TypeInfoPtr;
  666. ExtendedInfoRef : TypeInfoPtr;
  667. HelperProps : SmallInt;
  668. HelperUnit : ShortString
  669. // here the properties follow as array of TPropInfo
  670. );
  671. tkMethod:
  672. (MethodKind : TMethodKind;
  673. ParamCount : Byte;
  674. case Boolean of
  675. False: (ParamList : array[0..1023] of Char);
  676. { dummy for proper alignment }
  677. True: (ParamListDummy : Word);
  678. {in reality ParamList is a array[1..ParamCount] of:
  679. record
  680. Flags : TParamFlags;
  681. ParamName : ShortString;
  682. TypeName : ShortString;
  683. end;
  684. followed by
  685. ResultType : ShortString // for mkFunction, mkClassFunction only
  686. ResultTypeRef : PPTypeInfo; // for mkFunction, mkClassFunction only
  687. CC : TCallConv;
  688. ParamTypeRefs : array[1..ParamCount] of PPTypeInfo;}
  689. );
  690. tkProcVar:
  691. (ProcSig: TProcedureSignature);
  692. {$ifdef VER3_0}
  693. tkInt64:
  694. (MinInt64Value, MaxInt64Value: Int64);
  695. tkQWord:
  696. (MinQWordValue, MaxQWordValue: QWord);
  697. {$endif VER3_0}
  698. tkInterface:
  699. (
  700. IntfParentRef: TypeInfoPtr;
  701. IntfFlags : TIntfFlagsBase;
  702. GUID: TGUID;
  703. ThunkClass : PPTypeInfo;
  704. IntfUnit: ShortString;
  705. { PropertyTable: TPropData }
  706. { MethodTable: TIntfMethodTable }
  707. );
  708. tkInterfaceRaw:
  709. (
  710. RawIntfParentRef: TypeInfoPtr;
  711. RawIntfFlags : TIntfFlagsBase;
  712. IID: TGUID;
  713. RawThunkClass : PPTypeInfo;
  714. RawIntfUnit: ShortString;
  715. { IIDStr: ShortString; }
  716. { PropertyTable: TPropData }
  717. );
  718. tkArray:
  719. (ArrayData: TArrayTypeData);
  720. tkDynArray:
  721. (
  722. elSize : PtrUInt;
  723. elType2Ref : TypeInfoPtr;
  724. varType : Longint;
  725. elTypeRef : TypeInfoPtr;
  726. DynUnitName: ShortStringBase
  727. );
  728. tkClassRef:
  729. (InstanceTypeRef: TypeInfoPtr);
  730. tkPointer:
  731. (RefTypeRef: TypeInfoPtr);
  732. end;
  733. PPropInfo = ^TPropInfo;
  734. TPropData =
  735. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  736. packed
  737. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  738. record
  739. private
  740. function GetProp(Index: Word): PPropInfo;
  741. function GetTail: Pointer; inline;
  742. public
  743. PropCount : Word;
  744. PropList : record _alignmentdummy : ptrint; end;
  745. property Prop[Index: Word]: PPropInfo read GetProp;
  746. property Tail: Pointer read GetTail;
  747. end;
  748. {$PACKRECORDS 1}
  749. TPropInfo = packed record
  750. private
  751. function GetPropType: PTypeInfo; inline;
  752. function GetTail: Pointer; inline;
  753. function GetNext: PPropInfo; inline;
  754. public
  755. PropTypeRef : TypeInfoPtr;
  756. GetProc : CodePointer;
  757. SetProc : CodePointer;
  758. StoredProc : CodePointer;
  759. Index : Longint;
  760. Default : Longint;
  761. NameIndex : SmallInt;
  762. // contains the type of the Get/Set/Storedproc, see also ptxxx
  763. // bit 0..1 GetProc
  764. // 2..3 SetProc
  765. // 4..5 StoredProc
  766. // 6 : true, constant index property
  767. PropProcs : Byte;
  768. {$ifdef PROVIDE_ATTR_TABLE}
  769. AttributeTable : PAttributeTable;
  770. {$endif}
  771. Name : ShortString;
  772. property PropType: PTypeInfo read GetPropType;
  773. property Tail: Pointer read GetTail;
  774. property Next: PPropInfo read GetNext;
  775. end;
  776. TProcInfoProc = Procedure(PropInfo : PPropInfo) of object;
  777. PPropList = ^TPropList;
  778. TPropList = array[0..{$ifdef cpu16}(32768 div sizeof(PPropInfo))-2{$else}65535{$endif}] of PPropInfo;
  779. const
  780. tkString = tkSString;
  781. tkProcedure = tkProcVar; // for compatibility with Delphi
  782. tkAny = [Low(TTypeKind)..High(TTypeKind)];
  783. tkMethods = [tkMethod];
  784. tkProperties = tkAny-tkMethods-[tkUnknown];
  785. // general property handling
  786. Function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
  787. Function AlignTypeData(p : Pointer) : Pointer; inline;
  788. Function AlignTParamFlags(p : Pointer) : Pointer; inline;
  789. Function AlignPTypeInfo(p : Pointer) : Pointer; inline;
  790. Generic Function ConstParamIsRef<T>(aCallConv: TCallConv = ccReg): Boolean; inline;
  791. Function GetPropInfo(TypeInfo: PTypeInfo;const PropName: string): PPropInfo;
  792. Function GetPropInfo(TypeInfo: PTypeInfo;const PropName: string; AKinds: TTypeKinds): PPropInfo;
  793. Function GetPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  794. Function GetPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  795. Function GetPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  796. Function GetPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  797. Function FindPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  798. Function FindPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  799. Function FindPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  800. Function FindPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  801. Procedure GetPropInfos(TypeInfo: PTypeInfo; PropList: PPropList);
  802. Function GetPropList(TypeInfo: PTypeInfo; TypeKinds: TTypeKinds; PropList: PPropList; Sorted: boolean = true): longint;
  803. Function GetPropList(TypeInfo: PTypeInfo; out PropList: PPropList): SizeInt;
  804. function GetPropList(AClass: TClass; out PropList: PPropList): Integer;
  805. function GetPropList(Instance: TObject; out PropList: PPropList): Integer;
  806. // Property information routines.
  807. Function IsReadableProp(PropInfo : PPropInfo) : Boolean;
  808. Function IsReadableProp(Instance: TObject; const PropName: string): Boolean;
  809. Function IsReadableProp(AClass: TClass; const PropName: string): Boolean;
  810. Function IsWriteableProp(PropInfo : PPropInfo) : Boolean;
  811. Function IsWriteableProp(Instance: TObject; const PropName: string): Boolean;
  812. Function IsWriteableProp(AClass: TClass; const PropName: string): Boolean;
  813. Function IsStoredProp(Instance: TObject;PropInfo : PPropInfo) : Boolean;
  814. Function IsStoredProp(Instance: TObject; const PropName: string): Boolean;
  815. Function IsPublishedProp(Instance: TObject; const PropName: string): Boolean;
  816. Function IsPublishedProp(AClass: TClass; const PropName: string): Boolean;
  817. Function PropType(Instance: TObject; const PropName: string): TTypeKind;
  818. Function PropType(AClass: TClass; const PropName: string): TTypeKind;
  819. Function PropIsType(Instance: TObject; const PropName: string; TypeKind: TTypeKind): Boolean;
  820. Function PropIsType(AClass: TClass; const PropName: string; TypeKind: TTypeKind): Boolean;
  821. // subroutines to read/write properties
  822. Function GetOrdProp(Instance: TObject; PropInfo : PPropInfo) : Int64;
  823. Function GetOrdProp(Instance: TObject; const PropName: string): Int64;
  824. Procedure SetOrdProp(Instance: TObject; PropInfo : PPropInfo; Value : Int64);
  825. Procedure SetOrdProp(Instance: TObject; const PropName: string; Value: Int64);
  826. Function GetEnumProp(Instance: TObject; const PropName: string): string;
  827. Function GetEnumProp(Instance: TObject; const PropInfo: PPropInfo): string;
  828. Procedure SetEnumProp(Instance: TObject; const PropName: string;const Value: string);
  829. Procedure SetEnumProp(Instance: TObject; const PropInfo: PPropInfo;const Value: string);
  830. Function GetSetProp(Instance: TObject; const PropName: string): string;
  831. Function GetSetProp(Instance: TObject; const PropName: string; Brackets: Boolean): string;
  832. Function GetSetProp(Instance: TObject; const PropInfo: PPropInfo; Brackets: Boolean): string;
  833. Procedure SetSetProp(Instance: TObject; const PropName: string; const Value: string);
  834. Procedure SetSetProp(Instance: TObject; const PropInfo: PPropInfo; const Value: string);
  835. Function GetStrProp(Instance: TObject; PropInfo : PPropInfo) : Ansistring;
  836. Function GetStrProp(Instance: TObject; const PropName: string): string;
  837. Procedure SetStrProp(Instance: TObject; const PropName: string; const Value: AnsiString);
  838. Procedure SetStrProp(Instance: TObject; PropInfo : PPropInfo; const Value : Ansistring);
  839. Function GetWideStrProp(Instance: TObject; PropInfo: PPropInfo): WideString;
  840. Function GetWideStrProp(Instance: TObject; const PropName: string): WideString;
  841. Procedure SetWideStrProp(Instance: TObject; const PropName: string; const Value: WideString);
  842. Procedure SetWideStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: WideString);
  843. Function GetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo): UnicodeString;
  844. Function GetUnicodeStrProp(Instance: TObject; const PropName: string): UnicodeString;
  845. Procedure SetUnicodeStrProp(Instance: TObject; const PropName: string; const Value: UnicodeString);
  846. Procedure SetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: UnicodeString);
  847. Function GetRawbyteStrProp(Instance: TObject; PropInfo: PPropInfo): RawByteString;
  848. Function GetRawByteStrProp(Instance: TObject; const PropName: string): RawByteString;
  849. Procedure SetRawByteStrProp(Instance: TObject; const PropName: string; const Value: RawByteString);
  850. Procedure SetRawByteStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: RawByteString);
  851. {$ifndef FPUNONE}
  852. Function GetFloatProp(Instance: TObject; PropInfo : PPropInfo) : Extended;
  853. Function GetFloatProp(Instance: TObject; const PropName: string): Extended;
  854. Procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Extended);
  855. Procedure SetFloatProp(Instance: TObject; PropInfo : PPropInfo; Value : Extended);
  856. {$endif}
  857. Function GetObjectProp(Instance: TObject; const PropName: string): TObject;
  858. Function GetObjectProp(Instance: TObject; const PropName: string; MinClass: TClass): TObject;
  859. Function GetObjectProp(Instance: TObject; PropInfo: PPropInfo): TObject;
  860. Function GetObjectProp(Instance: TObject; PropInfo: PPropInfo; MinClass: TClass): TObject;
  861. Procedure SetObjectProp(Instance: TObject; const PropName: string; Value: TObject);
  862. Procedure SetObjectProp(Instance: TObject; PropInfo: PPropInfo; Value: TObject);
  863. Function GetObjectPropClass(Instance: TObject; const PropName: string): TClass;
  864. Function GetObjectPropClass(AClass: TClass; const PropName: string): TClass;
  865. Function GetMethodProp(Instance: TObject; PropInfo: PPropInfo) : TMethod;
  866. Function GetMethodProp(Instance: TObject; const PropName: string): TMethod;
  867. Procedure SetMethodProp(Instance: TObject; PropInfo: PPropInfo; const Value : TMethod);
  868. Procedure SetMethodProp(Instance: TObject; const PropName: string; const Value: TMethod);
  869. Function GetInt64Prop(Instance: TObject; PropInfo: PPropInfo): Int64;
  870. Function GetInt64Prop(Instance: TObject; const PropName: string): Int64;
  871. Procedure SetInt64Prop(Instance: TObject; PropInfo: PPropInfo; const Value: Int64);
  872. Procedure SetInt64Prop(Instance: TObject; const PropName: string; const Value: Int64);
  873. Function GetPropValue(Instance: TObject; const PropName: string): Variant;
  874. Function GetPropValue(Instance: TObject; const PropName: string; PreferStrings: Boolean): Variant;
  875. Function GetPropValue(Instance: TObject; PropInfo: PPropInfo): Variant;
  876. Function GetPropValue(Instance: TObject; PropInfo: PPropInfo; PreferStrings: Boolean): Variant;
  877. Procedure SetPropValue(Instance: TObject; const PropName: string; const Value: Variant);
  878. Procedure SetPropValue(Instance: TObject; PropInfo: PPropInfo; const Value: Variant);
  879. Function GetVariantProp(Instance: TObject; PropInfo : PPropInfo): Variant;
  880. Function GetVariantProp(Instance: TObject; const PropName: string): Variant;
  881. Procedure SetVariantProp(Instance: TObject; const PropName: string; const Value: Variant);
  882. Procedure SetVariantProp(Instance: TObject; PropInfo : PPropInfo; const Value: Variant);
  883. function GetInterfaceProp(Instance: TObject; const PropName: string): IInterface;
  884. function GetInterfaceProp(Instance: TObject; PropInfo: PPropInfo): IInterface;
  885. procedure SetInterfaceProp(Instance: TObject; const PropName: string; const Value: IInterface);
  886. procedure SetInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: IInterface);
  887. function GetRawInterfaceProp(Instance: TObject; const PropName: string): Pointer;
  888. function GetRawInterfaceProp(Instance: TObject; PropInfo: PPropInfo): Pointer;
  889. procedure SetRawInterfaceProp(Instance: TObject; const PropName: string; const Value: Pointer);
  890. procedure SetRawInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: Pointer);
  891. function GetDynArrayProp(Instance: TObject; const PropName: string): Pointer;
  892. function GetDynArrayProp(Instance: TObject; PropInfo: PPropInfo): Pointer;
  893. procedure SetDynArrayProp(Instance: TObject; const PropName: string; const Value: Pointer);
  894. procedure SetDynArrayProp(Instance: TObject; PropInfo: PPropInfo; const Value: Pointer);
  895. // Extended RTTI
  896. function GetAttributeTable(TypeInfo: PTypeInfo): PAttributeTable;
  897. function GetPropAttribute(PropInfo: PPropInfo; AttributeNr: Word): TCustomAttribute; inline;
  898. function GetAttribute(AttributeTable: PAttributeTable; AttributeNr: Word): TCustomAttribute;
  899. // Auxiliary routines, which may be useful
  900. Function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
  901. Function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
  902. function GetEnumNameCount(enum1: PTypeInfo): SizeInt;
  903. procedure AddEnumElementAliases(aTypeInfo: PTypeInfo; const aNames: array of string; aStartValue: Integer = 0);
  904. procedure RemoveEnumElementAliases(aTypeInfo: PTypeInfo);
  905. function GetEnumeratedAliasValue(aTypeInfo: PTypeInfo; const aName: string): Integer;
  906. function SetToArray(TypeInfo: PTypeInfo; Value: Pointer) : TBytes;
  907. function SetToArray(PropInfo: PPropInfo; Value: Pointer) : TBytes;
  908. function SetToArray(TypeInfo: PTypeInfo; Value: LongInt) : TBytes;
  909. function SetToArray(PropInfo: PPropInfo; Value: LongInt) : TBytes;
  910. function SetToString(TypeInfo: PTypeInfo; Value: LongInt; Brackets: Boolean) : String;
  911. function SetToString(PropInfo: PPropInfo; Value: LongInt; Brackets: Boolean) : String;
  912. function SetToString(PropInfo: PPropInfo; Value: LongInt) : String;
  913. function SetToString(TypeInfo: PTypeInfo; Value: Pointer; Brackets: Boolean = False) : String;
  914. function SetToString(PropInfo: PPropInfo; Value: Pointer; Brackets: Boolean = False) : String;
  915. function ArrayToSet(PropInfo: PPropInfo; const Value: array of Byte): LongInt;
  916. function ArrayToSet(TypeInfo: PTypeInfo; const Value: array of Byte): LongInt;
  917. procedure ArrayToSet(PropInfo: PPropInfo; const Value: array of Byte; Result: Pointer);
  918. procedure ArrayToSet(TypeInfo: PTypeInfo; const Value: array of Byte; Result: Pointer);
  919. function StringToSet(PropInfo: PPropInfo; const Value: string): LongInt;
  920. function StringToSet(TypeInfo: PTypeInfo; const Value: string): LongInt;
  921. procedure StringToSet(PropInfo: PPropInfo; const Value: String; Result: Pointer);
  922. procedure StringToSet(TypeInfo: PTypeInfo; const Value: String; Result: Pointer);
  923. const
  924. BooleanIdents: array[Boolean] of String = ('False', 'True');
  925. DotSep: String = '.';
  926. Type
  927. EPropertyError = Class(Exception);
  928. TGetPropValue = Function (Instance: TObject; PropInfo: PPropInfo; PreferStrings: Boolean) : Variant;
  929. TSetPropValue = Procedure (Instance: TObject; PropInfo: PPropInfo; const Value: Variant);
  930. TGetVariantProp = Function (Instance: TObject; PropInfo : PPropInfo): Variant;
  931. TSetVariantProp = Procedure (Instance: TObject; PropInfo : PPropInfo; const Value: Variant);
  932. EPropertyConvertError = class(Exception); // Not used (yet), but defined for compatibility.
  933. Const
  934. OnGetPropValue : TGetPropValue = Nil;
  935. OnSetPropValue : TSetPropValue = Nil;
  936. OnGetVariantprop : TGetVariantProp = Nil;
  937. OnSetVariantprop : TSetVariantProp = Nil;
  938. { for inlining }
  939. function DerefTypeInfoPtr(Info: TypeInfoPtr): PTypeInfo; inline;
  940. Implementation
  941. uses rtlconsts;
  942. type
  943. PMethod = ^TMethod;
  944. { ---------------------------------------------------------------------
  945. Auxiliary methods
  946. ---------------------------------------------------------------------}
  947. function aligntoptr(p : pointer) : pointer;inline;
  948. begin
  949. {$ifdef CPUM68K}
  950. result:=AlignTypeData(p);
  951. {$else CPUM68K}
  952. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  953. result:=align(p,sizeof(p));
  954. {$else FPC_REQUIRES_PROPER_ALIGNMENT}
  955. result:=p;
  956. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  957. {$endif CPUM68K}
  958. end;
  959. function DerefTypeInfoPtr(Info: TypeInfoPtr): PTypeInfo; inline;
  960. begin
  961. {$ifdef ver3_0}
  962. Result := Info;
  963. {$else}
  964. if not Assigned(Info) then
  965. Result := Nil
  966. else
  967. Result := Info^;
  968. {$endif}
  969. end;
  970. function GetAttributeTable(TypeInfo: PTypeInfo): PAttributeTable;
  971. {$ifdef PROVIDE_ATTR_TABLE}
  972. var
  973. TD: PTypeData;
  974. begin
  975. TD := GetTypeData(TypeInfo);
  976. Result:=TD^.AttributeTable;
  977. {$else}
  978. begin
  979. Result:=Nil;
  980. {$endif}
  981. end;
  982. function GetPropData(TypeInfo : PTypeInfo; TypeData: PTypeData) : PPropData; inline;
  983. var
  984. p: PtrUInt;
  985. begin
  986. p := PtrUInt(@TypeData^.UnitName) + SizeOf(TypeData^.UnitName[0]) + Length(TypeData^.UnitName);
  987. Result := PPropData(aligntoptr(Pointer(p)));
  988. end;
  989. function GetAttribute(AttributeTable: PAttributeTable; AttributeNr: Word): TCustomAttribute;
  990. begin
  991. if (AttributeTable=nil) or (AttributeNr>=AttributeTable^.AttributeCount) then
  992. result := nil
  993. else
  994. begin
  995. result := AttributeTable^.AttributesList[AttributeNr].AttrProc();
  996. end;
  997. end;
  998. function GetPropAttribute(PropInfo: PPropInfo; AttributeNr: Word): TCustomAttribute;
  999. begin
  1000. {$ifdef PROVIDE_ATTR_TABLE}
  1001. Result := GetAttribute(PropInfo^.AttributeTable, AttributeNr);
  1002. {$else}
  1003. Result := Nil;
  1004. {$endif}
  1005. end;
  1006. Function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
  1007. Var PS : PShortString;
  1008. PT : PTypeData;
  1009. begin
  1010. PT:=GetTypeData(TypeInfo);
  1011. if TypeInfo^.Kind=tkBool then
  1012. begin
  1013. case Value of
  1014. 0,1:
  1015. Result:=BooleanIdents[Boolean(Value)];
  1016. else
  1017. Result:='';
  1018. end;
  1019. end
  1020. else
  1021. begin
  1022. PS:=@PT^.NameList;
  1023. dec(Value,PT^.MinValue);
  1024. While Value>0 Do
  1025. begin
  1026. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  1027. Dec(Value);
  1028. end;
  1029. Result:=PS^;
  1030. end;
  1031. end;
  1032. Function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
  1033. Var PS : PShortString;
  1034. PT : PTypeData;
  1035. Count : longint;
  1036. sName: shortstring;
  1037. begin
  1038. If Length(Name)=0 then
  1039. exit(-1);
  1040. sName := Name;
  1041. PT:=GetTypeData(TypeInfo);
  1042. Count:=0;
  1043. Result:=-1;
  1044. if TypeInfo^.Kind=tkBool then
  1045. begin
  1046. If CompareText(BooleanIdents[false],Name)=0 then
  1047. result:=0
  1048. else if CompareText(BooleanIdents[true],Name)=0 then
  1049. result:=1;
  1050. end
  1051. else
  1052. begin
  1053. PS:=@PT^.NameList;
  1054. While (Result=-1) and (PByte(PS)^<>0) do
  1055. begin
  1056. If ShortCompareText(PS^, sName) = 0 then
  1057. Result:=Count+PT^.MinValue;
  1058. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  1059. Inc(Count);
  1060. end;
  1061. if Result=-1 then
  1062. Result:=GetEnumeratedAliasValue(TypeInfo,Name);
  1063. end;
  1064. end;
  1065. function GetEnumNameCount(enum1: PTypeInfo): SizeInt;
  1066. var
  1067. PS: PShortString;
  1068. PT: PTypeData;
  1069. Count: SizeInt;
  1070. begin
  1071. PT:=GetTypeData(enum1);
  1072. if enum1^.Kind=tkBool then
  1073. Result:=2
  1074. else
  1075. begin
  1076. Count:=0;
  1077. Result:=0;
  1078. PS:=@PT^.NameList;
  1079. While (PByte(PS)^<>0) do
  1080. begin
  1081. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  1082. Inc(Count);
  1083. end;
  1084. { the last string is the unit name }
  1085. Result := Count - 1;
  1086. end;
  1087. end;
  1088. Function SetToString(PropInfo: PPropInfo; Value: LongInt; Brackets: Boolean) : String;
  1089. begin
  1090. Result:=SetToString(PropInfo^.PropType, Value, Brackets);
  1091. end;
  1092. Function SetToString(TypeInfo: PTypeInfo; Value: LongInt; Brackets: Boolean) : String;
  1093. begin
  1094. {$if defined(FPC_BIG_ENDIAN)}
  1095. { correctly adjust packed sets that are smaller than 32-bit }
  1096. case GetTypeData(TypeInfo)^.OrdType of
  1097. otSByte,otUByte: Value := Value shl (SizeOf(Integer)*8-8);
  1098. otSWord,otUWord: Value := Value shl (SizeOf(Integer)*8-16);
  1099. end;
  1100. {$endif}
  1101. Result := SetToString(TypeInfo, @Value, Brackets);
  1102. end;
  1103. function SetToString(TypeInfo: PTypeInfo; Value: Pointer; Brackets: Boolean): String;
  1104. var
  1105. A: TBytes;
  1106. B: Byte;
  1107. PTI : PTypeInfo;
  1108. begin
  1109. PTI:=GetTypeData(TypeInfo)^.CompType;
  1110. A:=SetToArray(TypeInfo, Value);
  1111. Result := '';
  1112. for B in A do
  1113. If Result='' then
  1114. Result:=GetEnumName(PTI,B)
  1115. else
  1116. Result:=Result+','+GetEnumName(PTI,B);
  1117. if Brackets then
  1118. Result:='['+Result+']';
  1119. end;
  1120. Function SetToString(PropInfo: PPropInfo; Value: LongInt) : String;
  1121. begin
  1122. Result:=SetToString(PropInfo,Value,False);
  1123. end;
  1124. function SetToString(PropInfo: PPropInfo; Value: Pointer; Brackets: Boolean): String;
  1125. begin
  1126. Result := SetToString(PropInfo^.PropType, Value, Brackets);
  1127. end;
  1128. function SetToArray(TypeInfo: PTypeInfo; Value: Pointer) : TBytes;
  1129. type
  1130. tsetarr = bitpacked array[0..SizeOf(LongInt)*8-1] of 0..1;
  1131. Var
  1132. I,El,Els,Rem,V,Max : Integer;
  1133. PTD : PTypeData;
  1134. ValueArr : PLongInt;
  1135. begin
  1136. PTD := GetTypeData(TypeInfo);
  1137. ValueArr := PLongInt(Value);
  1138. Result:=[];
  1139. {$ifdef ver3_0}
  1140. case PTD^.OrdType of
  1141. otSByte, otUByte: begin
  1142. Els := 0;
  1143. Rem := 1;
  1144. end;
  1145. otSWord, otUWord: begin
  1146. Els := 0;
  1147. Rem := 2;
  1148. end;
  1149. otSLong, otULong: begin
  1150. Els := 1;
  1151. Rem := 0;
  1152. end;
  1153. end;
  1154. {$else}
  1155. Els := PTD^.SetSize div SizeOf(LongInt);
  1156. Rem := PTD^.SetSize mod SizeOf(LongInt);
  1157. {$endif}
  1158. {$ifdef ver3_0}
  1159. El := 0;
  1160. {$else}
  1161. for El := 0 to (PTD^.SetSize - 1) div SizeOf(LongInt) do
  1162. {$endif}
  1163. begin
  1164. if El = Els then
  1165. Max := Rem
  1166. else
  1167. Max := SizeOf(LongInt);
  1168. For I:=0 to Max*8-1 do
  1169. begin
  1170. if (tsetarr(ValueArr[El])[i]<>0) then
  1171. begin
  1172. V := I + SizeOf(LongInt) * 8 * El;
  1173. SetLength(Result, Length(Result)+1);
  1174. Result[High(Result)]:=V;
  1175. end;
  1176. end;
  1177. end;
  1178. end;
  1179. function SetToArray(PropInfo: PPropInfo; Value: Pointer) : TBytes;
  1180. begin
  1181. Result:=SetToArray(PropInfo^.PropType,Value);
  1182. end;
  1183. function SetToArray(TypeInfo: PTypeInfo; Value: LongInt) : TBytes;
  1184. begin
  1185. Result:=SetToArray(TypeInfo,@Value);
  1186. end;
  1187. function SetToArray(PropInfo: PPropInfo; Value: LongInt) : TBytes;
  1188. begin
  1189. Result:=SetToArray(PropInfo^.PropType,@Value);
  1190. end;
  1191. Const
  1192. SetDelim = ['[',']',',',' '];
  1193. Function GetNextElement(Var S : String) : String;
  1194. Var
  1195. J : Integer;
  1196. begin
  1197. J:=1;
  1198. Result:='';
  1199. If Length(S)>0 then
  1200. begin
  1201. While (J<=Length(S)) and Not (S[j] in SetDelim) do
  1202. Inc(j);
  1203. Result:=Copy(S,1,j-1);
  1204. Delete(S,1,j);
  1205. end;
  1206. end;
  1207. Function StringToSet(PropInfo: PPropInfo; const Value: string): LongInt;
  1208. begin
  1209. Result:=StringToSet(PropInfo^.PropType,Value);
  1210. end;
  1211. Function StringToSet(TypeInfo: PTypeInfo; const Value: string): LongInt;
  1212. begin
  1213. StringToSet(TypeInfo, Value, @Result);
  1214. {$if defined(FPC_BIG_ENDIAN)}
  1215. { correctly adjust packed sets that are smaller than 32-bit }
  1216. case GetTypeData(TypeInfo)^.OrdType of
  1217. otSByte,otUByte: Result := Result shr (SizeOf(Integer)*8-8);
  1218. otSWord,otUWord: Result := Result shr (SizeOf(Integer)*8-16);
  1219. end;
  1220. {$endif}
  1221. end;
  1222. procedure StringToSet(TypeInfo: PTypeInfo; const Value: String; Result: Pointer);
  1223. Var
  1224. S,T : String;
  1225. I, ElOfs, BitOfs : Integer;
  1226. PTD: PTypeData;
  1227. PTI : PTypeInfo;
  1228. A: TBytes;
  1229. begin
  1230. PTD:=GetTypeData(TypeInfo);
  1231. PTI:=PTD^.Comptype;
  1232. S:=Value;
  1233. I:=1;
  1234. If Length(S)>0 then
  1235. begin
  1236. While (I<=Length(S)) and (S[i] in SetDelim) do
  1237. Inc(I);
  1238. Delete(S,1,i-1);
  1239. end;
  1240. A:=[];
  1241. While (S<>'') do
  1242. begin
  1243. T:=GetNextElement(S);
  1244. if T<>'' then
  1245. begin
  1246. I:=GetEnumValue(PTI,T);
  1247. if (I<0) then
  1248. raise EPropertyError.CreateFmt(SErrUnknownEnumValue, [T]);
  1249. SetLength(A, Length(A)+1);
  1250. A[High(A)]:=I;
  1251. end;
  1252. end;
  1253. ArrayToSet(TypeInfo,A,Result);
  1254. end;
  1255. procedure StringToSet(PropInfo: PPropInfo; const Value: String; Result: Pointer);
  1256. begin
  1257. StringToSet(PropInfo^.PropType, Value, Result);
  1258. end;
  1259. Function ArrayToSet(PropInfo: PPropInfo; const Value: array of Byte): LongInt;
  1260. begin
  1261. Result:=ArrayToSet(PropInfo^.PropType,Value);
  1262. end;
  1263. Function ArrayToSet(TypeInfo: PTypeInfo; const Value: array of Byte): LongInt;
  1264. begin
  1265. ArrayToSet(TypeInfo, Value, @Result);
  1266. {$if defined(FPC_BIG_ENDIAN)}
  1267. { correctly adjust packed sets that are smaller than 32-bit }
  1268. case GetTypeData(TypeInfo)^.OrdType of
  1269. otSByte,otUByte: Result := Result shr (SizeOf(Integer)*8-8);
  1270. otSWord,otUWord: Result := Result shr (SizeOf(Integer)*8-16);
  1271. end;
  1272. {$endif}
  1273. end;
  1274. procedure ArrayToSet(TypeInfo: PTypeInfo; const Value: array of Byte; Result: Pointer);
  1275. Var
  1276. ElOfs, BitOfs : Integer;
  1277. PTD: PTypeData;
  1278. ResArr: PLongWord;
  1279. B: Byte;
  1280. begin
  1281. PTD:=GetTypeData(TypeInfo);
  1282. {$ifndef ver3_0}
  1283. FillChar(Result^, PTD^.SetSize, 0);
  1284. {$else}
  1285. PInteger(Result)^ := 0;
  1286. {$endif}
  1287. ResArr := PLongWord(Result);
  1288. for B in Value do
  1289. begin
  1290. ElOfs := B shr 5;
  1291. BitOfs := B and $1F;
  1292. {$ifdef FPC_BIG_ENDIAN}
  1293. { on Big Endian systems enum values start from the MSB, thus we need
  1294. to reverse the shift }
  1295. BitOfs := 31 - BitOfs;
  1296. {$endif}
  1297. ResArr[ElOfs] := ResArr[ElOfs] or (LongInt(1) shl BitOfs);
  1298. end;
  1299. end;
  1300. procedure ArrayToSet(PropInfo: PPropInfo; const Value: array of Byte; Result: Pointer);
  1301. begin
  1302. ArrayToSet(PropInfo^.PropType, Value, Result);
  1303. end;
  1304. Function AlignTypeData(p : Pointer) : Pointer;
  1305. {$packrecords c}
  1306. type
  1307. TAlignCheck = record
  1308. b : byte;
  1309. q : qword;
  1310. end;
  1311. {$packrecords default}
  1312. begin
  1313. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  1314. {$ifdef VER3_0}
  1315. Result:=Pointer(align(p,SizeOf(Pointer)));
  1316. {$else VER3_0}
  1317. Result:=Pointer(align(p,PtrInt(@TAlignCheck(nil^).q)))
  1318. {$endif VER3_0}
  1319. {$else FPC_REQUIRES_PROPER_ALIGNMENT}
  1320. Result:=p;
  1321. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  1322. end;
  1323. Function AlignTParamFlags(p : Pointer) : Pointer; inline;
  1324. {$packrecords c}
  1325. type
  1326. TAlignCheck = record
  1327. b : byte;
  1328. w : word;
  1329. end;
  1330. {$packrecords default}
  1331. begin
  1332. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  1333. Result:=Pointer(align(p,PtrInt(@TAlignCheck(nil^).w)))
  1334. {$else FPC_REQUIRES_PROPER_ALIGNMENT}
  1335. Result:=p;
  1336. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  1337. end;
  1338. Function AlignPTypeInfo(p : Pointer) : Pointer; inline;
  1339. {$packrecords c}
  1340. type
  1341. TAlignCheck = record
  1342. b : byte;
  1343. p : pointer;
  1344. end;
  1345. {$packrecords default}
  1346. begin
  1347. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  1348. Result:=Pointer(align(p,PtrInt(@TAlignCheck(nil^).p)))
  1349. {$else FPC_REQUIRES_PROPER_ALIGNMENT}
  1350. Result:=p;
  1351. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  1352. end;
  1353. Generic Function ConstParamIsRef<T>(aCallConv: TCallConv): Boolean;
  1354. Function SameAddrRegister(const aArg1: T; constref aArg2: T): Boolean; register;
  1355. begin
  1356. Result := @aArg1 = @aArg2;
  1357. end;
  1358. Function SameAddrCDecl(const aArg1: T; constref aArg2: T): Boolean; cdecl;
  1359. begin
  1360. Result := @aArg1 = @aArg2;
  1361. end;
  1362. {$if defined(cpui8086) or defined(cpui386)}
  1363. Function SameAddrPascal(const aArg1: T; constref aArg2: T): Boolean; pascal;
  1364. begin
  1365. Result := @aArg1 = @aArg2;
  1366. end;
  1367. {$endif}
  1368. Function SameAddrStdCall(const aArg1: T; constref aArg2: T): Boolean; stdcall;
  1369. begin
  1370. Result := @aArg1 = @aArg2;
  1371. end;
  1372. Function SameAddrCppDecl(const aArg1: T; constref aArg2: T): Boolean; cppdecl;
  1373. begin
  1374. Result := @aArg1 = @aArg2;
  1375. end;
  1376. {$if defined(cpui386)}
  1377. Function SameAddrOldFPCCall(const aArg1: T; constref aArg2: T): Boolean; oldfpccall;
  1378. begin
  1379. Result := @aArg1 = @aArg2;
  1380. end;
  1381. {$endif}
  1382. Function SameAddrMWPascal(const aArg1: T; constref aArg2: T): Boolean; mwpascal;
  1383. begin
  1384. Result := @aArg1 = @aArg2;
  1385. end;
  1386. var
  1387. v: T;
  1388. begin
  1389. v := Default(T);
  1390. case aCallConv of
  1391. ccReg:
  1392. Result := SameAddrRegister(v, v);
  1393. ccCdecl:
  1394. Result := SameAddrCDecl(v, v);
  1395. {$if defined(cpui386) or defined(cpui8086)}
  1396. ccPascal:
  1397. Result := SameAddrPascal(v, v);
  1398. {$endif}
  1399. {$if not defined(cpui386)}
  1400. ccOldFPCCall,
  1401. {$endif}
  1402. {$if not defined(cpui386) and not defined(cpui8086)}
  1403. ccPascal,
  1404. {$endif}
  1405. ccStdCall:
  1406. Result := SameAddrStdCall(v, v);
  1407. ccCppdecl:
  1408. Result := SameAddrCppDecl(v, v);
  1409. {$if defined(cpui386)}
  1410. ccOldFPCCall:
  1411. Result := SameAddrOldFPCCall(v, v);
  1412. {$endif}
  1413. ccMWPascal:
  1414. Result := SameAddrMWPascal(v, v);
  1415. else
  1416. raise EArgumentException.CreateFmt(SUnsupportedCallConv, [GetEnumName(PTypeInfo(TypeInfo(TCallConv)), Ord(aCallConv))]);
  1417. end;
  1418. end;
  1419. Function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
  1420. begin
  1421. GetTypeData:=AlignTypeData(pointer(TypeInfo)+2+PByte(pointer(TypeInfo)+1)^);
  1422. end;
  1423. { ---------------------------------------------------------------------
  1424. Basic Type information functions.
  1425. ---------------------------------------------------------------------}
  1426. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string) : PPropInfo;
  1427. var
  1428. hp : PTypeData;
  1429. i : longint;
  1430. p : shortstring;
  1431. pd : PPropData;
  1432. begin
  1433. P:=PropName; // avoid Ansi<->short conversion in a loop
  1434. while Assigned(TypeInfo) do
  1435. begin
  1436. // skip the name
  1437. hp:=GetTypeData(Typeinfo);
  1438. // the class info rtti the property rtti follows immediatly
  1439. pd := GetPropData(TypeInfo,hp);
  1440. Result:=PPropInfo(@pd^.PropList);
  1441. for i:=1 to pd^.PropCount do
  1442. begin
  1443. // found a property of that name ?
  1444. if ShortCompareText(Result^.Name, P) = 0 then
  1445. exit;
  1446. // skip to next property
  1447. Result:=PPropInfo(aligntoptr(pointer(@Result^.Name)+byte(Result^.Name[0])+1));
  1448. end;
  1449. // parent class
  1450. Typeinfo:=hp^.ParentInfo;
  1451. end;
  1452. Result:=Nil;
  1453. end;
  1454. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string; Akinds : TTypeKinds) : PPropInfo;
  1455. begin
  1456. Result:=GetPropInfo(TypeInfo,PropName);
  1457. If (Akinds<>[]) then
  1458. If (Result<>Nil) then
  1459. If Not (Result^.PropType^.Kind in AKinds) then
  1460. Result:=Nil;
  1461. end;
  1462. Function GetPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
  1463. begin
  1464. Result:=GetPropInfo(PTypeInfo(AClass.ClassInfo),PropName,AKinds);
  1465. end;
  1466. Function GetPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
  1467. begin
  1468. Result:=GetPropInfo(Instance.ClassType,PropName,AKinds);
  1469. end;
  1470. Function GetPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  1471. begin
  1472. Result:=GetPropInfo(Instance,PropName,[]);
  1473. end;
  1474. Function GetPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  1475. begin
  1476. Result:=GetPropInfo(AClass,PropName,[]);
  1477. end;
  1478. Function FindPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  1479. begin
  1480. result:=GetPropInfo(Instance, PropName);
  1481. if Result=nil then
  1482. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  1483. end;
  1484. Function FindPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  1485. begin
  1486. result:=GetPropInfo(Instance, PropName, AKinds);
  1487. if Result=nil then
  1488. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  1489. end;
  1490. Function FindPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  1491. begin
  1492. result:=GetPropInfo(AClass, PropName);
  1493. if result=nil then
  1494. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  1495. end;
  1496. Function FindPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  1497. begin
  1498. result:=GetPropInfo(AClass, PropName, AKinds);
  1499. if result=nil then
  1500. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  1501. end;
  1502. function IsReadableProp(PropInfo: PPropInfo): Boolean;
  1503. begin
  1504. Result:=(((PropInfo^.PropProcs) and 3) in [ptField,ptStatic,ptVirtual]);
  1505. end;
  1506. function IsReadableProp(Instance: TObject; const PropName: string): Boolean;
  1507. begin
  1508. Result:=IsReadableProp(FindPropInfo(Instance,PropName));
  1509. end;
  1510. function IsReadableProp(AClass: TClass; const PropName: string): Boolean;
  1511. begin
  1512. Result:=IsReadableProp(FindPropInfo(AClass,PropName));
  1513. end;
  1514. function IsWriteableProp(PropInfo: PPropInfo): Boolean;
  1515. begin
  1516. Result:=(((PropInfo^.PropProcs shr 2) and 3) in [ptField,ptStatic,ptVirtual]);
  1517. end;
  1518. function IsWriteableProp(Instance: TObject; const PropName: string): Boolean;
  1519. begin
  1520. Result:=IsWriteableProp(FindPropInfo(Instance,PropName));
  1521. end;
  1522. function IsWriteableProp(AClass: TClass; const PropName: string): Boolean;
  1523. begin
  1524. Result:=IsWriteableProp(FindPropInfo(AClass,PropName));
  1525. end;
  1526. Function IsStoredProp(Instance : TObject;PropInfo : PPropInfo) : Boolean;
  1527. type
  1528. TBooleanIndexFunc=function(Index:integer):boolean of object;
  1529. TBooleanFunc=function:boolean of object;
  1530. var
  1531. AMethod : TMethod;
  1532. begin
  1533. case (PropInfo^.PropProcs shr 4) and 3 of
  1534. ptField:
  1535. Result:=PBoolean(Pointer(Instance)+PtrUInt(PropInfo^.StoredProc))^;
  1536. ptConst:
  1537. Result:=LongBool(PropInfo^.StoredProc);
  1538. ptStatic,
  1539. ptVirtual:
  1540. begin
  1541. if (PropInfo^.PropProcs shr 4) and 3=ptstatic then
  1542. AMethod.Code:=PropInfo^.StoredProc
  1543. else
  1544. AMethod.Code:=pcodepointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.StoredProc))^;
  1545. AMethod.Data:=Instance;
  1546. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1547. Result:=TBooleanIndexFunc(AMethod)(PropInfo^.Index)
  1548. else
  1549. Result:=TBooleanFunc(AMethod)();
  1550. end;
  1551. end;
  1552. end;
  1553. Procedure GetPropInfos(TypeInfo : PTypeInfo;PropList : PPropList);
  1554. {
  1555. Store Pointers to property information in the list pointed
  1556. to by proplist. PRopList must contain enough space to hold ALL
  1557. properties.
  1558. }
  1559. Var
  1560. TD : PTypeData;
  1561. TP : PPropInfo;
  1562. Count : Longint;
  1563. begin
  1564. // Get this objects TOTAL published properties count
  1565. TD:=GetTypeData(TypeInfo);
  1566. // Clear list
  1567. FillChar(PropList^,TD^.PropCount*sizeof(Pointer),0);
  1568. repeat
  1569. TD:=GetTypeData(TypeInfo);
  1570. // published properties count for this object
  1571. TP:=PPropInfo(GetPropData(TypeInfo, TD));
  1572. Count:=PWord(TP)^;
  1573. // Now point TP to first propinfo record.
  1574. Inc(Pointer(TP),SizeOF(Word));
  1575. tp:=aligntoptr(tp);
  1576. While Count>0 do
  1577. begin
  1578. // Don't overwrite properties with the same name
  1579. if PropList^[TP^.NameIndex]=nil then
  1580. PropList^[TP^.NameIndex]:=TP;
  1581. // Point to TP next propinfo record.
  1582. // Located at Name[Length(Name)+1] !
  1583. TP:=aligntoptr(PPropInfo(pointer(@TP^.Name)+PByte(@TP^.Name)^+1));
  1584. Dec(Count);
  1585. end;
  1586. TypeInfo:=TD^.Parentinfo;
  1587. until TypeInfo=nil;
  1588. end;
  1589. Procedure InsertProp (PL : PProplist;PI : PPropInfo; Count : longint);
  1590. Var
  1591. I : Longint;
  1592. begin
  1593. I:=0;
  1594. While (I<Count) and (PI^.Name>PL^[I]^.Name) do
  1595. Inc(I);
  1596. If I<Count then
  1597. Move(PL^[I], PL^[I+1], (Count - I) * SizeOf(Pointer));
  1598. PL^[I]:=PI;
  1599. end;
  1600. Procedure InsertPropnosort (PL : PProplist;PI : PPropInfo; Count : longint);
  1601. begin
  1602. PL^[Count]:=PI;
  1603. end;
  1604. Type TInsertProp = Procedure (PL : PProplist;PI : PPropInfo; Count : longint);
  1605. //Const InsertProps : array[false..boolean] of TInsertProp = (InsertPropNoSort,InsertProp);
  1606. Function GetPropList(TypeInfo : PTypeInfo;TypeKinds : TTypeKinds; PropList : PPropList;Sorted : boolean = true):longint;
  1607. {
  1608. Store Pointers to property information OF A CERTAIN KIND in the list pointed
  1609. to by proplist. PRopList must contain enough space to hold ALL
  1610. properties.
  1611. }
  1612. Var
  1613. TempList : PPropList;
  1614. PropInfo : PPropinfo;
  1615. I,Count : longint;
  1616. DoInsertProp : TInsertProp;
  1617. begin
  1618. if sorted then
  1619. DoInsertProp:=@InsertProp
  1620. else
  1621. DoInsertProp:=@InsertPropnosort;
  1622. Result:=0;
  1623. Count:=GetTypeData(TypeInfo)^.Propcount;
  1624. If Count>0 then
  1625. begin
  1626. GetMem(TempList,Count*SizeOf(Pointer));
  1627. Try
  1628. GetPropInfos(TypeInfo,TempList);
  1629. For I:=0 to Count-1 do
  1630. begin
  1631. PropInfo:=TempList^[i];
  1632. If PropInfo^.PropType^.Kind in TypeKinds then
  1633. begin
  1634. If (PropList<>Nil) then
  1635. DoInsertProp(PropList,PropInfo,Result);
  1636. Inc(Result);
  1637. end;
  1638. end;
  1639. finally
  1640. FreeMem(TempList,Count*SizeOf(Pointer));
  1641. end;
  1642. end;
  1643. end;
  1644. Function GetPropList(TypeInfo: PTypeInfo; out PropList: PPropList): SizeInt;
  1645. begin
  1646. result:=GetTypeData(TypeInfo)^.Propcount;
  1647. if result>0 then
  1648. begin
  1649. getmem(PropList,result*sizeof(pointer));
  1650. GetPropInfos(TypeInfo,PropList);
  1651. end
  1652. else
  1653. PropList:=Nil;
  1654. end;
  1655. function GetPropList(AClass: TClass; out PropList: PPropList): Integer;
  1656. begin
  1657. Result := GetPropList(PTypeInfo(AClass.ClassInfo), PropList);
  1658. end;
  1659. function GetPropList(Instance: TObject; out PropList: PPropList): Integer;
  1660. begin
  1661. Result := GetPropList(Instance.ClassType, PropList);
  1662. end;
  1663. { ---------------------------------------------------------------------
  1664. Property access functions
  1665. ---------------------------------------------------------------------}
  1666. { ---------------------------------------------------------------------
  1667. Ordinal properties
  1668. ---------------------------------------------------------------------}
  1669. Function GetOrdProp(Instance : TObject;PropInfo : PPropInfo) : Int64;
  1670. type
  1671. TGetInt64ProcIndex=function(index:longint):Int64 of object;
  1672. TGetInt64Proc=function():Int64 of object;
  1673. TGetIntegerProcIndex=function(index:longint):longint of object;
  1674. TGetIntegerProc=function:longint of object;
  1675. TGetWordProcIndex=function(index:longint):word of object;
  1676. TGetWordProc=function:word of object;
  1677. TGetByteProcIndex=function(index:longint):Byte of object;
  1678. TGetByteProc=function:Byte of object;
  1679. var
  1680. TypeInfo: PTypeInfo;
  1681. AMethod : TMethod;
  1682. DataSize: Integer;
  1683. OrdType: TOrdType;
  1684. Signed: Boolean;
  1685. begin
  1686. Result:=0;
  1687. TypeInfo := PropInfo^.PropType;
  1688. Signed := false;
  1689. DataSize := 4;
  1690. case TypeInfo^.Kind of
  1691. // We keep this for backwards compatibility, but internally it is no longer used.
  1692. {$ifdef cpu64}
  1693. tkInterface,
  1694. tkInterfaceRaw,
  1695. tkDynArray,
  1696. tkClass:
  1697. DataSize:=8;
  1698. {$endif cpu64}
  1699. tkChar, tkBool:
  1700. DataSize:=1;
  1701. tkWChar:
  1702. DataSize:=2;
  1703. tkSet,
  1704. tkEnumeration,
  1705. tkInteger:
  1706. begin
  1707. OrdType:=GetTypeData(TypeInfo)^.OrdType;
  1708. case OrdType of
  1709. otSByte,otUByte: DataSize := 1;
  1710. otSWord,otUWord: DataSize := 2;
  1711. end;
  1712. Signed := OrdType in [otSByte,otSWord,otSLong];
  1713. end;
  1714. tkInt64 :
  1715. begin
  1716. DataSize:=8;
  1717. Signed:=true;
  1718. end;
  1719. tkQword :
  1720. begin
  1721. DataSize:=8;
  1722. Signed:=false;
  1723. end;
  1724. end;
  1725. case (PropInfo^.PropProcs) and 3 of
  1726. ptField:
  1727. if Signed then begin
  1728. case DataSize of
  1729. 1: Result:=PShortInt(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1730. 2: Result:=PSmallInt(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1731. 4: Result:=PLongint(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1732. 8: Result:=PInt64(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1733. end;
  1734. end else begin
  1735. case DataSize of
  1736. 1: Result:=PByte(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1737. 2: Result:=PWord(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1738. 4: Result:=PLongint(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1739. 8: Result:=PInt64(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1740. end;
  1741. end;
  1742. ptStatic,
  1743. ptVirtual:
  1744. begin
  1745. if (PropInfo^.PropProcs and 3)=ptStatic then
  1746. AMethod.Code:=PropInfo^.GetProc
  1747. else
  1748. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1749. AMethod.Data:=Instance;
  1750. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then begin
  1751. case DataSize of
  1752. 1: Result:=TGetByteProcIndex(AMethod)(PropInfo^.Index);
  1753. 2: Result:=TGetWordProcIndex(AMethod)(PropInfo^.Index);
  1754. 4: Result:=TGetIntegerProcIndex(AMethod)(PropInfo^.Index);
  1755. 8: result:=TGetInt64ProcIndex(AMethod)(PropInfo^.Index)
  1756. end;
  1757. end else begin
  1758. case DataSize of
  1759. 1: Result:=TGetByteProc(AMethod)();
  1760. 2: Result:=TGetWordProc(AMethod)();
  1761. 4: Result:=TGetIntegerProc(AMethod)();
  1762. 8: result:=TGetInt64Proc(AMethod)();
  1763. end;
  1764. end;
  1765. if Signed then begin
  1766. case DataSize of
  1767. 1: Result:=ShortInt(Result);
  1768. 2: Result:=SmallInt(Result);
  1769. end;
  1770. end;
  1771. end;
  1772. else
  1773. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  1774. end;
  1775. end;
  1776. Procedure SetOrdProp(Instance : TObject;PropInfo : PPropInfo;Value : Int64);
  1777. type
  1778. TSetInt64ProcIndex=procedure(index:longint;i:Int64) of object;
  1779. TSetInt64Proc=procedure(i:Int64) of object;
  1780. TSetIntegerProcIndex=procedure(index,i:longint) of object;
  1781. TSetIntegerProc=procedure(i:longint) of object;
  1782. var
  1783. DataSize: Integer;
  1784. AMethod : TMethod;
  1785. begin
  1786. if PropInfo^.PropType^.Kind in [tkInt64,tkQword
  1787. { why do we have to handle classes here, see also below? (FK) }
  1788. {$ifdef cpu64}
  1789. ,tkInterface
  1790. ,tkInterfaceRaw
  1791. ,tkDynArray
  1792. ,tkClass
  1793. {$endif cpu64}
  1794. ] then
  1795. DataSize := 8
  1796. else
  1797. DataSize := 4;
  1798. if not(PropInfo^.PropType^.Kind in [tkInt64,tkQword,tkClass,tkInterface,tkInterfaceRaw,tkDynArray]) then
  1799. begin
  1800. { cut off unnecessary stuff }
  1801. case GetTypeData(PropInfo^.PropType)^.OrdType of
  1802. otSWord,otUWord:
  1803. begin
  1804. Value:=Value and $ffff;
  1805. DataSize := 2;
  1806. end;
  1807. otSByte,otUByte:
  1808. begin
  1809. Value:=Value and $ff;
  1810. DataSize := 1;
  1811. end;
  1812. end;
  1813. end;
  1814. case (PropInfo^.PropProcs shr 2) and 3 of
  1815. ptField:
  1816. case DataSize of
  1817. 1: PByte(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Byte(Value);
  1818. 2: PWord(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Word(Value);
  1819. 4: PLongint(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Longint(Value);
  1820. 8: PInt64(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1821. end;
  1822. ptStatic,
  1823. ptVirtual:
  1824. begin
  1825. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1826. AMethod.Code:=PropInfo^.SetProc
  1827. else
  1828. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1829. AMethod.Data:=Instance;
  1830. if datasize=8 then
  1831. begin
  1832. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1833. TSetInt64ProcIndex(AMethod)(PropInfo^.Index,Value)
  1834. else
  1835. TSetInt64Proc(AMethod)(Value);
  1836. end
  1837. else
  1838. begin
  1839. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1840. TSetIntegerProcIndex(AMethod)(PropInfo^.Index,Value)
  1841. else
  1842. TSetIntegerProc(AMethod)(Value);
  1843. end;
  1844. end;
  1845. else
  1846. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  1847. end;
  1848. end;
  1849. Function GetOrdProp(Instance: TObject; const PropName: string): Int64;
  1850. begin
  1851. Result:=GetOrdProp(Instance,FindPropInfo(Instance,PropName));
  1852. end;
  1853. Procedure SetOrdProp(Instance: TObject; const PropName: string; Value: Int64);
  1854. begin
  1855. SetOrdProp(Instance,FindPropInfo(Instance,PropName),Value);
  1856. end;
  1857. Function GetEnumProp(Instance: TObject; Const PropInfo: PPropInfo): string;
  1858. begin
  1859. Result:=GetEnumName(PropInfo^.PropType, GetOrdProp(Instance, PropInfo));
  1860. end;
  1861. Function GetEnumProp(Instance: TObject; const PropName: string): string;
  1862. begin
  1863. Result:=GetEnumProp(Instance,FindPropInfo(Instance,PropName));
  1864. end;
  1865. Procedure SetEnumProp(Instance: TObject; const PropName: string; const Value: string);
  1866. begin
  1867. SetEnumProp(Instance,FindPropInfo(Instance,PropName),Value);
  1868. end;
  1869. Procedure SetEnumProp(Instance: TObject; Const PropInfo : PPropInfo; const Value: string);
  1870. Var
  1871. PV : Longint;
  1872. begin
  1873. If PropInfo<>Nil then
  1874. begin
  1875. PV:=GetEnumValue(PropInfo^.PropType, Value);
  1876. if (PV<0) then
  1877. raise EPropertyError.CreateFmt(SErrUnknownEnumValue, [Value]);
  1878. SetOrdProp(Instance, PropInfo,PV);
  1879. end;
  1880. end;
  1881. { ---------------------------------------------------------------------
  1882. Int64 wrappers
  1883. ---------------------------------------------------------------------}
  1884. Function GetInt64Prop(Instance: TObject; PropInfo: PPropInfo): Int64;
  1885. begin
  1886. Result:=GetOrdProp(Instance,PropInfo);
  1887. end;
  1888. procedure SetInt64Prop(Instance: TObject; PropInfo: PPropInfo; const Value: Int64);
  1889. begin
  1890. SetOrdProp(Instance,PropInfo,Value);
  1891. end;
  1892. Function GetInt64Prop(Instance: TObject; const PropName: string): Int64;
  1893. begin
  1894. Result:=GetInt64Prop(Instance,FindPropInfo(Instance,PropName));
  1895. end;
  1896. Procedure SetInt64Prop(Instance: TObject; const PropName: string; const Value: Int64);
  1897. begin
  1898. SetInt64Prop(Instance,FindPropInfo(Instance,PropName),Value);
  1899. end;
  1900. { ---------------------------------------------------------------------
  1901. Set properties
  1902. ---------------------------------------------------------------------}
  1903. Function GetSetProp(Instance: TObject; const PropName: string): string;
  1904. begin
  1905. Result:=GetSetProp(Instance,PropName,False);
  1906. end;
  1907. Function GetSetProp(Instance: TObject; const PropName: string; Brackets: Boolean): string;
  1908. begin
  1909. Result:=GetSetProp(Instance,FindPropInfo(Instance,PropName),Brackets);
  1910. end;
  1911. Function GetSetProp(Instance: TObject; const PropInfo: PPropInfo; Brackets: Boolean): string;
  1912. begin
  1913. Result:=SetToString(PropInfo,GetOrdProp(Instance,PropInfo),Brackets);
  1914. end;
  1915. Procedure SetSetProp(Instance: TObject; const PropName: string; const Value: string);
  1916. begin
  1917. SetSetProp(Instance,FindPropInfo(Instance,PropName),Value);
  1918. end;
  1919. Procedure SetSetProp(Instance: TObject; const PropInfo: PPropInfo; const Value: string);
  1920. begin
  1921. SetOrdProp(Instance,PropInfo,StringToSet(PropInfo,Value));
  1922. end;
  1923. { ---------------------------------------------------------------------
  1924. Pointer properties - internal only
  1925. ---------------------------------------------------------------------}
  1926. Function GetPointerProp(Instance: TObject; PropInfo : PPropInfo): Pointer;
  1927. Type
  1928. TGetPointerProcIndex = function (index:longint): Pointer of object;
  1929. TGetPointerProc = function (): Pointer of object;
  1930. var
  1931. AMethod : TMethod;
  1932. begin
  1933. case (PropInfo^.PropProcs) and 3 of
  1934. ptField:
  1935. Result := PPointer(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  1936. ptStatic,
  1937. ptVirtual:
  1938. begin
  1939. if (PropInfo^.PropProcs and 3)=ptStatic then
  1940. AMethod.Code:=PropInfo^.GetProc
  1941. else
  1942. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1943. AMethod.Data:=Instance;
  1944. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1945. Result:=TGetPointerProcIndex(AMethod)(PropInfo^.Index)
  1946. else
  1947. Result:=TGetPointerProc(AMethod)();
  1948. end;
  1949. else
  1950. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  1951. end;
  1952. end;
  1953. Procedure SetPointerProp(Instance: TObject; PropInfo : PPropInfo; Value: Pointer);
  1954. type
  1955. TSetPointerProcIndex = procedure(index: longint; p: pointer) of object;
  1956. TSetPointerProc = procedure(p: pointer) of object;
  1957. var
  1958. AMethod : TMethod;
  1959. begin
  1960. case (PropInfo^.PropProcs shr 2) and 3 of
  1961. ptField:
  1962. PPointer(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  1963. ptStatic,
  1964. ptVirtual:
  1965. begin
  1966. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1967. AMethod.Code:=PropInfo^.SetProc
  1968. else
  1969. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1970. AMethod.Data:=Instance;
  1971. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1972. TSetPointerProcIndex(AMethod)(PropInfo^.Index,Value)
  1973. else
  1974. TSetPointerProc(AMethod)(Value);
  1975. end;
  1976. else
  1977. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  1978. end;
  1979. end;
  1980. { ---------------------------------------------------------------------
  1981. Object properties
  1982. ---------------------------------------------------------------------}
  1983. Function GetObjectProp(Instance: TObject; const PropName: string): TObject;
  1984. begin
  1985. Result:=GetObjectProp(Instance,PropName,Nil);
  1986. end;
  1987. Function GetObjectProp(Instance: TObject; const PropName: string; MinClass: TClass): TObject;
  1988. begin
  1989. Result:=GetObjectProp(Instance,FindPropInfo(Instance,PropName),MinClass);
  1990. end;
  1991. Function GetObjectProp(Instance: TObject; PropInfo : PPropInfo): TObject;
  1992. begin
  1993. Result:=GetObjectProp(Instance,PropInfo,Nil);
  1994. end;
  1995. Function GetObjectProp(Instance: TObject; PropInfo : PPropInfo; MinClass: TClass): TObject;
  1996. begin
  1997. Result:=TObject(GetPointerProp(Instance,PropInfo));
  1998. If (MinClass<>Nil) and (Result<>Nil) Then
  1999. If Not Result.InheritsFrom(MinClass) then
  2000. Result:=Nil;
  2001. end;
  2002. Procedure SetObjectProp(Instance: TObject; const PropName: string; Value: TObject);
  2003. begin
  2004. SetObjectProp(Instance,FindPropInfo(Instance,PropName),Value);
  2005. end;
  2006. Procedure SetObjectProp(Instance: TObject; PropInfo : PPropInfo; Value: TObject);
  2007. begin
  2008. SetPointerProp(Instance,PropInfo,Pointer(Value));
  2009. end;
  2010. Function GetObjectPropClass(Instance: TObject; const PropName: string): TClass;
  2011. begin
  2012. Result:=GetTypeData(FindPropInfo(Instance,PropName,[tkClass])^.PropType)^.ClassType;
  2013. end;
  2014. Function GetObjectPropClass(AClass: TClass; const PropName: string): TClass;
  2015. begin
  2016. Result:=GetTypeData(FindPropInfo(AClass,PropName,[tkClass])^.PropType)^.ClassType;
  2017. end;
  2018. { ---------------------------------------------------------------------
  2019. Interface wrapprers
  2020. ---------------------------------------------------------------------}
  2021. function GetInterfaceProp(Instance: TObject; const PropName: string): IInterface;
  2022. begin
  2023. Result:=GetInterfaceProp(Instance,FindPropInfo(Instance,PropName));
  2024. end;
  2025. function GetInterfaceProp(Instance: TObject; PropInfo: PPropInfo): IInterface;
  2026. type
  2027. TGetInterfaceProc=function:IInterface of object;
  2028. TGetInterfaceProcIndex=function(index:longint):IInterface of object;
  2029. var
  2030. AMethod : TMethod;
  2031. begin
  2032. Result:=nil;
  2033. case (PropInfo^.PropProcs) and 3 of
  2034. ptField:
  2035. Result:=IInterface(PPointer(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^);
  2036. ptStatic,
  2037. ptVirtual:
  2038. begin
  2039. if (PropInfo^.PropProcs and 3)=ptStatic then
  2040. AMethod.Code:=PropInfo^.GetProc
  2041. else
  2042. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2043. AMethod.Data:=Instance;
  2044. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2045. Result:=TGetInterfaceProcIndex(AMethod)(PropInfo^.Index)
  2046. else
  2047. Result:=TGetInterfaceProc(AMethod)();
  2048. end;
  2049. else
  2050. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2051. end;
  2052. end;
  2053. procedure SetInterfaceProp(Instance: TObject; const PropName: string; const Value: IInterface);
  2054. begin
  2055. SetInterfaceProp(Instance,FindPropInfo(Instance,PropName),Value);
  2056. end;
  2057. procedure SetInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: IInterface);
  2058. type
  2059. TSetIntfStrProcIndex=procedure(index:longint;const i:IInterface) of object;
  2060. TSetIntfStrProc=procedure(i:IInterface) of object;
  2061. var
  2062. AMethod : TMethod;
  2063. begin
  2064. case Propinfo^.PropType^.Kind of
  2065. tkInterface:
  2066. begin
  2067. case (PropInfo^.PropProcs shr 2) and 3 of
  2068. ptField:
  2069. PInterface(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2070. ptStatic,
  2071. ptVirtual:
  2072. begin
  2073. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2074. AMethod.Code:=PropInfo^.SetProc
  2075. else
  2076. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2077. AMethod.Data:=Instance;
  2078. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2079. TSetIntfStrProcIndex(AMethod)(PropInfo^.Index,Value)
  2080. else
  2081. TSetIntfStrProc(AMethod)(Value);
  2082. end;
  2083. else
  2084. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2085. end;
  2086. end;
  2087. tkInterfaceRaw:
  2088. Raise Exception.Create('Cannot set RAW interface from IUnknown interface');
  2089. end;
  2090. end;
  2091. { ---------------------------------------------------------------------
  2092. RAW (Corba) Interface wrapprers
  2093. ---------------------------------------------------------------------}
  2094. function GetRawInterfaceProp(Instance: TObject; const PropName: string): Pointer;
  2095. begin
  2096. Result:=GetRawInterfaceProp(Instance,FindPropInfo(Instance,PropName));
  2097. end;
  2098. function GetRawInterfaceProp(Instance: TObject; PropInfo: PPropInfo): Pointer;
  2099. begin
  2100. Result:=GetPointerProp(Instance,PropInfo);
  2101. end;
  2102. procedure SetRawInterfaceProp(Instance: TObject; const PropName: string; const Value: Pointer);
  2103. begin
  2104. SetRawInterfaceProp(Instance,FindPropInfo(Instance,PropName),Value);
  2105. end;
  2106. procedure SetRawInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: Pointer);
  2107. begin
  2108. SetPointerProp(Instance,PropInfo,Value);
  2109. end;
  2110. { ---------------------------------------------------------------------
  2111. Dynamic array properties
  2112. ---------------------------------------------------------------------}
  2113. function GetDynArrayProp(Instance: TObject; const PropName: string): Pointer;
  2114. begin
  2115. Result:=GetDynArrayProp(Instance,FindPropInfo(Instance,PropName));
  2116. end;
  2117. function GetDynArrayProp(Instance: TObject; PropInfo: PPropInfo): Pointer;
  2118. type
  2119. { we need a dynamic array as that type is usually passed differently from
  2120. a plain pointer }
  2121. TDynArray=array of Byte;
  2122. TGetDynArrayProc=function:TDynArray of object;
  2123. TGetDynArrayProcIndex=function(index:longint):TDynArray of object;
  2124. var
  2125. AMethod : TMethod;
  2126. begin
  2127. Result:=nil;
  2128. if PropInfo^.PropType^.Kind<>tkDynArray then
  2129. Exit;
  2130. case (PropInfo^.PropProcs) and 3 of
  2131. ptField:
  2132. Result:=PPointer(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2133. ptStatic,
  2134. ptVirtual:
  2135. begin
  2136. if (PropInfo^.PropProcs and 3)=ptStatic then
  2137. AMethod.Code:=PropInfo^.GetProc
  2138. else
  2139. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2140. AMethod.Data:=Instance;
  2141. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2142. Result:=Pointer(TGetDynArrayProcIndex(AMethod)(PropInfo^.Index))
  2143. else
  2144. Result:=Pointer(TGetDynArrayProc(AMethod)());
  2145. end;
  2146. else
  2147. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2148. end;
  2149. end;
  2150. procedure SetDynArrayProp(Instance: TObject; const PropName: string; const Value: Pointer);
  2151. begin
  2152. SetDynArrayProp(Instance,FindPropInfo(Instance,PropName),Value);
  2153. end;
  2154. procedure SetDynArrayProp(Instance: TObject; PropInfo: PPropInfo; const Value: Pointer);
  2155. type
  2156. { we need a dynamic array as that type is usually passed differently from
  2157. a plain pointer }
  2158. TDynArray=array of Byte;
  2159. TSetDynArrayProcIndex=procedure(index:longint;const i:TDynArray) of object;
  2160. TSetDynArrayProc=procedure(i:TDynArray) of object;
  2161. var
  2162. AMethod: TMethod;
  2163. begin
  2164. if PropInfo^.PropType^.Kind<>tkDynArray then
  2165. Exit;
  2166. case (PropInfo^.PropProcs shr 2) and 3 of
  2167. ptField:
  2168. CopyArray(PPointer(Pointer(Instance)+PtrUInt(PropInfo^.SetProc)), @Value, PropInfo^.PropType, 1);
  2169. ptStatic,
  2170. ptVirtual:
  2171. begin
  2172. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2173. AMethod.Code:=PropInfo^.SetProc
  2174. else
  2175. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2176. AMethod.Data:=Instance;
  2177. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2178. TSetDynArrayProcIndex(AMethod)(PropInfo^.Index,TDynArray(Value))
  2179. else
  2180. TSetDynArrayProc(AMethod)(TDynArray(Value));
  2181. end;
  2182. else
  2183. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2184. end;
  2185. end;
  2186. { ---------------------------------------------------------------------
  2187. String properties
  2188. ---------------------------------------------------------------------}
  2189. Function GetStrProp(Instance: TObject; PropInfo: PPropInfo): AnsiString;
  2190. type
  2191. TGetShortStrProcIndex=function(index:longint):ShortString of object;
  2192. TGetShortStrProc=function():ShortString of object;
  2193. TGetAnsiStrProcIndex=function(index:longint):AnsiString of object;
  2194. TGetAnsiStrProc=function():AnsiString of object;
  2195. var
  2196. AMethod : TMethod;
  2197. begin
  2198. Result:='';
  2199. case Propinfo^.PropType^.Kind of
  2200. tkWString:
  2201. Result:=AnsiString(GetWideStrProp(Instance,PropInfo));
  2202. tkUString:
  2203. Result := AnsiString(GetUnicodeStrProp(Instance,PropInfo));
  2204. tkSString:
  2205. begin
  2206. case (PropInfo^.PropProcs) and 3 of
  2207. ptField:
  2208. Result := PShortString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  2209. ptStatic,
  2210. ptVirtual:
  2211. begin
  2212. if (PropInfo^.PropProcs and 3)=ptStatic then
  2213. AMethod.Code:=PropInfo^.GetProc
  2214. else
  2215. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2216. AMethod.Data:=Instance;
  2217. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2218. Result:=TGetShortStrProcIndex(AMethod)(PropInfo^.Index)
  2219. else
  2220. Result:=TGetShortStrProc(AMethod)();
  2221. end;
  2222. else
  2223. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2224. end;
  2225. end;
  2226. tkAString:
  2227. begin
  2228. case (PropInfo^.PropProcs) and 3 of
  2229. ptField:
  2230. Result := PAnsiString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  2231. ptStatic,
  2232. ptVirtual:
  2233. begin
  2234. if (PropInfo^.PropProcs and 3)=ptStatic then
  2235. AMethod.Code:=PropInfo^.GetProc
  2236. else
  2237. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2238. AMethod.Data:=Instance;
  2239. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2240. Result:=TGetAnsiStrProcIndex(AMethod)(PropInfo^.Index)
  2241. else
  2242. Result:=TGetAnsiStrProc(AMethod)();
  2243. end;
  2244. else
  2245. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2246. end;
  2247. end;
  2248. end;
  2249. end;
  2250. Procedure SetStrProp(Instance : TObject;PropInfo : PPropInfo; const Value : AnsiString);
  2251. type
  2252. TSetShortStrProcIndex=procedure(index:longint;const s:ShortString) of object;
  2253. TSetShortStrProc=procedure(const s:ShortString) of object;
  2254. TSetAnsiStrProcIndex=procedure(index:longint;s:AnsiString) of object;
  2255. TSetAnsiStrProc=procedure(s:AnsiString) of object;
  2256. var
  2257. AMethod : TMethod;
  2258. begin
  2259. case Propinfo^.PropType^.Kind of
  2260. tkWString:
  2261. SetWideStrProp(Instance,PropInfo,WideString(Value));
  2262. tkUString:
  2263. SetUnicodeStrProp(Instance,PropInfo,UnicodeString(Value));
  2264. tkSString:
  2265. begin
  2266. case (PropInfo^.PropProcs shr 2) and 3 of
  2267. ptField:
  2268. PShortString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  2269. ptStatic,
  2270. ptVirtual:
  2271. begin
  2272. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2273. AMethod.Code:=PropInfo^.SetProc
  2274. else
  2275. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2276. AMethod.Data:=Instance;
  2277. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2278. TSetShortStrProcIndex(AMethod)(PropInfo^.Index,Value)
  2279. else
  2280. TSetShortStrProc(AMethod)(Value);
  2281. end;
  2282. else
  2283. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2284. end;
  2285. end;
  2286. tkAString:
  2287. begin
  2288. case (PropInfo^.PropProcs shr 2) and 3 of
  2289. ptField:
  2290. PAnsiString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  2291. ptStatic,
  2292. ptVirtual:
  2293. begin
  2294. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2295. AMethod.Code:=PropInfo^.SetProc
  2296. else
  2297. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2298. AMethod.Data:=Instance;
  2299. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2300. TSetAnsiStrProcIndex(AMethod)(PropInfo^.Index,Value)
  2301. else
  2302. TSetAnsiStrProc(AMethod)(Value);
  2303. end;
  2304. else
  2305. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2306. end;
  2307. end;
  2308. end;
  2309. end;
  2310. Function GetStrProp(Instance: TObject; const PropName: string): string;
  2311. begin
  2312. Result:=GetStrProp(Instance,FindPropInfo(Instance,PropName));
  2313. end;
  2314. Procedure SetStrProp(Instance: TObject; const PropName: string; const Value: AnsiString);
  2315. begin
  2316. SetStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  2317. end;
  2318. Function GetWideStrProp(Instance: TObject; const PropName: string): WideString;
  2319. begin
  2320. Result:=GetWideStrProp(Instance, FindPropInfo(Instance, PropName));
  2321. end;
  2322. procedure SetWideStrProp(Instance: TObject; const PropName: string; const Value: WideString);
  2323. begin
  2324. SetWideStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  2325. end;
  2326. Function GetWideStrProp(Instance: TObject; PropInfo: PPropInfo): WideString;
  2327. type
  2328. TGetWideStrProcIndex=function(index:longint):WideString of object;
  2329. TGetWideStrProc=function():WideString of object;
  2330. var
  2331. AMethod : TMethod;
  2332. begin
  2333. Result:='';
  2334. case Propinfo^.PropType^.Kind of
  2335. tkSString,tkAString:
  2336. Result:=WideString(GetStrProp(Instance,PropInfo));
  2337. tkUString :
  2338. Result := GetUnicodeStrProp(Instance,PropInfo);
  2339. tkWString:
  2340. begin
  2341. case (PropInfo^.PropProcs) and 3 of
  2342. ptField:
  2343. Result := PWideString(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2344. ptStatic,
  2345. ptVirtual:
  2346. begin
  2347. if (PropInfo^.PropProcs and 3)=ptStatic then
  2348. AMethod.Code:=PropInfo^.GetProc
  2349. else
  2350. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2351. AMethod.Data:=Instance;
  2352. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2353. Result:=TGetWideStrProcIndex(AMethod)(PropInfo^.Index)
  2354. else
  2355. Result:=TGetWideStrProc(AMethod)();
  2356. end;
  2357. else
  2358. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2359. end;
  2360. end;
  2361. end;
  2362. end;
  2363. Procedure SetWideStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: WideString);
  2364. type
  2365. TSetWideStrProcIndex=procedure(index:longint;s:WideString) of object;
  2366. TSetWideStrProc=procedure(s:WideString) of object;
  2367. var
  2368. AMethod : TMethod;
  2369. begin
  2370. case Propinfo^.PropType^.Kind of
  2371. tkSString,tkAString:
  2372. SetStrProp(Instance,PropInfo,AnsiString(Value));
  2373. tkUString:
  2374. SetUnicodeStrProp(Instance,PropInfo,Value);
  2375. tkWString:
  2376. begin
  2377. case (PropInfo^.PropProcs shr 2) and 3 of
  2378. ptField:
  2379. PWideString(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2380. ptStatic,
  2381. ptVirtual:
  2382. begin
  2383. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2384. AMethod.Code:=PropInfo^.SetProc
  2385. else
  2386. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2387. AMethod.Data:=Instance;
  2388. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2389. TSetWideStrProcIndex(AMethod)(PropInfo^.Index,Value)
  2390. else
  2391. TSetWideStrProc(AMethod)(Value);
  2392. end;
  2393. else
  2394. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2395. end;
  2396. end;
  2397. end;
  2398. end;
  2399. Function GetUnicodeStrProp(Instance: TObject; const PropName: string): UnicodeString;
  2400. begin
  2401. Result:=GetUnicodeStrProp(Instance, FindPropInfo(Instance, PropName));
  2402. end;
  2403. procedure SetUnicodeStrProp(Instance: TObject; const PropName: string; const Value: UnicodeString);
  2404. begin
  2405. SetUnicodeStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  2406. end;
  2407. Function GetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo): UnicodeString;
  2408. type
  2409. TGetUnicodeStrProcIndex=function(index:longint):UnicodeString of object;
  2410. TGetUnicodeStrProc=function():UnicodeString of object;
  2411. var
  2412. AMethod : TMethod;
  2413. begin
  2414. Result:='';
  2415. case Propinfo^.PropType^.Kind of
  2416. tkSString,tkAString:
  2417. Result:=UnicodeString(GetStrProp(Instance,PropInfo));
  2418. tkWString:
  2419. Result:=GetWideStrProp(Instance,PropInfo);
  2420. tkUString:
  2421. begin
  2422. case (PropInfo^.PropProcs) and 3 of
  2423. ptField:
  2424. Result := PUnicodeString(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2425. ptStatic,
  2426. ptVirtual:
  2427. begin
  2428. if (PropInfo^.PropProcs and 3)=ptStatic then
  2429. AMethod.Code:=PropInfo^.GetProc
  2430. else
  2431. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2432. AMethod.Data:=Instance;
  2433. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2434. Result:=TGetUnicodeStrProcIndex(AMethod)(PropInfo^.Index)
  2435. else
  2436. Result:=TGetUnicodeStrProc(AMethod)();
  2437. end;
  2438. else
  2439. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2440. end;
  2441. end;
  2442. end;
  2443. end;
  2444. Procedure SetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: UnicodeString);
  2445. type
  2446. TSetUnicodeStrProcIndex=procedure(index:longint;s:UnicodeString) of object;
  2447. TSetUnicodeStrProc=procedure(s:UnicodeString) of object;
  2448. var
  2449. AMethod : TMethod;
  2450. begin
  2451. case Propinfo^.PropType^.Kind of
  2452. tkSString,tkAString:
  2453. SetStrProp(Instance,PropInfo,AnsiString(Value));
  2454. tkWString:
  2455. SetWideStrProp(Instance,PropInfo,Value);
  2456. tkUString:
  2457. begin
  2458. case (PropInfo^.PropProcs shr 2) and 3 of
  2459. ptField:
  2460. PUnicodeString(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2461. ptStatic,
  2462. ptVirtual:
  2463. begin
  2464. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2465. AMethod.Code:=PropInfo^.SetProc
  2466. else
  2467. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2468. AMethod.Data:=Instance;
  2469. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2470. TSetUnicodeStrProcIndex(AMethod)(PropInfo^.Index,Value)
  2471. else
  2472. TSetUnicodeStrProc(AMethod)(Value);
  2473. end;
  2474. else
  2475. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2476. end;
  2477. end;
  2478. end;
  2479. end;
  2480. function GetRawbyteStrProp(Instance: TObject; PropInfo: PPropInfo): RawByteString;
  2481. type
  2482. TGetRawByteStrProcIndex=function(index:longint): RawByteString of object;
  2483. TGetRawByteStrProc=function():RawByteString of object;
  2484. var
  2485. AMethod : TMethod;
  2486. begin
  2487. Result:='';
  2488. case Propinfo^.PropType^.Kind of
  2489. tkWString:
  2490. Result:=RawByteString(GetWideStrProp(Instance,PropInfo));
  2491. tkUString:
  2492. Result:=RawByteString(GetUnicodeStrProp(Instance,PropInfo));
  2493. tkSString:
  2494. Result:=RawByteString(GetStrProp(Instance,PropInfo));
  2495. tkAString:
  2496. begin
  2497. case (PropInfo^.PropProcs) and 3 of
  2498. ptField:
  2499. Result := PAnsiString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  2500. ptStatic,
  2501. ptVirtual:
  2502. begin
  2503. if (PropInfo^.PropProcs and 3)=ptStatic then
  2504. AMethod.Code:=PropInfo^.GetProc
  2505. else
  2506. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2507. AMethod.Data:=Instance;
  2508. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2509. Result:=TGetRawByteStrProcIndex(AMethod)(PropInfo^.Index)
  2510. else
  2511. Result:=TGetRawByteStrProc(AMethod)();
  2512. end;
  2513. else
  2514. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2515. end;
  2516. end;
  2517. end;
  2518. end;
  2519. function GetRawByteStrProp(Instance: TObject; const PropName: string): RawByteString;
  2520. begin
  2521. Result:=GetRawByteStrProp(Instance,FindPropInfo(Instance,PropName));
  2522. end;
  2523. procedure SetRawByteStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: RawByteString);
  2524. type
  2525. TSetRawByteStrProcIndex=procedure(index:longint;s:RawByteString) of object;
  2526. TSetRawByteStrProc=procedure(s:RawByteString) of object;
  2527. var
  2528. AMethod : TMethod;
  2529. begin
  2530. case Propinfo^.PropType^.Kind of
  2531. tkWString:
  2532. SetWideStrProp(Instance,PropInfo,WideString(Value));
  2533. tkUString:
  2534. SetUnicodeStrProp(Instance,PropInfo,UnicodeString(Value));
  2535. tkSString:
  2536. SetStrProp(Instance,PropInfo,Value); // Not 100% sure about this.
  2537. tkAString:
  2538. begin
  2539. case (PropInfo^.PropProcs shr 2) and 3 of
  2540. ptField:
  2541. PAnsiString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  2542. ptStatic,
  2543. ptVirtual:
  2544. begin
  2545. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2546. AMethod.Code:=PropInfo^.SetProc
  2547. else
  2548. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2549. AMethod.Data:=Instance;
  2550. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2551. TSetRawByteStrProcIndex(AMethod)(PropInfo^.Index,Value)
  2552. else
  2553. TSetRawByteStrProc(AMethod)(Value);
  2554. end;
  2555. else
  2556. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2557. end;
  2558. end;
  2559. end;
  2560. end;
  2561. procedure SetRawByteStrProp(Instance: TObject; const PropName: string; const Value: RawByteString);
  2562. begin
  2563. SetRawByteStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  2564. end;
  2565. {$ifndef FPUNONE}
  2566. { ---------------------------------------------------------------------
  2567. Float properties
  2568. ---------------------------------------------------------------------}
  2569. function GetFloatProp(Instance : TObject;PropInfo : PPropInfo) : Extended;
  2570. type
  2571. TGetExtendedProc = function:Extended of object;
  2572. TGetExtendedProcIndex = function(Index: integer): Extended of object;
  2573. TGetDoubleProc = function:Double of object;
  2574. TGetDoubleProcIndex = function(Index: integer): Double of object;
  2575. TGetSingleProc = function:Single of object;
  2576. TGetSingleProcIndex = function(Index: integer):Single of object;
  2577. TGetCurrencyProc = function : Currency of object;
  2578. TGetCurrencyProcIndex = function(Index: integer) : Currency of object;
  2579. var
  2580. AMethod : TMethod;
  2581. begin
  2582. Result:=0.0;
  2583. case PropInfo^.PropProcs and 3 of
  2584. ptField:
  2585. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  2586. ftSingle:
  2587. Result:=PSingle(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2588. ftDouble:
  2589. Result:=PDouble(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2590. ftExtended:
  2591. Result:=PExtended(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2592. ftcomp:
  2593. Result:=PComp(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2594. ftcurr:
  2595. Result:=PCurrency(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2596. end;
  2597. ptStatic,
  2598. ptVirtual:
  2599. begin
  2600. if (PropInfo^.PropProcs and 3)=ptStatic then
  2601. AMethod.Code:=PropInfo^.GetProc
  2602. else
  2603. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2604. AMethod.Data:=Instance;
  2605. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  2606. ftSingle:
  2607. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2608. Result:=TGetSingleProc(AMethod)()
  2609. else
  2610. Result:=TGetSingleProcIndex(AMethod)(PropInfo^.Index);
  2611. ftDouble:
  2612. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2613. Result:=TGetDoubleProc(AMethod)()
  2614. else
  2615. Result:=TGetDoubleProcIndex(AMethod)(PropInfo^.Index);
  2616. ftExtended:
  2617. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2618. Result:=TGetExtendedProc(AMethod)()
  2619. else
  2620. Result:=TGetExtendedProcIndex(AMethod)(PropInfo^.Index);
  2621. ftCurr:
  2622. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2623. Result:=TGetCurrencyProc(AMethod)()
  2624. else
  2625. Result:=TGetCurrencyProcIndex(AMethod)(PropInfo^.Index);
  2626. end;
  2627. end;
  2628. else
  2629. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2630. end;
  2631. end;
  2632. Procedure SetFloatProp(Instance : TObject;PropInfo : PPropInfo; Value : Extended);
  2633. type
  2634. TSetExtendedProc = procedure(const AValue: Extended) of object;
  2635. TSetExtendedProcIndex = procedure(Index: integer; AValue: Extended) of object;
  2636. TSetDoubleProc = procedure(const AValue: Double) of object;
  2637. TSetDoubleProcIndex = procedure(Index: integer; AValue: Double) of object;
  2638. TSetSingleProc = procedure(const AValue: Single) of object;
  2639. TSetSingleProcIndex = procedure(Index: integer; AValue: Single) of object;
  2640. TSetCurrencyProc = procedure(const AValue: Currency) of object;
  2641. TSetCurrencyProcIndex = procedure(Index: integer; AValue: Currency) of object;
  2642. Var
  2643. AMethod : TMethod;
  2644. begin
  2645. case (PropInfo^.PropProcs shr 2) and 3 of
  2646. ptfield:
  2647. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  2648. ftSingle:
  2649. PSingle(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2650. ftDouble:
  2651. PDouble(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2652. ftExtended:
  2653. PExtended(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2654. {$ifdef FPC_COMP_IS_INT64}
  2655. ftComp:
  2656. PComp(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=trunc(Value);
  2657. {$else FPC_COMP_IS_INT64}
  2658. ftComp:
  2659. PComp(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Comp(Value);
  2660. {$endif FPC_COMP_IS_INT64}
  2661. ftCurr:
  2662. PCurrency(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2663. end;
  2664. ptStatic,
  2665. ptVirtual:
  2666. begin
  2667. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2668. AMethod.Code:=PropInfo^.SetProc
  2669. else
  2670. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2671. AMethod.Data:=Instance;
  2672. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  2673. ftSingle:
  2674. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2675. TSetSingleProc(AMethod)(Value)
  2676. else
  2677. TSetSingleProcIndex(AMethod)(PropInfo^.Index,Value);
  2678. ftDouble:
  2679. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2680. TSetDoubleProc(AMethod)(Value)
  2681. else
  2682. TSetDoubleProcIndex(AMethod)(PropInfo^.Index,Value);
  2683. ftExtended:
  2684. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2685. TSetExtendedProc(AMethod)(Value)
  2686. else
  2687. TSetExtendedProcIndex(AMethod)(PropInfo^.Index,Value);
  2688. ftCurr:
  2689. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2690. TSetCurrencyProc(AMethod)(Value)
  2691. else
  2692. TSetCurrencyProcIndex(AMethod)(PropInfo^.Index,Value);
  2693. end;
  2694. end;
  2695. else
  2696. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2697. end;
  2698. end;
  2699. function GetFloatProp(Instance: TObject; const PropName: string): Extended;
  2700. begin
  2701. Result:=GetFloatProp(Instance,FindPropInfo(Instance,PropName))
  2702. end;
  2703. Procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Extended);
  2704. begin
  2705. SetFloatProp(Instance,FindPropInfo(Instance,PropName),Value);
  2706. end;
  2707. {$endif}
  2708. { ---------------------------------------------------------------------
  2709. Method properties
  2710. ---------------------------------------------------------------------}
  2711. Function GetMethodProp(Instance : TObject;PropInfo : PPropInfo) : TMethod;
  2712. type
  2713. TGetMethodProcIndex=function(Index: Longint): TMethod of object;
  2714. TGetMethodProc=function(): TMethod of object;
  2715. var
  2716. value: PMethod;
  2717. AMethod : TMethod;
  2718. begin
  2719. Result.Code:=nil;
  2720. Result.Data:=nil;
  2721. case (PropInfo^.PropProcs) and 3 of
  2722. ptField:
  2723. begin
  2724. Value:=PMethod(Pointer(Instance)+PtrUInt(PropInfo^.GetProc));
  2725. if Value<>nil then
  2726. Result:=Value^;
  2727. end;
  2728. ptStatic,
  2729. ptVirtual:
  2730. begin
  2731. if (PropInfo^.PropProcs and 3)=ptStatic then
  2732. AMethod.Code:=PropInfo^.GetProc
  2733. else
  2734. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2735. AMethod.Data:=Instance;
  2736. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2737. Result:=TGetMethodProcIndex(AMethod)(PropInfo^.Index)
  2738. else
  2739. Result:=TGetMethodProc(AMethod)();
  2740. end;
  2741. else
  2742. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2743. end;
  2744. end;
  2745. Procedure SetMethodProp(Instance : TObject;PropInfo : PPropInfo; const Value : TMethod);
  2746. type
  2747. TSetMethodProcIndex=procedure(index:longint;p:TMethod) of object;
  2748. TSetMethodProc=procedure(p:TMethod) of object;
  2749. var
  2750. AMethod : TMethod;
  2751. begin
  2752. case (PropInfo^.PropProcs shr 2) and 3 of
  2753. ptField:
  2754. PMethod(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^ := Value;
  2755. ptStatic,
  2756. ptVirtual:
  2757. begin
  2758. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2759. AMethod.Code:=PropInfo^.SetProc
  2760. else
  2761. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2762. AMethod.Data:=Instance;
  2763. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2764. TSetMethodProcIndex(AMethod)(PropInfo^.Index,Value)
  2765. else
  2766. TSetMethodProc(AMethod)(Value);
  2767. end;
  2768. else
  2769. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2770. end;
  2771. end;
  2772. Function GetMethodProp(Instance: TObject; const PropName: string): TMethod;
  2773. begin
  2774. Result:=GetMethodProp(Instance,FindPropInfo(Instance,PropName));
  2775. end;
  2776. Procedure SetMethodProp(Instance: TObject; const PropName: string; const Value: TMethod);
  2777. begin
  2778. SetMethodProp(Instance,FindPropInfo(Instance,PropName),Value);
  2779. end;
  2780. { ---------------------------------------------------------------------
  2781. Variant properties
  2782. ---------------------------------------------------------------------}
  2783. Procedure CheckVariantEvent(P : CodePointer);
  2784. begin
  2785. If (P=Nil) then
  2786. Raise Exception.Create(SErrNoVariantSupport);
  2787. end;
  2788. Function GetVariantProp(Instance : TObject;PropInfo : PPropInfo): Variant;
  2789. begin
  2790. CheckVariantEvent(CodePointer(OnGetVariantProp));
  2791. Result:=OnGetVariantProp(Instance,PropInfo);
  2792. end;
  2793. Procedure SetVariantProp(Instance : TObject;PropInfo : PPropInfo; const Value: Variant);
  2794. begin
  2795. CheckVariantEvent(CodePointer(OnSetVariantProp));
  2796. OnSetVariantProp(Instance,PropInfo,Value);
  2797. end;
  2798. Function GetVariantProp(Instance: TObject; const PropName: string): Variant;
  2799. begin
  2800. Result:=GetVariantProp(Instance,FindPropInfo(Instance,PropName));
  2801. end;
  2802. Procedure SetVariantProp(Instance: TObject; const PropName: string; const Value: Variant);
  2803. begin
  2804. SetVariantprop(instance,FindpropInfo(Instance,PropName),Value);
  2805. end;
  2806. { ---------------------------------------------------------------------
  2807. All properties through variant.
  2808. ---------------------------------------------------------------------}
  2809. Function GetPropValue(Instance: TObject; const PropName: string): Variant;
  2810. begin
  2811. Result := GetPropValue(Instance,FindPropInfo(Instance, PropName));
  2812. end;
  2813. Function GetPropValue(Instance: TObject; const PropName: string; PreferStrings: Boolean): Variant;
  2814. begin
  2815. Result := GetPropValue(Instance,FindPropInfo(Instance, PropName),PreferStrings);
  2816. end;
  2817. Function GetPropValue(Instance: TObject; PropInfo: PPropInfo): Variant;
  2818. begin
  2819. Result := GetPropValue(Instance, PropInfo, True);
  2820. end;
  2821. Function GetPropValue(Instance: TObject; PropInfo: PPropInfo; PreferStrings: Boolean): Variant;
  2822. begin
  2823. CheckVariantEvent(CodePointer(OnGetPropValue));
  2824. Result:=OnGetPropValue(Instance,PropInfo,PreferStrings);
  2825. end;
  2826. Procedure SetPropValue(Instance: TObject; const PropName: string; const Value: Variant);
  2827. begin
  2828. SetPropValue(Instance, FindPropInfo(Instance, PropName), Value);
  2829. end;
  2830. Procedure SetPropValue(Instance: TObject; PropInfo: PPropInfo; const Value: Variant);
  2831. begin
  2832. CheckVariantEvent(CodePointer(OnSetPropValue));
  2833. OnSetPropValue(Instance,PropInfo,Value);
  2834. end;
  2835. { ---------------------------------------------------------------------
  2836. Easy access methods that appeared in Delphi 5
  2837. ---------------------------------------------------------------------}
  2838. Function IsPublishedProp(Instance: TObject; const PropName: string): Boolean;
  2839. begin
  2840. Result:=GetPropInfo(Instance,PropName)<>Nil;
  2841. end;
  2842. Function IsPublishedProp(AClass: TClass; const PropName: string): Boolean;
  2843. begin
  2844. Result:=GetPropInfo(AClass,PropName)<>Nil;
  2845. end;
  2846. Function PropIsType(Instance: TObject; const PropName: string; TypeKind: TTypeKind): Boolean;
  2847. begin
  2848. Result:=PropType(Instance,PropName)=TypeKind
  2849. end;
  2850. Function PropIsType(AClass: TClass; const PropName: string; TypeKind: TTypeKind): Boolean;
  2851. begin
  2852. Result:=PropType(AClass,PropName)=TypeKind
  2853. end;
  2854. Function PropType(Instance: TObject; const PropName: string): TTypeKind;
  2855. begin
  2856. Result:=FindPropInfo(Instance,PropName)^.PropType^.Kind;
  2857. end;
  2858. Function PropType(AClass: TClass; const PropName: string): TTypeKind;
  2859. begin
  2860. Result:=FindPropInfo(AClass,PropName)^.PropType^.Kind;
  2861. end;
  2862. Function IsStoredProp(Instance: TObject; const PropName: string): Boolean;
  2863. begin
  2864. Result:=IsStoredProp(instance,FindPropInfo(Instance,PropName));
  2865. end;
  2866. { TParameterLocation }
  2867. function TParameterLocation.GetReference: Boolean;
  2868. begin
  2869. Result := (LocType and $80) <> 0;
  2870. end;
  2871. function TParameterLocation.GetRegType: TRegisterType;
  2872. begin
  2873. Result := TRegisterType(LocType and $7F);
  2874. end;
  2875. function TParameterLocation.GetShiftVal: Int8;
  2876. begin
  2877. if GetReference then begin
  2878. if Offset < Low(Int8) then
  2879. Result := Low(Int8)
  2880. else if Offset > High(Int8) then
  2881. Result := High(Int8)
  2882. else
  2883. Result := Offset;
  2884. end else
  2885. Result := 0;
  2886. end;
  2887. { TParameterLocations }
  2888. function TParameterLocations.GetLocation(aIndex: Byte): PParameterLocation;
  2889. begin
  2890. if aIndex >= Count then
  2891. Result := Nil
  2892. else
  2893. Result := PParameterLocation(PByte(aligntoptr(PByte(@Count) + SizeOf(Count))) + SizeOf(TParameterLocation) * aIndex);
  2894. end;
  2895. function TParameterLocations.GetTail: Pointer;
  2896. begin
  2897. Result := PByte(aligntoptr(PByte(@Count) + SizeOf(Count))) + SizeOf(TParameterLocation) * Count;
  2898. end;
  2899. { TProcedureParam }
  2900. function TProcedureParam.GetParamType: PTypeInfo;
  2901. begin
  2902. Result := DerefTypeInfoPtr(ParamTypeRef);
  2903. end;
  2904. function TProcedureParam.GetFlags: Byte;
  2905. begin
  2906. Result := PByte(@ParamFlags)^;
  2907. end;
  2908. { TManagedField }
  2909. function TManagedField.GetTypeRef: PTypeInfo;
  2910. begin
  2911. Result := DerefTypeInfoPtr(TypeRefRef);
  2912. end;
  2913. { TArrayTypeData }
  2914. function TArrayTypeData.GetElType: PTypeInfo;
  2915. begin
  2916. Result := DerefTypeInfoPtr(ElTypeRef);
  2917. end;
  2918. function TArrayTypeData.GetDims(aIndex: Byte): PTypeInfo;
  2919. begin
  2920. Result := DerefTypeInfoPtr(DimsRef[aIndex]);
  2921. end;
  2922. { TProcedureSignature }
  2923. function TProcedureSignature.GetResultType: PTypeInfo;
  2924. begin
  2925. Result := DerefTypeInfoPtr(ResultTypeRef);
  2926. end;
  2927. function TProcedureSignature.GetParam(ParamIndex: Integer): PProcedureParam;
  2928. begin
  2929. if (ParamIndex<0)or(ParamIndex>=ParamCount) then
  2930. Exit(nil);
  2931. Result := PProcedureParam(PByte(@Flags) + SizeOf(Self));
  2932. while ParamIndex > 0 do
  2933. begin
  2934. Result := PProcedureParam(aligntoptr((PByte(@Result^.Name) + (Length(Result^.Name) + 1) * SizeOf(AnsiChar))));
  2935. dec(ParamIndex);
  2936. end;
  2937. end;
  2938. { TVmtMethodParam }
  2939. function TVmtMethodParam.GetTail: Pointer;
  2940. begin
  2941. Result := PByte(@ParaLocs) + SizeOf(ParaLocs);
  2942. end;
  2943. function TVmtMethodParam.GetNext: PVmtMethodParam;
  2944. begin
  2945. Result := PVmtMethodParam(aligntoptr(Tail));
  2946. end;
  2947. function TVmtMethodParam.GetName: ShortString;
  2948. begin
  2949. Result := NamePtr^;
  2950. end;
  2951. { TIntfMethodEntry }
  2952. function TIntfMethodEntry.GetParam(Index: Word): PVmtMethodParam;
  2953. begin
  2954. if Index >= ParamCount then
  2955. Result := Nil
  2956. else
  2957. Result := PVmtMethodParam(PByte(aligntoptr(PByte(@NamePtr) + SizeOf(NamePtr))) + Index * PtrUInt(aligntoptr(Pointer(SizeOf(TVmtMethodParam)))));
  2958. end;
  2959. function TIntfMethodEntry.GetResultLocs: PParameterLocations;
  2960. begin
  2961. if not Assigned(ResultType) then
  2962. Result := Nil
  2963. else
  2964. Result := PParameterLocations(PByte(aligntoptr(PByte(@NamePtr) + SizeOf(NamePtr))) + ParamCount * PtrUInt(aligntoptr(Pointer(SizeOf(TVmtMethodParam)))));
  2965. end;
  2966. function TIntfMethodEntry.GetTail: Pointer;
  2967. begin
  2968. Result := PByte(@NamePtr) + SizeOf(NamePtr);
  2969. if ParamCount > 0 then
  2970. Result := PByte(aligntoptr(Result)) + ParamCount * PtrUInt(aligntoptr(Pointer(SizeOf(TVmtMethodParam))));
  2971. if Assigned(ResultType) then
  2972. Result := PByte(aligntoptr(Result)) + SizeOf(PParameterLocations);
  2973. end;
  2974. function TIntfMethodEntry.GetNext: PIntfMethodEntry;
  2975. begin
  2976. Result := PIntfMethodEntry(aligntoptr(Tail));
  2977. end;
  2978. function TIntfMethodEntry.GetName: ShortString;
  2979. begin
  2980. Result := NamePtr^;
  2981. end;
  2982. { TIntfMethodTable }
  2983. function TIntfMethodTable.GetMethod(Index: Word): PIntfMethodEntry;
  2984. begin
  2985. if (RTTICount = $FFFF) or (Index >= RTTICount) then
  2986. Result := Nil
  2987. else
  2988. begin
  2989. Result := aligntoptr(PIntfMethodEntry(PByte(@RTTICount) + SizeOf(RTTICount)));
  2990. while Index > 0 do
  2991. begin
  2992. Result := Result^.Next;
  2993. Dec(Index);
  2994. end;
  2995. end;
  2996. end;
  2997. { TVmtMethodTable }
  2998. function TVmtMethodTable.GetEntry(Index: LongWord): PVmtMethodEntry;
  2999. begin
  3000. Result := PVmtMethodEntry(@Entries[0]) + Index;
  3001. end;
  3002. { TVmtFieldTable }
  3003. function TVmtFieldTable.GetField(aIndex: Word): PVmtFieldEntry;
  3004. var
  3005. c: Word;
  3006. begin
  3007. if aIndex >= Count then
  3008. Exit(Nil);
  3009. c := aIndex;
  3010. Result := @Fields;
  3011. while c > 0 do begin
  3012. Result := Result^.Next;
  3013. Dec(c);
  3014. end;
  3015. end;
  3016. { TVmtFieldEntry }
  3017. function TVmtFieldEntry.GetNext: PVmtFieldEntry;
  3018. begin
  3019. Result := aligntoptr(Tail);
  3020. end;
  3021. function TVmtFieldEntry.GetTail: Pointer;
  3022. begin
  3023. Result := PByte(@Name) + Length(Name) + SizeOf(Byte);
  3024. end;
  3025. { TInterfaceData }
  3026. function TInterfaceData.GetUnitName: ShortString;
  3027. begin
  3028. Result := UnitNameField;
  3029. end;
  3030. function TInterfaceData.GetPropertyTable: PPropData;
  3031. var
  3032. p: PByte;
  3033. begin
  3034. p := PByte(@UnitNameField[0]) + SizeOf(UnitNameField[0]) + Length(UnitNameField);
  3035. Result := AlignTypeData(p);
  3036. end;
  3037. function TInterfaceData.GetMethodTable: PIntfMethodTable;
  3038. begin
  3039. Result := aligntoptr(PropertyTable^.Tail);
  3040. end;
  3041. { TInterfaceRawData }
  3042. function TInterfaceRawData.GetUnitName: ShortString;
  3043. begin
  3044. Result := UnitNameField;
  3045. end;
  3046. function TInterfaceRawData.GetIIDStr: ShortString;
  3047. begin
  3048. Result := PShortString(AlignTypeData(PByte(@UnitNameField[0]) + SizeOf(UnitNameField[0]) + Length(UnitNameField)))^;
  3049. end;
  3050. function TInterfaceRawData.GetPropertyTable: PPropData;
  3051. var
  3052. p: PByte;
  3053. begin
  3054. p := AlignTypeData(PByte(@UnitNameField[0]) + SizeOf(UnitNameField[0]) + Length(UnitNameField));
  3055. p := p + SizeOf(p^) + p^;
  3056. Result := aligntoptr(p);
  3057. end;
  3058. function TInterfaceRawData.GetMethodTable: PIntfMethodTable;
  3059. begin
  3060. Result := aligntoptr(PropertyTable^.Tail);
  3061. end;
  3062. { TClassData }
  3063. function TClassData.GetUnitName: ShortString;
  3064. begin
  3065. Result := UnitNameField;
  3066. end;
  3067. function TClassData.GetPropertyTable: PPropData;
  3068. var
  3069. p: PByte;
  3070. begin
  3071. p := PByte(@UnitNameField[0]) + SizeOf(UnitNameField[0]) + Length(UnitNameField);
  3072. Result := AlignToPtr(p);
  3073. end;
  3074. { TTypeData }
  3075. function TTypeData.GetBaseType: PTypeInfo;
  3076. begin
  3077. Result := DerefTypeInfoPtr(BaseTypeRef);
  3078. end;
  3079. function TTypeData.GetCompType: PTypeInfo;
  3080. begin
  3081. Result := DerefTypeInfoPtr(CompTypeRef);
  3082. end;
  3083. function TTypeData.GetParentInfo: PTypeInfo;
  3084. begin
  3085. Result := DerefTypeInfoPtr(ParentInfoRef);
  3086. end;
  3087. {$ifndef VER3_0}
  3088. function TTypeData.GetRecInitData: PRecInitData;
  3089. begin
  3090. Result := PRecInitData(aligntoptr(PTypeData(RecInitInfo+2+PByte(RecInitInfo+1)^)));
  3091. end;
  3092. {$endif}
  3093. function TTypeData.GetHelperParent: PTypeInfo;
  3094. begin
  3095. Result := DerefTypeInfoPtr(HelperParentRef);
  3096. end;
  3097. function TTypeData.GetExtendedInfo: PTypeInfo;
  3098. begin
  3099. Result := DerefTypeInfoPtr(ExtendedInfoRef);
  3100. end;
  3101. function TTypeData.GetIntfParent: PTypeInfo;
  3102. begin
  3103. Result := DerefTypeInfoPtr(IntfParentRef);
  3104. end;
  3105. function TTypeData.GetRawIntfParent: PTypeInfo;
  3106. begin
  3107. Result := DerefTypeInfoPtr(RawIntfParentRef);
  3108. end;
  3109. function TTypeData.GetIIDStr: ShortString;
  3110. begin
  3111. Result := PShortString(AlignTypeData(Pointer(@RawIntfUnit) + Length(RawIntfUnit) + 1))^;
  3112. end;
  3113. function TTypeData.GetElType: PTypeInfo;
  3114. begin
  3115. Result := DerefTypeInfoPtr(elTypeRef);
  3116. end;
  3117. function TTypeData.GetElType2: PTypeInfo;
  3118. begin
  3119. Result := DerefTypeInfoPtr(elType2Ref);
  3120. end;
  3121. function TTypeData.GetInstanceType: PTypeInfo;
  3122. begin
  3123. Result := DerefTypeInfoPtr(InstanceTypeRef);
  3124. end;
  3125. function TTypeData.GetRefType: PTypeInfo;
  3126. begin
  3127. Result := DerefTypeInfoPtr(RefTypeRef);
  3128. end;
  3129. { TPropData }
  3130. function TPropData.GetProp(Index: Word): PPropInfo;
  3131. begin
  3132. if Index >= PropCount then
  3133. Result := Nil
  3134. else
  3135. begin
  3136. Result := PPropInfo(aligntoptr(PByte(@PropCount) + SizeOf(PropCount)));
  3137. while Index > 0 do
  3138. begin
  3139. Result := aligntoptr(Result^.Tail);
  3140. Dec(Index);
  3141. end;
  3142. end;
  3143. end;
  3144. function TPropData.GetTail: Pointer;
  3145. begin
  3146. if PropCount = 0 then
  3147. Result := PByte(@PropCount) + SizeOf(PropCount)
  3148. else
  3149. Result := Prop[PropCount - 1]^.Tail;
  3150. end;
  3151. { TPropInfo }
  3152. function TPropInfo.GetPropType: PTypeInfo;
  3153. begin
  3154. Result := DerefTypeInfoPtr(PropTypeRef);
  3155. end;
  3156. function TPropInfo.GetTail: Pointer;
  3157. begin
  3158. Result := PByte(@Name[0]) + SizeOf(Name[0]) + Length(Name);
  3159. end;
  3160. function TPropInfo.GetNext: PPropInfo;
  3161. begin
  3162. Result := PPropInfo(aligntoptr(Tail));
  3163. end;
  3164. type
  3165. TElementAlias = record
  3166. Ordinal : Integer;
  3167. Alias : string;
  3168. end;
  3169. TElementAliasArray = Array of TElementAlias;
  3170. PElementAliasArray = ^TElementAliasArray;
  3171. TEnumeratedAliases = record
  3172. TypeInfo: PTypeInfo;
  3173. Aliases: TElementAliasArray;
  3174. end;
  3175. TEnumeratedAliasesArray = Array of TEnumeratedAliases;
  3176. Var
  3177. EnumeratedAliases : TEnumeratedAliasesArray;
  3178. Function IndexOfEnumeratedAliases(aTypeInfo : PTypeInfo) : integer;
  3179. begin
  3180. Result:=High(EnumeratedAliases);
  3181. while (Result>=0) and (EnumeratedAliases[Result].TypeInfo<>aTypeInfo) do
  3182. Dec(Result);
  3183. end;
  3184. Function GetEnumeratedAliases(aTypeInfo : PTypeInfo) : PElementAliasArray;
  3185. Var
  3186. I : integer;
  3187. begin
  3188. I:=IndexOfEnumeratedAliases(aTypeInfo);
  3189. if I=-1 then
  3190. Result:=Nil
  3191. else
  3192. Result:=@EnumeratedAliases[i].Aliases
  3193. end;
  3194. Function AddEnumeratedAliases(aTypeInfo : PTypeInfo) : PElementAliasArray;
  3195. Var
  3196. L : Integer;
  3197. begin
  3198. L:=Length(EnumeratedAliases);
  3199. SetLength(EnumeratedAliases,L+1);
  3200. EnumeratedAliases[L].TypeInfo:=aTypeInfo;
  3201. Result:=@EnumeratedAliases[L].Aliases;
  3202. end;
  3203. procedure RemoveEnumElementAliases(aTypeInfo: PTypeInfo);
  3204. Var
  3205. I,L : integer;
  3206. A : TEnumeratedAliases;
  3207. begin
  3208. I:=IndexOfEnumeratedAliases(aTypeInfo);
  3209. if I=-1 then
  3210. exit;
  3211. A:=EnumeratedAliases[i];
  3212. A.Aliases:=Nil;
  3213. A.TypeInfo:=Nil;
  3214. L:=High(EnumeratedAliases);
  3215. EnumeratedAliases[i]:=EnumeratedAliases[L];
  3216. EnumeratedAliases[L]:=A;
  3217. SetLength(EnumeratedAliases,L);
  3218. end;
  3219. Resourcestring
  3220. SErrNotAnEnumerated = 'Type information points to non-enumerated type';
  3221. SErrInvalidEnumeratedCount = 'Invalid number of enumerated values';
  3222. SErrDuplicateEnumerated = 'Duplicate alias for enumerated value';
  3223. procedure AddEnumElementAliases(aTypeInfo: PTypeInfo; const aNames: array of string; aStartValue: Integer = 0);
  3224. var
  3225. Aliases: PElementAliasArray;
  3226. A : TElementAliasArray;
  3227. L, I, J : Integer;
  3228. N : String;
  3229. PT : PTypeData;
  3230. begin
  3231. if (aTypeInfo^.Kind<>tkEnumeration) then
  3232. raise EArgumentException.Create(SErrNotAnEnumerated);
  3233. PT:=GetTypeData(aTypeInfo);
  3234. if (High(aNames)=-1) or ((aStartValue+High(aNames))> PT^.MaxValue) then
  3235. raise EArgumentException.Create(SErrInvalidEnumeratedCount);
  3236. Aliases:=GetEnumeratedAliases(aTypeInfo);
  3237. if (Aliases=Nil) then
  3238. Aliases:=AddEnumeratedAliases(aTypeInfo);
  3239. A:=Aliases^;
  3240. I:=0;
  3241. L:=Length(a);
  3242. SetLength(a,L+High(aNames)+1);
  3243. try
  3244. for N in aNames do
  3245. begin
  3246. for J:=0 to (L+I)-1 do
  3247. if SameText(N,A[J].Alias) then
  3248. raise EArgumentException.Create(SErrDuplicateEnumerated);
  3249. with A[L+I] do
  3250. begin
  3251. Ordinal:=aStartValue+I;
  3252. alias:=N;
  3253. end;
  3254. Inc(I);
  3255. end;
  3256. finally
  3257. // In case of exception, we need to correct the length.
  3258. if Length(A)<>I+L then
  3259. SetLength(A,I+L);
  3260. Aliases^:=A;
  3261. end;
  3262. end;
  3263. function GetEnumeratedAliasValue(aTypeInfo: PTypeInfo; const aName: string): Integer;
  3264. var
  3265. I : Integer;
  3266. Aliases: PElementAliasArray;
  3267. begin
  3268. Result:=-1;
  3269. Aliases:=GetEnumeratedAliases(aTypeInfo);
  3270. if (Aliases=Nil) then
  3271. Exit;
  3272. I:=High(Aliases^);
  3273. While (Result=-1) and (I>=0) do
  3274. begin
  3275. if SameText(Aliases^[I].Alias, aName) then
  3276. Result:=Aliases^[I].Ordinal;
  3277. Dec(I);
  3278. end;
  3279. end;
  3280. end.