typinfo.pp 154 KB

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