typinfo.pp 153 KB

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