typinfo.pp 153 KB

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