typinfo.pp 153 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184
  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. {$IFNDEF FPC_DOTTEDUNITS}
  14. unit TypInfo;
  15. {$ENDIF FPC_DOTTEDUNITS}
  16. interface
  17. {$MODE objfpc}
  18. {$MODESWITCH AdvancedRecords}
  19. {$inline on}
  20. {$macro on}
  21. {$h+}
  22. {$IFDEF FPC_DOTTEDUNITS}
  23. uses System.SysUtils;
  24. {$ELSE FPC_DOTTEDUNITS}
  25. uses SysUtils;
  26. {$ENDIF FPC_DOTTEDUNITS}
  27. // temporary types:
  28. type
  29. {$MINENUMSIZE 1 this saves a lot of memory }
  30. {$ifdef FPC_RTTI_PACKSET1}
  31. { for Delphi compatibility }
  32. {$packset 1}
  33. {$endif}
  34. { this alias and the following constant aliases are for backwards
  35. compatibility before TTypeKind was moved to System unit }
  36. TTypeKind = System.TTypeKind;
  37. const
  38. tkUnknown = System.tkUnknown;
  39. tkInteger = System.tkInteger;
  40. tkChar = System.tkChar;
  41. tkEnumeration = System.tkEnumeration;
  42. tkFloat = System.tkFloat;
  43. tkSet = System.tkSet;
  44. tkMethod = System.tkMethod;
  45. tkSString = System.tkSString;
  46. tkLString = System.tkLString;
  47. tkAString = System.tkAString;
  48. tkWString = System.tkWString;
  49. tkVariant = System.tkVariant;
  50. tkArray = System.tkArray;
  51. tkRecord = System.tkRecord;
  52. tkInterface = System.tkInterface;
  53. tkClass = System.tkClass;
  54. tkObject = System.tkObject;
  55. tkWChar = System.tkWChar;
  56. tkBool = System.tkBool;
  57. tkInt64 = System.tkInt64;
  58. tkQWord = System.tkQWord;
  59. tkDynArray = System.tkDynArray;
  60. tkInterfaceRaw = System.tkInterfaceRaw;
  61. tkProcVar = System.tkProcVar;
  62. tkUString = System.tkUString;
  63. tkUChar = System.tkUChar;
  64. tkHelper = System.tkHelper;
  65. tkFile = System.tkFile;
  66. tkClassRef = System.tkClassRef;
  67. tkPointer = System.tkPointer;
  68. type
  69. TOrdType = (otSByte,otUByte,otSWord,otUWord,otSLong,otULong,otSQWord,otUQWord);
  70. {$ifndef FPUNONE}
  71. TFloatType = (ftSingle,ftDouble,ftExtended,ftComp,ftCurr);
  72. {$endif}
  73. TMethodKind = (mkProcedure,mkFunction,mkConstructor,mkDestructor,
  74. mkClassProcedure,mkClassFunction,mkClassConstructor,
  75. mkClassDestructor,mkOperatorOverload);
  76. TParamFlag = (pfVar,pfConst,pfArray,pfAddress,pfReference,pfOut,pfConstRef
  77. {$ifndef VER3_0},pfHidden,pfHigh,pfSelf,pfVmt,pfResult{$endif VER3_0}
  78. );
  79. TParamFlags = set of TParamFlag;
  80. TIntfFlag = (ifHasGuid,ifDispInterface,ifDispatch,ifHasStrGUID);
  81. TIntfFlags = set of TIntfFlag;
  82. TIntfFlagsBase = set of TIntfFlag;
  83. // don't rely on integer values of TCallConv since it includes all conventions
  84. // which both Delphi and FPC support. In the future Delphi can support more and
  85. // FPC's own conventions will be shifted/reordered accordingly
  86. TCallConv = (ccReg, ccCdecl, ccPascal, ccStdCall, ccSafeCall,
  87. ccCppdecl, ccFar16, ccOldFPCCall, ccInternProc,
  88. ccSysCall, ccSoftFloat, ccMWPascal);
  89. {$push}
  90. {$scopedenums on}
  91. TSubRegister = (
  92. None,
  93. Lo,
  94. Hi,
  95. Word,
  96. DWord,
  97. QWord,
  98. FloatSingle,
  99. FloatDouble,
  100. FloatQuad,
  101. MultiMediaSingle,
  102. MultiMediaDouble,
  103. MultiMediaWhole,
  104. MultiMediaX,
  105. MultiMediaY
  106. );
  107. TRegisterType = (
  108. Invalid,
  109. Int,
  110. FP,
  111. MMX,
  112. MultiMedia,
  113. Special,
  114. Address
  115. );
  116. {$pop}
  117. {$IF FPC_FULLVERSION>=30301}
  118. {$DEFINE HAVE_INVOKEHELPER}
  119. {$DEFINE HAVE_HIDDENTHUNKCLASS}
  120. {$ENDIF}
  121. {$MINENUMSIZE DEFAULT}
  122. const
  123. ptField = 0;
  124. ptStatic = 1;
  125. ptVirtual = 2;
  126. ptConst = 3;
  127. RTTIFlagVisibilityMask = 3;
  128. RTTIFlagStrictVisibility = 1 shl 2;
  129. type
  130. TTypeKinds = set of TTypeKind;
  131. ShortStringBase = string[255];
  132. {$IFDEF HAVE_INVOKEHELPER}
  133. TInvokeHelper = procedure(Instance : Pointer; Args : PPointer);
  134. {$ENDIF}
  135. PParameterLocation = ^TParameterLocation;
  136. TParameterLocation =
  137. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  138. packed
  139. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  140. record
  141. private
  142. LocType: Byte;
  143. function GetRegType: TRegisterType; inline;
  144. function GetReference: Boolean; inline;
  145. function GetShiftVal: Int8; inline;
  146. public
  147. RegSub: TSubRegister;
  148. RegNumber: Word;
  149. { Stack offset if Reference, ShiftVal if not }
  150. Offset: SizeInt;
  151. { if Reference then the register is the index register otherwise the
  152. register in wihch (part of) the parameter resides }
  153. property Reference: Boolean read GetReference;
  154. property RegType: TRegisterType read GetRegType;
  155. { if Reference, otherwise 0 }
  156. property ShiftVal: Int8 read GetShiftVal;
  157. end;
  158. PParameterLocations = ^TParameterLocations;
  159. TParameterLocations =
  160. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  161. packed
  162. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  163. record
  164. private
  165. function GetLocation(aIndex: Byte): PParameterLocation; inline;
  166. function GetTail: Pointer; inline;
  167. public
  168. Count: Byte;
  169. property Location[Index: Byte]: PParameterLocation read GetLocation;
  170. property Tail: Pointer read GetTail;
  171. end;
  172. { The following three types are essentially copies from the TObject.FieldAddress
  173. function. If something is changed there, change it here as well }
  174. PVmtFieldClassTab = ^TVmtFieldClassTab;
  175. TVmtFieldClassTab =
  176. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  177. packed
  178. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  179. record
  180. Count: Word;
  181. ClassRef: array[0..0] of PClass;
  182. end;
  183. PVmtFieldEntry = ^TVmtFieldEntry;
  184. TVmtFieldEntry =
  185. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  186. packed
  187. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  188. record
  189. private
  190. function GetNext: PVmtFieldEntry; inline;
  191. function GetTail: Pointer; inline;
  192. public
  193. FieldOffset: SizeUInt;
  194. TypeIndex: Word;
  195. Name: ShortString;
  196. property Tail: Pointer read GetTail;
  197. property Next: PVmtFieldEntry read GetNext;
  198. end;
  199. PVmtFieldTable = ^TVmtFieldTable;
  200. TVmtFieldTable =
  201. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  202. packed
  203. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  204. record
  205. private
  206. function GetField(aIndex: Word): PVmtFieldEntry;
  207. function GetNext: Pointer;
  208. function GetTail: Pointer;
  209. public
  210. Count: Word;
  211. ClassTab: PVmtFieldClassTab;
  212. { should be array[Word] of TFieldInfo; but
  213. Elements have variant size! force at least proper alignment }
  214. Fields: array[0..0] of TVmtFieldEntry;
  215. property Field[aIndex: Word]: PVmtFieldEntry read GetField;
  216. property Tail: Pointer read GetTail;
  217. property Next: Pointer read GetNext;
  218. end;
  219. {$PACKRECORDS 1}
  220. TTypeInfo = record
  221. Kind : TTypeKind;
  222. Name : ShortString;
  223. // here the type data follows as TTypeData record
  224. end;
  225. PTypeInfo = ^TTypeInfo;
  226. PPTypeInfo = ^PTypeInfo;
  227. PPropData = ^TPropData;
  228. { Note: these are only for backwards compatibility. New type references should
  229. only use PPTypeInfo directly! }
  230. {$ifdef ver3_0}
  231. {$define TypeInfoPtr := PTypeInfo}
  232. {$else}
  233. {$define TypeInfoPtr := PPTypeInfo}
  234. {$endif}
  235. {$PACKRECORDS C}
  236. {$if not defined(VER3_0) and not defined(VER3_2)}
  237. {$define PROVIDE_ATTR_TABLE}
  238. {$endif}
  239. TAttributeProc = function : TCustomAttribute;
  240. TAttributeEntry =
  241. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  242. packed
  243. {$endif}
  244. record
  245. AttrType: PPTypeInfo;
  246. AttrCtor: CodePointer;
  247. AttrProc: TAttributeProc;
  248. ArgLen: Word;
  249. ArgData: Pointer;
  250. end;
  251. {$ifdef CPU16}
  252. TAttributeEntryList = array[0..(High(SizeUInt) div SizeOf(TAttributeEntry))-1] of TAttributeEntry;
  253. {$else CPU16}
  254. TAttributeEntryList = array[0..$ffff] of TAttributeEntry;
  255. {$endif CPU16}
  256. TAttributeTable =
  257. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  258. packed
  259. {$endif}
  260. record
  261. AttributeCount: word;
  262. AttributesList: TAttributeEntryList;
  263. end;
  264. PAttributeTable = ^TAttributeTable;
  265. // members of TTypeData
  266. TArrayTypeData =
  267. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  268. packed
  269. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  270. record
  271. private
  272. function GetElType: PTypeInfo; inline;
  273. function GetDims(aIndex: Byte): PTypeInfo; inline;
  274. public
  275. property ElType: PTypeInfo read GetElType;
  276. property Dims[Index: Byte]: PTypeInfo read GetDims;
  277. public
  278. Size: SizeInt;
  279. ElCount: SizeInt;
  280. ElTypeRef: TypeInfoPtr;
  281. DimCount: Byte;
  282. DimsRef: array[0..255] of TypeInfoPtr;
  283. end;
  284. PManagedField = ^TManagedField;
  285. TManagedField =
  286. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  287. packed
  288. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  289. record
  290. private
  291. function GetTypeRef: PTypeInfo; inline;
  292. public
  293. property TypeRef: PTypeInfo read GetTypeRef;
  294. public
  295. TypeRefRef: TypeInfoPtr;
  296. FldOffset: SizeInt;
  297. end;
  298. PInitManagedField = ^TInitManagedField;
  299. TInitManagedField = TManagedField;
  300. PProcedureParam = ^TProcedureParam;
  301. TProcedureParam =
  302. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  303. packed
  304. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  305. record
  306. private
  307. function GetParamType: PTypeInfo; inline;
  308. function GetFlags: Byte; inline;
  309. public
  310. property ParamType: PTypeInfo read GetParamType;
  311. property Flags: Byte read GetFlags;
  312. public
  313. ParamFlags: TParamFlags;
  314. ParamTypeRef: TypeInfoPtr;
  315. Name: ShortString;
  316. end;
  317. PProcedureSignature = ^TProcedureSignature;
  318. TProcedureSignature =
  319. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  320. packed
  321. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  322. record
  323. private
  324. function GetResultType: PTypeInfo; inline;
  325. public
  326. property ResultType: PTypeInfo read GetResultType;
  327. public
  328. Flags: Byte;
  329. CC: TCallConv;
  330. ResultTypeRef: TypeInfoPtr;
  331. ParamCount: Byte;
  332. {Params: array[0..ParamCount - 1] of TProcedureParam;}
  333. function GetParam(ParamIndex: Integer): PProcedureParam;
  334. end;
  335. PVmtMethodParam = ^TVmtMethodParam;
  336. TVmtMethodParam =
  337. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  338. packed
  339. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  340. record
  341. private
  342. function GetTail: Pointer; inline;
  343. function GetNext: PVmtMethodParam; inline;
  344. function GetName: ShortString; inline;
  345. public
  346. ParamType: PPTypeInfo;
  347. Flags: TParamFlags;
  348. NamePtr: PShortString;
  349. ParaLocs: PParameterLocations;
  350. property Name: ShortString read GetName;
  351. property Tail: Pointer read GetTail;
  352. property Next: PVmtMethodParam read GetNext;
  353. end;
  354. TVmtMethodParamArray = array[0..{$ifdef cpu16}(32768 div sizeof(TVmtMethodParam))-2{$else}65535{$endif}] of TVmtMethodParam;
  355. PVmtMethodParamArray = ^TVmtMethodParamArray;
  356. PIntfMethodEntry = ^TIntfMethodEntry;
  357. TIntfMethodEntry =
  358. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  359. packed
  360. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  361. record
  362. private
  363. function GetParam(Index: Word): PVmtMethodParam;
  364. function GetResultLocs: PParameterLocations; inline;
  365. function GetTail: Pointer; inline;
  366. function GetNext: PIntfMethodEntry; inline;
  367. function GetName: ShortString; inline;
  368. public
  369. ResultType: PPTypeInfo;
  370. CC: TCallConv;
  371. Kind: TMethodKind;
  372. ParamCount: Word;
  373. StackSize: SizeInt;
  374. {$IFDEF HAVE_INVOKEHELPER}
  375. InvokeHelper : TInvokeHelper;
  376. {$ENDIF}
  377. NamePtr: PShortString;
  378. { Params: array[0..ParamCount - 1] of TVmtMethodParam }
  379. { ResultLocs: PParameterLocations (if ResultType != Nil) }
  380. property Name: ShortString read GetName;
  381. property Param[Index: Word]: PVmtMethodParam read GetParam;
  382. property ResultLocs: PParameterLocations read GetResultLocs;
  383. property Tail: Pointer read GetTail;
  384. property Next: PIntfMethodEntry read GetNext;
  385. end;
  386. PIntfMethodTable = ^TIntfMethodTable;
  387. TIntfMethodTable =
  388. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  389. packed
  390. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  391. record
  392. private
  393. function GetMethod(Index: Word): PIntfMethodEntry;
  394. public
  395. Count: Word;
  396. { $FFFF if there is no further info, or the value of Count }
  397. RTTICount: Word;
  398. { Entry: array[0..Count - 1] of TIntfMethodEntry }
  399. property Method[Index: Word]: PIntfMethodEntry read GetMethod;
  400. end;
  401. PVmtMethodEntry = ^TVmtMethodEntry;
  402. TVmtMethodEntry =
  403. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  404. packed
  405. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  406. record
  407. Name: PShortString;
  408. CodeAddress: CodePointer;
  409. end;
  410. PVmtMethodTable = ^TVmtMethodTable;
  411. TVmtMethodTable =
  412. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  413. packed
  414. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  415. record
  416. private
  417. function GetEntry(Index: LongWord): PVmtMethodEntry; inline;
  418. public
  419. Count: LongWord;
  420. property Entry[Index: LongWord]: PVmtMethodEntry read GetEntry;
  421. private
  422. Entries: array[0..0] of TVmtMethodEntry;
  423. end;
  424. PVmtMethodExEntry = ^TVmtMethodExEntry;
  425. TVmtMethodExEntry =
  426. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  427. packed
  428. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  429. record
  430. private
  431. function GetParamsStart: PByte; inline;
  432. function GetMethodVisibility: TVisibilityClass;
  433. function GetParam(Index: Word): PVmtMethodParam;
  434. function GetResultLocs: PParameterLocations; inline;
  435. function GetStrictVisibility: Boolean;
  436. function GetTail: Pointer; inline;
  437. function GetNext: PVmtMethodExEntry; inline;
  438. function GetName: ShortString; inline;
  439. public
  440. ResultType: PPTypeInfo;
  441. CC: TCallConv;
  442. Kind: TMethodKind;
  443. ParamCount: Word;
  444. StackSize: SizeInt;
  445. {$IFDEF HAVE_INVOKEHELPER}
  446. InvokeHelper : TInvokeHelper;
  447. {$ENDIF}
  448. NamePtr: PShortString;
  449. Flags: Byte;
  450. VmtIndex: Smallint;
  451. property Name: ShortString read GetName;
  452. property Param[Index: Word]: PVmtMethodParam read GetParam;
  453. property ResultLocs: PParameterLocations read GetResultLocs;
  454. property Tail: Pointer read GetTail;
  455. property Next: PVmtMethodExEntry read GetNext;
  456. property MethodVisibility: TVisibilityClass read GetMethodVisibility;
  457. property StrictVisibility: Boolean read GetStrictVisibility;
  458. Private
  459. Params: array[0..0] of TVmtMethodParam;
  460. { ResultLocs: PParameterLocations (if ResultType != Nil) }
  461. end;
  462. TVmtMethodExEntryArray = array[0.. {$ifdef cpu16}(32768 div sizeof(TVmtMethodExEntry))-2{$else}65535{$endif}] of TVmtMethodExEntry;
  463. PVmtMethodExEntryArray = ^TVmtMethodExEntryArray;
  464. PVmtMethodExTable = ^TVmtMethodExTable;
  465. TVmtMethodExTable =
  466. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  467. packed
  468. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  469. record
  470. private
  471. Function GetMethod(Index: Word): PVmtMethodExEntry;
  472. public
  473. // LegacyCount,Count1: Word;
  474. Count: Word;
  475. property Method[Index: Word]: PVmtMethodExEntry read GetMethod;
  476. private
  477. Entries: array[0..0] of TVmtMethodExEntry
  478. end;
  479. PExtendedMethodInfoTable = ^TExtendedMethodInfoTable;
  480. TExtendedMethodInfoTable = array[0..{$ifdef cpu16}(32768 div sizeof(PVmtMethodExEntry))-2{$else}65535{$endif}] of PVmtMethodExEntry;
  481. PExtendedVmtFieldEntry = ^TExtendedVmtFieldEntry;
  482. PExtendedFieldEntry = PExtendedVmtFieldEntry; // For records, there is no VMT, but currently the layout is identical
  483. TExtendedVmtFieldEntry =
  484. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  485. packed
  486. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  487. record
  488. private
  489. function GetNext: PVmtFieldEntry;
  490. function GetStrictVisibility: Boolean;
  491. function GetTail: Pointer;
  492. function GetVisibility: TVisibilityClass;
  493. public
  494. FieldOffset: SizeUInt;
  495. FieldType: PPTypeInfo;
  496. Flags: Byte;
  497. Name: PShortString;
  498. property FieldVisibility: TVisibilityClass read GetVisibility;
  499. property StrictVisibility: Boolean read GetStrictVisibility;
  500. property Tail: Pointer read GetTail;
  501. property Next: PVmtFieldEntry read GetNext;
  502. end;
  503. PVmtExtendedFieldTable = ^TVmtExtendedFieldTable;
  504. PExtendedFieldTable = PVmtExtendedFieldTable; // For records, there is no VMT, but currently the layout is identical.
  505. TVmtExtendedFieldTable =
  506. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  507. packed
  508. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  509. record
  510. private
  511. function GetField(aIndex: Word): PExtendedVmtFieldEntry;
  512. function GetTail: Pointer;
  513. public
  514. FieldCount: Word;
  515. property Field[aIndex: Word]: PExtendedVmtFieldEntry read GetField;
  516. property Tail: Pointer read GetTail;
  517. private
  518. Entries: array[0..0] of TExtendedVmtFieldEntry;
  519. end;
  520. PExtendedFieldInfoTable = ^TExtendedFieldInfoTable;
  521. TExtendedFieldInfoTable = array[0..{$ifdef cpu16}(32768 div sizeof(PExtendedVmtFieldEntry))-2{$else}65535{$endif}] of PExtendedVmtFieldEntry;
  522. TRecOpOffsetEntry =
  523. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  524. packed
  525. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  526. record
  527. ManagementOperator: CodePointer;
  528. FieldOffset: SizeUInt;
  529. end;
  530. TRecOpOffsetTable =
  531. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  532. packed
  533. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  534. record
  535. Count: LongWord;
  536. Entries: array[0..0] of TRecOpOffsetEntry;
  537. end;
  538. PRecOpOffsetTable = ^TRecOpOffsetTable;
  539. PRecInitData = ^TRecInitData;
  540. TRecInitData =
  541. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  542. packed
  543. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  544. record
  545. {$ifdef PROVIDE_ATTR_TABLE}
  546. AttributeTable : PAttributeTable;
  547. {$endif}
  548. case TTypeKind of
  549. tkRecord: (
  550. Terminator: Pointer;
  551. Size: Longint;
  552. {$ifndef VER3_0}
  553. InitOffsetOp: PRecOpOffsetTable;
  554. ManagementOp: Pointer;
  555. {$endif}
  556. ManagedFieldCount: Longint;
  557. { ManagedFields: array[0..ManagedFieldCount - 1] of TInitManagedField ; }
  558. );
  559. { include for proper alignment }
  560. tkInt64: (
  561. dummy : Int64
  562. );
  563. end;
  564. PRecMethodParam = PVmtMethodParam;
  565. TRecMethodParam = TVmtMethodParam;
  566. PRecMethodExEntry = ^TRecMethodExEntry;
  567. TRecMethodExEntry =
  568. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  569. packed
  570. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  571. record
  572. private
  573. function GetParamsStart: PByte; inline;
  574. function GetMethodVisibility: TVisibilityClass;
  575. function GetParam(Index: Word): PRecMethodParam;
  576. function GetResultLocs: PParameterLocations; inline;
  577. function GetStrictVisibility: Boolean;
  578. function GetTail: Pointer; inline;
  579. function GetNext: PRecMethodExEntry; inline;
  580. function GetName: ShortString; inline;
  581. public
  582. ResultType: PPTypeInfo;
  583. CC: TCallConv;
  584. Kind: TMethodKind;
  585. ParamCount: Word;
  586. StackSize: SizeInt;
  587. {$IFDEF HAVE_INVOKEHELPER}
  588. InvokeHelper : TInvokeHelper;
  589. {$ENDIF}
  590. NamePtr: PShortString;
  591. Flags: Byte;
  592. { Params: array[0..ParamCount - 1] of TRecMethodParam }
  593. { ResultLocs: PParameterLocations (if ResultType != Nil) }
  594. property Name: ShortString read GetName;
  595. property Param[Index: Word]: PRecMethodParam read GetParam;
  596. property ResultLocs: PParameterLocations read GetResultLocs;
  597. property Tail: Pointer read GetTail;
  598. property Next: PRecMethodExEntry read GetNext;
  599. property MethodVisibility: TVisibilityClass read GetMethodVisibility;
  600. property StrictVisibility: Boolean read GetStrictVisibility;
  601. end;
  602. PRecMethodExTable = ^TRecMethodExTable;
  603. TRecMethodExTable =
  604. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  605. packed
  606. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  607. record
  608. private
  609. Function GetMethod(Index: Word): PRecMethodExEntry;
  610. public
  611. // LegacyCount,Count1: Word;
  612. Count: Word;
  613. { Entry: array[0..Count - 1] of TRecMethodExEntry }
  614. property Method[Index: Word]: PRecMethodExEntry read GetMethod;
  615. end;
  616. PRecordMethodInfoTable = ^TRecordMethodInfoTable;
  617. TRecordMethodInfoTable = array[0..{$ifdef cpu16}(32768 div sizeof(PRecMethodExEntry))-2{$else}65535{$endif}] of PRecMethodExEntry;
  618. PInterfaceData = ^TInterfaceData;
  619. TInterfaceData =
  620. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  621. packed
  622. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  623. record
  624. private
  625. function GetUnitName: ShortString; inline;
  626. function GetPropertyTable: PPropData; inline;
  627. function GetMethodTable: PIntfMethodTable; inline;
  628. public
  629. property UnitName: ShortString read GetUnitName;
  630. property PropertyTable: PPropData read GetPropertyTable;
  631. property MethodTable: PIntfMethodTable read GetMethodTable;
  632. public
  633. {$ifdef PROVIDE_ATTR_TABLE}
  634. AttributeTable : PAttributeTable;
  635. {$endif}
  636. case TTypeKind of
  637. tkInterface: (
  638. Parent: PPTypeInfo;
  639. Flags: TIntfFlagsBase;
  640. GUID: TGUID;
  641. {$IFDEF HAVE_HIDDENTHUNKCLASS}
  642. ThunkClass : PPTypeInfo;
  643. {$ENDIF}
  644. UnitNameField: ShortString;
  645. { PropertyTable: TPropData }
  646. { MethodTable: TIntfMethodTable }
  647. );
  648. { include for proper alignment }
  649. tkInt64: (
  650. dummy : Int64
  651. );
  652. {$ifndef FPUNONE}
  653. tkFloat:
  654. (FloatType : TFloatType
  655. );
  656. {$endif}
  657. end;
  658. PInterfaceRawData = ^TInterfaceRawData;
  659. TInterfaceRawData =
  660. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  661. packed
  662. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  663. record
  664. private
  665. function GetUnitName: ShortString; inline;
  666. function GetIIDStr: ShortString; inline;
  667. function GetPropertyTable: PPropData; inline;
  668. function GetMethodTable: PIntfMethodTable; inline;
  669. public
  670. property UnitName: ShortString read GetUnitName;
  671. property IIDStr: ShortString read GetIIDStr;
  672. property PropertyTable: PPropData read GetPropertyTable;
  673. property MethodTable: PIntfMethodTable read GetMethodTable;
  674. public
  675. {$ifdef PROVIDE_ATTR_TABLE}
  676. AttributeTable : PAttributeTable;
  677. {$endif}
  678. case TTypeKind of
  679. tkInterface: (
  680. Parent: PPTypeInfo;
  681. Flags : TIntfFlagsBase;
  682. IID: TGUID;
  683. {$IFDEF HAVE_HIDDENTHUNKCLASS}
  684. ThunkClass : PPTypeInfo;
  685. {$ENDIF}
  686. UnitNameField: ShortString;
  687. { IIDStr: ShortString; }
  688. { PropertyTable: TPropData }
  689. );
  690. { include for proper alignment }
  691. tkInt64: (
  692. dummy : Int64
  693. );
  694. {$ifndef FPUNONE}
  695. tkFloat:
  696. (FloatType : TFloatType
  697. );
  698. {$endif}
  699. end;
  700. PPropDataEx = ^TPropDataEx;
  701. PClassData = ^TClassData;
  702. TClassData =
  703. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  704. packed
  705. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  706. record
  707. private
  708. function GetExMethodTable: PVmtMethodExTable;
  709. function GetExPropertyTable: PPropDataEx;
  710. function GetUnitName: ShortString; inline;
  711. function GetPropertyTable: PPropData; inline;
  712. public
  713. property UnitName: ShortString read GetUnitName;
  714. property PropertyTable: PPropData read GetPropertyTable;
  715. property ExRTTITable: PPropDataEx read GetExPropertyTable;
  716. property ExMethodTable : PVmtMethodExTable Read GetExMethodTable;
  717. public
  718. {$ifdef PROVIDE_ATTR_TABLE}
  719. AttributeTable : PAttributeTable;
  720. {$endif}
  721. case TTypeKind of
  722. tkClass: (
  723. ClassType : TClass;
  724. Parent : PPTypeInfo;
  725. PropCount : SmallInt;
  726. UnitNameField : ShortString;
  727. { PropertyTable: TPropData }
  728. { ExRTTITable: TPropDataex }
  729. );
  730. { include for proper alignment }
  731. tkInt64: (
  732. dummy: Int64;
  733. );
  734. {$ifndef FPUNONE}
  735. tkFloat: (
  736. FloatType : TFloatType
  737. );
  738. {$endif}
  739. end;
  740. PRecordMethodTable = ^TRecordMethodTable;
  741. TRecordMethodTable = TRecMethodExTable;
  742. PRecordData = ^TRecordData;
  743. TRecordData =
  744. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  745. packed
  746. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  747. record
  748. private
  749. function GetExPropertyTable: PPropDataEx;
  750. function GetExtendedFieldCount: Longint;
  751. function GetExtendedFields: PExtendedFieldTable;
  752. function GetMethodTable: PRecordMethodTable;
  753. Public
  754. property ExtendedFields: PExtendedFieldTable read GetExtendedFields;
  755. property ExtendedFieldCount: Longint read GetExtendedFieldCount;
  756. property MethodTable: PRecordMethodTable read GetMethodTable;
  757. property ExRTTITable: PPropDataEx read GetExPropertyTable;
  758. public
  759. {$ifdef PROVIDE_ATTR_TABLE}
  760. AttributeTable: PAttributeTable;
  761. {$endif}
  762. case TTypeKind of
  763. tkRecord:
  764. (
  765. {$ifndef VER3_0}
  766. RecInitInfo: Pointer; { points to TTypeInfo followed by init table }
  767. {$endif VER3_0}
  768. RecSize: Longint;
  769. case Boolean of
  770. False: (ManagedFldCount: Longint deprecated 'Use RecInitData^.ManagedFieldCount or TotalFieldCount depending on your use case');
  771. True: (TotalFieldCount: Longint);
  772. {ManagedFields: array[1..TotalFieldCount] of TManagedField}
  773. { ExtendedFieldsCount : Longint }
  774. { ExtendedFields: array[0..ExtendedFieldsCount-1] of PExtendedFieldEntry }
  775. { MethodTable : TRecordMethodTable }
  776. { Properties }
  777. );
  778. { include for proper alignment }
  779. tkInt64: (
  780. dummy: Int64
  781. );
  782. {$ifndef FPUNONE}
  783. tkFloat:
  784. (FloatType: TFloatType
  785. );
  786. {$endif}
  787. end;
  788. PTypeData = ^TTypeData;
  789. TTypeData =
  790. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  791. packed
  792. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  793. record
  794. private
  795. function GetBaseType: PTypeInfo; inline;
  796. function GetCompType: PTypeInfo; inline;
  797. function GetParentInfo: PTypeInfo; inline;
  798. {$ifndef VER3_0}
  799. function GetRecInitData: PRecInitData; inline;
  800. {$endif}
  801. function GetHelperParent: PTypeInfo; inline;
  802. function GetExtendedInfo: PTypeInfo; inline;
  803. function GetIntfParent: PTypeInfo; inline;
  804. function GetRawIntfParent: PTypeInfo; inline;
  805. function GetIIDStr: ShortString; inline;
  806. function GetElType: PTypeInfo; inline;
  807. function GetElType2: PTypeInfo; inline;
  808. function GetInstanceType: PTypeInfo; inline;
  809. function GetRefType: PTypeInfo; inline;
  810. public
  811. { tkEnumeration }
  812. property BaseType: PTypeInfo read GetBaseType;
  813. { tkSet }
  814. property CompType: PTypeInfo read GetCompType;
  815. { tkClass }
  816. property ParentInfo: PTypeInfo read GetParentInfo;
  817. { tkRecord }
  818. {$ifndef VER3_0}
  819. property RecInitData: PRecInitData read GetRecInitData;
  820. {$endif}
  821. { tkHelper }
  822. property HelperParent: PTypeInfo read GetHelperParent;
  823. property ExtendedInfo: PTypeInfo read GetExtendedInfo;
  824. { tkInterface }
  825. property IntfParent: PTypeInfo read GetIntfParent;
  826. { tkInterfaceRaw }
  827. property RawIntfParent: PTypeInfo read GetRawIntfParent;
  828. property IIDStr: ShortString read GetIIDStr;
  829. { tkDynArray }
  830. property ElType2: PTypeInfo read GetElType2;
  831. property ElType: PTypeInfo read GetElType;
  832. { tkClassRef }
  833. property InstanceType: PTypeInfo read GetInstanceType;
  834. { tkPointer }
  835. property RefType: PTypeInfo read GetRefType;
  836. public
  837. {$ifdef PROVIDE_ATTR_TABLE}
  838. AttributeTable : PAttributeTable;
  839. {$endif}
  840. case TTypeKind of
  841. tkUnKnown,tkLString,tkWString,tkVariant,tkUString:
  842. ();
  843. tkAString:
  844. (CodePage: Word);
  845. {$ifndef VER3_0}
  846. tkInt64,tkQWord,
  847. {$endif VER3_0}
  848. tkInteger,tkChar,tkEnumeration,tkBool,tkWChar,tkSet:
  849. (OrdType : TOrdType;
  850. case TTypeKind of
  851. tkInteger,tkChar,tkEnumeration,tkBool,tkWChar : (
  852. MinValue,MaxValue : Longint;
  853. case TTypeKind of
  854. tkEnumeration:
  855. (
  856. BaseTypeRef : TypeInfoPtr;
  857. NameList : ShortString;
  858. {EnumUnitName: ShortString;})
  859. );
  860. {$ifndef VER3_0}
  861. {tkBool with OrdType=otSQWord }
  862. tkInt64:
  863. (MinInt64Value, MaxInt64Value: Int64);
  864. {tkBool with OrdType=otUQWord }
  865. tkQWord:
  866. (MinQWordValue, MaxQWordValue: QWord);
  867. {$endif VER3_0}
  868. tkSet:
  869. (
  870. {$ifndef VER3_0}
  871. SetSize : SizeInt;
  872. {$endif VER3_0}
  873. CompTypeRef : TypeInfoPtr
  874. )
  875. );
  876. {$ifndef FPUNONE}
  877. tkFloat:
  878. (FloatType : TFloatType);
  879. {$endif}
  880. tkSString:
  881. (MaxLength : Byte);
  882. tkClass:
  883. (ClassType : TClass;
  884. ParentInfoRef : TypeInfoPtr;
  885. PropCount : SmallInt;
  886. UnitName : ShortString;
  887. // here the properties follow as array of TPropInfo:
  888. {
  889. PropData: TPropData;
  890. // Extended RTTI
  891. PropDataEx: TPropDataEx;
  892. ClassAttrData: TAttrData;
  893. ArrayPropCount: Word;
  894. ArrayPropData: array[1..ArrayPropCount] of TArrayPropInfo;
  895. }
  896. );
  897. tkRecord:
  898. (
  899. {$ifndef VER3_0}
  900. RecInitInfo: Pointer; { points to TTypeInfo followed by init table }
  901. {$endif VER3_0}
  902. RecSize: Longint;
  903. case Boolean of
  904. False: (ManagedFldCount: Longint deprecated 'Use RecInitData^.ManagedFieldCount or TotalFieldCount depending on your use case');
  905. True: (TotalFieldCount: Longint);
  906. {ManagedFields: array[1..TotalFieldCount] of TManagedField}
  907. );
  908. tkHelper:
  909. (HelperParentRef : TypeInfoPtr;
  910. ExtendedInfoRef : TypeInfoPtr;
  911. HelperProps : SmallInt;
  912. HelperUnit : ShortString
  913. // here the properties follow as array of TPropInfo
  914. );
  915. tkMethod:
  916. (MethodKind : TMethodKind;
  917. ParamCount : Byte;
  918. case Boolean of
  919. False: (ParamList : array[0..1023] of AnsiChar);
  920. { dummy for proper alignment }
  921. True: (ParamListDummy : Word);
  922. {in reality ParamList is a array[1..ParamCount] of:
  923. record
  924. Flags : TParamFlags;
  925. ParamName : ShortString;
  926. TypeName : ShortString;
  927. end;
  928. followed by
  929. ResultType : ShortString // for mkFunction, mkClassFunction only
  930. ResultTypeRef : PPTypeInfo; // for mkFunction, mkClassFunction only
  931. CC : TCallConv;
  932. ParamTypeRefs : array[1..ParamCount] of PPTypeInfo;}
  933. );
  934. tkProcVar:
  935. (ProcSig: TProcedureSignature);
  936. {$ifdef VER3_0}
  937. tkInt64:
  938. (MinInt64Value, MaxInt64Value: Int64);
  939. tkQWord:
  940. (MinQWordValue, MaxQWordValue: QWord);
  941. {$endif VER3_0}
  942. tkInterface:
  943. (
  944. IntfParentRef: TypeInfoPtr;
  945. IntfFlags : TIntfFlagsBase;
  946. GUID: TGUID;
  947. ThunkClass : PPTypeInfo;
  948. IntfUnit: ShortString;
  949. { PropertyTable: TPropData }
  950. { MethodTable: TIntfMethodTable }
  951. );
  952. tkInterfaceRaw:
  953. (
  954. RawIntfParentRef: TypeInfoPtr;
  955. RawIntfFlags : TIntfFlagsBase;
  956. IID: TGUID;
  957. RawThunkClass : PPTypeInfo;
  958. RawIntfUnit: ShortString;
  959. { IIDStr: ShortString; }
  960. { PropertyTable: TPropData }
  961. );
  962. tkArray:
  963. (ArrayData: TArrayTypeData);
  964. tkDynArray:
  965. (
  966. elSize : PtrUInt;
  967. elType2Ref : TypeInfoPtr;
  968. varType : Longint;
  969. elTypeRef : TypeInfoPtr;
  970. DynUnitName: ShortStringBase
  971. );
  972. tkClassRef:
  973. (InstanceTypeRef: TypeInfoPtr);
  974. tkPointer:
  975. (RefTypeRef: TypeInfoPtr);
  976. end;
  977. PPropInfo = ^TPropInfo;
  978. TPropData =
  979. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  980. packed
  981. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  982. record
  983. private
  984. function GetProp(Index: Word): PPropInfo;
  985. function GetTail: Pointer; inline;
  986. public
  987. PropCount : Word;
  988. PropList : record _alignmentdummy : ptrint; end;
  989. property Prop[Index: Word]: PPropInfo read GetProp;
  990. property Tail: Pointer read GetTail;
  991. end;
  992. TPropInfoEx =
  993. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  994. packed
  995. {$ENDIF FPC_REQUIRES_PROPER_ALIGNMENT}
  996. record
  997. private
  998. function GetStrictVisibility: Boolean;
  999. function GetTail: Pointer;
  1000. function GetVisiblity: TVisibilityClass;
  1001. public
  1002. Flags: Byte;
  1003. Info: PPropInfo;
  1004. // AttrData: TAttrData
  1005. property Tail: Pointer read GetTail;
  1006. property Visibility: TVisibilityClass read GetVisiblity;
  1007. property StrictVisibility: Boolean read GetStrictVisibility;
  1008. end;
  1009. PPropInfoEx = ^TPropInfoEx;
  1010. TPropDataEx =
  1011. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  1012. packed
  1013. {$ENDIF FPC_REQUIRES_PROPER_ALIGNMENT}
  1014. record
  1015. private
  1016. function GetPropEx(Index: Word): PPropInfoEx;
  1017. function GetTail: Pointer; inline;
  1018. public
  1019. PropCount: Word;
  1020. // PropList: record alignmentdummy: ptrint; end;
  1021. property Prop[Index: Word]: PPropInfoex read GetPropEx;
  1022. property Tail: Pointer read GetTail;
  1023. private
  1024. // Dummy declaration
  1025. PropList: array[0..0] of TPropInfoEx;
  1026. end;
  1027. PPropListEx = ^TPropListEx;
  1028. TPropListEx = array[0..{$ifdef cpu16}(32768 div sizeof(PPropInfoEx))-2{$else}65535{$endif}] of PPropInfoEx;
  1029. {$PACKRECORDS 1}
  1030. TPropInfo = packed record
  1031. private
  1032. function GetPropType: PTypeInfo; inline;
  1033. function GetTail: Pointer; inline;
  1034. function GetNext: PPropInfo; inline;
  1035. public
  1036. PropTypeRef : TypeInfoPtr;
  1037. GetProc : CodePointer;
  1038. SetProc : CodePointer;
  1039. StoredProc : CodePointer;
  1040. Index : Longint;
  1041. Default : Longint;
  1042. NameIndex : SmallInt;
  1043. // contains the type of the Get/Set/Storedproc, see also ptxxx
  1044. // bit 0..1 GetProc
  1045. // 2..3 SetProc
  1046. // 4..5 StoredProc
  1047. // 6 : true, constant index property
  1048. PropProcs : Byte;
  1049. {$ifdef PROVIDE_ATTR_TABLE}
  1050. AttributeTable : PAttributeTable;
  1051. {$endif}
  1052. Name : ShortString;
  1053. property PropType: PTypeInfo read GetPropType;
  1054. property Tail: Pointer read GetTail;
  1055. property Next: PPropInfo read GetNext;
  1056. end;
  1057. TProcInfoProc = Procedure(PropInfo : PPropInfo) of object;
  1058. PPropList = ^TPropList;
  1059. TPropList = array[0..{$ifdef cpu16}(32768 div sizeof(PPropInfo))-2{$else}65535{$endif}] of PPropInfo;
  1060. const
  1061. tkString = tkSString;
  1062. tkProcedure = tkProcVar; // for compatibility with Delphi
  1063. tkAny = [Low(TTypeKind)..High(TTypeKind)];
  1064. tkMethods = [tkMethod];
  1065. tkProperties = tkAny-tkMethods-[tkUnknown];
  1066. // general property handling
  1067. Function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
  1068. Function AlignTypeData(p : Pointer) : Pointer; inline;
  1069. Function AlignTParamFlags(p : Pointer) : Pointer; inline;
  1070. Function AlignPTypeInfo(p : Pointer) : Pointer; inline;
  1071. Generic Function ConstParamIsRef<T>(aCallConv: TCallConv = ccReg): Boolean; inline;
  1072. Function GetPropInfo(TypeInfo: PTypeInfo;const PropName: string): PPropInfo;
  1073. Function GetPropInfo(TypeInfo: PTypeInfo;const PropName: string; AKinds: TTypeKinds): PPropInfo;
  1074. Function GetPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  1075. Function GetPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  1076. Function GetPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  1077. Function GetPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  1078. Function FindPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  1079. Function FindPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  1080. Function FindPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  1081. Function FindPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  1082. Procedure GetPropInfos(TypeInfo: PTypeInfo; PropList: PPropList);
  1083. Function GetPropList(TypeInfo: PTypeInfo; TypeKinds: TTypeKinds; PropList: PPropList; Sorted: boolean = true): longint;
  1084. Function GetPropList(TypeInfo: PTypeInfo; out PropList: PPropList): SizeInt;
  1085. function GetPropList(AClass: TClass; out PropList: PPropList): Integer;
  1086. function GetPropList(Instance: TObject; out PropList: PPropList): Integer;
  1087. // extended RTTI
  1088. Function GetPropInfosEx(TypeInfo: PTypeInfo; PropList: PPropListEx; Visibilities : TVisibilityClasses = []) : Integer;
  1089. Function GetPropListEx(TypeInfo: PTypeInfo; TypeKinds: TTypeKinds; PropList: PPropListEx; Sorted: boolean = true; Visibilities : TVisibilityClasses = []): longint;
  1090. Function GetPropListEx(TypeInfo: PTypeInfo; out PropList: PPropListEx; Visibilities : TVisibilityClasses = []): SizeInt;
  1091. Function GetPropListEx(AClass: TClass; out PropList: PPropListEx; Visibilities : TVisibilityClasses = []): Integer;
  1092. Function GetPropListEx(Instance: TObject; out PropList: PPropListEx; Visibilities : TVisibilityClasses = []): Integer;
  1093. Function GetFieldInfos(aClass: TClass; FieldList: PExtendedFieldInfoTable; Visibilities : TVisibilityClasses = []) : Integer;
  1094. Function GetFieldInfos(aRecord: PRecordData; FieldList: PExtendedFieldInfoTable; Visibilities : TVisibilityClasses = []) : Integer;
  1095. Function GetFieldInfos(TypeInfo: PTypeInfo; FieldList: PExtendedFieldInfoTable; Visibilities : TVisibilityClasses = []) : Integer;
  1096. Function GetFieldList(TypeInfo: PTypeInfo; TypeKinds: TTypeKinds; out FieldList: PExtendedFieldInfoTable; Sorted: boolean = true; Visibilities : TVisibilityClasses = []): longint;
  1097. Function GetFieldList(TypeInfo: PTypeInfo; out FieldList: PExtendedFieldInfoTable; Visibilities : TVisibilityClasses = []): SizeInt;
  1098. Function GetRecordFieldList(aRecord: PRecordData; Out FieldList: PExtendedFieldInfoTable; Visibilities : TVisibilityClasses = []) : Integer;
  1099. Function GetFieldList(AClass: TClass; out FieldList: PExtendedFieldInfoTable; Visibilities : TVisibilityClasses = []): Integer;
  1100. Function GetFieldList(Instance: TObject; out FieldList: PExtendedFieldInfoTable; Visibilities : TVisibilityClasses = []): Integer;
  1101. // Infos require initialized memory or nil to count
  1102. Function GetMethodInfos(aClass: TClass; MethodList: PExtendedMethodInfoTable; Visibilities : TVisibilityClasses = []) : Integer;
  1103. Function GetMethodInfos(TypeInfo: PTypeInfo; MethodList: PExtendedMethodInfoTable; Visibilities : TVisibilityClasses = []) : Integer;
  1104. Function GetRecordMethodInfos(aRecordData: PRecordData; MethodList: PRecordMethodInfoTable; Visibilities: TVisibilityClasses): Integer;
  1105. Function GetMethodInfos(aRecord: PRecordData; MethodList: PRecordMethodInfoTable; Visibilities : TVisibilityClasses = []) : Integer;
  1106. Function GetMethodInfos(TypeInfo: PTypeInfo; MethodList: PRecordMethodInfoTable; Visibilities : TVisibilityClasses = []) : Integer;
  1107. // List will initialize the memory
  1108. Function GetMethodList(TypeInfo: PTypeInfo; out MethodList: PExtendedMethodInfoTable; Sorted: boolean = true; Visibilities : TVisibilityClasses = []): longint;
  1109. Function GetMethodList(TypeInfo: PTypeInfo; out MethodList: PExtendedMethodInfoTable; Visibilities : TVisibilityClasses = []): longint;
  1110. Function GetMethodList(AClass: TClass; out MethodList: PExtendedMethodInfoTable; Visibilities : TVisibilityClasses = []): Integer;
  1111. Function GetMethodList(Instance: TObject; out MethodList: PExtendedMethodInfoTable; Visibilities : TVisibilityClasses = []): Integer;
  1112. Function GetMethodList(TypeInfo: PTypeInfo; out MethodList: PRecordMethodInfoTable; Sorted: boolean = true; Visibilities : TVisibilityClasses = []): longint;
  1113. Function GetMethodList(TypeInfo: PTypeInfo; out MethodList: PRecordMethodInfoTable; Visibilities : TVisibilityClasses = []): longint;
  1114. Function GetRecordMethodList(aRecord: PRecordData; Out MethodList: PRecordMethodInfoTable; Visibilities : TVisibilityClasses = []) : Integer;
  1115. // Property information routines.
  1116. Function IsReadableProp(PropInfo : PPropInfo) : Boolean;
  1117. Function IsReadableProp(Instance: TObject; const PropName: string): Boolean;
  1118. Function IsReadableProp(AClass: TClass; const PropName: string): Boolean;
  1119. Function IsWriteableProp(PropInfo : PPropInfo) : Boolean;
  1120. Function IsWriteableProp(Instance: TObject; const PropName: string): Boolean;
  1121. Function IsWriteableProp(AClass: TClass; const PropName: string): Boolean;
  1122. Function IsStoredProp(Instance: TObject;PropInfo : PPropInfo) : Boolean;
  1123. Function IsStoredProp(Instance: TObject; const PropName: string): Boolean;
  1124. Function IsPublishedProp(Instance: TObject; const PropName: string): Boolean;
  1125. Function IsPublishedProp(AClass: TClass; const PropName: string): Boolean;
  1126. Function PropType(Instance: TObject; const PropName: string): TTypeKind;
  1127. Function PropType(AClass: TClass; const PropName: string): TTypeKind;
  1128. Function PropIsType(Instance: TObject; const PropName: string; TypeKind: TTypeKind): Boolean;
  1129. Function PropIsType(AClass: TClass; const PropName: string; TypeKind: TTypeKind): Boolean;
  1130. // subroutines to read/write properties
  1131. Function GetOrdProp(Instance: TObject; PropInfo : PPropInfo) : Int64;
  1132. Function GetOrdProp(Instance: TObject; const PropName: string): Int64;
  1133. Procedure SetOrdProp(Instance: TObject; PropInfo : PPropInfo; Value : Int64);
  1134. Procedure SetOrdProp(Instance: TObject; const PropName: string; Value: Int64);
  1135. Function GetEnumProp(Instance: TObject; const PropName: string): string;
  1136. Function GetEnumProp(Instance: TObject; const PropInfo: PPropInfo): string;
  1137. Procedure SetEnumProp(Instance: TObject; const PropName: string;const Value: string);
  1138. Procedure SetEnumProp(Instance: TObject; const PropInfo: PPropInfo;const Value: string);
  1139. Function GetSetProp(Instance: TObject; const PropName: string): string;
  1140. Function GetSetProp(Instance: TObject; const PropName: string; Brackets: Boolean): string;
  1141. Function GetSetProp(Instance: TObject; const PropInfo: PPropInfo; Brackets: Boolean): string;
  1142. Procedure SetSetProp(Instance: TObject; const PropName: string; const Value: string);
  1143. Procedure SetSetProp(Instance: TObject; const PropInfo: PPropInfo; const Value: string);
  1144. Function GetStrProp(Instance: TObject; PropInfo : PPropInfo) : Ansistring;
  1145. Function GetStrProp(Instance: TObject; const PropName: string): string;
  1146. Procedure SetStrProp(Instance: TObject; const PropName: string; const Value: AnsiString);
  1147. Procedure SetStrProp(Instance: TObject; PropInfo : PPropInfo; const Value : Ansistring);
  1148. Function GetWideStrProp(Instance: TObject; PropInfo: PPropInfo): WideString;
  1149. Function GetWideStrProp(Instance: TObject; const PropName: string): WideString;
  1150. Procedure SetWideStrProp(Instance: TObject; const PropName: string; const Value: WideString);
  1151. Procedure SetWideStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: WideString);
  1152. Function GetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo): UnicodeString;
  1153. Function GetUnicodeStrProp(Instance: TObject; const PropName: string): UnicodeString;
  1154. Procedure SetUnicodeStrProp(Instance: TObject; const PropName: string; const Value: UnicodeString);
  1155. Procedure SetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: UnicodeString);
  1156. Function GetRawbyteStrProp(Instance: TObject; PropInfo: PPropInfo): RawByteString;
  1157. Function GetRawByteStrProp(Instance: TObject; const PropName: string): RawByteString;
  1158. Procedure SetRawByteStrProp(Instance: TObject; const PropName: string; const Value: RawByteString);
  1159. Procedure SetRawByteStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: RawByteString);
  1160. {$ifndef FPUNONE}
  1161. Function GetFloatProp(Instance: TObject; PropInfo : PPropInfo) : Extended;
  1162. Function GetFloatProp(Instance: TObject; const PropName: string): Extended;
  1163. Procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Extended);
  1164. Procedure SetFloatProp(Instance: TObject; PropInfo : PPropInfo; Value : Extended);
  1165. {$endif}
  1166. Function GetObjectProp(Instance: TObject; const PropName: string): TObject;
  1167. Function GetObjectProp(Instance: TObject; const PropName: string; MinClass: TClass): TObject;
  1168. Function GetObjectProp(Instance: TObject; PropInfo: PPropInfo): TObject;
  1169. Function GetObjectProp(Instance: TObject; PropInfo: PPropInfo; MinClass: TClass): TObject;
  1170. Procedure SetObjectProp(Instance: TObject; const PropName: string; Value: TObject);
  1171. Procedure SetObjectProp(Instance: TObject; PropInfo: PPropInfo; Value: TObject);
  1172. Function GetObjectPropClass(Instance: TObject; const PropName: string): TClass;
  1173. Function GetObjectPropClass(AClass: TClass; const PropName: string): TClass;
  1174. Function GetMethodProp(Instance: TObject; PropInfo: PPropInfo) : TMethod;
  1175. Function GetMethodProp(Instance: TObject; const PropName: string): TMethod;
  1176. Procedure SetMethodProp(Instance: TObject; PropInfo: PPropInfo; const Value : TMethod);
  1177. Procedure SetMethodProp(Instance: TObject; const PropName: string; const Value: TMethod);
  1178. Function GetInt64Prop(Instance: TObject; PropInfo: PPropInfo): Int64;
  1179. Function GetInt64Prop(Instance: TObject; const PropName: string): Int64;
  1180. Procedure SetInt64Prop(Instance: TObject; PropInfo: PPropInfo; const Value: Int64);
  1181. Procedure SetInt64Prop(Instance: TObject; const PropName: string; const Value: Int64);
  1182. Function GetPropValue(Instance: TObject; const PropName: string): Variant;
  1183. Function GetPropValue(Instance: TObject; const PropName: string; PreferStrings: Boolean): Variant;
  1184. Function GetPropValue(Instance: TObject; PropInfo: PPropInfo): Variant;
  1185. Function GetPropValue(Instance: TObject; PropInfo: PPropInfo; PreferStrings: Boolean): Variant;
  1186. Procedure SetPropValue(Instance: TObject; const PropName: string; const Value: Variant);
  1187. Procedure SetPropValue(Instance: TObject; PropInfo: PPropInfo; const Value: Variant);
  1188. Function GetVariantProp(Instance: TObject; PropInfo : PPropInfo): Variant;
  1189. Function GetVariantProp(Instance: TObject; const PropName: string): Variant;
  1190. Procedure SetVariantProp(Instance: TObject; const PropName: string; const Value: Variant);
  1191. Procedure SetVariantProp(Instance: TObject; PropInfo : PPropInfo; const Value: Variant);
  1192. function GetInterfaceProp(Instance: TObject; const PropName: string): IInterface;
  1193. function GetInterfaceProp(Instance: TObject; PropInfo: PPropInfo): IInterface;
  1194. procedure SetInterfaceProp(Instance: TObject; const PropName: string; const Value: IInterface);
  1195. procedure SetInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: IInterface);
  1196. function GetRawInterfaceProp(Instance: TObject; const PropName: string): Pointer;
  1197. function GetRawInterfaceProp(Instance: TObject; PropInfo: PPropInfo): Pointer;
  1198. procedure SetRawInterfaceProp(Instance: TObject; const PropName: string; const Value: Pointer);
  1199. procedure SetRawInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: Pointer);
  1200. function GetDynArrayProp(Instance: TObject; const PropName: string): Pointer;
  1201. function GetDynArrayProp(Instance: TObject; PropInfo: PPropInfo): Pointer;
  1202. procedure SetDynArrayProp(Instance: TObject; const PropName: string; const Value: Pointer);
  1203. procedure SetDynArrayProp(Instance: TObject; PropInfo: PPropInfo; const Value: Pointer);
  1204. // Extended RTTI
  1205. function GetAttributeTable(TypeInfo: PTypeInfo): PAttributeTable;
  1206. function GetPropAttribute(PropInfo: PPropInfo; AttributeNr: Word): TCustomAttribute; inline;
  1207. function GetAttribute(AttributeTable: PAttributeTable; AttributeNr: Word): TCustomAttribute;
  1208. {$IFDEF HAVE_INVOKEHELPER}
  1209. procedure CallInvokeHelper(aTypeInfo : PTypeInfo; Instance: Pointer; const aMethod : String; aArgs : PPointer);
  1210. {$ENDIF}
  1211. // Auxiliary routines, which may be useful
  1212. Function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
  1213. Function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
  1214. function GetEnumNameCount(enum1: PTypeInfo): SizeInt;
  1215. procedure AddEnumElementAliases(aTypeInfo: PTypeInfo; const aNames: array of string; aStartValue: Integer = 0);
  1216. procedure RemoveEnumElementAliases(aTypeInfo: PTypeInfo);
  1217. function GetEnumeratedAliasValue(aTypeInfo: PTypeInfo; const aName: string): Integer;
  1218. function SetToArray(TypeInfo: PTypeInfo; Value: Pointer) : TBytes;
  1219. function SetToArray(PropInfo: PPropInfo; Value: Pointer) : TBytes;
  1220. function SetToArray(TypeInfo: PTypeInfo; Value: LongInt) : TBytes;
  1221. function SetToArray(PropInfo: PPropInfo; Value: LongInt) : TBytes;
  1222. function SetToString(TypeInfo: PTypeInfo; Value: LongInt; Brackets: Boolean) : String;
  1223. function SetToString(PropInfo: PPropInfo; Value: LongInt; Brackets: Boolean) : String;
  1224. function SetToString(PropInfo: PPropInfo; Value: LongInt) : String;
  1225. function SetToString(TypeInfo: PTypeInfo; Value: Pointer; Brackets: Boolean = False) : String;
  1226. function SetToString(PropInfo: PPropInfo; Value: Pointer; Brackets: Boolean = False) : String;
  1227. function ArrayToSet(PropInfo: PPropInfo; const Value: array of Byte): LongInt;
  1228. function ArrayToSet(TypeInfo: PTypeInfo; const Value: array of Byte): LongInt;
  1229. procedure ArrayToSet(PropInfo: PPropInfo; const Value: array of Byte; Result: Pointer);
  1230. procedure ArrayToSet(TypeInfo: PTypeInfo; const Value: array of Byte; Result: Pointer);
  1231. function StringToSet(PropInfo: PPropInfo; const Value: string): LongInt;
  1232. function StringToSet(TypeInfo: PTypeInfo; const Value: string): LongInt;
  1233. procedure StringToSet(PropInfo: PPropInfo; const Value: String; Result: Pointer);
  1234. procedure StringToSet(TypeInfo: PTypeInfo; const Value: String; Result: Pointer);
  1235. const
  1236. BooleanIdents: array[Boolean] of String = ('False', 'True');
  1237. DotSep: String = '.';
  1238. Type
  1239. EPropertyError = Class(Exception);
  1240. TGetPropValue = Function (Instance: TObject; PropInfo: PPropInfo; PreferStrings: Boolean) : Variant;
  1241. TSetPropValue = Procedure (Instance: TObject; PropInfo: PPropInfo; const Value: Variant);
  1242. TGetVariantProp = Function (Instance: TObject; PropInfo : PPropInfo): Variant;
  1243. TSetVariantProp = Procedure (Instance: TObject; PropInfo : PPropInfo; const Value: Variant);
  1244. EPropertyConvertError = class(Exception); // Not used (yet), but defined for compatibility.
  1245. Const
  1246. OnGetPropValue : TGetPropValue = Nil;
  1247. OnSetPropValue : TSetPropValue = Nil;
  1248. OnGetVariantprop : TGetVariantProp = Nil;
  1249. OnSetVariantprop : TSetVariantProp = Nil;
  1250. { for inlining }
  1251. function DerefTypeInfoPtr(Info: TypeInfoPtr): PTypeInfo; inline;
  1252. Implementation
  1253. {$IFDEF FPC_DOTTEDUNITS}
  1254. uses System.RtlConsts;
  1255. {$ELSE FPC_DOTTEDUNITS}
  1256. uses rtlconsts;
  1257. {$ENDIF FPC_DOTTEDUNITS}
  1258. type
  1259. PMethod = ^TMethod;
  1260. { ---------------------------------------------------------------------
  1261. Auxiliary methods
  1262. ---------------------------------------------------------------------}
  1263. function aligntoptr(p : pointer) : pointer;inline;
  1264. begin
  1265. {$ifdef CPUM68K}
  1266. result:=AlignTypeData(p);
  1267. {$else CPUM68K}
  1268. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  1269. result:=align(p,sizeof(p));
  1270. {$else FPC_REQUIRES_PROPER_ALIGNMENT}
  1271. result:=p;
  1272. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  1273. {$endif CPUM68K}
  1274. end;
  1275. function DerefTypeInfoPtr(Info: TypeInfoPtr): PTypeInfo; inline;
  1276. begin
  1277. {$ifdef ver3_0}
  1278. Result := Info;
  1279. {$else}
  1280. if not Assigned(Info) then
  1281. Result := Nil
  1282. else
  1283. Result := Info^;
  1284. {$endif}
  1285. end;
  1286. function GetAttributeTable(TypeInfo: PTypeInfo): PAttributeTable;
  1287. {$ifdef PROVIDE_ATTR_TABLE}
  1288. var
  1289. TD: PTypeData;
  1290. begin
  1291. TD := GetTypeData(TypeInfo);
  1292. Result:=TD^.AttributeTable;
  1293. {$else}
  1294. begin
  1295. Result:=Nil;
  1296. {$endif}
  1297. end;
  1298. function GetPropData(TypeInfo : PTypeInfo; TypeData: PTypeData) : PPropData; inline;
  1299. var
  1300. p: PtrUInt;
  1301. begin
  1302. p := PtrUInt(@TypeData^.UnitName) + SizeOf(TypeData^.UnitName[0]) + Length(TypeData^.UnitName);
  1303. Result := PPropData(aligntoptr(Pointer(p)));
  1304. end;
  1305. function GetAttribute(AttributeTable: PAttributeTable; AttributeNr: Word): TCustomAttribute;
  1306. begin
  1307. if (AttributeTable=nil) or (AttributeNr>=AttributeTable^.AttributeCount) then
  1308. result := nil
  1309. else
  1310. begin
  1311. result := AttributeTable^.AttributesList[AttributeNr].AttrProc();
  1312. end;
  1313. end;
  1314. function GetPropAttribute(PropInfo: PPropInfo; AttributeNr: Word): TCustomAttribute;
  1315. begin
  1316. {$ifdef PROVIDE_ATTR_TABLE}
  1317. Result := GetAttribute(PropInfo^.AttributeTable, AttributeNr);
  1318. {$else}
  1319. Result := Nil;
  1320. {$endif}
  1321. end;
  1322. Function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
  1323. Var PS : PShortString;
  1324. PT : PTypeData;
  1325. begin
  1326. PT:=GetTypeData(TypeInfo);
  1327. if TypeInfo^.Kind=tkBool then
  1328. begin
  1329. case Value of
  1330. 0,1:
  1331. Result:=BooleanIdents[Boolean(Value)];
  1332. else
  1333. Result:='';
  1334. end;
  1335. end
  1336. else
  1337. begin
  1338. PS:=@PT^.NameList;
  1339. dec(Value,PT^.MinValue);
  1340. While Value>0 Do
  1341. begin
  1342. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  1343. Dec(Value);
  1344. end;
  1345. Result:=PS^;
  1346. end;
  1347. end;
  1348. Function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
  1349. Var PS : PShortString;
  1350. PT : PTypeData;
  1351. Count : longint;
  1352. sName: shortstring;
  1353. begin
  1354. If Length(Name)=0 then
  1355. exit(-1);
  1356. sName := Name;
  1357. PT:=GetTypeData(TypeInfo);
  1358. Count:=0;
  1359. Result:=-1;
  1360. if TypeInfo^.Kind=tkBool then
  1361. begin
  1362. If CompareText(BooleanIdents[false],Name)=0 then
  1363. result:=0
  1364. else if CompareText(BooleanIdents[true],Name)=0 then
  1365. result:=1;
  1366. end
  1367. else
  1368. begin
  1369. PS:=@PT^.NameList;
  1370. While (Result=-1) and (PByte(PS)^<>0) do
  1371. begin
  1372. If ShortCompareText(PS^, sName) = 0 then
  1373. Result:=Count+PT^.MinValue;
  1374. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  1375. Inc(Count);
  1376. end;
  1377. if Result=-1 then
  1378. Result:=GetEnumeratedAliasValue(TypeInfo,Name);
  1379. end;
  1380. end;
  1381. function GetEnumNameCount(enum1: PTypeInfo): SizeInt;
  1382. var
  1383. PS: PShortString;
  1384. begin
  1385. if enum1^.Kind=tkBool then
  1386. Result:=2
  1387. else
  1388. begin
  1389. { the last string is the unit name, so start at -1 }
  1390. PS:=@GetTypeData(enum1)^.NameList;
  1391. Result:=-1;
  1392. While (PByte(PS)^<>0) do
  1393. begin
  1394. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  1395. Inc(Result);
  1396. end;
  1397. end;
  1398. end;
  1399. Function SetToString(PropInfo: PPropInfo; Value: LongInt; Brackets: Boolean) : String;
  1400. begin
  1401. Result:=SetToString(PropInfo^.PropType, Value, Brackets);
  1402. end;
  1403. Function SetToString(TypeInfo: PTypeInfo; Value: LongInt; Brackets: Boolean) : String;
  1404. begin
  1405. {$if defined(FPC_BIG_ENDIAN)}
  1406. { correctly adjust packed sets that are smaller than 32-bit }
  1407. case GetTypeData(TypeInfo)^.OrdType of
  1408. otSByte,otUByte: Value := Value shl (SizeOf(Integer)*8-8);
  1409. otSWord,otUWord: Value := Value shl (SizeOf(Integer)*8-16);
  1410. end;
  1411. {$endif}
  1412. Result := SetToString(TypeInfo, @Value, Brackets);
  1413. end;
  1414. function SetToString(TypeInfo: PTypeInfo; Value: Pointer; Brackets: Boolean): String;
  1415. var
  1416. A: TBytes;
  1417. B: Byte;
  1418. PTI : PTypeInfo;
  1419. begin
  1420. PTI:=GetTypeData(TypeInfo)^.CompType;
  1421. A:=SetToArray(TypeInfo, Value);
  1422. Result := '';
  1423. for B in A do
  1424. If Result='' then
  1425. Result:=GetEnumName(PTI,B)
  1426. else
  1427. Result:=Result+','+GetEnumName(PTI,B);
  1428. if Brackets then
  1429. Result:='['+Result+']';
  1430. end;
  1431. Function SetToString(PropInfo: PPropInfo; Value: LongInt) : String;
  1432. begin
  1433. Result:=SetToString(PropInfo,Value,False);
  1434. end;
  1435. function SetToString(PropInfo: PPropInfo; Value: Pointer; Brackets: Boolean): String;
  1436. begin
  1437. Result := SetToString(PropInfo^.PropType, Value, Brackets);
  1438. end;
  1439. function SetToArray(TypeInfo: PTypeInfo; Value: Pointer) : TBytes;
  1440. type
  1441. tsetarr = bitpacked array[0..SizeOf(LongInt)*8-1] of 0..1;
  1442. Var
  1443. I,El,Els,Rem,V,Max : Integer;
  1444. PTD : PTypeData;
  1445. ValueArr : PLongInt;
  1446. begin
  1447. PTD := GetTypeData(TypeInfo);
  1448. ValueArr := PLongInt(Value);
  1449. Result:=[];
  1450. {$ifdef ver3_0}
  1451. case PTD^.OrdType of
  1452. otSByte, otUByte: begin
  1453. Els := 0;
  1454. Rem := 1;
  1455. end;
  1456. otSWord, otUWord: begin
  1457. Els := 0;
  1458. Rem := 2;
  1459. end;
  1460. otSLong, otULong: begin
  1461. Els := 1;
  1462. Rem := 0;
  1463. end;
  1464. end;
  1465. {$else}
  1466. Els := PTD^.SetSize div SizeOf(LongInt);
  1467. Rem := PTD^.SetSize mod SizeOf(LongInt);
  1468. {$endif}
  1469. {$ifdef ver3_0}
  1470. El := 0;
  1471. {$else}
  1472. for El := 0 to (PTD^.SetSize - 1) div SizeOf(LongInt) do
  1473. {$endif}
  1474. begin
  1475. if El = Els then
  1476. Max := Rem
  1477. else
  1478. Max := SizeOf(LongInt);
  1479. For I:=0 to Max*8-1 do
  1480. begin
  1481. if (tsetarr(ValueArr[El])[i]<>0) then
  1482. begin
  1483. V := I + SizeOf(LongInt) * 8 * El;
  1484. SetLength(Result, Length(Result)+1);
  1485. Result[High(Result)]:=V;
  1486. end;
  1487. end;
  1488. end;
  1489. end;
  1490. function SetToArray(PropInfo: PPropInfo; Value: Pointer) : TBytes;
  1491. begin
  1492. Result:=SetToArray(PropInfo^.PropType,Value);
  1493. end;
  1494. function SetToArray(TypeInfo: PTypeInfo; Value: LongInt) : TBytes;
  1495. begin
  1496. Result:=SetToArray(TypeInfo,@Value);
  1497. end;
  1498. function SetToArray(PropInfo: PPropInfo; Value: LongInt) : TBytes;
  1499. begin
  1500. Result:=SetToArray(PropInfo^.PropType,@Value);
  1501. end;
  1502. Const
  1503. SetDelim = ['[',']',',',' '];
  1504. Function GetNextElement(Var S : String) : String;
  1505. Var
  1506. J : Integer;
  1507. begin
  1508. J:=1;
  1509. Result:='';
  1510. If Length(S)>0 then
  1511. begin
  1512. While (J<=Length(S)) and Not (S[j] in SetDelim) do
  1513. Inc(j);
  1514. Result:=Copy(S,1,j-1);
  1515. Delete(S,1,j);
  1516. end;
  1517. end;
  1518. Function StringToSet(PropInfo: PPropInfo; const Value: string): LongInt;
  1519. begin
  1520. Result:=StringToSet(PropInfo^.PropType,Value);
  1521. end;
  1522. Function StringToSet(TypeInfo: PTypeInfo; const Value: string): LongInt;
  1523. begin
  1524. StringToSet(TypeInfo, Value, @Result);
  1525. {$if defined(FPC_BIG_ENDIAN)}
  1526. { correctly adjust packed sets that are smaller than 32-bit }
  1527. case GetTypeData(TypeInfo)^.OrdType of
  1528. otSByte,otUByte: Result := Result shr (SizeOf(Integer)*8-8);
  1529. otSWord,otUWord: Result := Result shr (SizeOf(Integer)*8-16);
  1530. end;
  1531. {$endif}
  1532. end;
  1533. procedure StringToSet(TypeInfo: PTypeInfo; const Value: String; Result: Pointer);
  1534. Var
  1535. S,T : String;
  1536. I, ElOfs, BitOfs : Integer;
  1537. PTD: PTypeData;
  1538. PTI : PTypeInfo;
  1539. A: TBytes;
  1540. begin
  1541. PTD:=GetTypeData(TypeInfo);
  1542. PTI:=PTD^.Comptype;
  1543. S:=Value;
  1544. I:=1;
  1545. If Length(S)>0 then
  1546. begin
  1547. While (I<=Length(S)) and (S[i] in SetDelim) do
  1548. Inc(I);
  1549. Delete(S,1,i-1);
  1550. end;
  1551. A:=[];
  1552. While (S<>'') do
  1553. begin
  1554. T:=GetNextElement(S);
  1555. if T<>'' then
  1556. begin
  1557. I:=GetEnumValue(PTI,T);
  1558. if (I<0) then
  1559. raise EPropertyError.CreateFmt(SErrUnknownEnumValue, [T]);
  1560. SetLength(A, Length(A)+1);
  1561. A[High(A)]:=I;
  1562. end;
  1563. end;
  1564. ArrayToSet(TypeInfo,A,Result);
  1565. end;
  1566. procedure StringToSet(PropInfo: PPropInfo; const Value: String; Result: Pointer);
  1567. begin
  1568. StringToSet(PropInfo^.PropType, Value, Result);
  1569. end;
  1570. Function ArrayToSet(PropInfo: PPropInfo; const Value: array of Byte): LongInt;
  1571. begin
  1572. Result:=ArrayToSet(PropInfo^.PropType,Value);
  1573. end;
  1574. Function ArrayToSet(TypeInfo: PTypeInfo; const Value: array of Byte): LongInt;
  1575. begin
  1576. ArrayToSet(TypeInfo, Value, @Result);
  1577. {$if defined(FPC_BIG_ENDIAN)}
  1578. { correctly adjust packed sets that are smaller than 32-bit }
  1579. case GetTypeData(TypeInfo)^.OrdType of
  1580. otSByte,otUByte: Result := Result shr (SizeOf(Integer)*8-8);
  1581. otSWord,otUWord: Result := Result shr (SizeOf(Integer)*8-16);
  1582. end;
  1583. {$endif}
  1584. end;
  1585. procedure ArrayToSet(TypeInfo: PTypeInfo; const Value: array of Byte; Result: Pointer);
  1586. Var
  1587. ElOfs, BitOfs : Integer;
  1588. PTD: PTypeData;
  1589. ResArr: PLongWord;
  1590. B: Byte;
  1591. begin
  1592. PTD:=GetTypeData(TypeInfo);
  1593. {$ifndef ver3_0}
  1594. FillChar(Result^, PTD^.SetSize, 0);
  1595. {$else}
  1596. PInteger(Result)^ := 0;
  1597. {$endif}
  1598. ResArr := PLongWord(Result);
  1599. for B in Value do
  1600. begin
  1601. ElOfs := B shr 5;
  1602. BitOfs := B and $1F;
  1603. {$ifdef FPC_BIG_ENDIAN}
  1604. { on Big Endian systems enum values start from the MSB, thus we need
  1605. to reverse the shift }
  1606. BitOfs := 31 - BitOfs;
  1607. {$endif}
  1608. ResArr[ElOfs] := ResArr[ElOfs] or (LongInt(1) shl BitOfs);
  1609. end;
  1610. end;
  1611. procedure ArrayToSet(PropInfo: PPropInfo; const Value: array of Byte; Result: Pointer);
  1612. begin
  1613. ArrayToSet(PropInfo^.PropType, Value, Result);
  1614. end;
  1615. Function AlignTypeData(p : Pointer) : Pointer;
  1616. {$packrecords c}
  1617. type
  1618. TAlignCheck = record
  1619. b : byte;
  1620. q : qword;
  1621. end;
  1622. {$packrecords default}
  1623. begin
  1624. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  1625. {$ifdef VER3_0}
  1626. Result:=Pointer(align(p,SizeOf(Pointer)));
  1627. {$else VER3_0}
  1628. Result:=Pointer(align(p,PtrInt(@TAlignCheck(nil^).q)))
  1629. {$endif VER3_0}
  1630. {$else FPC_REQUIRES_PROPER_ALIGNMENT}
  1631. Result:=p;
  1632. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  1633. end;
  1634. Function AlignTParamFlags(p : Pointer) : Pointer; inline;
  1635. {$packrecords c}
  1636. type
  1637. TAlignCheck = record
  1638. b : byte;
  1639. w : word;
  1640. end;
  1641. {$packrecords default}
  1642. begin
  1643. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  1644. Result:=Pointer(align(p,PtrInt(@TAlignCheck(nil^).w)))
  1645. {$else FPC_REQUIRES_PROPER_ALIGNMENT}
  1646. Result:=p;
  1647. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  1648. end;
  1649. Function AlignPTypeInfo(p : Pointer) : Pointer; inline;
  1650. {$packrecords c}
  1651. type
  1652. TAlignCheck = record
  1653. b : byte;
  1654. p : pointer;
  1655. end;
  1656. {$packrecords default}
  1657. begin
  1658. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  1659. Result:=Pointer(align(p,PtrInt(@TAlignCheck(nil^).p)))
  1660. {$else FPC_REQUIRES_PROPER_ALIGNMENT}
  1661. Result:=p;
  1662. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  1663. end;
  1664. Generic Function ConstParamIsRef<T>(aCallConv: TCallConv): Boolean;
  1665. Function SameAddrRegister(const aArg1: T; constref aArg2: T): Boolean; register;
  1666. begin
  1667. Result := @aArg1 = @aArg2;
  1668. end;
  1669. Function SameAddrCDecl(const aArg1: T; constref aArg2: T): Boolean; cdecl;
  1670. begin
  1671. Result := @aArg1 = @aArg2;
  1672. end;
  1673. {$if defined(cpui8086) or defined(cpui386)}
  1674. Function SameAddrPascal(const aArg1: T; constref aArg2: T): Boolean; pascal;
  1675. begin
  1676. Result := @aArg1 = @aArg2;
  1677. end;
  1678. {$endif}
  1679. Function SameAddrStdCall(const aArg1: T; constref aArg2: T): Boolean; stdcall;
  1680. begin
  1681. Result := @aArg1 = @aArg2;
  1682. end;
  1683. Function SameAddrCppDecl(const aArg1: T; constref aArg2: T): Boolean; cppdecl;
  1684. begin
  1685. Result := @aArg1 = @aArg2;
  1686. end;
  1687. {$if defined(cpui386)}
  1688. Function SameAddrOldFPCCall(const aArg1: T; constref aArg2: T): Boolean; oldfpccall;
  1689. begin
  1690. Result := @aArg1 = @aArg2;
  1691. end;
  1692. {$endif}
  1693. Function SameAddrMWPascal(const aArg1: T; constref aArg2: T): Boolean; mwpascal;
  1694. begin
  1695. Result := @aArg1 = @aArg2;
  1696. end;
  1697. var
  1698. v: T;
  1699. begin
  1700. v := Default(T);
  1701. case aCallConv of
  1702. ccReg:
  1703. Result := SameAddrRegister(v, v);
  1704. ccCdecl:
  1705. Result := SameAddrCDecl(v, v);
  1706. {$if defined(cpui386) or defined(cpui8086)}
  1707. ccPascal:
  1708. Result := SameAddrPascal(v, v);
  1709. {$endif}
  1710. {$if not defined(cpui386)}
  1711. ccOldFPCCall,
  1712. {$endif}
  1713. {$if not defined(cpui386) and not defined(cpui8086)}
  1714. ccPascal,
  1715. {$endif}
  1716. ccStdCall:
  1717. Result := SameAddrStdCall(v, v);
  1718. ccCppdecl:
  1719. Result := SameAddrCppDecl(v, v);
  1720. {$if defined(cpui386)}
  1721. ccOldFPCCall:
  1722. Result := SameAddrOldFPCCall(v, v);
  1723. {$endif}
  1724. ccMWPascal:
  1725. Result := SameAddrMWPascal(v, v);
  1726. else
  1727. raise EArgumentException.CreateFmt(SUnsupportedCallConv, [GetEnumName(PTypeInfo(TypeInfo(TCallConv)), Ord(aCallConv))]);
  1728. end;
  1729. end;
  1730. Function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
  1731. begin
  1732. GetTypeData:=AlignTypeData(pointer(TypeInfo)+2+PByte(pointer(TypeInfo)+1)^);
  1733. end;
  1734. { ---------------------------------------------------------------------
  1735. Basic Type information functions.
  1736. ---------------------------------------------------------------------}
  1737. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string) : PPropInfo;
  1738. var
  1739. hp : PTypeData;
  1740. i : longint;
  1741. p : shortstring;
  1742. pd : PPropData;
  1743. begin
  1744. P:=PropName; // avoid Ansi<->short conversion in a loop
  1745. while Assigned(TypeInfo) do
  1746. begin
  1747. // skip the name
  1748. hp:=GetTypeData(Typeinfo);
  1749. // the class info rtti the property rtti follows immediatly
  1750. pd := GetPropData(TypeInfo,hp);
  1751. Result:=PPropInfo(@pd^.PropList);
  1752. for i:=1 to pd^.PropCount do
  1753. begin
  1754. // found a property of that name ?
  1755. if ShortCompareText(Result^.Name, P) = 0 then
  1756. exit;
  1757. // skip to next property
  1758. Result:=PPropInfo(aligntoptr(pointer(@Result^.Name)+byte(Result^.Name[0])+1));
  1759. end;
  1760. // parent class
  1761. Typeinfo:=hp^.ParentInfo;
  1762. end;
  1763. Result:=Nil;
  1764. end;
  1765. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string; Akinds : TTypeKinds) : PPropInfo;
  1766. begin
  1767. Result:=GetPropInfo(TypeInfo,PropName);
  1768. If (Akinds<>[]) then
  1769. If (Result<>Nil) then
  1770. If Not (Result^.PropType^.Kind in AKinds) then
  1771. Result:=Nil;
  1772. end;
  1773. Function GetPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
  1774. begin
  1775. Result:=GetPropInfo(PTypeInfo(AClass.ClassInfo),PropName,AKinds);
  1776. end;
  1777. Function GetPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
  1778. begin
  1779. Result:=GetPropInfo(Instance.ClassType,PropName,AKinds);
  1780. end;
  1781. Function GetPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  1782. begin
  1783. Result:=GetPropInfo(Instance,PropName,[]);
  1784. end;
  1785. Function GetPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  1786. begin
  1787. Result:=GetPropInfo(AClass,PropName,[]);
  1788. end;
  1789. Function FindPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  1790. begin
  1791. result:=GetPropInfo(Instance, PropName);
  1792. if Result=nil then
  1793. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  1794. end;
  1795. Function FindPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  1796. begin
  1797. result:=GetPropInfo(Instance, PropName, AKinds);
  1798. if Result=nil then
  1799. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  1800. end;
  1801. Function FindPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  1802. begin
  1803. result:=GetPropInfo(AClass, PropName);
  1804. if result=nil then
  1805. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  1806. end;
  1807. Function FindPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  1808. begin
  1809. result:=GetPropInfo(AClass, PropName, AKinds);
  1810. if result=nil then
  1811. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  1812. end;
  1813. function IsReadableProp(PropInfo: PPropInfo): Boolean;
  1814. begin
  1815. Result:=(((PropInfo^.PropProcs) and 3) in [ptField,ptStatic,ptVirtual]);
  1816. end;
  1817. function IsReadableProp(Instance: TObject; const PropName: string): Boolean;
  1818. begin
  1819. Result:=IsReadableProp(FindPropInfo(Instance,PropName));
  1820. end;
  1821. function IsReadableProp(AClass: TClass; const PropName: string): Boolean;
  1822. begin
  1823. Result:=IsReadableProp(FindPropInfo(AClass,PropName));
  1824. end;
  1825. function IsWriteableProp(PropInfo: PPropInfo): Boolean;
  1826. begin
  1827. Result:=(((PropInfo^.PropProcs shr 2) and 3) in [ptField,ptStatic,ptVirtual]);
  1828. end;
  1829. function IsWriteableProp(Instance: TObject; const PropName: string): Boolean;
  1830. begin
  1831. Result:=IsWriteableProp(FindPropInfo(Instance,PropName));
  1832. end;
  1833. function IsWriteableProp(AClass: TClass; const PropName: string): Boolean;
  1834. begin
  1835. Result:=IsWriteableProp(FindPropInfo(AClass,PropName));
  1836. end;
  1837. Function IsStoredProp(Instance: TObject;PropInfo : PPropInfo) : Boolean;
  1838. type
  1839. TBooleanIndexFunc=function(Index:integer):boolean of object;
  1840. TBooleanFunc=function:boolean of object;
  1841. var
  1842. AMethod : TMethod;
  1843. begin
  1844. case (PropInfo^.PropProcs shr 4) and 3 of
  1845. ptField:
  1846. Result:=PBoolean(Pointer(Instance)+PtrUInt(PropInfo^.StoredProc))^;
  1847. ptConst:
  1848. Result:=LongBool(PropInfo^.StoredProc);
  1849. ptStatic,
  1850. ptVirtual:
  1851. begin
  1852. if (PropInfo^.PropProcs shr 4) and 3=ptstatic then
  1853. AMethod.Code:=PropInfo^.StoredProc
  1854. else
  1855. AMethod.Code:=pcodepointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.StoredProc))^;
  1856. AMethod.Data:=Instance;
  1857. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1858. Result:=TBooleanIndexFunc(AMethod)(PropInfo^.Index)
  1859. else
  1860. Result:=TBooleanFunc(AMethod)();
  1861. end;
  1862. end;
  1863. end;
  1864. Function GetClassPropInfosEx(TypeInfo: PTypeInfo; PropList: PPropListEx; Visibilities: TVisibilityClasses): Integer;
  1865. Var
  1866. TD : PPropDataEx;
  1867. TP : PPropInfoEx;
  1868. I,Count : Longint;
  1869. begin
  1870. Result:=0;
  1871. // Clear list
  1872. repeat
  1873. TD:=PClassData(GetTypeData(TypeInfo))^.ExRTTITable;
  1874. if PropList<>Nil then
  1875. FillChar(PropList^,TD^.PropCount*sizeof(PPropInfoEx),0);
  1876. Count:=TD^.PropCount;
  1877. // Now point TP to first propinfo record.
  1878. For I:=0 to Count-1 do
  1879. begin
  1880. TP:=TD^.Prop[I];
  1881. if ([]=Visibilities) or (TP^.Visibility in Visibilities) then
  1882. begin
  1883. // When passing nil, we just need the count
  1884. if Assigned(PropList) then
  1885. PropList^[Result]:=TD^.Prop[i];
  1886. Inc(Result);
  1887. end;
  1888. end;
  1889. if PClassData(GetTypeData(TypeInfo))^.Parent=Nil then
  1890. TypeInfo:=Nil
  1891. else
  1892. TypeInfo:=PClassData(GetTypeData(TypeInfo))^.Parent^;
  1893. until TypeInfo=nil;
  1894. end;
  1895. Function GetRecordPropInfosEx(TypeInfo: PTypeInfo; PropList: PPropListEx; Visibilities: TVisibilityClasses): Integer;
  1896. Var
  1897. TD : PPropDataEx;
  1898. TP : PPropListEx;
  1899. Offset,I,Count : Longint;
  1900. begin
  1901. Result:=0;
  1902. // Clear list
  1903. TD:=PRecordData(GetTypeData(TypeInfo))^.ExRTTITable;
  1904. Count:=TD^.PropCount;
  1905. // Now point TP to first propinfo record.
  1906. Inc(Pointer(TP),SizeOF(Word));
  1907. tp:=aligntoptr(tp);
  1908. For I:=0 to Count-1 do
  1909. if ([]=Visibilities) or (PropList^[Result]^.Visibility in Visibilities) then
  1910. begin
  1911. // When passing nil, we just need the count
  1912. if Assigned(PropList) then
  1913. PropList^[Result]:=TD^.Prop[i];
  1914. Inc(Result);
  1915. end;
  1916. end;
  1917. Function GetPropInfosEx(TypeInfo: PTypeInfo; PropList: PPropListEx; Visibilities: TVisibilityClasses): Integer;
  1918. begin
  1919. if TypeInfo^.Kind=tkClass then
  1920. Result:=GetClassPropInfosEx(TypeInfo,PropList,Visibilities)
  1921. else if TypeInfo^.Kind=tkRecord then
  1922. Result:=GetRecordPropInfosEx(TypeInfo,PropList,Visibilities)
  1923. else
  1924. Result:=0;
  1925. end;
  1926. Procedure InsertPropEx (PL : PProplistEx;PI : PPropInfoEx; Count : longint);
  1927. Var
  1928. I : Longint;
  1929. begin
  1930. I:=0;
  1931. While (I<Count) and (PI^.Info^.Name>PL^[I]^.Info^.Name) do
  1932. Inc(I);
  1933. If I<Count then
  1934. Move(PL^[I], PL^[I+1], (Count - I) * SizeOf(Pointer));
  1935. PL^[I]:=PI;
  1936. end;
  1937. Procedure InsertPropnosortEx (PL : PProplistEx;PI : PPropInfoEx; Count : longint);
  1938. begin
  1939. PL^[Count]:=PI;
  1940. end;
  1941. Function GetPropListEx(TypeInfo: PTypeInfo; TypeKinds: TTypeKinds; PropList: PPropListEx; Sorted: boolean;
  1942. Visibilities: TVisibilityClasses): longint;
  1943. Type
  1944. TInsertPropEx = Procedure (PL : PProplistEx;PI : PPropInfoex; Count : longint);
  1945. {
  1946. Store Pointers to property information OF A CERTAIN KIND in the list pointed
  1947. to by proplist. PRopList must contain enough space to hold ALL
  1948. properties.
  1949. }
  1950. Var
  1951. TempList : PPropListEx;
  1952. PropInfo : PPropinfoEx;
  1953. I,Count : longint;
  1954. DoInsertPropEx : TInsertPropEx;
  1955. begin
  1956. if sorted then
  1957. DoInsertPropEx:=@InsertPropEx
  1958. else
  1959. DoInsertPropEx:=@InsertPropnosortEx;
  1960. Result:=0;
  1961. Count:=GetPropListEx(TypeInfo,TempList,Visibilities);
  1962. Try
  1963. For I:=0 to Count-1 do
  1964. begin
  1965. PropInfo:=TempList^[i];
  1966. If PropInfo^.Info^.PropType^.Kind in TypeKinds then
  1967. begin
  1968. If (PropList<>Nil) then
  1969. DoInsertPropEx(PropList,PropInfo,Result);
  1970. Inc(Result);
  1971. end;
  1972. end;
  1973. finally
  1974. FreeMem(TempList,Count*SizeOf(Pointer));
  1975. end;
  1976. end;
  1977. Function GetPropListEx(TypeInfo: PTypeInfo; out PropList: PPropListEx; Visibilities: TVisibilityClasses): SizeInt;
  1978. begin
  1979. // When passing nil, we get the count
  1980. result:=GetPropInfosEx(TypeInfo,Nil,Visibilities);
  1981. if result>0 then
  1982. begin
  1983. getmem(PropList,result*sizeof(pointer));
  1984. GetPropInfosEx(TypeInfo,PropList);
  1985. end
  1986. else
  1987. PropList:=Nil;
  1988. end;
  1989. Function GetPropListEx(AClass: TClass; out PropList: PPropListEx; Visibilities : TVisibilityClasses = []): Integer;
  1990. begin
  1991. Result:=GetPropListEx(PTypeInfo(aClass.ClassInfo),PropList,Visibilities);
  1992. end;
  1993. Function GetPropListEx(Instance: TObject; out PropList: PPropListEx; Visibilities : TVisibilityClasses = []): Integer;
  1994. begin
  1995. Result:=GetPropListEx(Instance.ClassType,PropList,Visibilities);
  1996. end;
  1997. Function GetFieldInfos(aRecord: PRecordData; FieldList: PExtendedFieldInfoTable; Visibilities: TVisibilityClasses): Integer;
  1998. Var
  1999. FieldTable: PExtendedFieldTable;
  2000. FieldEntry: PExtendedFieldEntry;
  2001. I : Integer;
  2002. begin
  2003. Result:=0;
  2004. if aRecord=Nil then exit;
  2005. FieldTable:=aRecord^.ExtendedFields;
  2006. if FieldTable=Nil then exit;
  2007. if FieldList<>Nil then
  2008. FillChar(FieldList^[Result],FieldTable^.FieldCount*sizeof(Pointer),0);
  2009. For I:=0 to FieldTable^.FieldCount-1 do
  2010. begin
  2011. FieldEntry:=FieldTable^.Field[i];
  2012. if ([]=Visibilities) or (FieldEntry^.FieldVisibility in Visibilities) then
  2013. begin
  2014. if Assigned(FieldList) then
  2015. FieldList^[Result]:=FieldEntry;
  2016. Inc(Result);
  2017. end;
  2018. end;
  2019. end;
  2020. Function GetFieldInfos(aClass: TClass; FieldList: PExtendedFieldInfoTable; Visibilities: TVisibilityClasses): Integer;
  2021. var
  2022. vmt: PVmt;
  2023. FieldTable: PVmtExtendedFieldTable;
  2024. FieldEntry: PExtendedVmtFieldEntry;
  2025. FieldEntryD: TExtendedVmtFieldEntry;
  2026. i: longint;
  2027. function AlignToFieldEntry(aPtr: Pointer): Pointer; inline;
  2028. begin
  2029. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  2030. { align to largest field of TVmtFieldInfo }
  2031. Result := Align(aPtr, SizeOf(PtrUInt));
  2032. {$else}
  2033. Result := aPtr;
  2034. {$endif}
  2035. end;
  2036. begin
  2037. Result:=0;
  2038. vmt := PVmt(AClass);
  2039. while vmt <> nil do
  2040. begin
  2041. // a class can have 0 fields...
  2042. if vmt^.vFieldTable<>Nil then
  2043. begin
  2044. FieldTable := PVmtExtendedFieldTable(AlignToFieldEntry(PVmtFieldTable(vmt^.vFieldTable)^.Next));
  2045. For I:=0 to FieldTable^.FieldCount-1 do
  2046. begin
  2047. FieldEntry:=FieldTable^.Field[i];
  2048. FieldEntryD:=FieldEntry^;
  2049. if ([]=Visibilities) or (FieldEntry^.FieldVisibility in Visibilities) then
  2050. begin
  2051. if Assigned(FieldList) then
  2052. FieldList^[Result]:=FieldEntry;
  2053. Inc(Result);
  2054. end;
  2055. end;
  2056. end;
  2057. { Go to parent type }
  2058. vmt:=vmt^.vParent;
  2059. end;
  2060. end;
  2061. Function GetFieldInfos(TypeInfo: PTypeInfo; FieldList: PExtendedFieldInfoTable; Visibilities: TVisibilityClasses): Integer;
  2062. begin
  2063. if TypeInfo^.Kind=tkRecord then
  2064. Result:=GetFieldInfos(PRecordData(GetTypeData(TypeInfo)),FieldList,Visibilities)
  2065. else if TypeInfo^.Kind=tkClass then
  2066. Result:=GetFieldInfos((PClassData(GetTypeData(TypeInfo))^.ClassType),FieldList,Visibilities)
  2067. else
  2068. Result:=0
  2069. end;
  2070. Procedure InsertFieldEntry (PL : PExtendedFieldInfoTable;PI : PExtendedVmtFieldEntry; Count : longint);
  2071. Var
  2072. I : Longint;
  2073. begin
  2074. I:=0;
  2075. While (I<Count) and (PI^.Name^>PL^[I]^.Name^) do
  2076. Inc(I);
  2077. If I<Count then
  2078. Move(PL^[I], PL^[I+1], (Count - I) * SizeOf(Pointer));
  2079. PL^[I]:=PI;
  2080. end;
  2081. Procedure InsertFieldEntryNoSort (PL : PExtendedFieldInfoTable;PI : PExtendedVmtFieldEntry; Count : longint);
  2082. begin
  2083. PL^[Count]:=PI;
  2084. end;
  2085. Function GetFieldList(TypeInfo: PTypeInfo; TypeKinds: TTypeKinds; out FieldList: PExtendedFieldInfoTable; Sorted: boolean;
  2086. Visibilities: TVisibilityClasses): longint;
  2087. Type
  2088. TInsertField = Procedure (PL : PExtendedFieldInfoTable;PI : PExtendedVmtFieldEntry; Count : longint);
  2089. {
  2090. Store Pointers to property information OF A CERTAIN KIND in the list pointed
  2091. to by proplist. PRopList must contain enough space to hold ALL
  2092. properties.
  2093. }
  2094. Var
  2095. TempList : PExtendedFieldInfoTable;
  2096. FieldEntry : PExtendedVmtFieldEntry;
  2097. I,Count : longint;
  2098. DoInsertField : TInsertField;
  2099. begin
  2100. if sorted then
  2101. DoInsertField:=@InsertFieldEntry
  2102. else
  2103. DoInsertField:=@InsertFieldEntryNoSort;
  2104. Result:=0;
  2105. Count:=GetFieldList(TypeInfo,TempList,Visibilities);
  2106. Try
  2107. For I:=0 to Count-1 do
  2108. begin
  2109. FieldEntry:=TempList^[i];
  2110. If PPTypeInfo(FieldEntry^.FieldType)^^.Kind in TypeKinds then
  2111. begin
  2112. If (FieldList<>Nil) then
  2113. DoInsertField(FieldList,FieldEntry,Result);
  2114. Inc(Result);
  2115. end;
  2116. end;
  2117. finally
  2118. FreeMem(TempList);
  2119. end;
  2120. end;
  2121. Function GetRecordFieldList(aRecord: PRecordData; out FieldList: PExtendedFieldInfoTable; Visibilities: TVisibilityClasses
  2122. ): Integer;
  2123. Var
  2124. aCount : Integer;
  2125. begin
  2126. Result:=0;
  2127. aCount:=GetFieldInfos(aRecord,Nil,[]);
  2128. FieldList:=Getmem(aCount*SizeOf(Pointer));
  2129. try
  2130. Result:=GetFieldInfos(aRecord,FieldList,Visibilities);
  2131. except
  2132. FreeMem(FieldList);
  2133. Raise;
  2134. end;
  2135. end;
  2136. Function GetFieldList(TypeInfo: PTypeInfo; out FieldList : PExtendedFieldInfoTable; Visibilities: TVisibilityClasses): SizeInt;
  2137. begin
  2138. if TypeInfo^.Kind=tkRecord then
  2139. Result:=GetRecordFieldList(PRecordData(GetTypeData(TypeInfo)),FieldList,Visibilities)
  2140. else if TypeInfo^.Kind=tkClass then
  2141. Result:=GetFieldInfos((PClassData(GetTypeData(TypeInfo))^.ClassType),FieldList,Visibilities)
  2142. else
  2143. Result:=0
  2144. end;
  2145. Function GetFieldList(AClass: TClass; out FieldList: PExtendedFieldInfoTable; Visibilities: TVisibilityClasses): Integer;
  2146. Var
  2147. aCount : Integer;
  2148. begin
  2149. Result:=0;
  2150. aCount:=GetFieldInfos(aClass,Nil,Visibilities);
  2151. FieldList:=Getmem(aCount*SizeOf(Pointer));
  2152. try
  2153. Result:=GetFieldInfos(aClass,FieldList,Visibilities);
  2154. except
  2155. FreeMem(FieldList);
  2156. Raise;
  2157. end;
  2158. end;
  2159. Function GetFieldList(Instance: TObject; out FieldList: PExtendedFieldInfoTable; Visibilities: TVisibilityClasses): Integer;
  2160. begin
  2161. Result:=GetFieldList(Instance.ClassType,FieldList,Visibilities);
  2162. end;
  2163. { -- Methods -- }
  2164. Function GetMethodInfos(aRecord: PRecordData; MethodList: PRecordMethodInfoTable; Visibilities: TVisibilityClasses): Integer;
  2165. begin
  2166. Result:=GetRecordMethodInfos(aRecord,MethodList,Visibilities)
  2167. end;
  2168. Function GetClassMethodInfos(aClassData: PClassData; MethodList: PExtendedMethodInfoTable; Visibilities: TVisibilityClasses): Integer;
  2169. var
  2170. MethodTable: PVmtMethodExTable;
  2171. MethodEntry: PVmtMethodExEntry;
  2172. i: longint;
  2173. begin
  2174. Result:=0;
  2175. While aClassData<>Nil do
  2176. begin
  2177. MethodTable:=aClassData^.ExMethodTable;
  2178. // if LegacyCount=0 then Count1 and Count are not available.
  2179. if (MethodTable<>Nil) and (MethodTable^.Count<>0) then
  2180. begin
  2181. For I:=0 to MethodTable^.Count-1 do
  2182. begin
  2183. MethodEntry:=MethodTable^.Method[i];
  2184. if ([]=Visibilities) or (MethodEntry^.MethodVisibility in Visibilities) then
  2185. begin
  2186. if Assigned(MethodList) then
  2187. MethodList^[Result]:=MethodEntry;
  2188. Inc(Result);
  2189. end;
  2190. end;
  2191. end;
  2192. { Go to parent type }
  2193. if aClassData^.Parent=Nil then
  2194. aClassData:=Nil
  2195. else
  2196. aClassData:=PClassData(GetTypeData(aClassData^.Parent^)); ;
  2197. end;
  2198. end;
  2199. Function GetMethodInfos(aClass: TClass; MethodList: PExtendedMethodInfoTable; Visibilities: TVisibilityClasses): Integer;
  2200. begin
  2201. Result:=GetMethodInfos(PTypeInfo(aClass.ClassInfo),MethodList,Visibilities);
  2202. end;
  2203. Function GetMethodInfos(TypeInfo: PTypeInfo; MethodList: PRecordMethodInfoTable; Visibilities : TVisibilityClasses = []) : Integer;
  2204. begin
  2205. if TypeInfo^.Kind=tkRecord then
  2206. Result:=GetRecordMethodInfos(PRecordData(GetTypeData(TypeInfo)),MethodList,Visibilities)
  2207. else
  2208. Result:=0
  2209. end;
  2210. Function GetMethodInfos(TypeInfo: PTypeInfo; MethodList: PExtendedMethodInfoTable; Visibilities: TVisibilityClasses): Integer;
  2211. begin
  2212. if TypeInfo^.Kind=tkClass then
  2213. Result:=GetClassMethodInfos(PClassData(GetTypeData(TypeInfo)),MethodList,Visibilities)
  2214. else
  2215. Result:=0
  2216. end;
  2217. Procedure InsertMethodEntry (PL : PExtendedMethodInfoTable;PI : PVmtMethodExEntry; Count : longint);
  2218. Var
  2219. I : Longint;
  2220. begin
  2221. I:=0;
  2222. While (I<Count) and (PI^.GetName >PL^[I]^.GetName) do
  2223. Inc(I);
  2224. If I<Count then
  2225. Move(PL^[I], PL^[I+1], (Count - I) * SizeOf(Pointer));
  2226. PL^[I]:=PI;
  2227. end;
  2228. Procedure InsertMethodEntryNoSort (PL : PExtendedMethodInfoTable;PI : PVmtMethodExEntry; Count : longint);
  2229. begin
  2230. PL^[Count]:=PI;
  2231. end;
  2232. Function GetMethodList(TypeInfo: PTypeInfo; out MethodList: PExtendedMethodInfoTable; Sorted: boolean;
  2233. Visibilities: TVisibilityClasses): longint;
  2234. Type
  2235. TInsertMethod = Procedure (PL : PExtendedMethodInfoTable;PI : PVmtMethodExEntry; Count : longint);
  2236. {
  2237. Store Pointers to method information OF A CERTAIN visibility in the list pointed
  2238. to by methodlist. MethodList must contain enough space to hold ALL methods.
  2239. }
  2240. Var
  2241. TempList : PExtendedMethodInfoTable;
  2242. MethodEntry : PVmtMethodExEntry;
  2243. I,aCount : longint;
  2244. DoInsertMethod : TInsertMethod;
  2245. begin
  2246. MethodList:=nil;
  2247. Result:=0;
  2248. aCount:=GetMethodList(TypeInfo,TempList,Visibilities);
  2249. if aCount=0 then
  2250. exit;
  2251. if sorted then
  2252. DoInsertMethod:=@InsertMethodEntry
  2253. else
  2254. DoInsertMethod:=@InsertMethodEntryNoSort;
  2255. MethodList:=GetMem(aCount*SizeOf(Pointer));
  2256. Try
  2257. For I:=0 to aCount-1 do
  2258. begin
  2259. MethodEntry:=TempList^[i];
  2260. DoInsertMethod(MethodList,MethodEntry,Result);
  2261. Inc(Result);
  2262. end;
  2263. finally
  2264. FreeMem(TempList);
  2265. end;
  2266. end;
  2267. Procedure InsertRecMethodEntry (PL : PRecordMethodInfoTable;PI : PRecMethodExEntry; Count : longint);
  2268. Var
  2269. I : Longint;
  2270. begin
  2271. I:=0;
  2272. While (I<Count) and (PI^.GetName >PL^[I]^.GetName) do
  2273. Inc(I);
  2274. If I<Count then
  2275. Move(PL^[I], PL^[I+1], (Count - I) * SizeOf(Pointer));
  2276. PL^[I]:=PI;
  2277. end;
  2278. Procedure InsertRecMethodEntryNoSort (PL : PRecordMethodInfoTable;PI : PRecMethodExEntry; Count : longint);
  2279. begin
  2280. PL^[Count]:=PI;
  2281. end;
  2282. Function GetMethodList(TypeInfo: PTypeInfo; out MethodList: PRecordMethodInfoTable; Sorted: boolean = true; Visibilities : TVisibilityClasses = []): longint;
  2283. Type
  2284. TInsertMethod = Procedure (PL : PRecordMethodInfoTable;PI : PRecMethodExEntry; Count : longint);
  2285. {
  2286. Store Pointers to method information OF A CERTAIN visibility in the list pointed
  2287. to by methodlist. MethodList must contain enough space to hold ALL methods.
  2288. }
  2289. Var
  2290. TempList : PRecordMethodInfoTable;
  2291. MethodEntry : PRecMethodExEntry;
  2292. I,aCount : longint;
  2293. DoInsertMethod : TInsertMethod;
  2294. begin
  2295. MethodList:=nil;
  2296. Result:=0;
  2297. aCount:=GetMethodList(TypeInfo,TempList,Visibilities);
  2298. if aCount=0 then
  2299. exit;
  2300. if sorted then
  2301. DoInsertMethod:=@InsertRecMethodEntry
  2302. else
  2303. DoInsertMethod:=@InsertRecMethodEntryNoSort;
  2304. MethodList:=GetMem(aCount*SizeOf(Pointer));
  2305. Try
  2306. For I:=0 to aCount-1 do
  2307. begin
  2308. MethodEntry:=TempList^[i];
  2309. DoInsertMethod(MethodList,MethodEntry,Result);
  2310. Inc(Result);
  2311. end;
  2312. finally
  2313. FreeMem(TempList);
  2314. end;
  2315. end;
  2316. Function GetRecordMethodInfos(aRecordData: PRecordData; MethodList: PRecordMethodInfoTable; Visibilities: TVisibilityClasses): Integer;
  2317. var
  2318. MethodTable: PRecordMethodTable;
  2319. MethodEntry: PRecMethodExEntry;
  2320. i: longint;
  2321. begin
  2322. Result:=0;
  2323. if aRecordData=Nil then
  2324. Exit;
  2325. MethodTable:=aRecordData^.GetMethodTable;
  2326. if MethodTable=Nil then
  2327. Exit;
  2328. For I:=0 to MethodTable^.Count-1 do
  2329. begin
  2330. MethodEntry:=MethodTable^.Method[i];
  2331. if ([]=Visibilities) or (MethodEntry^.MethodVisibility in Visibilities) then
  2332. begin
  2333. if Assigned(MethodList) then
  2334. MethodList^[Result]:=MethodEntry;
  2335. Inc(Result);
  2336. end;
  2337. end;
  2338. end;
  2339. Function GetRecordMethodList(aRecord: PRecordData; out MethodList: PRecordMethodInfoTable; Visibilities: TVisibilityClasses
  2340. ): Integer;
  2341. Var
  2342. aCount : Integer;
  2343. begin
  2344. Result:=0;
  2345. aCount:=GetRecordMethodInfos(aRecord,Nil,Visibilities);
  2346. if aCount=0 then
  2347. exit;
  2348. MethodList:=Getmem(aCount*SizeOf(Pointer));
  2349. try
  2350. Result:=GetRecordMethodInfos(aRecord,MethodList,Visibilities);
  2351. except
  2352. FreeMem(MethodList);
  2353. Raise;
  2354. end;
  2355. end;
  2356. Function GetMethodList(TypeInfo: PTypeInfo; out MethodList: PRecordMethodInfoTable; Visibilities : TVisibilityClasses = []): longint;
  2357. Var
  2358. aCount : Integer;
  2359. begin
  2360. Result:=0;
  2361. aCount:=GetMethodInfos(TypeInfo,PRecordMethodInfoTable(Nil),Visibilities);
  2362. MethodList:=Getmem(aCount*SizeOf(Pointer));
  2363. try
  2364. Result:=GetMethodInfos(TypeInfo,MethodList,Visibilities);
  2365. except
  2366. FreeMem(MethodList);
  2367. Raise;
  2368. end;
  2369. end;
  2370. Function GetMethodList(TypeInfo: PTypeInfo; out MethodList: PExtendedMethodInfoTable; Visibilities : TVisibilityClasses = []): longint;
  2371. Var
  2372. aCount : Integer;
  2373. begin
  2374. Result:=0;
  2375. aCount:=GetMethodInfos(TypeInfo,PExtendedMethodInfoTable(Nil),Visibilities);
  2376. MethodList:=Getmem(aCount*SizeOf(Pointer));
  2377. try
  2378. Result:=GetMethodInfos(TypeInfo,MethodList,Visibilities);
  2379. except
  2380. FreeMem(MethodList);
  2381. Raise;
  2382. end;
  2383. end;
  2384. Function GetMethodList(AClass: TClass; out MethodList: PExtendedMethodInfoTable; Visibilities: TVisibilityClasses): Integer;
  2385. Var
  2386. aCount : Integer;
  2387. begin
  2388. Result:=0;
  2389. aCount:=GetMethodInfos(aClass,Nil,[]);
  2390. MethodList:=Getmem(aCount*SizeOf(Pointer));
  2391. try
  2392. Result:=GetMethodInfos(aClass,MethodList,Visibilities);
  2393. except
  2394. FreeMem(MethodList);
  2395. Raise;
  2396. end;
  2397. end;
  2398. Function GetMethodList(Instance: TObject; out MethodList: PExtendedMethodInfoTable; Visibilities: TVisibilityClasses): Integer;
  2399. begin
  2400. Result:=GetMethodList(Instance.ClassType,MethodList,Visibilities);
  2401. end;
  2402. { -- Properties -- }
  2403. Procedure GetPropInfos(TypeInfo : PTypeInfo;PropList : PPropList);
  2404. {
  2405. Store Pointers to property information in the list pointed
  2406. to by proplist. PRopList must contain enough space to hold ALL
  2407. properties.
  2408. }
  2409. Var
  2410. TD : PTypeData;
  2411. TP : PPropInfo;
  2412. Count : Longint;
  2413. begin
  2414. // Get this objects TOTAL published properties count
  2415. TD:=GetTypeData(TypeInfo);
  2416. // Clear list
  2417. FillChar(PropList^,TD^.PropCount*sizeof(Pointer),0);
  2418. repeat
  2419. TD:=GetTypeData(TypeInfo);
  2420. // published properties count for this object
  2421. TP:=PPropInfo(GetPropData(TypeInfo, TD));
  2422. Count:=PWord(TP)^;
  2423. // Now point TP to first propinfo record.
  2424. Inc(Pointer(TP),SizeOF(Word));
  2425. tp:=aligntoptr(tp);
  2426. While Count>0 do
  2427. begin
  2428. // Don't overwrite properties with the same name
  2429. if PropList^[TP^.NameIndex]=nil then
  2430. PropList^[TP^.NameIndex]:=TP;
  2431. // Point to TP next propinfo record.
  2432. // Located at Name[Length(Name)+1] !
  2433. TP:=aligntoptr(PPropInfo(pointer(@TP^.Name)+PByte(@TP^.Name)^+1));
  2434. Dec(Count);
  2435. end;
  2436. TypeInfo:=TD^.Parentinfo;
  2437. until TypeInfo=nil;
  2438. end;
  2439. Procedure InsertProp (PL : PProplist;PI : PPropInfo; Count : longint);
  2440. Var
  2441. I : Longint;
  2442. begin
  2443. I:=0;
  2444. While (I<Count) and (PI^.Name>PL^[I]^.Name) do
  2445. Inc(I);
  2446. If I<Count then
  2447. Move(PL^[I], PL^[I+1], (Count - I) * SizeOf(Pointer));
  2448. PL^[I]:=PI;
  2449. end;
  2450. Procedure InsertPropnosort (PL : PProplist;PI : PPropInfo; Count : longint);
  2451. begin
  2452. PL^[Count]:=PI;
  2453. end;
  2454. Type TInsertProp = Procedure (PL : PProplist;PI : PPropInfo; Count : longint);
  2455. //Const InsertProps : array[false..boolean] of TInsertProp = (InsertPropNoSort,InsertProp);
  2456. Function GetPropList(TypeInfo : PTypeInfo;TypeKinds : TTypeKinds; PropList : PPropList;Sorted : boolean = true):longint;
  2457. {
  2458. Store Pointers to property information OF A CERTAIN KIND in the list pointed
  2459. to by proplist. PRopList must contain enough space to hold ALL
  2460. properties.
  2461. }
  2462. Var
  2463. TempList : PPropList;
  2464. PropInfo : PPropinfo;
  2465. I,Count : longint;
  2466. DoInsertProp : TInsertProp;
  2467. begin
  2468. if sorted then
  2469. DoInsertProp:=@InsertProp
  2470. else
  2471. DoInsertProp:=@InsertPropnosort;
  2472. Result:=0;
  2473. Count:=GetTypeData(TypeInfo)^.Propcount;
  2474. If Count>0 then
  2475. begin
  2476. GetMem(TempList,Count*SizeOf(Pointer));
  2477. Try
  2478. GetPropInfos(TypeInfo,TempList);
  2479. For I:=0 to Count-1 do
  2480. begin
  2481. PropInfo:=TempList^[i];
  2482. If PropInfo^.PropType^.Kind in TypeKinds then
  2483. begin
  2484. If (PropList<>Nil) then
  2485. DoInsertProp(PropList,PropInfo,Result);
  2486. Inc(Result);
  2487. end;
  2488. end;
  2489. finally
  2490. FreeMem(TempList,Count*SizeOf(Pointer));
  2491. end;
  2492. end;
  2493. end;
  2494. Function GetPropList(TypeInfo: PTypeInfo; out PropList: PPropList): SizeInt;
  2495. begin
  2496. result:=GetTypeData(TypeInfo)^.Propcount;
  2497. if result>0 then
  2498. begin
  2499. getmem(PropList,result*sizeof(pointer));
  2500. GetPropInfos(TypeInfo,PropList);
  2501. end
  2502. else
  2503. PropList:=Nil;
  2504. end;
  2505. function GetPropList(AClass: TClass; out PropList: PPropList): Integer;
  2506. begin
  2507. Result := GetPropList(PTypeInfo(AClass.ClassInfo), PropList);
  2508. end;
  2509. function GetPropList(Instance: TObject; out PropList: PPropList): Integer;
  2510. begin
  2511. Result := GetPropList(Instance.ClassType, PropList);
  2512. end;
  2513. { ---------------------------------------------------------------------
  2514. Property access functions
  2515. ---------------------------------------------------------------------}
  2516. { ---------------------------------------------------------------------
  2517. Ordinal properties
  2518. ---------------------------------------------------------------------}
  2519. Function GetOrdProp(Instance : TObject;PropInfo : PPropInfo) : Int64;
  2520. type
  2521. TGetInt64ProcIndex=function(index:longint):Int64 of object;
  2522. TGetInt64Proc=function():Int64 of object;
  2523. TGetIntegerProcIndex=function(index:longint):longint of object;
  2524. TGetIntegerProc=function:longint of object;
  2525. TGetWordProcIndex=function(index:longint):word of object;
  2526. TGetWordProc=function:word of object;
  2527. TGetByteProcIndex=function(index:longint):Byte of object;
  2528. TGetByteProc=function:Byte of object;
  2529. var
  2530. TypeInfo: PTypeInfo;
  2531. AMethod : TMethod;
  2532. DataSize: Integer;
  2533. OrdType: TOrdType;
  2534. Signed: Boolean;
  2535. begin
  2536. Result:=0;
  2537. TypeInfo := PropInfo^.PropType;
  2538. Signed := false;
  2539. DataSize := 4;
  2540. case TypeInfo^.Kind of
  2541. // We keep this for backwards compatibility, but internally it is no longer used.
  2542. {$ifdef cpu64}
  2543. tkInterface,
  2544. tkInterfaceRaw,
  2545. tkDynArray,
  2546. tkClass:
  2547. DataSize:=8;
  2548. {$endif cpu64}
  2549. tkChar, tkBool:
  2550. DataSize:=1;
  2551. tkWChar:
  2552. DataSize:=2;
  2553. tkSet,
  2554. tkEnumeration,
  2555. tkInteger:
  2556. begin
  2557. OrdType:=GetTypeData(TypeInfo)^.OrdType;
  2558. case OrdType of
  2559. otSByte,otUByte: DataSize := 1;
  2560. otSWord,otUWord: DataSize := 2;
  2561. end;
  2562. Signed := OrdType in [otSByte,otSWord,otSLong];
  2563. end;
  2564. tkInt64 :
  2565. begin
  2566. DataSize:=8;
  2567. Signed:=true;
  2568. end;
  2569. tkQword :
  2570. begin
  2571. DataSize:=8;
  2572. Signed:=false;
  2573. end;
  2574. end;
  2575. case (PropInfo^.PropProcs) and 3 of
  2576. ptField:
  2577. if Signed then begin
  2578. case DataSize of
  2579. 1: Result:=PShortInt(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2580. 2: Result:=PSmallInt(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2581. 4: Result:=PLongint(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2582. 8: Result:=PInt64(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2583. end;
  2584. end else begin
  2585. case DataSize of
  2586. 1: Result:=PByte(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2587. 2: Result:=PWord(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2588. 4: Result:=PLongint(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2589. 8: Result:=PInt64(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2590. end;
  2591. end;
  2592. ptStatic,
  2593. ptVirtual:
  2594. begin
  2595. if (PropInfo^.PropProcs and 3)=ptStatic then
  2596. AMethod.Code:=PropInfo^.GetProc
  2597. else
  2598. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2599. AMethod.Data:=Instance;
  2600. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then begin
  2601. case DataSize of
  2602. 1: Result:=TGetByteProcIndex(AMethod)(PropInfo^.Index);
  2603. 2: Result:=TGetWordProcIndex(AMethod)(PropInfo^.Index);
  2604. 4: Result:=TGetIntegerProcIndex(AMethod)(PropInfo^.Index);
  2605. 8: result:=TGetInt64ProcIndex(AMethod)(PropInfo^.Index)
  2606. end;
  2607. end else begin
  2608. case DataSize of
  2609. 1: Result:=TGetByteProc(AMethod)();
  2610. 2: Result:=TGetWordProc(AMethod)();
  2611. 4: Result:=TGetIntegerProc(AMethod)();
  2612. 8: result:=TGetInt64Proc(AMethod)();
  2613. end;
  2614. end;
  2615. if Signed then begin
  2616. case DataSize of
  2617. 1: Result:=ShortInt(Result);
  2618. 2: Result:=SmallInt(Result);
  2619. end;
  2620. end;
  2621. end;
  2622. else
  2623. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2624. end;
  2625. end;
  2626. Procedure SetOrdProp(Instance : TObject;PropInfo : PPropInfo;Value : Int64);
  2627. type
  2628. TSetInt64ProcIndex=procedure(index:longint;i:Int64) of object;
  2629. TSetInt64Proc=procedure(i:Int64) of object;
  2630. TSetIntegerProcIndex=procedure(index,i:longint) of object;
  2631. TSetIntegerProc=procedure(i:longint) of object;
  2632. var
  2633. DataSize: Integer;
  2634. AMethod : TMethod;
  2635. begin
  2636. if PropInfo^.PropType^.Kind in [tkInt64,tkQword
  2637. { why do we have to handle classes here, see also below? (FK) }
  2638. {$ifdef cpu64}
  2639. ,tkInterface
  2640. ,tkInterfaceRaw
  2641. ,tkDynArray
  2642. ,tkClass
  2643. {$endif cpu64}
  2644. ] then
  2645. DataSize := 8
  2646. else
  2647. DataSize := 4;
  2648. if not(PropInfo^.PropType^.Kind in [tkInt64,tkQword,tkClass,tkInterface,tkInterfaceRaw,tkDynArray]) then
  2649. begin
  2650. { cut off unnecessary stuff }
  2651. case GetTypeData(PropInfo^.PropType)^.OrdType of
  2652. otSWord,otUWord:
  2653. begin
  2654. Value:=Value and $ffff;
  2655. DataSize := 2;
  2656. end;
  2657. otSByte,otUByte:
  2658. begin
  2659. Value:=Value and $ff;
  2660. DataSize := 1;
  2661. end;
  2662. end;
  2663. end;
  2664. case (PropInfo^.PropProcs shr 2) and 3 of
  2665. ptField:
  2666. case DataSize of
  2667. 1: PByte(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Byte(Value);
  2668. 2: PWord(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Word(Value);
  2669. 4: PLongint(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Longint(Value);
  2670. 8: PInt64(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2671. end;
  2672. ptStatic,
  2673. ptVirtual:
  2674. begin
  2675. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2676. AMethod.Code:=PropInfo^.SetProc
  2677. else
  2678. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2679. AMethod.Data:=Instance;
  2680. if datasize=8 then
  2681. begin
  2682. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2683. TSetInt64ProcIndex(AMethod)(PropInfo^.Index,Value)
  2684. else
  2685. TSetInt64Proc(AMethod)(Value);
  2686. end
  2687. else
  2688. begin
  2689. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2690. TSetIntegerProcIndex(AMethod)(PropInfo^.Index,Value)
  2691. else
  2692. TSetIntegerProc(AMethod)(Value);
  2693. end;
  2694. end;
  2695. else
  2696. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2697. end;
  2698. end;
  2699. Function GetOrdProp(Instance: TObject; const PropName: string): Int64;
  2700. begin
  2701. Result:=GetOrdProp(Instance,FindPropInfo(Instance,PropName));
  2702. end;
  2703. Procedure SetOrdProp(Instance: TObject; const PropName: string; Value: Int64);
  2704. begin
  2705. SetOrdProp(Instance,FindPropInfo(Instance,PropName),Value);
  2706. end;
  2707. Function GetEnumProp(Instance: TObject; Const PropInfo: PPropInfo): string;
  2708. begin
  2709. Result:=GetEnumName(PropInfo^.PropType, GetOrdProp(Instance, PropInfo));
  2710. end;
  2711. Function GetEnumProp(Instance: TObject; const PropName: string): string;
  2712. begin
  2713. Result:=GetEnumProp(Instance,FindPropInfo(Instance,PropName));
  2714. end;
  2715. Procedure SetEnumProp(Instance: TObject; const PropName: string; const Value: string);
  2716. begin
  2717. SetEnumProp(Instance,FindPropInfo(Instance,PropName),Value);
  2718. end;
  2719. Procedure SetEnumProp(Instance: TObject; Const PropInfo : PPropInfo; const Value: string);
  2720. Var
  2721. PV : Longint;
  2722. begin
  2723. If PropInfo<>Nil then
  2724. begin
  2725. PV:=GetEnumValue(PropInfo^.PropType, Value);
  2726. if (PV<0) then
  2727. raise EPropertyError.CreateFmt(SErrUnknownEnumValue, [Value]);
  2728. SetOrdProp(Instance, PropInfo,PV);
  2729. end;
  2730. end;
  2731. { ---------------------------------------------------------------------
  2732. Int64 wrappers
  2733. ---------------------------------------------------------------------}
  2734. Function GetInt64Prop(Instance: TObject; PropInfo: PPropInfo): Int64;
  2735. begin
  2736. Result:=GetOrdProp(Instance,PropInfo);
  2737. end;
  2738. procedure SetInt64Prop(Instance: TObject; PropInfo: PPropInfo; const Value: Int64);
  2739. begin
  2740. SetOrdProp(Instance,PropInfo,Value);
  2741. end;
  2742. Function GetInt64Prop(Instance: TObject; const PropName: string): Int64;
  2743. begin
  2744. Result:=GetInt64Prop(Instance,FindPropInfo(Instance,PropName));
  2745. end;
  2746. Procedure SetInt64Prop(Instance: TObject; const PropName: string; const Value: Int64);
  2747. begin
  2748. SetInt64Prop(Instance,FindPropInfo(Instance,PropName),Value);
  2749. end;
  2750. { ---------------------------------------------------------------------
  2751. Set properties
  2752. ---------------------------------------------------------------------}
  2753. Function GetSetProp(Instance: TObject; const PropName: string): string;
  2754. begin
  2755. Result:=GetSetProp(Instance,PropName,False);
  2756. end;
  2757. Function GetSetProp(Instance: TObject; const PropName: string; Brackets: Boolean): string;
  2758. begin
  2759. Result:=GetSetProp(Instance,FindPropInfo(Instance,PropName),Brackets);
  2760. end;
  2761. Function GetSetProp(Instance: TObject; const PropInfo: PPropInfo; Brackets: Boolean): string;
  2762. begin
  2763. Result:=SetToString(PropInfo,GetOrdProp(Instance,PropInfo),Brackets);
  2764. end;
  2765. Procedure SetSetProp(Instance: TObject; const PropName: string; const Value: string);
  2766. begin
  2767. SetSetProp(Instance,FindPropInfo(Instance,PropName),Value);
  2768. end;
  2769. Procedure SetSetProp(Instance: TObject; const PropInfo: PPropInfo; const Value: string);
  2770. begin
  2771. SetOrdProp(Instance,PropInfo,StringToSet(PropInfo,Value));
  2772. end;
  2773. { ---------------------------------------------------------------------
  2774. Pointer properties - internal only
  2775. ---------------------------------------------------------------------}
  2776. Function GetPointerProp(Instance: TObject; PropInfo : PPropInfo): Pointer;
  2777. Type
  2778. TGetPointerProcIndex = function (index:longint): Pointer of object;
  2779. TGetPointerProc = function (): Pointer of object;
  2780. var
  2781. AMethod : TMethod;
  2782. begin
  2783. case (PropInfo^.PropProcs) and 3 of
  2784. ptField:
  2785. Result := PPointer(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  2786. ptStatic,
  2787. ptVirtual:
  2788. begin
  2789. if (PropInfo^.PropProcs and 3)=ptStatic then
  2790. AMethod.Code:=PropInfo^.GetProc
  2791. else
  2792. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2793. AMethod.Data:=Instance;
  2794. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2795. Result:=TGetPointerProcIndex(AMethod)(PropInfo^.Index)
  2796. else
  2797. Result:=TGetPointerProc(AMethod)();
  2798. end;
  2799. else
  2800. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2801. end;
  2802. end;
  2803. Procedure SetPointerProp(Instance: TObject; PropInfo : PPropInfo; Value: Pointer);
  2804. type
  2805. TSetPointerProcIndex = procedure(index: longint; p: pointer) of object;
  2806. TSetPointerProc = procedure(p: pointer) of object;
  2807. var
  2808. AMethod : TMethod;
  2809. begin
  2810. case (PropInfo^.PropProcs shr 2) and 3 of
  2811. ptField:
  2812. PPointer(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  2813. ptStatic,
  2814. ptVirtual:
  2815. begin
  2816. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2817. AMethod.Code:=PropInfo^.SetProc
  2818. else
  2819. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2820. AMethod.Data:=Instance;
  2821. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2822. TSetPointerProcIndex(AMethod)(PropInfo^.Index,Value)
  2823. else
  2824. TSetPointerProc(AMethod)(Value);
  2825. end;
  2826. else
  2827. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2828. end;
  2829. end;
  2830. { ---------------------------------------------------------------------
  2831. Object properties
  2832. ---------------------------------------------------------------------}
  2833. Function GetObjectProp(Instance: TObject; const PropName: string): TObject;
  2834. begin
  2835. Result:=GetObjectProp(Instance,PropName,Nil);
  2836. end;
  2837. Function GetObjectProp(Instance: TObject; const PropName: string; MinClass: TClass): TObject;
  2838. begin
  2839. Result:=GetObjectProp(Instance,FindPropInfo(Instance,PropName),MinClass);
  2840. end;
  2841. Function GetObjectProp(Instance: TObject; PropInfo : PPropInfo): TObject;
  2842. begin
  2843. Result:=GetObjectProp(Instance,PropInfo,Nil);
  2844. end;
  2845. Function GetObjectProp(Instance: TObject; PropInfo : PPropInfo; MinClass: TClass): TObject;
  2846. begin
  2847. Result:=TObject(GetPointerProp(Instance,PropInfo));
  2848. If (MinClass<>Nil) and (Result<>Nil) Then
  2849. If Not Result.InheritsFrom(MinClass) then
  2850. Result:=Nil;
  2851. end;
  2852. Procedure SetObjectProp(Instance: TObject; const PropName: string; Value: TObject);
  2853. begin
  2854. SetObjectProp(Instance,FindPropInfo(Instance,PropName),Value);
  2855. end;
  2856. Procedure SetObjectProp(Instance: TObject; PropInfo : PPropInfo; Value: TObject);
  2857. begin
  2858. SetPointerProp(Instance,PropInfo,Pointer(Value));
  2859. end;
  2860. Function GetObjectPropClass(Instance: TObject; const PropName: string): TClass;
  2861. begin
  2862. Result:=GetTypeData(FindPropInfo(Instance,PropName,[tkClass])^.PropType)^.ClassType;
  2863. end;
  2864. Function GetObjectPropClass(AClass: TClass; const PropName: string): TClass;
  2865. begin
  2866. Result:=GetTypeData(FindPropInfo(AClass,PropName,[tkClass])^.PropType)^.ClassType;
  2867. end;
  2868. { ---------------------------------------------------------------------
  2869. Interface wrapprers
  2870. ---------------------------------------------------------------------}
  2871. function GetInterfaceProp(Instance: TObject; const PropName: string): IInterface;
  2872. begin
  2873. Result:=GetInterfaceProp(Instance,FindPropInfo(Instance,PropName));
  2874. end;
  2875. function GetInterfaceProp(Instance: TObject; PropInfo: PPropInfo): IInterface;
  2876. type
  2877. TGetInterfaceProc=function:IInterface of object;
  2878. TGetInterfaceProcIndex=function(index:longint):IInterface of object;
  2879. var
  2880. AMethod : TMethod;
  2881. begin
  2882. Result:=nil;
  2883. case (PropInfo^.PropProcs) and 3 of
  2884. ptField:
  2885. Result:=IInterface(PPointer(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^);
  2886. ptStatic,
  2887. ptVirtual:
  2888. begin
  2889. if (PropInfo^.PropProcs and 3)=ptStatic then
  2890. AMethod.Code:=PropInfo^.GetProc
  2891. else
  2892. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2893. AMethod.Data:=Instance;
  2894. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2895. Result:=TGetInterfaceProcIndex(AMethod)(PropInfo^.Index)
  2896. else
  2897. Result:=TGetInterfaceProc(AMethod)();
  2898. end;
  2899. else
  2900. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2901. end;
  2902. end;
  2903. procedure SetInterfaceProp(Instance: TObject; const PropName: string; const Value: IInterface);
  2904. begin
  2905. SetInterfaceProp(Instance,FindPropInfo(Instance,PropName),Value);
  2906. end;
  2907. procedure SetInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: IInterface);
  2908. type
  2909. TSetIntfStrProcIndex=procedure(index:longint;const i:IInterface) of object;
  2910. TSetIntfStrProc=procedure(i:IInterface) of object;
  2911. var
  2912. AMethod : TMethod;
  2913. begin
  2914. case Propinfo^.PropType^.Kind of
  2915. tkInterface:
  2916. begin
  2917. case (PropInfo^.PropProcs shr 2) and 3 of
  2918. ptField:
  2919. PInterface(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2920. ptStatic,
  2921. ptVirtual:
  2922. begin
  2923. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2924. AMethod.Code:=PropInfo^.SetProc
  2925. else
  2926. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2927. AMethod.Data:=Instance;
  2928. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2929. TSetIntfStrProcIndex(AMethod)(PropInfo^.Index,Value)
  2930. else
  2931. TSetIntfStrProc(AMethod)(Value);
  2932. end;
  2933. else
  2934. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2935. end;
  2936. end;
  2937. tkInterfaceRaw:
  2938. Raise Exception.Create('Cannot set RAW interface from IUnknown interface');
  2939. end;
  2940. end;
  2941. { ---------------------------------------------------------------------
  2942. RAW (Corba) Interface wrapprers
  2943. ---------------------------------------------------------------------}
  2944. function GetRawInterfaceProp(Instance: TObject; const PropName: string): Pointer;
  2945. begin
  2946. Result:=GetRawInterfaceProp(Instance,FindPropInfo(Instance,PropName));
  2947. end;
  2948. function GetRawInterfaceProp(Instance: TObject; PropInfo: PPropInfo): Pointer;
  2949. begin
  2950. Result:=GetPointerProp(Instance,PropInfo);
  2951. end;
  2952. procedure SetRawInterfaceProp(Instance: TObject; const PropName: string; const Value: Pointer);
  2953. begin
  2954. SetRawInterfaceProp(Instance,FindPropInfo(Instance,PropName),Value);
  2955. end;
  2956. procedure SetRawInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: Pointer);
  2957. begin
  2958. SetPointerProp(Instance,PropInfo,Value);
  2959. end;
  2960. { ---------------------------------------------------------------------
  2961. Dynamic array properties
  2962. ---------------------------------------------------------------------}
  2963. function GetDynArrayProp(Instance: TObject; const PropName: string): Pointer;
  2964. begin
  2965. Result:=GetDynArrayProp(Instance,FindPropInfo(Instance,PropName));
  2966. end;
  2967. function GetDynArrayProp(Instance: TObject; PropInfo: PPropInfo): Pointer;
  2968. type
  2969. { we need a dynamic array as that type is usually passed differently from
  2970. a plain pointer }
  2971. TDynArray=array of Byte;
  2972. TGetDynArrayProc=function:TDynArray of object;
  2973. TGetDynArrayProcIndex=function(index:longint):TDynArray of object;
  2974. var
  2975. AMethod : TMethod;
  2976. begin
  2977. Result:=nil;
  2978. if PropInfo^.PropType^.Kind<>tkDynArray then
  2979. Exit;
  2980. case (PropInfo^.PropProcs) and 3 of
  2981. ptField:
  2982. Result:=PPointer(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2983. ptStatic,
  2984. ptVirtual:
  2985. begin
  2986. if (PropInfo^.PropProcs and 3)=ptStatic then
  2987. AMethod.Code:=PropInfo^.GetProc
  2988. else
  2989. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2990. AMethod.Data:=Instance;
  2991. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2992. Result:=Pointer(TGetDynArrayProcIndex(AMethod)(PropInfo^.Index))
  2993. else
  2994. Result:=Pointer(TGetDynArrayProc(AMethod)());
  2995. end;
  2996. else
  2997. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2998. end;
  2999. end;
  3000. procedure SetDynArrayProp(Instance: TObject; const PropName: string; const Value: Pointer);
  3001. begin
  3002. SetDynArrayProp(Instance,FindPropInfo(Instance,PropName),Value);
  3003. end;
  3004. procedure SetDynArrayProp(Instance: TObject; PropInfo: PPropInfo; const Value: Pointer);
  3005. type
  3006. { we need a dynamic array as that type is usually passed differently from
  3007. a plain pointer }
  3008. TDynArray=array of Byte;
  3009. TSetDynArrayProcIndex=procedure(index:longint;const i:TDynArray) of object;
  3010. TSetDynArrayProc=procedure(i:TDynArray) of object;
  3011. var
  3012. AMethod: TMethod;
  3013. begin
  3014. if PropInfo^.PropType^.Kind<>tkDynArray then
  3015. Exit;
  3016. case (PropInfo^.PropProcs shr 2) and 3 of
  3017. ptField:
  3018. CopyArray(PPointer(Pointer(Instance)+PtrUInt(PropInfo^.SetProc)), @Value, PropInfo^.PropType, 1);
  3019. ptStatic,
  3020. ptVirtual:
  3021. begin
  3022. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  3023. AMethod.Code:=PropInfo^.SetProc
  3024. else
  3025. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  3026. AMethod.Data:=Instance;
  3027. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  3028. TSetDynArrayProcIndex(AMethod)(PropInfo^.Index,TDynArray(Value))
  3029. else
  3030. TSetDynArrayProc(AMethod)(TDynArray(Value));
  3031. end;
  3032. else
  3033. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  3034. end;
  3035. end;
  3036. { ---------------------------------------------------------------------
  3037. String properties
  3038. ---------------------------------------------------------------------}
  3039. Function GetStrProp(Instance: TObject; PropInfo: PPropInfo): AnsiString;
  3040. type
  3041. TGetShortStrProcIndex=function(index:longint):ShortString of object;
  3042. TGetShortStrProc=function():ShortString of object;
  3043. TGetAnsiStrProcIndex=function(index:longint):AnsiString of object;
  3044. TGetAnsiStrProc=function():AnsiString of object;
  3045. var
  3046. AMethod : TMethod;
  3047. begin
  3048. Result:='';
  3049. case Propinfo^.PropType^.Kind of
  3050. tkWString:
  3051. Result:=AnsiString(GetWideStrProp(Instance,PropInfo));
  3052. tkUString:
  3053. Result := AnsiString(GetUnicodeStrProp(Instance,PropInfo));
  3054. tkSString:
  3055. begin
  3056. case (PropInfo^.PropProcs) and 3 of
  3057. ptField:
  3058. Result := PShortString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  3059. ptStatic,
  3060. ptVirtual:
  3061. begin
  3062. if (PropInfo^.PropProcs and 3)=ptStatic then
  3063. AMethod.Code:=PropInfo^.GetProc
  3064. else
  3065. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  3066. AMethod.Data:=Instance;
  3067. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  3068. Result:=TGetShortStrProcIndex(AMethod)(PropInfo^.Index)
  3069. else
  3070. Result:=TGetShortStrProc(AMethod)();
  3071. end;
  3072. else
  3073. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  3074. end;
  3075. end;
  3076. tkAString:
  3077. begin
  3078. case (PropInfo^.PropProcs) and 3 of
  3079. ptField:
  3080. Result := PAnsiString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  3081. ptStatic,
  3082. ptVirtual:
  3083. begin
  3084. if (PropInfo^.PropProcs and 3)=ptStatic then
  3085. AMethod.Code:=PropInfo^.GetProc
  3086. else
  3087. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  3088. AMethod.Data:=Instance;
  3089. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  3090. Result:=TGetAnsiStrProcIndex(AMethod)(PropInfo^.Index)
  3091. else
  3092. Result:=TGetAnsiStrProc(AMethod)();
  3093. end;
  3094. else
  3095. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  3096. end;
  3097. end;
  3098. end;
  3099. end;
  3100. Procedure SetStrProp(Instance : TObject;PropInfo : PPropInfo; const Value : AnsiString);
  3101. type
  3102. TSetShortStrProcIndex=procedure(index:longint;const s:ShortString) of object;
  3103. TSetShortStrProc=procedure(const s:ShortString) of object;
  3104. TSetAnsiStrProcIndex=procedure(index:longint;s:AnsiString) of object;
  3105. TSetAnsiStrProc=procedure(s:AnsiString) of object;
  3106. var
  3107. AMethod : TMethod;
  3108. begin
  3109. case Propinfo^.PropType^.Kind of
  3110. tkWString:
  3111. SetWideStrProp(Instance,PropInfo,WideString(Value));
  3112. tkUString:
  3113. SetUnicodeStrProp(Instance,PropInfo,UnicodeString(Value));
  3114. tkSString:
  3115. begin
  3116. case (PropInfo^.PropProcs shr 2) and 3 of
  3117. ptField:
  3118. PShortString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  3119. ptStatic,
  3120. ptVirtual:
  3121. begin
  3122. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  3123. AMethod.Code:=PropInfo^.SetProc
  3124. else
  3125. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  3126. AMethod.Data:=Instance;
  3127. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  3128. TSetShortStrProcIndex(AMethod)(PropInfo^.Index,Value)
  3129. else
  3130. TSetShortStrProc(AMethod)(Value);
  3131. end;
  3132. else
  3133. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  3134. end;
  3135. end;
  3136. tkAString:
  3137. begin
  3138. case (PropInfo^.PropProcs shr 2) and 3 of
  3139. ptField:
  3140. PAnsiString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  3141. ptStatic,
  3142. ptVirtual:
  3143. begin
  3144. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  3145. AMethod.Code:=PropInfo^.SetProc
  3146. else
  3147. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  3148. AMethod.Data:=Instance;
  3149. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  3150. TSetAnsiStrProcIndex(AMethod)(PropInfo^.Index,Value)
  3151. else
  3152. TSetAnsiStrProc(AMethod)(Value);
  3153. end;
  3154. else
  3155. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  3156. end;
  3157. end;
  3158. end;
  3159. end;
  3160. Function GetStrProp(Instance: TObject; const PropName: string): string;
  3161. begin
  3162. Result:=GetStrProp(Instance,FindPropInfo(Instance,PropName));
  3163. end;
  3164. Procedure SetStrProp(Instance: TObject; const PropName: string; const Value: AnsiString);
  3165. begin
  3166. SetStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  3167. end;
  3168. Function GetWideStrProp(Instance: TObject; const PropName: string): WideString;
  3169. begin
  3170. Result:=GetWideStrProp(Instance, FindPropInfo(Instance, PropName));
  3171. end;
  3172. procedure SetWideStrProp(Instance: TObject; const PropName: string; const Value: WideString);
  3173. begin
  3174. SetWideStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  3175. end;
  3176. Function GetWideStrProp(Instance: TObject; PropInfo: PPropInfo): WideString;
  3177. type
  3178. TGetWideStrProcIndex=function(index:longint):WideString of object;
  3179. TGetWideStrProc=function():WideString of object;
  3180. var
  3181. AMethod : TMethod;
  3182. begin
  3183. Result:='';
  3184. case Propinfo^.PropType^.Kind of
  3185. tkSString,tkAString:
  3186. Result:=WideString(GetStrProp(Instance,PropInfo));
  3187. tkUString :
  3188. Result := GetUnicodeStrProp(Instance,PropInfo);
  3189. tkWString:
  3190. begin
  3191. case (PropInfo^.PropProcs) and 3 of
  3192. ptField:
  3193. Result := PWideString(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  3194. ptStatic,
  3195. ptVirtual:
  3196. begin
  3197. if (PropInfo^.PropProcs and 3)=ptStatic then
  3198. AMethod.Code:=PropInfo^.GetProc
  3199. else
  3200. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  3201. AMethod.Data:=Instance;
  3202. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  3203. Result:=TGetWideStrProcIndex(AMethod)(PropInfo^.Index)
  3204. else
  3205. Result:=TGetWideStrProc(AMethod)();
  3206. end;
  3207. else
  3208. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  3209. end;
  3210. end;
  3211. end;
  3212. end;
  3213. Procedure SetWideStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: WideString);
  3214. type
  3215. TSetWideStrProcIndex=procedure(index:longint;s:WideString) of object;
  3216. TSetWideStrProc=procedure(s:WideString) of object;
  3217. var
  3218. AMethod : TMethod;
  3219. begin
  3220. case Propinfo^.PropType^.Kind of
  3221. tkSString,tkAString:
  3222. SetStrProp(Instance,PropInfo,AnsiString(Value));
  3223. tkUString:
  3224. SetUnicodeStrProp(Instance,PropInfo,Value);
  3225. tkWString:
  3226. begin
  3227. case (PropInfo^.PropProcs shr 2) and 3 of
  3228. ptField:
  3229. PWideString(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  3230. ptStatic,
  3231. ptVirtual:
  3232. begin
  3233. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  3234. AMethod.Code:=PropInfo^.SetProc
  3235. else
  3236. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  3237. AMethod.Data:=Instance;
  3238. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  3239. TSetWideStrProcIndex(AMethod)(PropInfo^.Index,Value)
  3240. else
  3241. TSetWideStrProc(AMethod)(Value);
  3242. end;
  3243. else
  3244. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  3245. end;
  3246. end;
  3247. end;
  3248. end;
  3249. Function GetUnicodeStrProp(Instance: TObject; const PropName: string): UnicodeString;
  3250. begin
  3251. Result:=GetUnicodeStrProp(Instance, FindPropInfo(Instance, PropName));
  3252. end;
  3253. procedure SetUnicodeStrProp(Instance: TObject; const PropName: string; const Value: UnicodeString);
  3254. begin
  3255. SetUnicodeStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  3256. end;
  3257. Function GetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo): UnicodeString;
  3258. type
  3259. TGetUnicodeStrProcIndex=function(index:longint):UnicodeString of object;
  3260. TGetUnicodeStrProc=function():UnicodeString of object;
  3261. var
  3262. AMethod : TMethod;
  3263. begin
  3264. Result:='';
  3265. case Propinfo^.PropType^.Kind of
  3266. tkSString,tkAString:
  3267. Result:=UnicodeString(GetStrProp(Instance,PropInfo));
  3268. tkWString:
  3269. Result:=GetWideStrProp(Instance,PropInfo);
  3270. tkUString:
  3271. begin
  3272. case (PropInfo^.PropProcs) and 3 of
  3273. ptField:
  3274. Result := PUnicodeString(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  3275. ptStatic,
  3276. ptVirtual:
  3277. begin
  3278. if (PropInfo^.PropProcs and 3)=ptStatic then
  3279. AMethod.Code:=PropInfo^.GetProc
  3280. else
  3281. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  3282. AMethod.Data:=Instance;
  3283. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  3284. Result:=TGetUnicodeStrProcIndex(AMethod)(PropInfo^.Index)
  3285. else
  3286. Result:=TGetUnicodeStrProc(AMethod)();
  3287. end;
  3288. else
  3289. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  3290. end;
  3291. end;
  3292. end;
  3293. end;
  3294. Procedure SetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: UnicodeString);
  3295. type
  3296. TSetUnicodeStrProcIndex=procedure(index:longint;s:UnicodeString) of object;
  3297. TSetUnicodeStrProc=procedure(s:UnicodeString) of object;
  3298. var
  3299. AMethod : TMethod;
  3300. begin
  3301. case Propinfo^.PropType^.Kind of
  3302. tkSString,tkAString:
  3303. SetStrProp(Instance,PropInfo,AnsiString(Value));
  3304. tkWString:
  3305. SetWideStrProp(Instance,PropInfo,Value);
  3306. tkUString:
  3307. begin
  3308. case (PropInfo^.PropProcs shr 2) and 3 of
  3309. ptField:
  3310. PUnicodeString(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  3311. ptStatic,
  3312. ptVirtual:
  3313. begin
  3314. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  3315. AMethod.Code:=PropInfo^.SetProc
  3316. else
  3317. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  3318. AMethod.Data:=Instance;
  3319. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  3320. TSetUnicodeStrProcIndex(AMethod)(PropInfo^.Index,Value)
  3321. else
  3322. TSetUnicodeStrProc(AMethod)(Value);
  3323. end;
  3324. else
  3325. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  3326. end;
  3327. end;
  3328. end;
  3329. end;
  3330. function GetRawbyteStrProp(Instance: TObject; PropInfo: PPropInfo): RawByteString;
  3331. type
  3332. TGetRawByteStrProcIndex=function(index:longint): RawByteString of object;
  3333. TGetRawByteStrProc=function():RawByteString of object;
  3334. var
  3335. AMethod : TMethod;
  3336. begin
  3337. Result:='';
  3338. case Propinfo^.PropType^.Kind of
  3339. tkWString:
  3340. Result:=RawByteString(GetWideStrProp(Instance,PropInfo));
  3341. tkUString:
  3342. Result:=RawByteString(GetUnicodeStrProp(Instance,PropInfo));
  3343. tkSString:
  3344. Result:=RawByteString(GetStrProp(Instance,PropInfo));
  3345. tkAString:
  3346. begin
  3347. case (PropInfo^.PropProcs) and 3 of
  3348. ptField:
  3349. Result := PAnsiString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  3350. ptStatic,
  3351. ptVirtual:
  3352. begin
  3353. if (PropInfo^.PropProcs and 3)=ptStatic then
  3354. AMethod.Code:=PropInfo^.GetProc
  3355. else
  3356. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  3357. AMethod.Data:=Instance;
  3358. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  3359. Result:=TGetRawByteStrProcIndex(AMethod)(PropInfo^.Index)
  3360. else
  3361. Result:=TGetRawByteStrProc(AMethod)();
  3362. end;
  3363. else
  3364. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  3365. end;
  3366. end;
  3367. end;
  3368. end;
  3369. function GetRawByteStrProp(Instance: TObject; const PropName: string): RawByteString;
  3370. begin
  3371. Result:=GetRawByteStrProp(Instance,FindPropInfo(Instance,PropName));
  3372. end;
  3373. procedure SetRawByteStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: RawByteString);
  3374. type
  3375. TSetRawByteStrProcIndex=procedure(index:longint;s:RawByteString) of object;
  3376. TSetRawByteStrProc=procedure(s:RawByteString) of object;
  3377. var
  3378. AMethod : TMethod;
  3379. begin
  3380. case Propinfo^.PropType^.Kind of
  3381. tkWString:
  3382. SetWideStrProp(Instance,PropInfo,WideString(Value));
  3383. tkUString:
  3384. SetUnicodeStrProp(Instance,PropInfo,UnicodeString(Value));
  3385. tkSString:
  3386. SetStrProp(Instance,PropInfo,Value); // Not 100% sure about this.
  3387. tkAString:
  3388. begin
  3389. case (PropInfo^.PropProcs shr 2) and 3 of
  3390. ptField:
  3391. PAnsiString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  3392. ptStatic,
  3393. ptVirtual:
  3394. begin
  3395. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  3396. AMethod.Code:=PropInfo^.SetProc
  3397. else
  3398. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  3399. AMethod.Data:=Instance;
  3400. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  3401. TSetRawByteStrProcIndex(AMethod)(PropInfo^.Index,Value)
  3402. else
  3403. TSetRawByteStrProc(AMethod)(Value);
  3404. end;
  3405. else
  3406. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  3407. end;
  3408. end;
  3409. end;
  3410. end;
  3411. procedure SetRawByteStrProp(Instance: TObject; const PropName: string; const Value: RawByteString);
  3412. begin
  3413. SetRawByteStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  3414. end;
  3415. {$ifndef FPUNONE}
  3416. { ---------------------------------------------------------------------
  3417. Float properties
  3418. ---------------------------------------------------------------------}
  3419. function GetFloatProp(Instance : TObject;PropInfo : PPropInfo) : Extended;
  3420. type
  3421. TGetExtendedProc = function:Extended of object;
  3422. TGetExtendedProcIndex = function(Index: integer): Extended of object;
  3423. TGetDoubleProc = function:Double of object;
  3424. TGetDoubleProcIndex = function(Index: integer): Double of object;
  3425. TGetSingleProc = function:Single of object;
  3426. TGetSingleProcIndex = function(Index: integer):Single of object;
  3427. TGetCurrencyProc = function : Currency of object;
  3428. TGetCurrencyProcIndex = function(Index: integer) : Currency of object;
  3429. var
  3430. AMethod : TMethod;
  3431. begin
  3432. Result:=0.0;
  3433. case PropInfo^.PropProcs and 3 of
  3434. ptField:
  3435. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  3436. ftSingle:
  3437. Result:=PSingle(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  3438. ftDouble:
  3439. Result:=PDouble(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  3440. ftExtended:
  3441. Result:=PExtended(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  3442. ftcomp:
  3443. Result:=PComp(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  3444. ftcurr:
  3445. Result:=PCurrency(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  3446. end;
  3447. ptStatic,
  3448. ptVirtual:
  3449. begin
  3450. if (PropInfo^.PropProcs and 3)=ptStatic then
  3451. AMethod.Code:=PropInfo^.GetProc
  3452. else
  3453. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  3454. AMethod.Data:=Instance;
  3455. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  3456. ftSingle:
  3457. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  3458. Result:=TGetSingleProc(AMethod)()
  3459. else
  3460. Result:=TGetSingleProcIndex(AMethod)(PropInfo^.Index);
  3461. ftDouble:
  3462. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  3463. Result:=TGetDoubleProc(AMethod)()
  3464. else
  3465. Result:=TGetDoubleProcIndex(AMethod)(PropInfo^.Index);
  3466. ftExtended:
  3467. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  3468. Result:=TGetExtendedProc(AMethod)()
  3469. else
  3470. Result:=TGetExtendedProcIndex(AMethod)(PropInfo^.Index);
  3471. ftCurr:
  3472. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  3473. Result:=TGetCurrencyProc(AMethod)()
  3474. else
  3475. Result:=TGetCurrencyProcIndex(AMethod)(PropInfo^.Index);
  3476. end;
  3477. end;
  3478. else
  3479. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  3480. end;
  3481. end;
  3482. Procedure SetFloatProp(Instance : TObject;PropInfo : PPropInfo; Value : Extended);
  3483. type
  3484. TSetExtendedProc = procedure(const AValue: Extended) of object;
  3485. TSetExtendedProcIndex = procedure(Index: integer; AValue: Extended) of object;
  3486. TSetDoubleProc = procedure(const AValue: Double) of object;
  3487. TSetDoubleProcIndex = procedure(Index: integer; AValue: Double) of object;
  3488. TSetSingleProc = procedure(const AValue: Single) of object;
  3489. TSetSingleProcIndex = procedure(Index: integer; AValue: Single) of object;
  3490. TSetCurrencyProc = procedure(const AValue: Currency) of object;
  3491. TSetCurrencyProcIndex = procedure(Index: integer; AValue: Currency) of object;
  3492. Var
  3493. AMethod : TMethod;
  3494. begin
  3495. case (PropInfo^.PropProcs shr 2) and 3 of
  3496. ptfield:
  3497. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  3498. ftSingle:
  3499. PSingle(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  3500. ftDouble:
  3501. PDouble(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  3502. ftExtended:
  3503. PExtended(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  3504. {$ifdef FPC_COMP_IS_INT64}
  3505. ftComp:
  3506. PComp(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=trunc(Value);
  3507. {$else FPC_COMP_IS_INT64}
  3508. ftComp:
  3509. PComp(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Comp(Value);
  3510. {$endif FPC_COMP_IS_INT64}
  3511. ftCurr:
  3512. PCurrency(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  3513. end;
  3514. ptStatic,
  3515. ptVirtual:
  3516. begin
  3517. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  3518. AMethod.Code:=PropInfo^.SetProc
  3519. else
  3520. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  3521. AMethod.Data:=Instance;
  3522. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  3523. ftSingle:
  3524. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  3525. TSetSingleProc(AMethod)(Value)
  3526. else
  3527. TSetSingleProcIndex(AMethod)(PropInfo^.Index,Value);
  3528. ftDouble:
  3529. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  3530. TSetDoubleProc(AMethod)(Value)
  3531. else
  3532. TSetDoubleProcIndex(AMethod)(PropInfo^.Index,Value);
  3533. ftExtended:
  3534. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  3535. TSetExtendedProc(AMethod)(Value)
  3536. else
  3537. TSetExtendedProcIndex(AMethod)(PropInfo^.Index,Value);
  3538. ftCurr:
  3539. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  3540. TSetCurrencyProc(AMethod)(Value)
  3541. else
  3542. TSetCurrencyProcIndex(AMethod)(PropInfo^.Index,Value);
  3543. end;
  3544. end;
  3545. else
  3546. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  3547. end;
  3548. end;
  3549. function GetFloatProp(Instance: TObject; const PropName: string): Extended;
  3550. begin
  3551. Result:=GetFloatProp(Instance,FindPropInfo(Instance,PropName))
  3552. end;
  3553. Procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Extended);
  3554. begin
  3555. SetFloatProp(Instance,FindPropInfo(Instance,PropName),Value);
  3556. end;
  3557. {$endif}
  3558. { ---------------------------------------------------------------------
  3559. Method properties
  3560. ---------------------------------------------------------------------}
  3561. Function GetMethodProp(Instance : TObject;PropInfo : PPropInfo) : TMethod;
  3562. type
  3563. TGetMethodProcIndex=function(Index: Longint): TMethod of object;
  3564. TGetMethodProc=function(): TMethod of object;
  3565. var
  3566. value: PMethod;
  3567. AMethod : TMethod;
  3568. begin
  3569. Result.Code:=nil;
  3570. Result.Data:=nil;
  3571. case (PropInfo^.PropProcs) and 3 of
  3572. ptField:
  3573. begin
  3574. Value:=PMethod(Pointer(Instance)+PtrUInt(PropInfo^.GetProc));
  3575. if Value<>nil then
  3576. Result:=Value^;
  3577. end;
  3578. ptStatic,
  3579. ptVirtual:
  3580. begin
  3581. if (PropInfo^.PropProcs and 3)=ptStatic then
  3582. AMethod.Code:=PropInfo^.GetProc
  3583. else
  3584. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  3585. AMethod.Data:=Instance;
  3586. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  3587. Result:=TGetMethodProcIndex(AMethod)(PropInfo^.Index)
  3588. else
  3589. Result:=TGetMethodProc(AMethod)();
  3590. end;
  3591. else
  3592. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  3593. end;
  3594. end;
  3595. Procedure SetMethodProp(Instance : TObject;PropInfo : PPropInfo; const Value : TMethod);
  3596. type
  3597. TSetMethodProcIndex=procedure(index:longint;p:TMethod) of object;
  3598. TSetMethodProc=procedure(p:TMethod) of object;
  3599. var
  3600. AMethod : TMethod;
  3601. begin
  3602. case (PropInfo^.PropProcs shr 2) and 3 of
  3603. ptField:
  3604. PMethod(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^ := Value;
  3605. ptStatic,
  3606. ptVirtual:
  3607. begin
  3608. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  3609. AMethod.Code:=PropInfo^.SetProc
  3610. else
  3611. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  3612. AMethod.Data:=Instance;
  3613. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  3614. TSetMethodProcIndex(AMethod)(PropInfo^.Index,Value)
  3615. else
  3616. TSetMethodProc(AMethod)(Value);
  3617. end;
  3618. else
  3619. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  3620. end;
  3621. end;
  3622. Function GetMethodProp(Instance: TObject; const PropName: string): TMethod;
  3623. begin
  3624. Result:=GetMethodProp(Instance,FindPropInfo(Instance,PropName));
  3625. end;
  3626. Procedure SetMethodProp(Instance: TObject; const PropName: string; const Value: TMethod);
  3627. begin
  3628. SetMethodProp(Instance,FindPropInfo(Instance,PropName),Value);
  3629. end;
  3630. { ---------------------------------------------------------------------
  3631. Variant properties
  3632. ---------------------------------------------------------------------}
  3633. Procedure CheckVariantEvent(P : CodePointer);
  3634. begin
  3635. If (P=Nil) then
  3636. Raise Exception.Create(SErrNoVariantSupport);
  3637. end;
  3638. Function GetVariantProp(Instance : TObject;PropInfo : PPropInfo): Variant;
  3639. begin
  3640. CheckVariantEvent(CodePointer(OnGetVariantProp));
  3641. Result:=OnGetVariantProp(Instance,PropInfo);
  3642. end;
  3643. Procedure SetVariantProp(Instance : TObject;PropInfo : PPropInfo; const Value: Variant);
  3644. begin
  3645. CheckVariantEvent(CodePointer(OnSetVariantProp));
  3646. OnSetVariantProp(Instance,PropInfo,Value);
  3647. end;
  3648. Function GetVariantProp(Instance: TObject; const PropName: string): Variant;
  3649. begin
  3650. Result:=GetVariantProp(Instance,FindPropInfo(Instance,PropName));
  3651. end;
  3652. Procedure SetVariantProp(Instance: TObject; const PropName: string; const Value: Variant);
  3653. begin
  3654. SetVariantprop(instance,FindpropInfo(Instance,PropName),Value);
  3655. end;
  3656. { ---------------------------------------------------------------------
  3657. All properties through variant.
  3658. ---------------------------------------------------------------------}
  3659. Function GetPropValue(Instance: TObject; const PropName: string): Variant;
  3660. begin
  3661. Result := GetPropValue(Instance,FindPropInfo(Instance, PropName));
  3662. end;
  3663. Function GetPropValue(Instance: TObject; const PropName: string; PreferStrings: Boolean): Variant;
  3664. begin
  3665. Result := GetPropValue(Instance,FindPropInfo(Instance, PropName),PreferStrings);
  3666. end;
  3667. Function GetPropValue(Instance: TObject; PropInfo: PPropInfo): Variant;
  3668. begin
  3669. Result := GetPropValue(Instance, PropInfo, True);
  3670. end;
  3671. Function GetPropValue(Instance: TObject; PropInfo: PPropInfo; PreferStrings: Boolean): Variant;
  3672. begin
  3673. CheckVariantEvent(CodePointer(OnGetPropValue));
  3674. Result:=OnGetPropValue(Instance,PropInfo,PreferStrings);
  3675. end;
  3676. Procedure SetPropValue(Instance: TObject; const PropName: string; const Value: Variant);
  3677. begin
  3678. SetPropValue(Instance, FindPropInfo(Instance, PropName), Value);
  3679. end;
  3680. Procedure SetPropValue(Instance: TObject; PropInfo: PPropInfo; const Value: Variant);
  3681. begin
  3682. CheckVariantEvent(CodePointer(OnSetPropValue));
  3683. OnSetPropValue(Instance,PropInfo,Value);
  3684. end;
  3685. { ---------------------------------------------------------------------
  3686. Easy access methods that appeared in Delphi 5
  3687. ---------------------------------------------------------------------}
  3688. Function IsPublishedProp(Instance: TObject; const PropName: string): Boolean;
  3689. begin
  3690. Result:=GetPropInfo(Instance,PropName)<>Nil;
  3691. end;
  3692. Function IsPublishedProp(AClass: TClass; const PropName: string): Boolean;
  3693. begin
  3694. Result:=GetPropInfo(AClass,PropName)<>Nil;
  3695. end;
  3696. Function PropIsType(Instance: TObject; const PropName: string; TypeKind: TTypeKind): Boolean;
  3697. begin
  3698. Result:=PropType(Instance,PropName)=TypeKind
  3699. end;
  3700. Function PropIsType(AClass: TClass; const PropName: string; TypeKind: TTypeKind): Boolean;
  3701. begin
  3702. Result:=PropType(AClass,PropName)=TypeKind
  3703. end;
  3704. Function PropType(Instance: TObject; const PropName: string): TTypeKind;
  3705. begin
  3706. Result:=FindPropInfo(Instance,PropName)^.PropType^.Kind;
  3707. end;
  3708. Function PropType(AClass: TClass; const PropName: string): TTypeKind;
  3709. begin
  3710. Result:=FindPropInfo(AClass,PropName)^.PropType^.Kind;
  3711. end;
  3712. Function IsStoredProp(Instance: TObject; const PropName: string): Boolean;
  3713. begin
  3714. Result:=IsStoredProp(instance,FindPropInfo(Instance,PropName));
  3715. end;
  3716. { TVmtMethodExTable }
  3717. function TVmtMethodExTable.GetMethod(Index: Word): PVmtMethodExEntry;
  3718. var
  3719. Arr : PVmtMethodExEntryArray;
  3720. begin
  3721. if (Index >= Count) then
  3722. Result := Nil
  3723. else
  3724. begin
  3725. { Arr:=PVmtMethodExEntryArray(@Entries[0]);
  3726. Result:=@(Arr^[Index]);}
  3727. Result := PVmtMethodExEntry(@Entries[0]);
  3728. while Index > 0 do
  3729. begin
  3730. Result := Result^.Next;
  3731. Dec(Index);
  3732. end;
  3733. end;
  3734. end;
  3735. { TRecMethodExTable }
  3736. function TRecMethodExTable.GetMethod(Index: Word): PRecMethodExEntry;
  3737. begin
  3738. if (Index >= Count) then
  3739. Result := Nil
  3740. else
  3741. begin
  3742. Result := aligntoptr(PRecMethodExEntry(PByte(@Count) + SizeOf(Count)));
  3743. while Index > 0 do
  3744. begin
  3745. Result := Result^.Next;
  3746. Dec(Index);
  3747. end;
  3748. end;
  3749. end;
  3750. { TRecordData }
  3751. function TRecordData.GetExPropertyTable: PPropDataEx;
  3752. var
  3753. MT : PRecordMethodTable;
  3754. begin
  3755. MT:=GetMethodTable;
  3756. if MT^.Count=0 then
  3757. Result:=PPropDataEx(aligntoptr(PByte(@(MT^.Count))+SizeOf(Word)))
  3758. else
  3759. Result:=PPropDataEx(MT^.Method[MT^.Count-1]^.Tail);
  3760. end;
  3761. function TRecordData.GetExtendedFieldCount: Longint;
  3762. begin
  3763. Result:= PLongint(PByte(@TotalFieldCount)+SizeOf(Longint)+(TotalFieldCount*SizeOf(TManagedField)))^
  3764. end;
  3765. function TRecordData.GetExtendedFields: PExtendedFieldTable;
  3766. begin
  3767. Result:=PExtendedFieldTable(PByte(@TotalFieldCount)+SizeOf(Longint)+(TotalFieldCount*SizeOf(TManagedField)))
  3768. end;
  3769. function TRecordData.GetMethodTable: PRecordMethodTable;
  3770. begin
  3771. Result:=PRecordMethodTable(GetExtendedFields^.Tail);
  3772. end;
  3773. { TVmtExtendedFieldTable }
  3774. function TVmtExtendedFieldTable.GetField(aIndex: Word): PExtendedVmtFieldEntry;
  3775. begin
  3776. Result:=Nil;
  3777. If aIndex>=FieldCount then exit;
  3778. Result:=PExtendedVmtFieldEntry(@Entries +aIndex *SizeOf(TExtendedVmtFieldEntry));
  3779. end;
  3780. function TVmtExtendedFieldTable.GetTail: Pointer;
  3781. begin
  3782. if FieldCount=0 then
  3783. Result:=@FieldCount+SizeOf(Word)
  3784. else
  3785. Result:=GetField(FieldCount-1)^.Tail;
  3786. end;
  3787. { TExtendedVmtFieldEntry }
  3788. function TExtendedVmtFieldEntry.GetNext: PVmtFieldEntry;
  3789. begin
  3790. Result := aligntoptr(Tail);
  3791. end;
  3792. function TExtendedVmtFieldEntry.GetStrictVisibility: Boolean;
  3793. begin
  3794. Result:=(Flags and RTTIFlagStrictVisibility)<>0;
  3795. end;
  3796. function TExtendedVmtFieldEntry.GetTail: Pointer;
  3797. begin
  3798. Result := PByte(@Name) + SizeOf(Pointer);
  3799. end;
  3800. function TExtendedVmtFieldEntry.GetVisibility: TVisibilityClass;
  3801. begin
  3802. Result:=TVisibilityClass(Flags and RTTIFlagVisibilityMask); // For the time being, maybe we need a AND $07 or so later on.
  3803. end;
  3804. { TPropInfoEx }
  3805. function TPropInfoEx.GetStrictVisibility: Boolean;
  3806. begin
  3807. Result:=(Flags and RTTIFlagStrictVisibility)<>0;
  3808. end;
  3809. function TPropInfoEx.GetTail: Pointer;
  3810. begin
  3811. Result := PByte(@Flags) + SizeOf(Self);
  3812. end;
  3813. function TPropInfoEx.GetVisiblity: TVisibilityClass;
  3814. begin
  3815. Result:=TVisibilityClass(Flags and RTTIFlagVisibilityMask);
  3816. end;
  3817. { TPropDataEx }
  3818. function TPropDataEx.GetPropEx(Index: Word): PPropInfoEx;
  3819. begin
  3820. if Index >= PropCount then
  3821. Result := Nil
  3822. else
  3823. begin
  3824. Result := PPropInfoEx(aligntoptr(@PropList));
  3825. while Index > 0 do
  3826. begin
  3827. Result := aligntoptr(Result^.Tail);
  3828. Dec(Index);
  3829. end;
  3830. end;
  3831. end;
  3832. function TPropDataEx.GetTail: Pointer;
  3833. begin
  3834. if PropCount = 0 then
  3835. Result := @Proplist
  3836. else
  3837. Result := Prop[PropCount - 1]^.Tail;
  3838. end;
  3839. { TParameterLocation }
  3840. function TParameterLocation.GetReference: Boolean;
  3841. begin
  3842. Result := (LocType and $80) <> 0;
  3843. end;
  3844. function TParameterLocation.GetRegType: TRegisterType;
  3845. begin
  3846. Result := TRegisterType(LocType and $7F);
  3847. end;
  3848. function TParameterLocation.GetShiftVal: Int8;
  3849. begin
  3850. if GetReference then begin
  3851. if Offset < Low(Int8) then
  3852. Result := Low(Int8)
  3853. else if Offset > High(Int8) then
  3854. Result := High(Int8)
  3855. else
  3856. Result := Offset;
  3857. end else
  3858. Result := 0;
  3859. end;
  3860. { TParameterLocations }
  3861. function TParameterLocations.GetLocation(aIndex: Byte): PParameterLocation;
  3862. begin
  3863. if aIndex >= Count then
  3864. Result := Nil
  3865. else
  3866. Result := PParameterLocation(PByte(aligntoptr(PByte(@Count) + SizeOf(Count))) + SizeOf(TParameterLocation) * aIndex);
  3867. end;
  3868. function TParameterLocations.GetTail: Pointer;
  3869. begin
  3870. Result := PByte(aligntoptr(PByte(@Count) + SizeOf(Count))) + SizeOf(TParameterLocation) * Count;
  3871. end;
  3872. { TProcedureParam }
  3873. function TProcedureParam.GetParamType: PTypeInfo;
  3874. begin
  3875. Result := DerefTypeInfoPtr(ParamTypeRef);
  3876. end;
  3877. function TProcedureParam.GetFlags: Byte;
  3878. begin
  3879. Result := PByte(@ParamFlags)^;
  3880. end;
  3881. { TManagedField }
  3882. function TManagedField.GetTypeRef: PTypeInfo;
  3883. begin
  3884. Result := DerefTypeInfoPtr(TypeRefRef);
  3885. end;
  3886. { TArrayTypeData }
  3887. function TArrayTypeData.GetElType: PTypeInfo;
  3888. begin
  3889. Result := DerefTypeInfoPtr(ElTypeRef);
  3890. end;
  3891. function TArrayTypeData.GetDims(aIndex: Byte): PTypeInfo;
  3892. begin
  3893. Result := DerefTypeInfoPtr(DimsRef[aIndex]);
  3894. end;
  3895. { TProcedureSignature }
  3896. function TProcedureSignature.GetResultType: PTypeInfo;
  3897. begin
  3898. Result := DerefTypeInfoPtr(ResultTypeRef);
  3899. end;
  3900. function TProcedureSignature.GetParam(ParamIndex: Integer): PProcedureParam;
  3901. begin
  3902. if (ParamIndex<0)or(ParamIndex>=ParamCount) then
  3903. Exit(nil);
  3904. Result := PProcedureParam(PByte(@Flags) + SizeOf(Self));
  3905. while ParamIndex > 0 do
  3906. begin
  3907. Result := PProcedureParam(aligntoptr((PByte(@Result^.Name) + (Length(Result^.Name) + 1) * SizeOf(AnsiChar))));
  3908. dec(ParamIndex);
  3909. end;
  3910. end;
  3911. { TVmtMethodParam }
  3912. function TVmtMethodParam.GetTail: Pointer;
  3913. begin
  3914. Result := PByte(@ParaLocs) + SizeOf(ParaLocs);
  3915. end;
  3916. function TVmtMethodParam.GetNext: PVmtMethodParam;
  3917. begin
  3918. Result := PVmtMethodParam(aligntoptr(Tail));
  3919. end;
  3920. function TVmtMethodParam.GetName: ShortString;
  3921. begin
  3922. Result := NamePtr^;
  3923. end;
  3924. { TIntfMethodEntry }
  3925. function TIntfMethodEntry.GetParam(Index: Word): PVmtMethodParam;
  3926. begin
  3927. if Index >= ParamCount then
  3928. Result := Nil
  3929. else
  3930. Result := PVmtMethodParam(PByte(aligntoptr(PByte(@NamePtr) + SizeOf(NamePtr))) + Index * PtrUInt(aligntoptr(Pointer(SizeOf(TVmtMethodParam)))));
  3931. end;
  3932. function TIntfMethodEntry.GetResultLocs: PParameterLocations;
  3933. begin
  3934. if not Assigned(ResultType) then
  3935. Result := Nil
  3936. else
  3937. Result := PParameterLocations(PByte(aligntoptr(PByte(@NamePtr) + SizeOf(NamePtr))) + ParamCount * PtrUInt(aligntoptr(Pointer(SizeOf(TVmtMethodParam)))));
  3938. end;
  3939. function TIntfMethodEntry.GetTail: Pointer;
  3940. begin
  3941. Result := PByte(@NamePtr) + SizeOf(NamePtr);
  3942. if ParamCount > 0 then
  3943. Result := PByte(aligntoptr(Result)) + ParamCount * PtrUInt(aligntoptr(Pointer(SizeOf(TVmtMethodParam))));
  3944. if Assigned(ResultType) then
  3945. Result := PByte(aligntoptr(Result)) + SizeOf(PParameterLocations);
  3946. end;
  3947. function TIntfMethodEntry.GetNext: PIntfMethodEntry;
  3948. begin
  3949. Result := PIntfMethodEntry(aligntoptr(Tail));
  3950. end;
  3951. function TIntfMethodEntry.GetName: ShortString;
  3952. begin
  3953. Result := NamePtr^;
  3954. end;
  3955. { TIntfMethodTable }
  3956. function TIntfMethodTable.GetMethod(Index: Word): PIntfMethodEntry;
  3957. begin
  3958. if (RTTICount = $FFFF) or (Index >= RTTICount) then
  3959. Result := Nil
  3960. else
  3961. begin
  3962. Result := aligntoptr(PIntfMethodEntry(PByte(@RTTICount) + SizeOf(RTTICount)));
  3963. while Index > 0 do
  3964. begin
  3965. Result := Result^.Next;
  3966. Dec(Index);
  3967. end;
  3968. end;
  3969. end;
  3970. { TVmtMethodExEntry }
  3971. function TVmtMethodExEntry.GetParamsStart: PByte;
  3972. begin
  3973. Result:=@Params
  3974. end;
  3975. function TVmtMethodExEntry.GetMethodVisibility: TVisibilityClass;
  3976. begin
  3977. Result:=TVisibilityClass(Flags and RTTIFlagVisibilityMask);
  3978. end;
  3979. function TVMTMethodExEntry.GetParam(Index: Word): PVmtMethodParam;
  3980. begin
  3981. if Index >= ParamCount then
  3982. Result := Nil
  3983. else
  3984. Result := PVmtMethodParam(@params) + Index;
  3985. end;
  3986. function TVMTMethodExEntry.GetResultLocs: PParameterLocations;
  3987. begin
  3988. if not Assigned(ResultType) then
  3989. Result := Nil
  3990. else
  3991. Result := PParameterLocations(AlignToPtr(Param[ParamCount-1]^.Tail))
  3992. end;
  3993. function TVmtMethodExEntry.GetStrictVisibility: Boolean;
  3994. begin
  3995. Result:=(Flags and RTTIFlagStrictVisibility)<>0;
  3996. end;
  3997. function TVMTMethodExEntry.GetTail: Pointer;
  3998. var
  3999. I : integer;
  4000. begin
  4001. if ParamCount = 0 then
  4002. Result := PByte(@VmtIndex) + SizeOf(VmtIndex)
  4003. else
  4004. Result:=Param[ParamCount-1]^.GetTail;
  4005. if Assigned(ResultType) then
  4006. Result := PByte(aligntoptr(Result)) + SizeOf(PParameterLocations);
  4007. end;
  4008. function TVmtMethodExEntry.GetNext: PVmtMethodExEntry;
  4009. begin
  4010. Result := PVmtMethodExEntry(Tail);
  4011. end;
  4012. function TVMTMethodExEntry.GetName: ShortString;
  4013. begin
  4014. Result := NamePtr^;
  4015. end;
  4016. { TRecMethodExEntry }
  4017. function TRecMethodExEntry.GetParamsStart: PByte;
  4018. begin
  4019. Result:=PByte(aligntoptr(PByte(@NamePtr) + SizeOf(NamePtr)+SizeOf(FLags)));
  4020. end;
  4021. function TRecMethodExEntry.GetMethodVisibility: TVisibilityClass;
  4022. begin
  4023. Result:=TVisibilityClass(Flags and RTTIFlagVisibilityMask);
  4024. end;
  4025. function TRecMethodExEntry.GetParam(Index: Word): PRecMethodParam;
  4026. begin
  4027. if Index >= ParamCount then
  4028. Result := Nil
  4029. else
  4030. Result := PRecMethodParam(GetParamsStart + Index * PtrUInt(aligntoptr(Pointer(SizeOf(TRecMethodParam)))));
  4031. end;
  4032. function TRecMethodExEntry.GetResultLocs: PParameterLocations;
  4033. begin
  4034. if not Assigned(ResultType) then
  4035. Result := Nil
  4036. else
  4037. Result := PParameterLocations(GetParamsStart + ParamCount * PtrUInt(aligntoptr(Pointer(SizeOf(TRecMethodParam)))));
  4038. end;
  4039. function TRecMethodExEntry.GetStrictVisibility: Boolean;
  4040. begin
  4041. Result:=(Flags and RTTIFlagStrictVisibility)<>0;
  4042. end;
  4043. function TRecMethodExEntry.GetTail: Pointer;
  4044. begin
  4045. Result := PByte(@Flags) + SizeOf(Flags);
  4046. if ParamCount > 0 then
  4047. Result := PByte(aligntoptr(Result)) + ParamCount * PtrUInt(aligntoptr(Pointer(SizeOf(TRecMethodParam))));
  4048. if Assigned(ResultType) then
  4049. Result := PByte(aligntoptr(Result)) + SizeOf(PParameterLocations);
  4050. end;
  4051. function TRecMethodExEntry.GetNext: PRecMethodExEntry;
  4052. begin
  4053. Result := PRecMethodExEntry(aligntoptr(Tail));
  4054. end;
  4055. function TRecMethodExEntry.GetName: ShortString;
  4056. begin
  4057. Result := NamePtr^;
  4058. end;
  4059. { TVmtMethodTable }
  4060. function TVmtMethodTable.GetEntry(Index: LongWord): PVmtMethodEntry;
  4061. begin
  4062. Result := PVmtMethodEntry(@Entries[0]) + Index;
  4063. end;
  4064. { TVmtFieldTable }
  4065. function TVmtFieldTable.GetField(aIndex: Word): PVmtFieldEntry;
  4066. var
  4067. c: Word;
  4068. begin
  4069. if aIndex >= Count then
  4070. Exit(Nil);
  4071. c := aIndex;
  4072. Result := @Fields;
  4073. while c > 0 do begin
  4074. Result := Result^.Next;
  4075. Dec(c);
  4076. end;
  4077. end;
  4078. function TVmtFieldTable.GetNext: Pointer;
  4079. begin
  4080. Result := Tail;
  4081. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  4082. { align to largest field of TVmtFieldEntry(!) }
  4083. Result := Align(Result, SizeOf(PtrUInt));
  4084. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  4085. end;
  4086. function TVmtFieldTable.GetTail: Pointer;
  4087. begin
  4088. if Count=0 then
  4089. Result := @Fields
  4090. else
  4091. Result:=GetField(Count-1)^.Tail;
  4092. end;
  4093. { TVmtFieldEntry }
  4094. function TVmtFieldEntry.GetNext: PVmtFieldEntry;
  4095. begin
  4096. Result := Tail;
  4097. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  4098. { align to largest field of TVmtFieldEntry }
  4099. Result := Align(Result, SizeOf(PtrUInt));
  4100. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  4101. end;
  4102. function TVmtFieldEntry.GetTail: Pointer;
  4103. begin
  4104. Result := PByte(@Name) + Length(Name) + SizeOf(Byte);
  4105. end;
  4106. { TInterfaceData }
  4107. function TInterfaceData.GetUnitName: ShortString;
  4108. begin
  4109. Result := UnitNameField;
  4110. end;
  4111. function TInterfaceData.GetPropertyTable: PPropData;
  4112. var
  4113. p: PByte;
  4114. begin
  4115. p := PByte(@UnitNameField[0]) + SizeOf(UnitNameField[0]) + Length(UnitNameField);
  4116. Result := AlignTypeData(p);
  4117. end;
  4118. function TInterfaceData.GetMethodTable: PIntfMethodTable;
  4119. begin
  4120. Result := aligntoptr(PropertyTable^.Tail);
  4121. end;
  4122. { TInterfaceRawData }
  4123. function TInterfaceRawData.GetUnitName: ShortString;
  4124. begin
  4125. Result := UnitNameField;
  4126. end;
  4127. function TInterfaceRawData.GetIIDStr: ShortString;
  4128. begin
  4129. Result := PShortString(AlignTypeData(PByte(@UnitNameField[0]) + SizeOf(UnitNameField[0]) + Length(UnitNameField)))^;
  4130. end;
  4131. function TInterfaceRawData.GetPropertyTable: PPropData;
  4132. var
  4133. p: PByte;
  4134. begin
  4135. p := AlignTypeData(PByte(@UnitNameField[0]) + SizeOf(UnitNameField[0]) + Length(UnitNameField));
  4136. p := p + SizeOf(p^) + p^;
  4137. Result := aligntoptr(p);
  4138. end;
  4139. function TInterfaceRawData.GetMethodTable: PIntfMethodTable;
  4140. begin
  4141. Result := aligntoptr(PropertyTable^.Tail);
  4142. end;
  4143. { TClassData }
  4144. function TClassData.GetExMethodTable: PVmtMethodExTable;
  4145. { Copied from objpas.inc}
  4146. type
  4147. {$push}
  4148. {$packrecords normal}
  4149. tmethodnamerec =
  4150. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  4151. packed
  4152. {$endif}
  4153. record
  4154. name : pshortstring;
  4155. addr : codepointer;
  4156. end;
  4157. tmethodnametable =
  4158. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  4159. packed
  4160. {$endif}
  4161. record
  4162. count : dword;
  4163. entries : packed array[0..0] of tmethodnamerec;
  4164. end;
  4165. {$pop}
  4166. pmethodnametable = ^tmethodnametable;
  4167. var
  4168. ovmt : PVmt;
  4169. methodtable: pmethodnametable;
  4170. begin
  4171. Result:=Nil;
  4172. oVmt:=PVmt(ClassType);
  4173. methodtable:=pmethodnametable(ovmt^.vMethodTable);
  4174. // Shift till after
  4175. if methodtable<>Nil then
  4176. PByte(Result):=PByte(@methodtable^.Entries)+ SizeOf(tmethodnamerec) * methodtable^.count;
  4177. end;
  4178. function TClassData.GetExPropertyTable: PPropDataEx;
  4179. begin
  4180. Result:=aligntoptr(PPropDataEx(GetPropertyTable^.GetTail));
  4181. end;
  4182. function TClassData.GetUnitName: ShortString;
  4183. begin
  4184. Result := UnitNameField;
  4185. end;
  4186. function TClassData.GetPropertyTable: PPropData;
  4187. var
  4188. p: PByte;
  4189. begin
  4190. p := PByte(@UnitNameField[0]) + SizeOf(UnitNameField[0]) + Length(UnitNameField);
  4191. Result := AlignToPtr(p);
  4192. end;
  4193. { TTypeData }
  4194. function TTypeData.GetBaseType: PTypeInfo;
  4195. begin
  4196. Result := DerefTypeInfoPtr(BaseTypeRef);
  4197. end;
  4198. function TTypeData.GetCompType: PTypeInfo;
  4199. begin
  4200. Result := DerefTypeInfoPtr(CompTypeRef);
  4201. end;
  4202. function TTypeData.GetParentInfo: PTypeInfo;
  4203. begin
  4204. Result := DerefTypeInfoPtr(ParentInfoRef);
  4205. end;
  4206. {$ifndef VER3_0}
  4207. function TTypeData.GetRecInitData: PRecInitData;
  4208. begin
  4209. Result := PRecInitData(aligntoptr(PTypeData(RecInitInfo+2+PByte(RecInitInfo+1)^)));
  4210. end;
  4211. {$endif}
  4212. function TTypeData.GetHelperParent: PTypeInfo;
  4213. begin
  4214. Result := DerefTypeInfoPtr(HelperParentRef);
  4215. end;
  4216. function TTypeData.GetExtendedInfo: PTypeInfo;
  4217. begin
  4218. Result := DerefTypeInfoPtr(ExtendedInfoRef);
  4219. end;
  4220. function TTypeData.GetIntfParent: PTypeInfo;
  4221. begin
  4222. Result := DerefTypeInfoPtr(IntfParentRef);
  4223. end;
  4224. function TTypeData.GetRawIntfParent: PTypeInfo;
  4225. begin
  4226. Result := DerefTypeInfoPtr(RawIntfParentRef);
  4227. end;
  4228. function TTypeData.GetIIDStr: ShortString;
  4229. begin
  4230. Result := PShortString(AlignTypeData(Pointer(@RawIntfUnit) + Length(RawIntfUnit) + 1))^;
  4231. end;
  4232. function TTypeData.GetElType: PTypeInfo;
  4233. begin
  4234. Result := DerefTypeInfoPtr(elTypeRef);
  4235. end;
  4236. function TTypeData.GetElType2: PTypeInfo;
  4237. begin
  4238. Result := DerefTypeInfoPtr(elType2Ref);
  4239. end;
  4240. function TTypeData.GetInstanceType: PTypeInfo;
  4241. begin
  4242. Result := DerefTypeInfoPtr(InstanceTypeRef);
  4243. end;
  4244. function TTypeData.GetRefType: PTypeInfo;
  4245. begin
  4246. Result := DerefTypeInfoPtr(RefTypeRef);
  4247. end;
  4248. { TPropData }
  4249. function TPropData.GetProp(Index: Word): PPropInfo;
  4250. begin
  4251. if Index >= PropCount then
  4252. Result := Nil
  4253. else
  4254. begin
  4255. Result := PPropInfo(aligntoptr(PByte(@PropCount) + SizeOf(PropCount)));
  4256. while Index > 0 do
  4257. begin
  4258. Result := aligntoptr(Result^.Tail);
  4259. Dec(Index);
  4260. end;
  4261. end;
  4262. end;
  4263. function TPropData.GetTail: Pointer;
  4264. begin
  4265. if PropCount = 0 then
  4266. Result := PByte(@PropCount) + SizeOf(PropCount)
  4267. else
  4268. Result := Prop[PropCount - 1]^.Tail;
  4269. end;
  4270. { TPropInfo }
  4271. function TPropInfo.GetPropType: PTypeInfo;
  4272. begin
  4273. Result := DerefTypeInfoPtr(PropTypeRef);
  4274. end;
  4275. function TPropInfo.GetTail: Pointer;
  4276. begin
  4277. Result := PByte(@Name[0]) + SizeOf(Name[0]) + Length(Name);
  4278. end;
  4279. function TPropInfo.GetNext: PPropInfo;
  4280. begin
  4281. Result := PPropInfo(aligntoptr(Tail));
  4282. end;
  4283. type
  4284. TElementAlias = record
  4285. Ordinal : Integer;
  4286. Alias : string;
  4287. end;
  4288. TElementAliasArray = Array of TElementAlias;
  4289. PElementAliasArray = ^TElementAliasArray;
  4290. TEnumeratedAliases = record
  4291. TypeInfo: PTypeInfo;
  4292. Aliases: TElementAliasArray;
  4293. end;
  4294. TEnumeratedAliasesArray = Array of TEnumeratedAliases;
  4295. Var
  4296. EnumeratedAliases : TEnumeratedAliasesArray;
  4297. Function IndexOfEnumeratedAliases(aTypeInfo : PTypeInfo) : integer;
  4298. begin
  4299. Result:=High(EnumeratedAliases);
  4300. while (Result>=0) and (EnumeratedAliases[Result].TypeInfo<>aTypeInfo) do
  4301. Dec(Result);
  4302. end;
  4303. Function GetEnumeratedAliases(aTypeInfo : PTypeInfo) : PElementAliasArray;
  4304. Var
  4305. I : integer;
  4306. begin
  4307. I:=IndexOfEnumeratedAliases(aTypeInfo);
  4308. if I=-1 then
  4309. Result:=Nil
  4310. else
  4311. Result:=@EnumeratedAliases[i].Aliases
  4312. end;
  4313. Function AddEnumeratedAliases(aTypeInfo : PTypeInfo) : PElementAliasArray;
  4314. Var
  4315. L : Integer;
  4316. begin
  4317. L:=Length(EnumeratedAliases);
  4318. SetLength(EnumeratedAliases,L+1);
  4319. EnumeratedAliases[L].TypeInfo:=aTypeInfo;
  4320. Result:=@EnumeratedAliases[L].Aliases;
  4321. end;
  4322. procedure RemoveEnumElementAliases(aTypeInfo: PTypeInfo);
  4323. Var
  4324. I,L : integer;
  4325. A : TEnumeratedAliases;
  4326. begin
  4327. I:=IndexOfEnumeratedAliases(aTypeInfo);
  4328. if I=-1 then
  4329. exit;
  4330. A:=EnumeratedAliases[i];
  4331. A.Aliases:=Nil;
  4332. A.TypeInfo:=Nil;
  4333. L:=High(EnumeratedAliases);
  4334. EnumeratedAliases[i]:=EnumeratedAliases[L];
  4335. EnumeratedAliases[L]:=A;
  4336. SetLength(EnumeratedAliases,L);
  4337. end;
  4338. Resourcestring
  4339. SErrNotAnEnumerated = 'Type information points to non-enumerated type';
  4340. SErrInvalidEnumeratedCount = 'Invalid number of enumerated values';
  4341. SErrDuplicateEnumerated = 'Duplicate alias for enumerated value';
  4342. procedure AddEnumElementAliases(aTypeInfo: PTypeInfo; const aNames: array of string; aStartValue: Integer = 0);
  4343. var
  4344. Aliases: PElementAliasArray;
  4345. A : TElementAliasArray;
  4346. L, I, J : Integer;
  4347. N : String;
  4348. PT : PTypeData;
  4349. begin
  4350. if (aTypeInfo^.Kind<>tkEnumeration) then
  4351. raise EArgumentException.Create(SErrNotAnEnumerated);
  4352. PT:=GetTypeData(aTypeInfo);
  4353. if (High(aNames)=-1) or ((aStartValue+High(aNames))> PT^.MaxValue) then
  4354. raise EArgumentException.Create(SErrInvalidEnumeratedCount);
  4355. Aliases:=GetEnumeratedAliases(aTypeInfo);
  4356. if (Aliases=Nil) then
  4357. Aliases:=AddEnumeratedAliases(aTypeInfo);
  4358. A:=Aliases^;
  4359. I:=0;
  4360. L:=Length(a);
  4361. SetLength(a,L+High(aNames)+1);
  4362. try
  4363. for N in aNames do
  4364. begin
  4365. for J:=0 to (L+I)-1 do
  4366. if SameText(N,A[J].Alias) then
  4367. raise EArgumentException.Create(SErrDuplicateEnumerated);
  4368. with A[L+I] do
  4369. begin
  4370. Ordinal:=aStartValue+I;
  4371. alias:=N;
  4372. end;
  4373. Inc(I);
  4374. end;
  4375. finally
  4376. // In case of exception, we need to correct the length.
  4377. if Length(A)<>I+L then
  4378. SetLength(A,I+L);
  4379. Aliases^:=A;
  4380. end;
  4381. end;
  4382. function GetEnumeratedAliasValue(aTypeInfo: PTypeInfo; const aName: string): Integer;
  4383. var
  4384. I : Integer;
  4385. Aliases: PElementAliasArray;
  4386. begin
  4387. Result:=-1;
  4388. Aliases:=GetEnumeratedAliases(aTypeInfo);
  4389. if (Aliases=Nil) then
  4390. Exit;
  4391. I:=High(Aliases^);
  4392. While (Result=-1) and (I>=0) do
  4393. begin
  4394. if SameText(Aliases^[I].Alias, aName) then
  4395. Result:=Aliases^[I].Ordinal;
  4396. Dec(I);
  4397. end;
  4398. end;
  4399. {$IFDEF HAVE_INVOKEHELPER}
  4400. procedure CallInvokeHelper(Instance: Pointer; aMethod : PIntfMethodEntry; aArgs : PPointer);
  4401. begin
  4402. if (aMethod=Nil) then
  4403. Raise EArgumentNilException.Create('Cannot call invoke helper on nil method info');
  4404. if (aMethod^.InvokeHelper=Nil) then
  4405. Raise EArgumentException.CreateFmt('Method %s has no invoke helper.',[aMethod^.Name]);
  4406. aMethod^.InvokeHelper(Instance,aArgs);
  4407. end;
  4408. procedure CallInvokeHelper(aTypeInfo : PTypeInfo; Instance: Pointer; const aMethod : String; aArgs : PPointer);
  4409. Var
  4410. Data : PInterfaceData;
  4411. DataR : PInterfaceRawData;
  4412. MethodTable : PIntfMethodTable;
  4413. MethodEntry : PIntfMethodEntry;
  4414. I : Integer;
  4415. begin
  4416. If Instance=Nil then
  4417. Raise EArgumentNilException.Create('Cannot call invoke helper on nil instance');
  4418. if not (aTypeInfo^.Kind in [tkInterface,tkInterfaceRaw]) then
  4419. Raise EArgumentException.Create('Cannot call invoke helper non non-interfaces');
  4420. // Get method table
  4421. if (aTypeInfo^.Kind=tkInterface) then
  4422. begin
  4423. Data:=PInterfaceData(GetTypeData(aTypeInfo));
  4424. MethodTable:=Data^.MethodTable;
  4425. end
  4426. else
  4427. begin
  4428. DataR:=PInterfaceRawData(GetTypeData(aTypeInfo));
  4429. MethodTable:=DataR^.MethodTable;
  4430. end;
  4431. // Search method in method table
  4432. MethodEntry:=nil;
  4433. I:=MethodTable^.Count-1;
  4434. While (MethodEntry=Nil) and (I>=0) do
  4435. begin
  4436. MethodEntry:=MethodTable^.Method[i];
  4437. if not SameText(MethodEntry^.Name,aMethod) then
  4438. MethodEntry:=Nil;
  4439. Dec(I);
  4440. end;
  4441. if MethodEntry=Nil then
  4442. Raise EArgumentException.CreateFmt('Interface %s has no method %s.',[aTypeInfo^.Name,aMethod]);
  4443. CallInvokeHelper(Instance,MethodEntry,aArgs);
  4444. end;
  4445. {$ENDIF HAVE_INVOKEHELPER}
  4446. end.