typinfo.pp 154 KB

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