typinfo.pp 153 KB

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