typinfo.pp 153 KB

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