typinfo.pp 154 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164
  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. begin
  2705. Result:=GetOrdProp(Instance,PropInfo);
  2706. end;
  2707. procedure SetInt64Prop(Instance: TObject; PropInfo: PPropInfo; const Value: Int64);
  2708. begin
  2709. SetOrdProp(Instance,PropInfo,Value);
  2710. end;
  2711. Function GetInt64Prop(Instance: TObject; const PropName: string): Int64;
  2712. begin
  2713. Result:=GetInt64Prop(Instance,FindPropInfo(Instance,PropName));
  2714. end;
  2715. Procedure SetInt64Prop(Instance: TObject; const PropName: string; const Value: Int64);
  2716. begin
  2717. SetInt64Prop(Instance,FindPropInfo(Instance,PropName),Value);
  2718. end;
  2719. { ---------------------------------------------------------------------
  2720. Set properties
  2721. ---------------------------------------------------------------------}
  2722. Function GetSetProp(Instance: TObject; const PropName: string): string;
  2723. begin
  2724. Result:=GetSetProp(Instance,PropName,False);
  2725. end;
  2726. Function GetSetProp(Instance: TObject; const PropName: string; Brackets: Boolean): string;
  2727. begin
  2728. Result:=GetSetProp(Instance,FindPropInfo(Instance,PropName),Brackets);
  2729. end;
  2730. Function GetSetProp(Instance: TObject; const PropInfo: PPropInfo; Brackets: Boolean): string;
  2731. begin
  2732. Result:=SetToString(PropInfo,GetOrdProp(Instance,PropInfo),Brackets);
  2733. end;
  2734. Procedure SetSetProp(Instance: TObject; const PropName: string; const Value: string);
  2735. begin
  2736. SetSetProp(Instance,FindPropInfo(Instance,PropName),Value);
  2737. end;
  2738. Procedure SetSetProp(Instance: TObject; const PropInfo: PPropInfo; const Value: string);
  2739. begin
  2740. SetOrdProp(Instance,PropInfo,StringToSet(PropInfo,Value));
  2741. end;
  2742. { ---------------------------------------------------------------------
  2743. Pointer properties - internal only
  2744. ---------------------------------------------------------------------}
  2745. Function GetPointerProp(Instance: TObject; PropInfo : PPropInfo): Pointer;
  2746. Type
  2747. TGetPointerProcIndex = function (index:longint): Pointer of object;
  2748. TGetPointerProc = function (): Pointer of object;
  2749. var
  2750. AMethod : TMethod;
  2751. begin
  2752. case (PropInfo^.PropProcs) and 3 of
  2753. ptField:
  2754. Result := PPointer(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  2755. ptStatic,
  2756. ptVirtual:
  2757. begin
  2758. if (PropInfo^.PropProcs and 3)=ptStatic then
  2759. AMethod.Code:=PropInfo^.GetProc
  2760. else
  2761. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2762. AMethod.Data:=Instance;
  2763. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2764. Result:=TGetPointerProcIndex(AMethod)(PropInfo^.Index)
  2765. else
  2766. Result:=TGetPointerProc(AMethod)();
  2767. end;
  2768. else
  2769. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2770. end;
  2771. end;
  2772. Procedure SetPointerProp(Instance: TObject; PropInfo : PPropInfo; Value: Pointer);
  2773. type
  2774. TSetPointerProcIndex = procedure(index: longint; p: pointer) of object;
  2775. TSetPointerProc = procedure(p: pointer) of object;
  2776. var
  2777. AMethod : TMethod;
  2778. begin
  2779. case (PropInfo^.PropProcs shr 2) and 3 of
  2780. ptField:
  2781. PPointer(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  2782. ptStatic,
  2783. ptVirtual:
  2784. begin
  2785. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2786. AMethod.Code:=PropInfo^.SetProc
  2787. else
  2788. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2789. AMethod.Data:=Instance;
  2790. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2791. TSetPointerProcIndex(AMethod)(PropInfo^.Index,Value)
  2792. else
  2793. TSetPointerProc(AMethod)(Value);
  2794. end;
  2795. else
  2796. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2797. end;
  2798. end;
  2799. { ---------------------------------------------------------------------
  2800. Object properties
  2801. ---------------------------------------------------------------------}
  2802. Function GetObjectProp(Instance: TObject; const PropName: string): TObject;
  2803. begin
  2804. Result:=GetObjectProp(Instance,PropName,Nil);
  2805. end;
  2806. Function GetObjectProp(Instance: TObject; const PropName: string; MinClass: TClass): TObject;
  2807. begin
  2808. Result:=GetObjectProp(Instance,FindPropInfo(Instance,PropName),MinClass);
  2809. end;
  2810. Function GetObjectProp(Instance: TObject; PropInfo : PPropInfo): TObject;
  2811. begin
  2812. Result:=GetObjectProp(Instance,PropInfo,Nil);
  2813. end;
  2814. Function GetObjectProp(Instance: TObject; PropInfo : PPropInfo; MinClass: TClass): TObject;
  2815. begin
  2816. Result:=TObject(GetPointerProp(Instance,PropInfo));
  2817. If (MinClass<>Nil) and (Result<>Nil) Then
  2818. If Not Result.InheritsFrom(MinClass) then
  2819. Result:=Nil;
  2820. end;
  2821. Procedure SetObjectProp(Instance: TObject; const PropName: string; Value: TObject);
  2822. begin
  2823. SetObjectProp(Instance,FindPropInfo(Instance,PropName),Value);
  2824. end;
  2825. Procedure SetObjectProp(Instance: TObject; PropInfo : PPropInfo; Value: TObject);
  2826. begin
  2827. SetPointerProp(Instance,PropInfo,Pointer(Value));
  2828. end;
  2829. Function GetObjectPropClass(Instance: TObject; const PropName: string): TClass;
  2830. begin
  2831. Result:=GetTypeData(FindPropInfo(Instance,PropName,[tkClass])^.PropType)^.ClassType;
  2832. end;
  2833. Function GetObjectPropClass(AClass: TClass; const PropName: string): TClass;
  2834. begin
  2835. Result:=GetTypeData(FindPropInfo(AClass,PropName,[tkClass])^.PropType)^.ClassType;
  2836. end;
  2837. { ---------------------------------------------------------------------
  2838. Interface wrapprers
  2839. ---------------------------------------------------------------------}
  2840. function GetInterfaceProp(Instance: TObject; const PropName: string): IInterface;
  2841. begin
  2842. Result:=GetInterfaceProp(Instance,FindPropInfo(Instance,PropName));
  2843. end;
  2844. function GetInterfaceProp(Instance: TObject; PropInfo: PPropInfo): IInterface;
  2845. type
  2846. TGetInterfaceProc=function:IInterface of object;
  2847. TGetInterfaceProcIndex=function(index:longint):IInterface of object;
  2848. var
  2849. AMethod : TMethod;
  2850. begin
  2851. Result:=nil;
  2852. case (PropInfo^.PropProcs) and 3 of
  2853. ptField:
  2854. Result:=IInterface(PPointer(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^);
  2855. ptStatic,
  2856. ptVirtual:
  2857. begin
  2858. if (PropInfo^.PropProcs and 3)=ptStatic then
  2859. AMethod.Code:=PropInfo^.GetProc
  2860. else
  2861. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2862. AMethod.Data:=Instance;
  2863. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2864. Result:=TGetInterfaceProcIndex(AMethod)(PropInfo^.Index)
  2865. else
  2866. Result:=TGetInterfaceProc(AMethod)();
  2867. end;
  2868. else
  2869. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2870. end;
  2871. end;
  2872. procedure SetInterfaceProp(Instance: TObject; const PropName: string; const Value: IInterface);
  2873. begin
  2874. SetInterfaceProp(Instance,FindPropInfo(Instance,PropName),Value);
  2875. end;
  2876. procedure SetInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: IInterface);
  2877. type
  2878. TSetIntfStrProcIndex=procedure(index:longint;const i:IInterface) of object;
  2879. TSetIntfStrProc=procedure(i:IInterface) of object;
  2880. var
  2881. AMethod : TMethod;
  2882. begin
  2883. case Propinfo^.PropType^.Kind of
  2884. tkInterface:
  2885. begin
  2886. case (PropInfo^.PropProcs shr 2) and 3 of
  2887. ptField:
  2888. PInterface(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2889. ptStatic,
  2890. ptVirtual:
  2891. begin
  2892. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2893. AMethod.Code:=PropInfo^.SetProc
  2894. else
  2895. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2896. AMethod.Data:=Instance;
  2897. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2898. TSetIntfStrProcIndex(AMethod)(PropInfo^.Index,Value)
  2899. else
  2900. TSetIntfStrProc(AMethod)(Value);
  2901. end;
  2902. else
  2903. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2904. end;
  2905. end;
  2906. tkInterfaceRaw:
  2907. Raise Exception.Create('Cannot set RAW interface from IUnknown interface');
  2908. end;
  2909. end;
  2910. { ---------------------------------------------------------------------
  2911. RAW (Corba) Interface wrapprers
  2912. ---------------------------------------------------------------------}
  2913. function GetRawInterfaceProp(Instance: TObject; const PropName: string): Pointer;
  2914. begin
  2915. Result:=GetRawInterfaceProp(Instance,FindPropInfo(Instance,PropName));
  2916. end;
  2917. function GetRawInterfaceProp(Instance: TObject; PropInfo: PPropInfo): Pointer;
  2918. begin
  2919. Result:=GetPointerProp(Instance,PropInfo);
  2920. end;
  2921. procedure SetRawInterfaceProp(Instance: TObject; const PropName: string; const Value: Pointer);
  2922. begin
  2923. SetRawInterfaceProp(Instance,FindPropInfo(Instance,PropName),Value);
  2924. end;
  2925. procedure SetRawInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: Pointer);
  2926. begin
  2927. SetPointerProp(Instance,PropInfo,Value);
  2928. end;
  2929. { ---------------------------------------------------------------------
  2930. Dynamic array properties
  2931. ---------------------------------------------------------------------}
  2932. function GetDynArrayProp(Instance: TObject; const PropName: string): Pointer;
  2933. begin
  2934. Result:=GetDynArrayProp(Instance,FindPropInfo(Instance,PropName));
  2935. end;
  2936. function GetDynArrayProp(Instance: TObject; PropInfo: PPropInfo): Pointer;
  2937. type
  2938. { we need a dynamic array as that type is usually passed differently from
  2939. a plain pointer }
  2940. TDynArray=array of Byte;
  2941. TGetDynArrayProc=function:TDynArray of object;
  2942. TGetDynArrayProcIndex=function(index:longint):TDynArray of object;
  2943. var
  2944. AMethod : TMethod;
  2945. begin
  2946. Result:=nil;
  2947. if PropInfo^.PropType^.Kind<>tkDynArray then
  2948. Exit;
  2949. case (PropInfo^.PropProcs) and 3 of
  2950. ptField:
  2951. Result:=PPointer(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2952. ptStatic,
  2953. ptVirtual:
  2954. begin
  2955. if (PropInfo^.PropProcs and 3)=ptStatic then
  2956. AMethod.Code:=PropInfo^.GetProc
  2957. else
  2958. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2959. AMethod.Data:=Instance;
  2960. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2961. Result:=Pointer(TGetDynArrayProcIndex(AMethod)(PropInfo^.Index))
  2962. else
  2963. Result:=Pointer(TGetDynArrayProc(AMethod)());
  2964. end;
  2965. else
  2966. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2967. end;
  2968. end;
  2969. procedure SetDynArrayProp(Instance: TObject; const PropName: string; const Value: Pointer);
  2970. begin
  2971. SetDynArrayProp(Instance,FindPropInfo(Instance,PropName),Value);
  2972. end;
  2973. procedure SetDynArrayProp(Instance: TObject; PropInfo: PPropInfo; const Value: Pointer);
  2974. type
  2975. { we need a dynamic array as that type is usually passed differently from
  2976. a plain pointer }
  2977. TDynArray=array of Byte;
  2978. TSetDynArrayProcIndex=procedure(index:longint;const i:TDynArray) of object;
  2979. TSetDynArrayProc=procedure(i:TDynArray) of object;
  2980. var
  2981. AMethod: TMethod;
  2982. begin
  2983. if PropInfo^.PropType^.Kind<>tkDynArray then
  2984. Exit;
  2985. case (PropInfo^.PropProcs shr 2) and 3 of
  2986. ptField:
  2987. CopyArray(PPointer(Pointer(Instance)+PtrUInt(PropInfo^.SetProc)), @Value, PropInfo^.PropType, 1);
  2988. ptStatic,
  2989. ptVirtual:
  2990. begin
  2991. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2992. AMethod.Code:=PropInfo^.SetProc
  2993. else
  2994. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2995. AMethod.Data:=Instance;
  2996. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2997. TSetDynArrayProcIndex(AMethod)(PropInfo^.Index,TDynArray(Value))
  2998. else
  2999. TSetDynArrayProc(AMethod)(TDynArray(Value));
  3000. end;
  3001. else
  3002. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  3003. end;
  3004. end;
  3005. { ---------------------------------------------------------------------
  3006. String properties
  3007. ---------------------------------------------------------------------}
  3008. Function GetStrProp(Instance: TObject; PropInfo: PPropInfo): AnsiString;
  3009. type
  3010. TGetShortStrProcIndex=function(index:longint):ShortString of object;
  3011. TGetShortStrProc=function():ShortString of object;
  3012. TGetAnsiStrProcIndex=function(index:longint):AnsiString of object;
  3013. TGetAnsiStrProc=function():AnsiString of object;
  3014. var
  3015. AMethod : TMethod;
  3016. begin
  3017. Result:='';
  3018. case Propinfo^.PropType^.Kind of
  3019. tkWString:
  3020. Result:=AnsiString(GetWideStrProp(Instance,PropInfo));
  3021. tkUString:
  3022. Result := AnsiString(GetUnicodeStrProp(Instance,PropInfo));
  3023. tkSString:
  3024. begin
  3025. case (PropInfo^.PropProcs) and 3 of
  3026. ptField:
  3027. Result := PShortString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  3028. ptStatic,
  3029. ptVirtual:
  3030. begin
  3031. if (PropInfo^.PropProcs and 3)=ptStatic then
  3032. AMethod.Code:=PropInfo^.GetProc
  3033. else
  3034. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  3035. AMethod.Data:=Instance;
  3036. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  3037. Result:=TGetShortStrProcIndex(AMethod)(PropInfo^.Index)
  3038. else
  3039. Result:=TGetShortStrProc(AMethod)();
  3040. end;
  3041. else
  3042. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  3043. end;
  3044. end;
  3045. tkAString:
  3046. begin
  3047. case (PropInfo^.PropProcs) and 3 of
  3048. ptField:
  3049. Result := PAnsiString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  3050. ptStatic,
  3051. ptVirtual:
  3052. begin
  3053. if (PropInfo^.PropProcs and 3)=ptStatic then
  3054. AMethod.Code:=PropInfo^.GetProc
  3055. else
  3056. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  3057. AMethod.Data:=Instance;
  3058. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  3059. Result:=TGetAnsiStrProcIndex(AMethod)(PropInfo^.Index)
  3060. else
  3061. Result:=TGetAnsiStrProc(AMethod)();
  3062. end;
  3063. else
  3064. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  3065. end;
  3066. end;
  3067. end;
  3068. end;
  3069. Procedure SetStrProp(Instance : TObject;PropInfo : PPropInfo; const Value : AnsiString);
  3070. type
  3071. TSetShortStrProcIndex=procedure(index:longint;const s:ShortString) of object;
  3072. TSetShortStrProc=procedure(const s:ShortString) of object;
  3073. TSetAnsiStrProcIndex=procedure(index:longint;s:AnsiString) of object;
  3074. TSetAnsiStrProc=procedure(s:AnsiString) of object;
  3075. var
  3076. AMethod : TMethod;
  3077. begin
  3078. case Propinfo^.PropType^.Kind of
  3079. tkWString:
  3080. SetWideStrProp(Instance,PropInfo,WideString(Value));
  3081. tkUString:
  3082. SetUnicodeStrProp(Instance,PropInfo,UnicodeString(Value));
  3083. tkSString:
  3084. begin
  3085. case (PropInfo^.PropProcs shr 2) and 3 of
  3086. ptField:
  3087. PShortString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  3088. ptStatic,
  3089. ptVirtual:
  3090. begin
  3091. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  3092. AMethod.Code:=PropInfo^.SetProc
  3093. else
  3094. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  3095. AMethod.Data:=Instance;
  3096. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  3097. TSetShortStrProcIndex(AMethod)(PropInfo^.Index,Value)
  3098. else
  3099. TSetShortStrProc(AMethod)(Value);
  3100. end;
  3101. else
  3102. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  3103. end;
  3104. end;
  3105. tkAString:
  3106. begin
  3107. case (PropInfo^.PropProcs shr 2) and 3 of
  3108. ptField:
  3109. PAnsiString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  3110. ptStatic,
  3111. ptVirtual:
  3112. begin
  3113. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  3114. AMethod.Code:=PropInfo^.SetProc
  3115. else
  3116. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  3117. AMethod.Data:=Instance;
  3118. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  3119. TSetAnsiStrProcIndex(AMethod)(PropInfo^.Index,Value)
  3120. else
  3121. TSetAnsiStrProc(AMethod)(Value);
  3122. end;
  3123. else
  3124. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  3125. end;
  3126. end;
  3127. end;
  3128. end;
  3129. Function GetStrProp(Instance: TObject; const PropName: string): string;
  3130. begin
  3131. Result:=GetStrProp(Instance,FindPropInfo(Instance,PropName));
  3132. end;
  3133. Procedure SetStrProp(Instance: TObject; const PropName: string; const Value: AnsiString);
  3134. begin
  3135. SetStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  3136. end;
  3137. Function GetWideStrProp(Instance: TObject; const PropName: string): WideString;
  3138. begin
  3139. Result:=GetWideStrProp(Instance, FindPropInfo(Instance, PropName));
  3140. end;
  3141. procedure SetWideStrProp(Instance: TObject; const PropName: string; const Value: WideString);
  3142. begin
  3143. SetWideStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  3144. end;
  3145. Function GetWideStrProp(Instance: TObject; PropInfo: PPropInfo): WideString;
  3146. type
  3147. TGetWideStrProcIndex=function(index:longint):WideString of object;
  3148. TGetWideStrProc=function():WideString of object;
  3149. var
  3150. AMethod : TMethod;
  3151. begin
  3152. Result:='';
  3153. case Propinfo^.PropType^.Kind of
  3154. tkSString,tkAString:
  3155. Result:=WideString(GetStrProp(Instance,PropInfo));
  3156. tkUString :
  3157. Result := GetUnicodeStrProp(Instance,PropInfo);
  3158. tkWString:
  3159. begin
  3160. case (PropInfo^.PropProcs) and 3 of
  3161. ptField:
  3162. Result := PWideString(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  3163. ptStatic,
  3164. ptVirtual:
  3165. begin
  3166. if (PropInfo^.PropProcs and 3)=ptStatic then
  3167. AMethod.Code:=PropInfo^.GetProc
  3168. else
  3169. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  3170. AMethod.Data:=Instance;
  3171. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  3172. Result:=TGetWideStrProcIndex(AMethod)(PropInfo^.Index)
  3173. else
  3174. Result:=TGetWideStrProc(AMethod)();
  3175. end;
  3176. else
  3177. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  3178. end;
  3179. end;
  3180. end;
  3181. end;
  3182. Procedure SetWideStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: WideString);
  3183. type
  3184. TSetWideStrProcIndex=procedure(index:longint;s:WideString) of object;
  3185. TSetWideStrProc=procedure(s:WideString) of object;
  3186. var
  3187. AMethod : TMethod;
  3188. begin
  3189. case Propinfo^.PropType^.Kind of
  3190. tkSString,tkAString:
  3191. SetStrProp(Instance,PropInfo,AnsiString(Value));
  3192. tkUString:
  3193. SetUnicodeStrProp(Instance,PropInfo,Value);
  3194. tkWString:
  3195. begin
  3196. case (PropInfo^.PropProcs shr 2) and 3 of
  3197. ptField:
  3198. PWideString(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  3199. ptStatic,
  3200. ptVirtual:
  3201. begin
  3202. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  3203. AMethod.Code:=PropInfo^.SetProc
  3204. else
  3205. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  3206. AMethod.Data:=Instance;
  3207. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  3208. TSetWideStrProcIndex(AMethod)(PropInfo^.Index,Value)
  3209. else
  3210. TSetWideStrProc(AMethod)(Value);
  3211. end;
  3212. else
  3213. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  3214. end;
  3215. end;
  3216. end;
  3217. end;
  3218. Function GetUnicodeStrProp(Instance: TObject; const PropName: string): UnicodeString;
  3219. begin
  3220. Result:=GetUnicodeStrProp(Instance, FindPropInfo(Instance, PropName));
  3221. end;
  3222. procedure SetUnicodeStrProp(Instance: TObject; const PropName: string; const Value: UnicodeString);
  3223. begin
  3224. SetUnicodeStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  3225. end;
  3226. Function GetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo): UnicodeString;
  3227. type
  3228. TGetUnicodeStrProcIndex=function(index:longint):UnicodeString of object;
  3229. TGetUnicodeStrProc=function():UnicodeString of object;
  3230. var
  3231. AMethod : TMethod;
  3232. begin
  3233. Result:='';
  3234. case Propinfo^.PropType^.Kind of
  3235. tkSString,tkAString:
  3236. Result:=UnicodeString(GetStrProp(Instance,PropInfo));
  3237. tkWString:
  3238. Result:=GetWideStrProp(Instance,PropInfo);
  3239. tkUString:
  3240. begin
  3241. case (PropInfo^.PropProcs) and 3 of
  3242. ptField:
  3243. Result := PUnicodeString(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  3244. ptStatic,
  3245. ptVirtual:
  3246. begin
  3247. if (PropInfo^.PropProcs and 3)=ptStatic then
  3248. AMethod.Code:=PropInfo^.GetProc
  3249. else
  3250. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  3251. AMethod.Data:=Instance;
  3252. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  3253. Result:=TGetUnicodeStrProcIndex(AMethod)(PropInfo^.Index)
  3254. else
  3255. Result:=TGetUnicodeStrProc(AMethod)();
  3256. end;
  3257. else
  3258. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  3259. end;
  3260. end;
  3261. end;
  3262. end;
  3263. Procedure SetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: UnicodeString);
  3264. type
  3265. TSetUnicodeStrProcIndex=procedure(index:longint;s:UnicodeString) of object;
  3266. TSetUnicodeStrProc=procedure(s:UnicodeString) of object;
  3267. var
  3268. AMethod : TMethod;
  3269. begin
  3270. case Propinfo^.PropType^.Kind of
  3271. tkSString,tkAString:
  3272. SetStrProp(Instance,PropInfo,AnsiString(Value));
  3273. tkWString:
  3274. SetWideStrProp(Instance,PropInfo,Value);
  3275. tkUString:
  3276. begin
  3277. case (PropInfo^.PropProcs shr 2) and 3 of
  3278. ptField:
  3279. PUnicodeString(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  3280. ptStatic,
  3281. ptVirtual:
  3282. begin
  3283. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  3284. AMethod.Code:=PropInfo^.SetProc
  3285. else
  3286. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  3287. AMethod.Data:=Instance;
  3288. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  3289. TSetUnicodeStrProcIndex(AMethod)(PropInfo^.Index,Value)
  3290. else
  3291. TSetUnicodeStrProc(AMethod)(Value);
  3292. end;
  3293. else
  3294. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  3295. end;
  3296. end;
  3297. end;
  3298. end;
  3299. function GetRawbyteStrProp(Instance: TObject; PropInfo: PPropInfo): RawByteString;
  3300. type
  3301. TGetRawByteStrProcIndex=function(index:longint): RawByteString of object;
  3302. TGetRawByteStrProc=function():RawByteString of object;
  3303. var
  3304. AMethod : TMethod;
  3305. begin
  3306. Result:='';
  3307. case Propinfo^.PropType^.Kind of
  3308. tkWString:
  3309. Result:=RawByteString(GetWideStrProp(Instance,PropInfo));
  3310. tkUString:
  3311. Result:=RawByteString(GetUnicodeStrProp(Instance,PropInfo));
  3312. tkSString:
  3313. Result:=RawByteString(GetStrProp(Instance,PropInfo));
  3314. tkAString:
  3315. begin
  3316. case (PropInfo^.PropProcs) and 3 of
  3317. ptField:
  3318. Result := PAnsiString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  3319. ptStatic,
  3320. ptVirtual:
  3321. begin
  3322. if (PropInfo^.PropProcs and 3)=ptStatic then
  3323. AMethod.Code:=PropInfo^.GetProc
  3324. else
  3325. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  3326. AMethod.Data:=Instance;
  3327. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  3328. Result:=TGetRawByteStrProcIndex(AMethod)(PropInfo^.Index)
  3329. else
  3330. Result:=TGetRawByteStrProc(AMethod)();
  3331. end;
  3332. else
  3333. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  3334. end;
  3335. end;
  3336. end;
  3337. end;
  3338. function GetRawByteStrProp(Instance: TObject; const PropName: string): RawByteString;
  3339. begin
  3340. Result:=GetRawByteStrProp(Instance,FindPropInfo(Instance,PropName));
  3341. end;
  3342. procedure SetRawByteStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: RawByteString);
  3343. type
  3344. TSetRawByteStrProcIndex=procedure(index:longint;s:RawByteString) of object;
  3345. TSetRawByteStrProc=procedure(s:RawByteString) of object;
  3346. var
  3347. AMethod : TMethod;
  3348. begin
  3349. case Propinfo^.PropType^.Kind of
  3350. tkWString:
  3351. SetWideStrProp(Instance,PropInfo,WideString(Value));
  3352. tkUString:
  3353. SetUnicodeStrProp(Instance,PropInfo,UnicodeString(Value));
  3354. tkSString:
  3355. SetStrProp(Instance,PropInfo,Value); // Not 100% sure about this.
  3356. tkAString:
  3357. begin
  3358. case (PropInfo^.PropProcs shr 2) and 3 of
  3359. ptField:
  3360. PAnsiString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  3361. ptStatic,
  3362. ptVirtual:
  3363. begin
  3364. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  3365. AMethod.Code:=PropInfo^.SetProc
  3366. else
  3367. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  3368. AMethod.Data:=Instance;
  3369. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  3370. TSetRawByteStrProcIndex(AMethod)(PropInfo^.Index,Value)
  3371. else
  3372. TSetRawByteStrProc(AMethod)(Value);
  3373. end;
  3374. else
  3375. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  3376. end;
  3377. end;
  3378. end;
  3379. end;
  3380. procedure SetRawByteStrProp(Instance: TObject; const PropName: string; const Value: RawByteString);
  3381. begin
  3382. SetRawByteStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  3383. end;
  3384. {$ifndef FPUNONE}
  3385. { ---------------------------------------------------------------------
  3386. Float properties
  3387. ---------------------------------------------------------------------}
  3388. function GetFloatProp(Instance : TObject;PropInfo : PPropInfo) : Extended;
  3389. type
  3390. TGetExtendedProc = function:Extended of object;
  3391. TGetExtendedProcIndex = function(Index: integer): Extended of object;
  3392. TGetDoubleProc = function:Double of object;
  3393. TGetDoubleProcIndex = function(Index: integer): Double of object;
  3394. TGetSingleProc = function:Single of object;
  3395. TGetSingleProcIndex = function(Index: integer):Single of object;
  3396. TGetCurrencyProc = function : Currency of object;
  3397. TGetCurrencyProcIndex = function(Index: integer) : Currency of object;
  3398. var
  3399. AMethod : TMethod;
  3400. begin
  3401. Result:=0.0;
  3402. case PropInfo^.PropProcs and 3 of
  3403. ptField:
  3404. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  3405. ftSingle:
  3406. Result:=PSingle(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  3407. ftDouble:
  3408. Result:=PDouble(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  3409. ftExtended:
  3410. Result:=PExtended(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  3411. ftcomp:
  3412. Result:=PComp(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  3413. ftcurr:
  3414. Result:=PCurrency(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  3415. end;
  3416. ptStatic,
  3417. ptVirtual:
  3418. begin
  3419. if (PropInfo^.PropProcs and 3)=ptStatic then
  3420. AMethod.Code:=PropInfo^.GetProc
  3421. else
  3422. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  3423. AMethod.Data:=Instance;
  3424. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  3425. ftSingle:
  3426. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  3427. Result:=TGetSingleProc(AMethod)()
  3428. else
  3429. Result:=TGetSingleProcIndex(AMethod)(PropInfo^.Index);
  3430. ftDouble:
  3431. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  3432. Result:=TGetDoubleProc(AMethod)()
  3433. else
  3434. Result:=TGetDoubleProcIndex(AMethod)(PropInfo^.Index);
  3435. ftExtended:
  3436. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  3437. Result:=TGetExtendedProc(AMethod)()
  3438. else
  3439. Result:=TGetExtendedProcIndex(AMethod)(PropInfo^.Index);
  3440. ftCurr:
  3441. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  3442. Result:=TGetCurrencyProc(AMethod)()
  3443. else
  3444. Result:=TGetCurrencyProcIndex(AMethod)(PropInfo^.Index);
  3445. end;
  3446. end;
  3447. else
  3448. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  3449. end;
  3450. end;
  3451. Procedure SetFloatProp(Instance : TObject;PropInfo : PPropInfo; Value : Extended);
  3452. type
  3453. TSetExtendedProc = procedure(const AValue: Extended) of object;
  3454. TSetExtendedProcIndex = procedure(Index: integer; AValue: Extended) of object;
  3455. TSetDoubleProc = procedure(const AValue: Double) of object;
  3456. TSetDoubleProcIndex = procedure(Index: integer; AValue: Double) of object;
  3457. TSetSingleProc = procedure(const AValue: Single) of object;
  3458. TSetSingleProcIndex = procedure(Index: integer; AValue: Single) of object;
  3459. TSetCurrencyProc = procedure(const AValue: Currency) of object;
  3460. TSetCurrencyProcIndex = procedure(Index: integer; AValue: Currency) of object;
  3461. Var
  3462. AMethod : TMethod;
  3463. begin
  3464. case (PropInfo^.PropProcs shr 2) and 3 of
  3465. ptfield:
  3466. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  3467. ftSingle:
  3468. PSingle(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  3469. ftDouble:
  3470. PDouble(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  3471. ftExtended:
  3472. PExtended(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  3473. {$ifdef FPC_COMP_IS_INT64}
  3474. ftComp:
  3475. PComp(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=trunc(Value);
  3476. {$else FPC_COMP_IS_INT64}
  3477. ftComp:
  3478. PComp(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Comp(Value);
  3479. {$endif FPC_COMP_IS_INT64}
  3480. ftCurr:
  3481. PCurrency(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  3482. end;
  3483. ptStatic,
  3484. ptVirtual:
  3485. begin
  3486. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  3487. AMethod.Code:=PropInfo^.SetProc
  3488. else
  3489. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  3490. AMethod.Data:=Instance;
  3491. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  3492. ftSingle:
  3493. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  3494. TSetSingleProc(AMethod)(Value)
  3495. else
  3496. TSetSingleProcIndex(AMethod)(PropInfo^.Index,Value);
  3497. ftDouble:
  3498. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  3499. TSetDoubleProc(AMethod)(Value)
  3500. else
  3501. TSetDoubleProcIndex(AMethod)(PropInfo^.Index,Value);
  3502. ftExtended:
  3503. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  3504. TSetExtendedProc(AMethod)(Value)
  3505. else
  3506. TSetExtendedProcIndex(AMethod)(PropInfo^.Index,Value);
  3507. ftCurr:
  3508. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  3509. TSetCurrencyProc(AMethod)(Value)
  3510. else
  3511. TSetCurrencyProcIndex(AMethod)(PropInfo^.Index,Value);
  3512. end;
  3513. end;
  3514. else
  3515. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  3516. end;
  3517. end;
  3518. function GetFloatProp(Instance: TObject; const PropName: string): Extended;
  3519. begin
  3520. Result:=GetFloatProp(Instance,FindPropInfo(Instance,PropName))
  3521. end;
  3522. Procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Extended);
  3523. begin
  3524. SetFloatProp(Instance,FindPropInfo(Instance,PropName),Value);
  3525. end;
  3526. {$endif}
  3527. { ---------------------------------------------------------------------
  3528. Method properties
  3529. ---------------------------------------------------------------------}
  3530. Function GetMethodProp(Instance : TObject;PropInfo : PPropInfo) : TMethod;
  3531. type
  3532. TGetMethodProcIndex=function(Index: Longint): TMethod of object;
  3533. TGetMethodProc=function(): TMethod of object;
  3534. var
  3535. value: PMethod;
  3536. AMethod : TMethod;
  3537. begin
  3538. Result.Code:=nil;
  3539. Result.Data:=nil;
  3540. case (PropInfo^.PropProcs) and 3 of
  3541. ptField:
  3542. begin
  3543. Value:=PMethod(Pointer(Instance)+PtrUInt(PropInfo^.GetProc));
  3544. if Value<>nil then
  3545. Result:=Value^;
  3546. end;
  3547. ptStatic,
  3548. ptVirtual:
  3549. begin
  3550. if (PropInfo^.PropProcs and 3)=ptStatic then
  3551. AMethod.Code:=PropInfo^.GetProc
  3552. else
  3553. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  3554. AMethod.Data:=Instance;
  3555. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  3556. Result:=TGetMethodProcIndex(AMethod)(PropInfo^.Index)
  3557. else
  3558. Result:=TGetMethodProc(AMethod)();
  3559. end;
  3560. else
  3561. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  3562. end;
  3563. end;
  3564. Procedure SetMethodProp(Instance : TObject;PropInfo : PPropInfo; const Value : TMethod);
  3565. type
  3566. TSetMethodProcIndex=procedure(index:longint;p:TMethod) of object;
  3567. TSetMethodProc=procedure(p:TMethod) of object;
  3568. var
  3569. AMethod : TMethod;
  3570. begin
  3571. case (PropInfo^.PropProcs shr 2) and 3 of
  3572. ptField:
  3573. PMethod(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^ := Value;
  3574. ptStatic,
  3575. ptVirtual:
  3576. begin
  3577. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  3578. AMethod.Code:=PropInfo^.SetProc
  3579. else
  3580. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  3581. AMethod.Data:=Instance;
  3582. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  3583. TSetMethodProcIndex(AMethod)(PropInfo^.Index,Value)
  3584. else
  3585. TSetMethodProc(AMethod)(Value);
  3586. end;
  3587. else
  3588. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  3589. end;
  3590. end;
  3591. Function GetMethodProp(Instance: TObject; const PropName: string): TMethod;
  3592. begin
  3593. Result:=GetMethodProp(Instance,FindPropInfo(Instance,PropName));
  3594. end;
  3595. Procedure SetMethodProp(Instance: TObject; const PropName: string; const Value: TMethod);
  3596. begin
  3597. SetMethodProp(Instance,FindPropInfo(Instance,PropName),Value);
  3598. end;
  3599. { ---------------------------------------------------------------------
  3600. Variant properties
  3601. ---------------------------------------------------------------------}
  3602. Procedure CheckVariantEvent(P : CodePointer);
  3603. begin
  3604. If (P=Nil) then
  3605. Raise Exception.Create(SErrNoVariantSupport);
  3606. end;
  3607. Function GetVariantProp(Instance : TObject;PropInfo : PPropInfo): Variant;
  3608. begin
  3609. CheckVariantEvent(CodePointer(OnGetVariantProp));
  3610. Result:=OnGetVariantProp(Instance,PropInfo);
  3611. end;
  3612. Procedure SetVariantProp(Instance : TObject;PropInfo : PPropInfo; const Value: Variant);
  3613. begin
  3614. CheckVariantEvent(CodePointer(OnSetVariantProp));
  3615. OnSetVariantProp(Instance,PropInfo,Value);
  3616. end;
  3617. Function GetVariantProp(Instance: TObject; const PropName: string): Variant;
  3618. begin
  3619. Result:=GetVariantProp(Instance,FindPropInfo(Instance,PropName));
  3620. end;
  3621. Procedure SetVariantProp(Instance: TObject; const PropName: string; const Value: Variant);
  3622. begin
  3623. SetVariantprop(instance,FindpropInfo(Instance,PropName),Value);
  3624. end;
  3625. { ---------------------------------------------------------------------
  3626. All properties through variant.
  3627. ---------------------------------------------------------------------}
  3628. Function GetPropValue(Instance: TObject; const PropName: string): Variant;
  3629. begin
  3630. Result := GetPropValue(Instance,FindPropInfo(Instance, PropName));
  3631. end;
  3632. Function GetPropValue(Instance: TObject; const PropName: string; PreferStrings: Boolean): Variant;
  3633. begin
  3634. Result := GetPropValue(Instance,FindPropInfo(Instance, PropName),PreferStrings);
  3635. end;
  3636. Function GetPropValue(Instance: TObject; PropInfo: PPropInfo): Variant;
  3637. begin
  3638. Result := GetPropValue(Instance, PropInfo, True);
  3639. end;
  3640. Function GetPropValue(Instance: TObject; PropInfo: PPropInfo; PreferStrings: Boolean): Variant;
  3641. begin
  3642. CheckVariantEvent(CodePointer(OnGetPropValue));
  3643. Result:=OnGetPropValue(Instance,PropInfo,PreferStrings);
  3644. end;
  3645. Procedure SetPropValue(Instance: TObject; const PropName: string; const Value: Variant);
  3646. begin
  3647. SetPropValue(Instance, FindPropInfo(Instance, PropName), Value);
  3648. end;
  3649. Procedure SetPropValue(Instance: TObject; PropInfo: PPropInfo; const Value: Variant);
  3650. begin
  3651. CheckVariantEvent(CodePointer(OnSetPropValue));
  3652. OnSetPropValue(Instance,PropInfo,Value);
  3653. end;
  3654. { ---------------------------------------------------------------------
  3655. Easy access methods that appeared in Delphi 5
  3656. ---------------------------------------------------------------------}
  3657. Function IsPublishedProp(Instance: TObject; const PropName: string): Boolean;
  3658. begin
  3659. Result:=GetPropInfo(Instance,PropName)<>Nil;
  3660. end;
  3661. Function IsPublishedProp(AClass: TClass; const PropName: string): Boolean;
  3662. begin
  3663. Result:=GetPropInfo(AClass,PropName)<>Nil;
  3664. end;
  3665. Function PropIsType(Instance: TObject; const PropName: string; TypeKind: TTypeKind): Boolean;
  3666. begin
  3667. Result:=PropType(Instance,PropName)=TypeKind
  3668. end;
  3669. Function PropIsType(AClass: TClass; const PropName: string; TypeKind: TTypeKind): Boolean;
  3670. begin
  3671. Result:=PropType(AClass,PropName)=TypeKind
  3672. end;
  3673. Function PropType(Instance: TObject; const PropName: string): TTypeKind;
  3674. begin
  3675. Result:=FindPropInfo(Instance,PropName)^.PropType^.Kind;
  3676. end;
  3677. Function PropType(AClass: TClass; const PropName: string): TTypeKind;
  3678. begin
  3679. Result:=FindPropInfo(AClass,PropName)^.PropType^.Kind;
  3680. end;
  3681. Function IsStoredProp(Instance: TObject; const PropName: string): Boolean;
  3682. begin
  3683. Result:=IsStoredProp(instance,FindPropInfo(Instance,PropName));
  3684. end;
  3685. { TVmtMethodExTable }
  3686. function TVmtMethodExTable.GetMethod(Index: Word): PVmtMethodExEntry;
  3687. var
  3688. Arr : PVmtMethodExEntryArray;
  3689. begin
  3690. if (Index >= Count) then
  3691. Result := Nil
  3692. else
  3693. begin
  3694. { Arr:=PVmtMethodExEntryArray(@Entries[0]);
  3695. Result:=@(Arr^[Index]);}
  3696. Result := PVmtMethodExEntry(@Entries[0]);
  3697. while Index > 0 do
  3698. begin
  3699. Result := Result^.Next;
  3700. Dec(Index);
  3701. end;
  3702. end;
  3703. end;
  3704. { TRecMethodExTable }
  3705. function TRecMethodExTable.GetMethod(Index: Word): PRecMethodExEntry;
  3706. begin
  3707. if (Index >= Count) then
  3708. Result := Nil
  3709. else
  3710. begin
  3711. Result := aligntoptr(PRecMethodExEntry(PByte(@Count) + SizeOf(Count)));
  3712. while Index > 0 do
  3713. begin
  3714. Result := Result^.Next;
  3715. Dec(Index);
  3716. end;
  3717. end;
  3718. end;
  3719. { TRecordData }
  3720. function TRecordData.GetExPropertyTable: PPropDataEx;
  3721. var
  3722. MT : PRecordMethodTable;
  3723. begin
  3724. MT:=GetMethodTable;
  3725. if MT^.Count=0 then
  3726. Result:=PPropDataEx(aligntoptr(PByte(@(MT^.Count))+SizeOf(Word)))
  3727. else
  3728. Result:=PPropDataEx(MT^.Method[MT^.Count-1]^.Tail);
  3729. end;
  3730. function TRecordData.GetExtendedFieldCount: Longint;
  3731. begin
  3732. Result:= PLongint(PByte(@TotalFieldCount)+SizeOf(Longint)+(TotalFieldCount*SizeOf(TManagedField)))^
  3733. end;
  3734. function TRecordData.GetExtendedFields: PExtendedFieldTable;
  3735. begin
  3736. Result:=PExtendedFieldTable(PByte(@TotalFieldCount)+SizeOf(Longint)+(TotalFieldCount*SizeOf(TManagedField)))
  3737. end;
  3738. function TRecordData.GetMethodTable: PRecordMethodTable;
  3739. begin
  3740. Result:=PRecordMethodTable(GetExtendedFields^.Tail);
  3741. end;
  3742. { TVmtExtendedFieldTable }
  3743. function TVmtExtendedFieldTable.GetField(aIndex: Word): PExtendedVmtFieldEntry;
  3744. begin
  3745. Result:=Nil;
  3746. If aIndex>=FieldCount then exit;
  3747. Result:=PExtendedVmtFieldEntry(@Entries +aIndex *SizeOf(TExtendedVmtFieldEntry));
  3748. end;
  3749. function TVmtExtendedFieldTable.GetTail: Pointer;
  3750. begin
  3751. if FieldCount=0 then
  3752. Result:=@FieldCount+SizeOf(Word)
  3753. else
  3754. Result:=GetField(FieldCount-1)^.Tail;
  3755. end;
  3756. { TExtendedVmtFieldEntry }
  3757. function TExtendedVmtFieldEntry.GetNext: PVmtFieldEntry;
  3758. begin
  3759. Result := aligntoptr(Tail);
  3760. end;
  3761. function TExtendedVmtFieldEntry.GetStrictVisibility: Boolean;
  3762. begin
  3763. Result:=(Flags and RTTIFlagStrictVisibility)<>0;
  3764. end;
  3765. function TExtendedVmtFieldEntry.GetTail: Pointer;
  3766. begin
  3767. Result := PByte(@Name) + SizeOf(Pointer) ;
  3768. {$ifdef PROVIDE_ATTR_TABLE}
  3769. Result := Result + SizeOf(Pointer) ;
  3770. {$ENDIF}
  3771. end;
  3772. function TExtendedVmtFieldEntry.GetVisibility: TVisibilityClass;
  3773. begin
  3774. Result:=TVisibilityClass(Flags and RTTIFlagVisibilityMask); // For the time being, maybe we need a AND $07 or so later on.
  3775. end;
  3776. { TPropInfoEx }
  3777. function TPropInfoEx.GetStrictVisibility: Boolean;
  3778. begin
  3779. Result:=(Flags and RTTIFlagStrictVisibility)<>0;
  3780. end;
  3781. function TPropInfoEx.GetTail: Pointer;
  3782. begin
  3783. Result := PByte(@Flags) + SizeOf(Self);
  3784. end;
  3785. function TPropInfoEx.GetVisiblity: TVisibilityClass;
  3786. begin
  3787. Result:=TVisibilityClass(Flags and RTTIFlagVisibilityMask);
  3788. end;
  3789. { TPropDataEx }
  3790. function TPropDataEx.GetPropEx(Index: Word): PPropInfoEx;
  3791. begin
  3792. if Index >= PropCount then
  3793. Result := Nil
  3794. else
  3795. begin
  3796. Result := PPropInfoEx(aligntoptr(@PropList));
  3797. while Index > 0 do
  3798. begin
  3799. Result := aligntoptr(Result^.Tail);
  3800. Dec(Index);
  3801. end;
  3802. end;
  3803. end;
  3804. function TPropDataEx.GetTail: Pointer;
  3805. begin
  3806. if PropCount = 0 then
  3807. Result := @Proplist
  3808. else
  3809. Result := Prop[PropCount - 1]^.Tail;
  3810. end;
  3811. { TParameterLocation }
  3812. function TParameterLocation.GetReference: Boolean;
  3813. begin
  3814. Result := (LocType and $80) <> 0;
  3815. end;
  3816. function TParameterLocation.GetRegType: TRegisterType;
  3817. begin
  3818. Result := TRegisterType(LocType and $7F);
  3819. end;
  3820. function TParameterLocation.GetShiftVal: Int8;
  3821. begin
  3822. if GetReference then begin
  3823. if Offset < Low(Int8) then
  3824. Result := Low(Int8)
  3825. else if Offset > High(Int8) then
  3826. Result := High(Int8)
  3827. else
  3828. Result := Offset;
  3829. end else
  3830. Result := 0;
  3831. end;
  3832. { TParameterLocations }
  3833. function TParameterLocations.GetLocation(aIndex: Byte): PParameterLocation;
  3834. begin
  3835. if aIndex >= Count then
  3836. Result := Nil
  3837. else
  3838. Result := PParameterLocation(PByte(aligntoptr(PByte(@Count) + SizeOf(Count))) + SizeOf(TParameterLocation) * aIndex);
  3839. end;
  3840. function TParameterLocations.GetTail: Pointer;
  3841. begin
  3842. Result := PByte(aligntoptr(PByte(@Count) + SizeOf(Count))) + SizeOf(TParameterLocation) * Count;
  3843. end;
  3844. { TProcedureParam }
  3845. function TProcedureParam.GetParamType: PTypeInfo;
  3846. begin
  3847. Result := DerefTypeInfoPtr(ParamTypeRef);
  3848. end;
  3849. function TProcedureParam.GetFlags: Byte;
  3850. begin
  3851. Result := PByte(@ParamFlags)^;
  3852. end;
  3853. { TManagedField }
  3854. function TManagedField.GetTypeRef: PTypeInfo;
  3855. begin
  3856. Result := DerefTypeInfoPtr(TypeRefRef);
  3857. end;
  3858. { TArrayTypeData }
  3859. function TArrayTypeData.GetElType: PTypeInfo;
  3860. begin
  3861. Result := DerefTypeInfoPtr(ElTypeRef);
  3862. end;
  3863. function TArrayTypeData.GetDims(aIndex: Byte): PTypeInfo;
  3864. begin
  3865. Result := DerefTypeInfoPtr(DimsRef[aIndex]);
  3866. end;
  3867. { TProcedureSignature }
  3868. function TProcedureSignature.GetResultType: PTypeInfo;
  3869. begin
  3870. Result := DerefTypeInfoPtr(ResultTypeRef);
  3871. end;
  3872. function TProcedureSignature.GetParam(ParamIndex: Integer): PProcedureParam;
  3873. begin
  3874. if (ParamIndex<0)or(ParamIndex>=ParamCount) then
  3875. Exit(nil);
  3876. Result := PProcedureParam(PByte(@Flags) + SizeOf(Self));
  3877. while ParamIndex > 0 do
  3878. begin
  3879. Result := PProcedureParam(aligntoptr((PByte(@Result^.Name) + (Length(Result^.Name) + 1) * SizeOf(AnsiChar))));
  3880. dec(ParamIndex);
  3881. end;
  3882. end;
  3883. { TVmtMethodParam }
  3884. function TVmtMethodParam.GetTail: Pointer;
  3885. begin
  3886. Result := PByte(@ParaLocs) + SizeOf(ParaLocs);
  3887. end;
  3888. function TVmtMethodParam.GetNext: PVmtMethodParam;
  3889. begin
  3890. Result := PVmtMethodParam(aligntoptr(Tail));
  3891. end;
  3892. function TVmtMethodParam.GetName: ShortString;
  3893. begin
  3894. Result := NamePtr^;
  3895. end;
  3896. { TIntfMethodEntry }
  3897. function TIntfMethodEntry.GetParam(Index: Word): PVmtMethodParam;
  3898. begin
  3899. if Index >= ParamCount then
  3900. Result := Nil
  3901. else
  3902. Result := PVmtMethodParam(PByte(aligntoptr(PByte(@NamePtr) + SizeOf(NamePtr))) + Index * PtrUInt(aligntoptr(Pointer(SizeOf(TVmtMethodParam)))));
  3903. end;
  3904. function TIntfMethodEntry.GetResultLocs: PParameterLocations;
  3905. begin
  3906. if not Assigned(ResultType) then
  3907. Result := Nil
  3908. else
  3909. Result := PParameterLocations(PByte(aligntoptr(PByte(@NamePtr) + SizeOf(NamePtr))) + ParamCount * PtrUInt(aligntoptr(Pointer(SizeOf(TVmtMethodParam)))));
  3910. end;
  3911. function TIntfMethodEntry.GetTail: Pointer;
  3912. begin
  3913. Result := PByte(@NamePtr) + SizeOf(NamePtr);
  3914. if ParamCount > 0 then
  3915. Result := PByte(aligntoptr(Result)) + ParamCount * PtrUInt(aligntoptr(Pointer(SizeOf(TVmtMethodParam))));
  3916. if Assigned(ResultType) then
  3917. Result := PByte(aligntoptr(Result)) + SizeOf(PParameterLocations);
  3918. end;
  3919. function TIntfMethodEntry.GetNext: PIntfMethodEntry;
  3920. begin
  3921. Result := PIntfMethodEntry(aligntoptr(Tail));
  3922. end;
  3923. function TIntfMethodEntry.GetName: ShortString;
  3924. begin
  3925. Result := NamePtr^;
  3926. end;
  3927. { TIntfMethodTable }
  3928. function TIntfMethodTable.GetMethod(Index: Word): PIntfMethodEntry;
  3929. begin
  3930. if (RTTICount = $FFFF) or (Index >= RTTICount) then
  3931. Result := Nil
  3932. else
  3933. begin
  3934. Result := aligntoptr(PIntfMethodEntry(PByte(@RTTICount) + SizeOf(RTTICount)));
  3935. while Index > 0 do
  3936. begin
  3937. Result := Result^.Next;
  3938. Dec(Index);
  3939. end;
  3940. end;
  3941. end;
  3942. { TVmtMethodExEntry }
  3943. function TVmtMethodExEntry.GetParamsStart: PByte;
  3944. begin
  3945. Result:=@Params
  3946. end;
  3947. function TVmtMethodExEntry.GetMethodVisibility: TVisibilityClass;
  3948. begin
  3949. Result:=TVisibilityClass(Flags and RTTIFlagVisibilityMask);
  3950. end;
  3951. function TVMTMethodExEntry.GetParam(Index: Word): PVmtMethodParam;
  3952. begin
  3953. if Index >= ParamCount then
  3954. Result := Nil
  3955. else
  3956. Result := PVmtMethodParam(@params) + Index;
  3957. end;
  3958. function TVMTMethodExEntry.GetResultLocs: PParameterLocations;
  3959. begin
  3960. if not Assigned(ResultType) then
  3961. Result := Nil
  3962. else
  3963. Result := PParameterLocations(AlignToPtr(Param[ParamCount-1]^.Tail))
  3964. end;
  3965. function TVmtMethodExEntry.GetStrictVisibility: Boolean;
  3966. begin
  3967. Result:=(Flags and RTTIFlagStrictVisibility)<>0;
  3968. end;
  3969. function TVMTMethodExEntry.GetTail: Pointer;
  3970. var
  3971. I : integer;
  3972. begin
  3973. if ParamCount = 0 then
  3974. {$IFNDEF VER3_2}
  3975. Result := PByte(@CodeAddress) + SizeOf(CodePointer)+SizeOf(AttributeTable)
  3976. {$ELSE}
  3977. Result := PByte(@VmtIndex) + SizeOf(VmtIndex)
  3978. {$ENDIF}
  3979. else
  3980. Result:=Param[ParamCount-1]^.GetTail;
  3981. if Assigned(ResultType) then
  3982. Result := PByte(aligntoptr(Result)) + SizeOf(PParameterLocations);
  3983. end;
  3984. function TVmtMethodExEntry.GetNext: PVmtMethodExEntry;
  3985. begin
  3986. Result := PVmtMethodExEntry(Tail);
  3987. end;
  3988. function TVMTMethodExEntry.GetName: ShortString;
  3989. begin
  3990. Result := NamePtr^;
  3991. end;
  3992. { TRecMethodExEntry }
  3993. function TRecMethodExEntry.GetParamsStart: PByte;
  3994. begin
  3995. Result:=PByte(aligntoptr(PByte(@NamePtr) + SizeOf(NamePtr)+SizeOf(FLags)));
  3996. {$IFNDEF VER3_2}
  3997. Result:=Result+SizeOf(CodeAddress)+SizeOf(AttributeTable);
  3998. {$ENDIF}
  3999. end;
  4000. function TRecMethodExEntry.GetMethodVisibility: TVisibilityClass;
  4001. begin
  4002. Result:=TVisibilityClass(Flags and RTTIFlagVisibilityMask);
  4003. end;
  4004. function TRecMethodExEntry.GetParam(Index: Word): PRecMethodParam;
  4005. begin
  4006. if Index >= ParamCount then
  4007. Result := Nil
  4008. else
  4009. Result := PRecMethodParam(GetParamsStart + Index * PtrUInt(aligntoptr(Pointer(SizeOf(TRecMethodParam)))));
  4010. end;
  4011. function TRecMethodExEntry.GetResultLocs: PParameterLocations;
  4012. begin
  4013. if not Assigned(ResultType) then
  4014. Result := Nil
  4015. else
  4016. Result := PParameterLocations(GetParamsStart + ParamCount * PtrUInt(aligntoptr(Pointer(SizeOf(TRecMethodParam)))));
  4017. end;
  4018. function TRecMethodExEntry.GetStrictVisibility: Boolean;
  4019. begin
  4020. Result:=(Flags and RTTIFlagStrictVisibility)<>0;
  4021. end;
  4022. function TRecMethodExEntry.GetTail: Pointer;
  4023. begin
  4024. Result := GetParamsStart;
  4025. if ParamCount > 0 then
  4026. Result := PByte(aligntoptr(Result)) + ParamCount * PtrUInt(aligntoptr(Pointer(SizeOf(TRecMethodParam))));
  4027. if Assigned(ResultType) then
  4028. Result := PByte(aligntoptr(Result)) + SizeOf(PParameterLocations);
  4029. end;
  4030. function TRecMethodExEntry.GetNext: PRecMethodExEntry;
  4031. begin
  4032. Result := PRecMethodExEntry(aligntoptr(Tail));
  4033. end;
  4034. function TRecMethodExEntry.GetName: ShortString;
  4035. begin
  4036. Result := NamePtr^;
  4037. end;
  4038. { TVmtMethodTable }
  4039. function TVmtMethodTable.GetEntry(Index: LongWord): PVmtMethodEntry;
  4040. begin
  4041. Result := PVmtMethodEntry(@Entries[0]) + Index;
  4042. end;
  4043. { TVmtFieldTable }
  4044. function TVmtFieldTable.GetField(aIndex: Word): PVmtFieldEntry;
  4045. var
  4046. c: Word;
  4047. begin
  4048. if aIndex >= Count then
  4049. Exit(Nil);
  4050. c := aIndex;
  4051. Result := @Fields;
  4052. while c > 0 do begin
  4053. Result := Result^.Next;
  4054. Dec(c);
  4055. end;
  4056. end;
  4057. function TVmtFieldTable.GetNext: Pointer;
  4058. begin
  4059. Result := Tail;
  4060. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  4061. { align to largest field of TVmtFieldEntry(!) }
  4062. Result := Align(Result, SizeOf(PtrUInt));
  4063. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  4064. end;
  4065. function TVmtFieldTable.GetTail: Pointer;
  4066. begin
  4067. if Count=0 then
  4068. Result := @Fields
  4069. else
  4070. Result:=GetField(Count-1)^.Tail;
  4071. end;
  4072. { TVmtFieldEntry }
  4073. function TVmtFieldEntry.GetNext: PVmtFieldEntry;
  4074. begin
  4075. Result := Tail;
  4076. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  4077. { align to largest field of TVmtFieldEntry }
  4078. Result := Align(Result, SizeOf(PtrUInt));
  4079. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  4080. end;
  4081. function TVmtFieldEntry.GetTail: Pointer;
  4082. begin
  4083. Result := PByte(@Name) + Length(Name) + SizeOf(Byte);
  4084. end;
  4085. { TInterfaceData }
  4086. function TInterfaceData.GetUnitName: ShortString;
  4087. begin
  4088. Result := UnitNameField;
  4089. end;
  4090. function TInterfaceData.GetPropertyTable: PPropData;
  4091. var
  4092. p: PByte;
  4093. begin
  4094. p := PByte(@UnitNameField[0]) + SizeOf(UnitNameField[0]) + Length(UnitNameField);
  4095. Result := AlignTypeData(p);
  4096. end;
  4097. function TInterfaceData.GetMethodTable: PIntfMethodTable;
  4098. begin
  4099. Result := aligntoptr(PropertyTable^.Tail);
  4100. end;
  4101. { TInterfaceRawData }
  4102. function TInterfaceRawData.GetUnitName: ShortString;
  4103. begin
  4104. Result := UnitNameField;
  4105. end;
  4106. function TInterfaceRawData.GetIIDStr: ShortString;
  4107. begin
  4108. Result := PShortString(AlignTypeData(PByte(@UnitNameField[0]) + SizeOf(UnitNameField[0]) + Length(UnitNameField)))^;
  4109. end;
  4110. function TInterfaceRawData.GetPropertyTable: PPropData;
  4111. var
  4112. p: PByte;
  4113. begin
  4114. p := AlignTypeData(PByte(@UnitNameField[0]) + SizeOf(UnitNameField[0]) + Length(UnitNameField));
  4115. p := p + SizeOf(p^) + p^;
  4116. Result := aligntoptr(p);
  4117. end;
  4118. function TInterfaceRawData.GetMethodTable: PIntfMethodTable;
  4119. begin
  4120. Result := aligntoptr(PropertyTable^.Tail);
  4121. end;
  4122. { TClassData }
  4123. function TClassData.GetExMethodTable: PVmtMethodExTable;
  4124. { Copied from objpas.inc}
  4125. type
  4126. {$push}
  4127. {$packrecords normal}
  4128. tmethodnamerec =
  4129. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  4130. packed
  4131. {$endif}
  4132. record
  4133. name : pshortstring;
  4134. addr : codepointer;
  4135. end;
  4136. tmethodnametable =
  4137. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  4138. packed
  4139. {$endif}
  4140. record
  4141. count : dword;
  4142. entries : packed array[0..0] of tmethodnamerec;
  4143. end;
  4144. {$pop}
  4145. pmethodnametable = ^tmethodnametable;
  4146. var
  4147. ovmt : PVmt;
  4148. methodtable: pmethodnametable;
  4149. begin
  4150. Result:=Nil;
  4151. oVmt:=PVmt(ClassType);
  4152. methodtable:=pmethodnametable(ovmt^.vMethodTable);
  4153. // Shift till after
  4154. if methodtable<>Nil then
  4155. PByte(Result):=PByte(@methodtable^.Entries)+ SizeOf(tmethodnamerec) * methodtable^.count;
  4156. end;
  4157. function TClassData.GetExPropertyTable: PPropDataEx;
  4158. begin
  4159. Result:=aligntoptr(PPropDataEx(GetPropertyTable^.GetTail));
  4160. end;
  4161. function TClassData.GetUnitName: ShortString;
  4162. begin
  4163. Result := UnitNameField;
  4164. end;
  4165. function TClassData.GetPropertyTable: PPropData;
  4166. var
  4167. p: PByte;
  4168. begin
  4169. p := PByte(@UnitNameField[0]) + SizeOf(UnitNameField[0]) + Length(UnitNameField);
  4170. Result := AlignToPtr(p);
  4171. end;
  4172. { TTypeData }
  4173. function TTypeData.GetBaseType: PTypeInfo;
  4174. begin
  4175. Result := DerefTypeInfoPtr(BaseTypeRef);
  4176. end;
  4177. function TTypeData.GetCompType: PTypeInfo;
  4178. begin
  4179. Result := DerefTypeInfoPtr(CompTypeRef);
  4180. end;
  4181. function TTypeData.GetParentInfo: PTypeInfo;
  4182. begin
  4183. Result := DerefTypeInfoPtr(ParentInfoRef);
  4184. end;
  4185. function TTypeData.GetRecInitData: PRecInitData;
  4186. begin
  4187. Result := PRecInitData(aligntoptr(PTypeData(RecInitInfo+2+PByte(RecInitInfo+1)^)));
  4188. end;
  4189. function TTypeData.GetHelperParent: PTypeInfo;
  4190. begin
  4191. Result := DerefTypeInfoPtr(HelperParentRef);
  4192. end;
  4193. function TTypeData.GetExtendedInfo: PTypeInfo;
  4194. begin
  4195. Result := DerefTypeInfoPtr(ExtendedInfoRef);
  4196. end;
  4197. function TTypeData.GetIntfParent: PTypeInfo;
  4198. begin
  4199. Result := DerefTypeInfoPtr(IntfParentRef);
  4200. end;
  4201. function TTypeData.GetRawIntfParent: PTypeInfo;
  4202. begin
  4203. Result := DerefTypeInfoPtr(RawIntfParentRef);
  4204. end;
  4205. function TTypeData.GetIIDStr: ShortString;
  4206. begin
  4207. Result := PShortString(AlignTypeData(Pointer(@RawIntfUnit) + Length(RawIntfUnit) + 1))^;
  4208. end;
  4209. function TTypeData.GetElType: PTypeInfo;
  4210. begin
  4211. Result := DerefTypeInfoPtr(elTypeRef);
  4212. end;
  4213. function TTypeData.GetElType2: PTypeInfo;
  4214. begin
  4215. Result := DerefTypeInfoPtr(elType2Ref);
  4216. end;
  4217. function TTypeData.GetInstanceType: PTypeInfo;
  4218. begin
  4219. Result := DerefTypeInfoPtr(InstanceTypeRef);
  4220. end;
  4221. function TTypeData.GetRefType: PTypeInfo;
  4222. begin
  4223. Result := DerefTypeInfoPtr(RefTypeRef);
  4224. end;
  4225. { TPropData }
  4226. function TPropData.GetProp(Index: Word): PPropInfo;
  4227. begin
  4228. if Index >= PropCount then
  4229. Result := Nil
  4230. else
  4231. begin
  4232. Result := PPropInfo(aligntoptr(PByte(@PropCount) + SizeOf(PropCount)));
  4233. while Index > 0 do
  4234. begin
  4235. Result := aligntoptr(Result^.Tail);
  4236. Dec(Index);
  4237. end;
  4238. end;
  4239. end;
  4240. function TPropData.GetTail: Pointer;
  4241. begin
  4242. if PropCount = 0 then
  4243. Result := PByte(@PropCount) + SizeOf(PropCount)
  4244. else
  4245. Result := Prop[PropCount - 1]^.Tail;
  4246. end;
  4247. { TPropInfo }
  4248. function TPropInfo.GetPropType: PTypeInfo;
  4249. begin
  4250. Result := DerefTypeInfoPtr(PropTypeRef);
  4251. end;
  4252. function TPropInfo.GetTail: Pointer;
  4253. begin
  4254. Result := PByte(@Name[0]) + SizeOf(Name[0]) + Length(Name);
  4255. end;
  4256. function TPropInfo.GetNext: PPropInfo;
  4257. begin
  4258. Result := PPropInfo(aligntoptr(Tail));
  4259. end;
  4260. type
  4261. TElementAlias = record
  4262. Ordinal : Integer;
  4263. Alias : string;
  4264. end;
  4265. TElementAliasArray = Array of TElementAlias;
  4266. PElementAliasArray = ^TElementAliasArray;
  4267. TEnumeratedAliases = record
  4268. TypeInfo: PTypeInfo;
  4269. Aliases: TElementAliasArray;
  4270. end;
  4271. TEnumeratedAliasesArray = Array of TEnumeratedAliases;
  4272. Var
  4273. EnumeratedAliases : TEnumeratedAliasesArray;
  4274. Function IndexOfEnumeratedAliases(aTypeInfo : PTypeInfo) : integer;
  4275. begin
  4276. Result:=High(EnumeratedAliases);
  4277. while (Result>=0) and (EnumeratedAliases[Result].TypeInfo<>aTypeInfo) do
  4278. Dec(Result);
  4279. end;
  4280. Function GetEnumeratedAliases(aTypeInfo : PTypeInfo) : PElementAliasArray;
  4281. Var
  4282. I : integer;
  4283. begin
  4284. I:=IndexOfEnumeratedAliases(aTypeInfo);
  4285. if I=-1 then
  4286. Result:=Nil
  4287. else
  4288. Result:=@EnumeratedAliases[i].Aliases
  4289. end;
  4290. Function AddEnumeratedAliases(aTypeInfo : PTypeInfo) : PElementAliasArray;
  4291. Var
  4292. L : Integer;
  4293. begin
  4294. L:=Length(EnumeratedAliases);
  4295. SetLength(EnumeratedAliases,L+1);
  4296. EnumeratedAliases[L].TypeInfo:=aTypeInfo;
  4297. Result:=@EnumeratedAliases[L].Aliases;
  4298. end;
  4299. procedure RemoveEnumElementAliases(aTypeInfo: PTypeInfo);
  4300. Var
  4301. I,L : integer;
  4302. A : TEnumeratedAliases;
  4303. begin
  4304. I:=IndexOfEnumeratedAliases(aTypeInfo);
  4305. if I=-1 then
  4306. exit;
  4307. A:=EnumeratedAliases[i];
  4308. A.Aliases:=Nil;
  4309. A.TypeInfo:=Nil;
  4310. L:=High(EnumeratedAliases);
  4311. EnumeratedAliases[i]:=EnumeratedAliases[L];
  4312. EnumeratedAliases[L]:=A;
  4313. SetLength(EnumeratedAliases,L);
  4314. end;
  4315. Resourcestring
  4316. SErrNotAnEnumerated = 'Type information points to non-enumerated type';
  4317. SErrInvalidEnumeratedCount = 'Invalid number of enumerated values';
  4318. SErrDuplicateEnumerated = 'Duplicate alias for enumerated value';
  4319. procedure AddEnumElementAliases(aTypeInfo: PTypeInfo; const aNames: array of string; aStartValue: Integer = 0);
  4320. var
  4321. Aliases: PElementAliasArray;
  4322. A : TElementAliasArray;
  4323. L, I, J : Integer;
  4324. N : String;
  4325. PT : PTypeData;
  4326. begin
  4327. if (aTypeInfo^.Kind<>tkEnumeration) then
  4328. raise EArgumentException.Create(SErrNotAnEnumerated);
  4329. PT:=GetTypeData(aTypeInfo);
  4330. if (High(aNames)=-1) or ((aStartValue+High(aNames))> PT^.MaxValue) then
  4331. raise EArgumentException.Create(SErrInvalidEnumeratedCount);
  4332. Aliases:=GetEnumeratedAliases(aTypeInfo);
  4333. if (Aliases=Nil) then
  4334. Aliases:=AddEnumeratedAliases(aTypeInfo);
  4335. A:=Aliases^;
  4336. I:=0;
  4337. L:=Length(a);
  4338. SetLength(a,L+High(aNames)+1);
  4339. try
  4340. for N in aNames do
  4341. begin
  4342. for J:=0 to (L+I)-1 do
  4343. if SameText(N,A[J].Alias) then
  4344. raise EArgumentException.Create(SErrDuplicateEnumerated);
  4345. with A[L+I] do
  4346. begin
  4347. Ordinal:=aStartValue+I;
  4348. alias:=N;
  4349. end;
  4350. Inc(I);
  4351. end;
  4352. finally
  4353. // In case of exception, we need to correct the length.
  4354. if Length(A)<>I+L then
  4355. SetLength(A,I+L);
  4356. Aliases^:=A;
  4357. end;
  4358. end;
  4359. function GetEnumeratedAliasValue(aTypeInfo: PTypeInfo; const aName: string): Integer;
  4360. var
  4361. I : Integer;
  4362. Aliases: PElementAliasArray;
  4363. begin
  4364. Result:=-1;
  4365. Aliases:=GetEnumeratedAliases(aTypeInfo);
  4366. if (Aliases=Nil) then
  4367. Exit;
  4368. I:=High(Aliases^);
  4369. While (Result=-1) and (I>=0) do
  4370. begin
  4371. if SameText(Aliases^[I].Alias, aName) then
  4372. Result:=Aliases^[I].Ordinal;
  4373. Dec(I);
  4374. end;
  4375. end;
  4376. {$IFDEF HAVE_INVOKEHELPER}
  4377. procedure CallInvokeHelper(Instance: Pointer; aMethod : PIntfMethodEntry; aArgs : PPointer);
  4378. begin
  4379. if (aMethod=Nil) then
  4380. Raise EArgumentNilException.Create('Cannot call invoke helper on nil method info');
  4381. if (aMethod^.InvokeHelper=Nil) then
  4382. Raise EArgumentException.CreateFmt('Method %s has no invoke helper.',[aMethod^.Name]);
  4383. aMethod^.InvokeHelper(Instance,aArgs);
  4384. end;
  4385. procedure CallInvokeHelper(aTypeInfo : PTypeInfo; Instance: Pointer; const aMethod : String; aArgs : PPointer);
  4386. Var
  4387. Data : PInterfaceData;
  4388. DataR : PInterfaceRawData;
  4389. MethodTable : PIntfMethodTable;
  4390. MethodEntry : PIntfMethodEntry;
  4391. I : Integer;
  4392. begin
  4393. If Instance=Nil then
  4394. Raise EArgumentNilException.Create('Cannot call invoke helper on nil instance');
  4395. if not (aTypeInfo^.Kind in [tkInterface,tkInterfaceRaw]) then
  4396. Raise EArgumentException.Create('Cannot call invoke helper non non-interfaces');
  4397. // Get method table
  4398. if (aTypeInfo^.Kind=tkInterface) then
  4399. begin
  4400. Data:=PInterfaceData(GetTypeData(aTypeInfo));
  4401. MethodTable:=Data^.MethodTable;
  4402. end
  4403. else
  4404. begin
  4405. DataR:=PInterfaceRawData(GetTypeData(aTypeInfo));
  4406. MethodTable:=DataR^.MethodTable;
  4407. end;
  4408. // Search method in method table
  4409. MethodEntry:=nil;
  4410. I:=MethodTable^.Count-1;
  4411. While (MethodEntry=Nil) and (I>=0) do
  4412. begin
  4413. MethodEntry:=MethodTable^.Method[i];
  4414. if not SameText(MethodEntry^.Name,aMethod) then
  4415. MethodEntry:=Nil;
  4416. Dec(I);
  4417. end;
  4418. if MethodEntry=Nil then
  4419. Raise EArgumentException.CreateFmt('Interface %s has no method %s.',[aTypeInfo^.Name,aMethod]);
  4420. CallInvokeHelper(Instance,MethodEntry,aArgs);
  4421. end;
  4422. {$ENDIF HAVE_INVOKEHELPER}
  4423. end.