typinfo.pp 150 KB

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