typinfo.pp 110 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659
  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 own conventions will be shifted/reordered accordinly
  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. type
  118. TTypeKinds = set of TTypeKind;
  119. ShortStringBase = string[255];
  120. PParameterLocation = ^TParameterLocation;
  121. TParameterLocation =
  122. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  123. packed
  124. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  125. record
  126. private
  127. LocType: Byte;
  128. function GetRegType: TRegisterType; inline;
  129. function GetReference: Boolean; inline;
  130. function GetShiftVal: Int8; inline;
  131. public
  132. RegSub: TSubRegister;
  133. RegNumber: Word;
  134. { Stack offset if Reference, ShiftVal if not }
  135. Offset: SizeInt;
  136. { if Reference then the register is the index register otherwise the
  137. register in wihch (part of) the parameter resides }
  138. property Reference: Boolean read GetReference;
  139. property RegType: TRegisterType read GetRegType;
  140. { if Reference, otherwise 0 }
  141. property ShiftVal: Int8 read GetShiftVal;
  142. end;
  143. PParameterLocations = ^TParameterLocations;
  144. TParameterLocations =
  145. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  146. packed
  147. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  148. record
  149. private
  150. function GetLocation(aIndex: Byte): PParameterLocation; inline;
  151. function GetTail: Pointer; inline;
  152. public
  153. Count: Byte;
  154. property Location[Index: Byte]: PParameterLocation read GetLocation;
  155. property Tail: Pointer read GetTail;
  156. end;
  157. PVmtFieldClassTab = ^TVmtFieldClassTab;
  158. TVmtFieldClassTab =
  159. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  160. packed
  161. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  162. record
  163. Count: Word;
  164. ClassRef: array[0..0] of PClass;
  165. end;
  166. PVmtFieldEntry = ^TVmtFieldEntry;
  167. TVmtFieldEntry =
  168. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  169. packed
  170. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  171. record
  172. private
  173. function GetNext: PVmtFieldEntry; inline;
  174. function GetTail: Pointer; inline;
  175. public
  176. FieldOffset: PtrUInt;
  177. TypeIndex: Word;
  178. Name: ShortString;
  179. property Tail: Pointer read GetTail;
  180. property Next: PVmtFieldEntry read GetNext;
  181. end;
  182. PVmtFieldTable = ^TVmtFieldTable;
  183. TVmtFieldTable =
  184. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  185. packed
  186. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  187. record
  188. private
  189. function GetField(aIndex: Word): PVmtFieldEntry;
  190. public
  191. Count: Word;
  192. ClassTab: PVmtFieldClassTab;
  193. { should be array[Word] of TFieldInfo; but
  194. Elements have variant size! force at least proper alignment }
  195. Fields: array[0..0] of TVmtFieldEntry;
  196. property Field[aIndex: Word]: PVmtFieldEntry read GetField;
  197. end;
  198. TRTTIUnitOption = (rmoHasAttributes);
  199. TRTTIUnitOptions = set of TRTTIUnitOption;
  200. {$PACKRECORDS 1}
  201. PUnitInfo = ^TUnitInfo;
  202. TUnitInfo =
  203. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  204. packed
  205. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  206. record
  207. UnitOptions: TRTTIUnitOptions;
  208. UnitName: shortstring;
  209. end;
  210. TTypeInfo = record
  211. Kind : TTypeKind;
  212. Name : ShortString;
  213. // here the type data follows as TTypeData record
  214. end;
  215. PTypeInfo = ^TTypeInfo;
  216. PPTypeInfo = ^PTypeInfo;
  217. PPropData = ^TPropData;
  218. { Note: these are only for backwards compatibility. New type references should
  219. only use PPTypeInfo directly! }
  220. {$ifdef ver3_0}
  221. {$define TypeInfoPtr := PTypeInfo}
  222. {$else}
  223. {$define TypeInfoPtr := PPTypeInfo}
  224. {$endif}
  225. {$PACKRECORDS C}
  226. // members of TTypeData
  227. TArrayTypeData =
  228. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  229. packed
  230. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  231. record
  232. private
  233. function GetElType: PTypeInfo; inline;
  234. function GetDims(aIndex: Byte): PTypeInfo; inline;
  235. public
  236. property ElType: PTypeInfo read GetElType;
  237. property Dims[Index: Byte]: PTypeInfo read GetDims;
  238. public
  239. Size: SizeInt;
  240. ElCount: SizeInt;
  241. ElTypeRef: TypeInfoPtr;
  242. DimCount: Byte;
  243. DimsRef: array[0..255] of TypeInfoPtr;
  244. end;
  245. PManagedField = ^TManagedField;
  246. TManagedField =
  247. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  248. packed
  249. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  250. record
  251. private
  252. function GetTypeRef: PTypeInfo; inline;
  253. public
  254. property TypeRef: PTypeInfo read GetTypeRef;
  255. public
  256. TypeRefRef: TypeInfoPtr;
  257. FldOffset: SizeInt;
  258. end;
  259. PInitManagedField = ^TInitManagedField;
  260. TInitManagedField = TManagedField;
  261. PProcedureParam = ^TProcedureParam;
  262. TProcedureParam =
  263. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  264. packed
  265. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  266. record
  267. private
  268. function GetParamType: PTypeInfo; inline;
  269. function GetFlags: Byte; inline;
  270. public
  271. property ParamType: PTypeInfo read GetParamType;
  272. property Flags: Byte read GetFlags;
  273. public
  274. ParamFlags: TParamFlags;
  275. ParamTypeRef: TypeInfoPtr;
  276. Name: ShortString;
  277. end;
  278. TProcedureSignature =
  279. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  280. packed
  281. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  282. record
  283. private
  284. function GetResultType: PTypeInfo; inline;
  285. public
  286. property ResultType: PTypeInfo read GetResultType;
  287. public
  288. Flags: Byte;
  289. CC: TCallConv;
  290. ResultTypeRef: TypeInfoPtr;
  291. ParamCount: Byte;
  292. {Params: array[0..ParamCount - 1] of TProcedureParam;}
  293. function GetParam(ParamIndex: Integer): PProcedureParam;
  294. end;
  295. PVmtMethodParam = ^TVmtMethodParam;
  296. TVmtMethodParam =
  297. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  298. packed
  299. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  300. record
  301. private
  302. function GetTail: Pointer; inline;
  303. function GetNext: PVmtMethodParam; inline;
  304. function GetName: ShortString; inline;
  305. public
  306. ParamType: PPTypeInfo;
  307. Flags: TParamFlags;
  308. NamePtr: PShortString;
  309. ParaLocs: PParameterLocations;
  310. property Name: ShortString read GetName;
  311. property Tail: Pointer read GetTail;
  312. property Next: PVmtMethodParam read GetNext;
  313. end;
  314. PIntfMethodEntry = ^TIntfMethodEntry;
  315. TIntfMethodEntry =
  316. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  317. packed
  318. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  319. record
  320. private
  321. function GetParam(Index: Word): PVmtMethodParam;
  322. function GetResultLocs: PParameterLocations; inline;
  323. function GetTail: Pointer; inline;
  324. function GetNext: PIntfMethodEntry; inline;
  325. function GetName: ShortString; inline;
  326. public
  327. ResultType: PPTypeInfo;
  328. CC: TCallConv;
  329. Kind: TMethodKind;
  330. ParamCount: Word;
  331. StackSize: SizeInt;
  332. NamePtr: PShortString;
  333. { Params: array[0..ParamCount - 1] of TVmtMethodParam }
  334. { ResultLocs: PParameterLocations (if ResultType != Nil) }
  335. property Name: ShortString read GetName;
  336. property Param[Index: Word]: PVmtMethodParam read GetParam;
  337. property ResultLocs: PParameterLocations read GetResultLocs;
  338. property Tail: Pointer read GetTail;
  339. property Next: PIntfMethodEntry read GetNext;
  340. end;
  341. PIntfMethodTable = ^TIntfMethodTable;
  342. TIntfMethodTable =
  343. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  344. packed
  345. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  346. record
  347. private
  348. function GetMethod(Index: Word): PIntfMethodEntry;
  349. public
  350. Count: Word;
  351. { $FFFF if there is no further info, or the value of Count }
  352. RTTICount: Word;
  353. { Entry: array[0..Count - 1] of TIntfMethodEntry }
  354. property Method[Index: Word]: PIntfMethodEntry read GetMethod;
  355. end;
  356. PVmtMethodEntry = ^TVmtMethodEntry;
  357. TVmtMethodEntry =
  358. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  359. packed
  360. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  361. record
  362. Name: PShortString;
  363. CodeAddress: CodePointer;
  364. end;
  365. PVmtMethodTable = ^TVmtMethodTable;
  366. TVmtMethodTable =
  367. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  368. packed
  369. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  370. record
  371. private
  372. function GetEntry(Index: LongWord): PVmtMethodEntry; inline;
  373. public
  374. Count: LongWord;
  375. property Entry[Index: LongWord]: PVmtMethodEntry read GetEntry;
  376. private
  377. Entries: array[0..0] of TVmtMethodEntry;
  378. end;
  379. TRecOpOffsetEntry =
  380. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  381. packed
  382. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  383. record
  384. ManagementOperator: CodePointer;
  385. FieldOffset: SizeUInt;
  386. end;
  387. TRecOpOffsetTable =
  388. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  389. packed
  390. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  391. record
  392. Count: LongWord;
  393. Entries: array[0..0] of TRecOpOffsetEntry;
  394. end;
  395. PRecOpOffsetTable = ^TRecOpOffsetTable;
  396. PRecInitData = ^TRecInitData;
  397. TRecInitData =
  398. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  399. packed
  400. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  401. record
  402. Terminator: Pointer;
  403. Size: Integer;
  404. {$ifndef VER3_0}
  405. InitOffsetOp: PRecOpOffsetTable;
  406. ManagementOp: Pointer;
  407. {$endif}
  408. ManagedFieldCount: Integer;
  409. { ManagedFields: array[0..ManagedFieldCount - 1] of TInitManagedField ; }
  410. end;
  411. PInterfaceData = ^TInterfaceData;
  412. TInterfaceData =
  413. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  414. packed
  415. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  416. record
  417. private
  418. function GetUnitName: ShortString; inline;
  419. function GetPropertyTable: PPropData; inline;
  420. function GetMethodTable: PIntfMethodTable; inline;
  421. public
  422. Parent: PPTypeInfo;
  423. Flags: TIntfFlagsBase;
  424. GUID: TGUID;
  425. property UnitName: ShortString read GetUnitName;
  426. property PropertyTable: PPropData read GetPropertyTable;
  427. property MethodTable: PIntfMethodTable read GetMethodTable;
  428. private
  429. UnitNameField: ShortString;
  430. { PropertyTable: TPropData }
  431. { MethodTable: TIntfMethodTable }
  432. end;
  433. PInterfaceRawData = ^TInterfaceRawData;
  434. TInterfaceRawData =
  435. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  436. packed
  437. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  438. record
  439. private
  440. function GetUnitName: ShortString; inline;
  441. function GetIIDStr: ShortString; inline;
  442. function GetPropertyTable: PPropData; inline;
  443. function GetMethodTable: PIntfMethodTable; inline;
  444. public
  445. Parent: PPTypeInfo;
  446. Flags : TIntfFlagsBase;
  447. IID: TGUID;
  448. property UnitName: ShortString read GetUnitName;
  449. property IIDStr: ShortString read GetIIDStr;
  450. property PropertyTable: PPropData read GetPropertyTable;
  451. property MethodTable: PIntfMethodTable read GetMethodTable;
  452. private
  453. UnitNameField: ShortString;
  454. { IIDStr: ShortString; }
  455. { PropertyTable: TPropData }
  456. end;
  457. PClassData = ^TClassData;
  458. TClassData =
  459. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  460. packed
  461. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  462. record
  463. private
  464. function GetUnitName: ShortString; inline;
  465. function GetPropertyTable: PPropData; inline;
  466. public
  467. ClassType : TClass;
  468. Parent : PPTypeInfo;
  469. PropCount : SmallInt;
  470. property UnitName: ShortString read GetUnitName;
  471. property PropertyTable: PPropData read GetPropertyTable;
  472. private
  473. UnitNameField : ShortString;
  474. { PropertyTable: TPropData }
  475. end;
  476. TAttributeProc = function : TCustomAttribute;
  477. PAttributeProcList = ^TAttributeProcList;
  478. TAttributeProcList = array[0..$ffff] of TAttributeProc;
  479. TAttributeData =
  480. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  481. packed
  482. {$endif}
  483. record
  484. AttributeCount: word;
  485. AttributesList: TAttributeProcList;
  486. end;
  487. PAttributeData = ^TAttributeData;
  488. PTypeData = ^TTypeData;
  489. TTypeData =
  490. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  491. packed
  492. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  493. record
  494. private
  495. function GetBaseType: PTypeInfo; inline;
  496. function GetCompType: PTypeInfo; inline;
  497. function GetParentInfo: PTypeInfo; inline;
  498. {$ifndef VER3_0}
  499. function GetRecInitData: PRecInitData; inline;
  500. {$endif}
  501. function GetHelperParent: PTypeInfo; inline;
  502. function GetExtendedInfo: PTypeInfo; inline;
  503. function GetIntfParent: PTypeInfo; inline;
  504. function GetRawIntfParent: PTypeInfo; inline;
  505. function GetIIDStr: ShortString; inline;
  506. function GetElType: PTypeInfo; inline;
  507. function GetElType2: PTypeInfo; inline;
  508. function GetInstanceType: PTypeInfo; inline;
  509. function GetRefType: PTypeInfo; inline;
  510. public
  511. { tkEnumeration }
  512. property BaseType: PTypeInfo read GetBaseType;
  513. { tkSet }
  514. property CompType: PTypeInfo read GetCompType;
  515. { tkClass }
  516. property ParentInfo: PTypeInfo read GetParentInfo;
  517. { tkRecord }
  518. {$ifndef VER3_0}
  519. property RecInitData: PRecInitData read GetRecInitData;
  520. {$endif}
  521. { tkHelper }
  522. property HelperParent: PTypeInfo read GetHelperParent;
  523. property ExtendedInfo: PTypeInfo read GetExtendedInfo;
  524. { tkInterface }
  525. property IntfParent: PTypeInfo read GetIntfParent;
  526. { tkInterfaceRaw }
  527. property RawIntfParent: PTypeInfo read GetRawIntfParent;
  528. property IIDStr: ShortString read GetIIDStr;
  529. { tkDynArray }
  530. property ElType2: PTypeInfo read GetElType2;
  531. property ElType: PTypeInfo read GetElType;
  532. { tkClassRef }
  533. property InstanceType: PTypeInfo read GetInstanceType;
  534. { tkPointer }
  535. property RefType: PTypeInfo read GetRefType;
  536. public
  537. function UnitName: string;
  538. case TTypeKind of
  539. tkUnKnown,tkLString,tkWString,tkVariant,tkUString:
  540. ();
  541. tkAString:
  542. (CodePage: Word);
  543. {$ifndef VER3_0}
  544. tkInt64,tkQWord,
  545. {$endif VER3_0}
  546. tkInteger,tkChar,tkEnumeration,tkBool,tkWChar,tkSet:
  547. (OrdType : TOrdType;
  548. case TTypeKind of
  549. tkInteger,tkChar,tkEnumeration,tkBool,tkWChar : (
  550. MinValue,MaxValue : Longint;
  551. case TTypeKind of
  552. tkEnumeration:
  553. (
  554. BaseTypeRef : TypeInfoPtr;
  555. NameList : ShortString;
  556. {EnumUnitName: ShortString;})
  557. );
  558. {$ifndef VER3_0}
  559. {tkBool with OrdType=otSQWord }
  560. tkInt64:
  561. (MinInt64Value, MaxInt64Value: Int64);
  562. {tkBool with OrdType=otUQWord }
  563. tkQWord:
  564. (MinQWordValue, MaxQWordValue: QWord);
  565. {$endif VER3_0}
  566. tkSet:
  567. (
  568. {$ifndef VER3_0}
  569. SetSize : SizeInt;
  570. {$endif VER3_0}
  571. CompTypeRef : TypeInfoPtr
  572. )
  573. );
  574. {$ifndef FPUNONE}
  575. tkFloat:
  576. (FloatType : TFloatType);
  577. {$endif}
  578. tkSString:
  579. (MaxLength : Byte);
  580. tkClass:
  581. (ClassType : TClass;
  582. ParentInfoRef : TypeInfoPtr;
  583. PropCount : SmallInt;
  584. UnitInfo : PUnitInfo
  585. // AttributeTable: PAttributeData;
  586. // here the properties follow as array of TPropInfo
  587. );
  588. tkRecord:
  589. (
  590. {$ifndef VER3_0}
  591. RecInitInfo: Pointer; { points to TTypeInfo followed by init table }
  592. {$endif VER3_0}
  593. RecSize: Integer;
  594. case Boolean of
  595. False: (ManagedFldCount: Integer deprecated 'Use RecInitData^.ManagedFieldCount or TotalFieldCount depending on your use case');
  596. True: (TotalFieldCount: Integer);
  597. {ManagedFields: array[1..TotalFieldCount] of TManagedField}
  598. );
  599. tkHelper:
  600. (HelperParentRef : TypeInfoPtr;
  601. ExtendedInfoRef : TypeInfoPtr;
  602. HelperProps : SmallInt;
  603. HelperUnit : ShortString
  604. // here the properties follow as array of TPropInfo
  605. );
  606. tkMethod:
  607. (MethodKind : TMethodKind;
  608. ParamCount : Byte;
  609. ParamList : array[0..1023] of Char
  610. {in reality ParamList is a array[1..ParamCount] of:
  611. record
  612. Flags : TParamFlags;
  613. ParamName : ShortString;
  614. TypeName : ShortString;
  615. end;
  616. followed by
  617. ResultType : ShortString // for mkFunction, mkClassFunction only
  618. ResultTypeRef : PPTypeInfo; // for mkFunction, mkClassFunction only
  619. CC : TCallConv;
  620. ParamTypeRefs : array[1..ParamCount] of PPTypeInfo;}
  621. );
  622. tkProcVar:
  623. (ProcSig: TProcedureSignature);
  624. {$ifdef VER3_0}
  625. tkInt64:
  626. (MinInt64Value, MaxInt64Value: Int64);
  627. tkQWord:
  628. (MinQWordValue, MaxQWordValue: QWord);
  629. {$endif VER3_0}
  630. tkInterface:
  631. (
  632. IntfParentRef: TypeInfoPtr;
  633. IntfFlags : TIntfFlagsBase;
  634. GUID: TGUID;
  635. IntfUnit: ShortString;
  636. { PropertyTable: TPropData }
  637. { MethodTable: TIntfMethodTable }
  638. );
  639. tkInterfaceRaw:
  640. (
  641. RawIntfParentRef: TypeInfoPtr;
  642. RawIntfFlags : TIntfFlagsBase;
  643. IID: TGUID;
  644. RawIntfUnit: ShortString;
  645. { IIDStr: ShortString; }
  646. { PropertyTable: TPropData }
  647. );
  648. tkArray:
  649. (ArrayData: TArrayTypeData);
  650. tkDynArray:
  651. (
  652. elSize : PtrUInt;
  653. elType2Ref : TypeInfoPtr;
  654. varType : Longint;
  655. elTypeRef : TypeInfoPtr;
  656. DynUnitName: ShortStringBase
  657. );
  658. tkClassRef:
  659. (InstanceTypeRef: TypeInfoPtr);
  660. tkPointer:
  661. (RefTypeRef: TypeInfoPtr);
  662. end;
  663. PPropInfo = ^TPropInfo;
  664. TPropData =
  665. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  666. packed
  667. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  668. record
  669. private
  670. function GetProp(Index: Word): PPropInfo;
  671. function GetTail: Pointer; inline;
  672. public
  673. PropCount : Word;
  674. PropList : record _alignmentdummy : ptrint; end;
  675. property Prop[Index: Word]: PPropInfo read GetProp;
  676. property Tail: Pointer read GetTail;
  677. end;
  678. {$PACKRECORDS 1}
  679. TPropInfo = packed record
  680. private
  681. function GetPropType: PTypeInfo; inline;
  682. function GetTail: Pointer; inline;
  683. function GetNext: PPropInfo; inline;
  684. public
  685. PropTypeRef : TypeInfoPtr;
  686. GetProc : CodePointer;
  687. SetProc : CodePointer;
  688. StoredProc : CodePointer;
  689. Index : Integer;
  690. Default : Longint;
  691. NameIndex : SmallInt;
  692. // contains the type of the Get/Set/Storedproc, see also ptxxx
  693. // bit 0..1 GetProc
  694. // 2..3 SetProc
  695. // 4..5 StoredProc
  696. // 6 : true, constant index property
  697. PropProcs : Byte;
  698. AttributeTable : PAttributeData;
  699. Name : ShortString;
  700. property PropType: PTypeInfo read GetPropType;
  701. property Tail: Pointer read GetTail;
  702. property Next: PPropInfo read GetNext;
  703. end;
  704. TProcInfoProc = Procedure(PropInfo : PPropInfo) of object;
  705. PPropList = ^TPropList;
  706. TPropList = array[0..{$ifdef cpu16}(32768 div sizeof(PPropInfo))-2{$else}65535{$endif}] of PPropInfo;
  707. PUnitInfoList = ^TUnitInfoList;
  708. TUnitInfoList = record
  709. UnitCount: IntPtr;
  710. Units: array[0..65535] of PUnitInfo;
  711. end;
  712. const
  713. tkString = tkSString;
  714. tkProcedure = tkProcVar; // for compatibility with Delphi
  715. tkAny = [Low(TTypeKind)..High(TTypeKind)];
  716. tkMethods = [tkMethod];
  717. tkProperties = tkAny-tkMethods-[tkUnknown];
  718. // general property handling
  719. Function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
  720. Function AlignTypeData(p : Pointer) : Pointer; inline;
  721. Function GetPropInfo(TypeInfo: PTypeInfo;const PropName: string): PPropInfo;
  722. Function GetPropInfo(TypeInfo: PTypeInfo;const PropName: string; AKinds: TTypeKinds): PPropInfo;
  723. Function GetPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  724. Function GetPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  725. Function GetPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  726. Function GetPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  727. Function FindPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  728. Function FindPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  729. Function FindPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  730. Function FindPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  731. Procedure GetPropInfos(TypeInfo: PTypeInfo; PropList: PPropList);
  732. Function GetPropList(TypeInfo: PTypeInfo; TypeKinds: TTypeKinds; PropList: PPropList; Sorted: boolean = true): longint;
  733. Function GetPropList(TypeInfo: PTypeInfo; out PropList: PPropList): SizeInt;
  734. function GetPropList(AClass: TClass; out PropList: PPropList): Integer;
  735. function GetPropList(Instance: TObject; out PropList: PPropList): Integer;
  736. // Property information routines.
  737. Function IsReadableProp(PropInfo : PPropInfo) : Boolean;
  738. Function IsReadableProp(Instance: TObject; const PropName: string): Boolean;
  739. Function IsReadableProp(AClass: TClass; const PropName: string): Boolean;
  740. Function IsWriteableProp(PropInfo : PPropInfo) : Boolean;
  741. Function IsWriteableProp(Instance: TObject; const PropName: string): Boolean;
  742. Function IsWriteableProp(AClass: TClass; const PropName: string): Boolean;
  743. Function IsStoredProp(Instance: TObject;PropInfo : PPropInfo) : Boolean;
  744. Function IsStoredProp(Instance: TObject; const PropName: string): Boolean;
  745. Function IsPublishedProp(Instance: TObject; const PropName: string): Boolean;
  746. Function IsPublishedProp(AClass: TClass; const PropName: string): Boolean;
  747. Function PropType(Instance: TObject; const PropName: string): TTypeKind;
  748. Function PropType(AClass: TClass; const PropName: string): TTypeKind;
  749. Function PropIsType(Instance: TObject; const PropName: string; TypeKind: TTypeKind): Boolean;
  750. Function PropIsType(AClass: TClass; const PropName: string; TypeKind: TTypeKind): Boolean;
  751. // subroutines to read/write properties
  752. Function GetOrdProp(Instance: TObject; PropInfo : PPropInfo) : Int64;
  753. Function GetOrdProp(Instance: TObject; const PropName: string): Int64;
  754. Procedure SetOrdProp(Instance: TObject; PropInfo : PPropInfo; Value : Int64);
  755. Procedure SetOrdProp(Instance: TObject; const PropName: string; Value: Int64);
  756. Function GetEnumProp(Instance: TObject; const PropName: string): string;
  757. Function GetEnumProp(Instance: TObject; const PropInfo: PPropInfo): string;
  758. Procedure SetEnumProp(Instance: TObject; const PropName: string;const Value: string);
  759. Procedure SetEnumProp(Instance: TObject; const PropInfo: PPropInfo;const Value: string);
  760. Function GetSetProp(Instance: TObject; const PropName: string): string;
  761. Function GetSetProp(Instance: TObject; const PropName: string; Brackets: Boolean): string;
  762. Function GetSetProp(Instance: TObject; const PropInfo: PPropInfo; Brackets: Boolean): string;
  763. Procedure SetSetProp(Instance: TObject; const PropName: string; const Value: string);
  764. Procedure SetSetProp(Instance: TObject; const PropInfo: PPropInfo; const Value: string);
  765. Function GetStrProp(Instance: TObject; PropInfo : PPropInfo) : Ansistring;
  766. Function GetStrProp(Instance: TObject; const PropName: string): string;
  767. Procedure SetStrProp(Instance: TObject; const PropName: string; const Value: AnsiString);
  768. Procedure SetStrProp(Instance: TObject; PropInfo : PPropInfo; const Value : Ansistring);
  769. Function GetWideStrProp(Instance: TObject; PropInfo: PPropInfo): WideString;
  770. Function GetWideStrProp(Instance: TObject; const PropName: string): WideString;
  771. Procedure SetWideStrProp(Instance: TObject; const PropName: string; const Value: WideString);
  772. Procedure SetWideStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: WideString);
  773. Function GetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo): UnicodeString;
  774. Function GetUnicodeStrProp(Instance: TObject; const PropName: string): UnicodeString;
  775. Procedure SetUnicodeStrProp(Instance: TObject; const PropName: string; const Value: UnicodeString);
  776. Procedure SetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: UnicodeString);
  777. Function GetRawbyteStrProp(Instance: TObject; PropInfo: PPropInfo): RawByteString;
  778. Function GetRawByteStrProp(Instance: TObject; const PropName: string): RawByteString;
  779. Procedure SetRawByteStrProp(Instance: TObject; const PropName: string; const Value: RawByteString);
  780. Procedure SetRawByteStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: RawByteString);
  781. {$ifndef FPUNONE}
  782. Function GetFloatProp(Instance: TObject; PropInfo : PPropInfo) : Extended;
  783. Function GetFloatProp(Instance: TObject; const PropName: string): Extended;
  784. Procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Extended);
  785. Procedure SetFloatProp(Instance: TObject; PropInfo : PPropInfo; Value : Extended);
  786. {$endif}
  787. Function GetObjectProp(Instance: TObject; const PropName: string): TObject;
  788. Function GetObjectProp(Instance: TObject; const PropName: string; MinClass: TClass): TObject;
  789. Function GetObjectProp(Instance: TObject; PropInfo: PPropInfo): TObject;
  790. Function GetObjectProp(Instance: TObject; PropInfo: PPropInfo; MinClass: TClass): TObject;
  791. Procedure SetObjectProp(Instance: TObject; const PropName: string; Value: TObject);
  792. Procedure SetObjectProp(Instance: TObject; PropInfo: PPropInfo; Value: TObject);
  793. Function GetObjectPropClass(Instance: TObject; const PropName: string): TClass;
  794. Function GetObjectPropClass(AClass: TClass; const PropName: string): TClass;
  795. Function GetMethodProp(Instance: TObject; PropInfo: PPropInfo) : TMethod;
  796. Function GetMethodProp(Instance: TObject; const PropName: string): TMethod;
  797. Procedure SetMethodProp(Instance: TObject; PropInfo: PPropInfo; const Value : TMethod);
  798. Procedure SetMethodProp(Instance: TObject; const PropName: string; const Value: TMethod);
  799. Function GetInt64Prop(Instance: TObject; PropInfo: PPropInfo): Int64;
  800. Function GetInt64Prop(Instance: TObject; const PropName: string): Int64;
  801. Procedure SetInt64Prop(Instance: TObject; PropInfo: PPropInfo; const Value: Int64);
  802. Procedure SetInt64Prop(Instance: TObject; const PropName: string; const Value: Int64);
  803. Function GetPropValue(Instance: TObject; const PropName: string): Variant;
  804. Function GetPropValue(Instance: TObject; const PropName: string; PreferStrings: Boolean): Variant;
  805. Function GetPropValue(Instance: TObject; PropInfo: PPropInfo): Variant;
  806. Function GetPropValue(Instance: TObject; PropInfo: PPropInfo; PreferStrings: Boolean): Variant;
  807. Procedure SetPropValue(Instance: TObject; const PropName: string; const Value: Variant);
  808. Procedure SetPropValue(Instance: TObject; PropInfo: PPropInfo; const Value: Variant);
  809. Function GetVariantProp(Instance: TObject; PropInfo : PPropInfo): Variant;
  810. Function GetVariantProp(Instance: TObject; const PropName: string): Variant;
  811. Procedure SetVariantProp(Instance: TObject; const PropName: string; const Value: Variant);
  812. Procedure SetVariantProp(Instance: TObject; PropInfo : PPropInfo; const Value: Variant);
  813. function GetInterfaceProp(Instance: TObject; const PropName: string): IInterface;
  814. function GetInterfaceProp(Instance: TObject; PropInfo: PPropInfo): IInterface;
  815. procedure SetInterfaceProp(Instance: TObject; const PropName: string; const Value: IInterface);
  816. procedure SetInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: IInterface);
  817. function GetRawInterfaceProp(Instance: TObject; const PropName: string): Pointer;
  818. function GetRawInterfaceProp(Instance: TObject; PropInfo: PPropInfo): Pointer;
  819. procedure SetRawInterfaceProp(Instance: TObject; const PropName: string; const Value: Pointer);
  820. procedure SetRawInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: Pointer);
  821. function GetDynArrayProp(Instance: TObject; const PropName: string): Pointer;
  822. function GetDynArrayProp(Instance: TObject; PropInfo: PPropInfo): Pointer;
  823. procedure SetDynArrayProp(Instance: TObject; const PropName: string; const Value: Pointer);
  824. procedure SetDynArrayProp(Instance: TObject; PropInfo: PPropInfo; const Value: Pointer);
  825. // Extended RTTI
  826. function GetUnitList: PUnitInfoList;
  827. function GetFirstTypeinfoFromUnit(AUnitInfo: PUnitInfo): PTypeInfo;
  828. function GetNextTypeInfo(ATypeInfo: PTypeInfo): PTypeInfo;
  829. function GetAttributeData(TypeInfo: PTypeInfo): PAttributeData;
  830. function GetPropAttribute(PropInfo: PPropInfo; AttributeNr: Word): TCustomAttribute;
  831. function GetAttribute(AttributeData: PAttributeData; AttributeNr: Word): TCustomAttribute;
  832. // Auxiliary routines, which may be useful
  833. Function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
  834. Function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
  835. function GetEnumNameCount(enum1: PTypeInfo): SizeInt;
  836. procedure AddEnumElementAliases(aTypeInfo: PTypeInfo; const aNames: array of string; aStartValue: Integer = 0);
  837. procedure RemoveEnumElementAliases(aTypeInfo: PTypeInfo);
  838. function GetEnumeratedAliasValue(aTypeInfo: PTypeInfo; const aName: string): Integer;
  839. function SetToString(TypeInfo: PTypeInfo; Value: LongInt; Brackets: Boolean) : String;
  840. function SetToString(PropInfo: PPropInfo; Value: LongInt; Brackets: Boolean) : String;
  841. function SetToString(PropInfo: PPropInfo; Value: LongInt) : String;
  842. function SetToString(TypeInfo: PTypeInfo; Value: Pointer; Brackets: Boolean = False) : String;
  843. function SetToString(PropInfo: PPropInfo; Value: Pointer; Brackets: Boolean = False) : String;
  844. function StringToSet(PropInfo: PPropInfo; const Value: string): LongInt;
  845. function StringToSet(TypeInfo: PTypeInfo; const Value: string): LongInt;
  846. procedure StringToSet(PropInfo: PPropInfo; const Value: String; Result: Pointer);
  847. procedure StringToSet(TypeInfo: PTypeInfo; const Value: String; Result: Pointer);
  848. const
  849. BooleanIdents: array[Boolean] of String = ('False', 'True');
  850. DotSep: String = '.';
  851. Type
  852. EPropertyError = Class(Exception);
  853. TGetPropValue = Function (Instance: TObject; PropInfo: PPropInfo; PreferStrings: Boolean) : Variant;
  854. TSetPropValue = Procedure (Instance: TObject; PropInfo: PPropInfo; const Value: Variant);
  855. TGetVariantProp = Function (Instance: TObject; PropInfo : PPropInfo): Variant;
  856. TSetVariantProp = Procedure (Instance: TObject; PropInfo : PPropInfo; const Value: Variant);
  857. EPropertyConvertError = class(Exception); // Not used (yet), but defined for compatibility.
  858. Const
  859. OnGetPropValue : TGetPropValue = Nil;
  860. OnSetPropValue : TSetPropValue = Nil;
  861. OnGetVariantprop : TGetVariantProp = Nil;
  862. OnSetVariantprop : TSetVariantProp = Nil;
  863. { for inlining }
  864. function DerefTypeInfoPtr(Info: TypeInfoPtr): PTypeInfo; inline;
  865. Implementation
  866. uses rtlconsts;
  867. type
  868. PMethod = ^TMethod;
  869. { ---------------------------------------------------------------------
  870. TTypeData methods
  871. ---------------------------------------------------------------------}
  872. function TTypeData.UnitName: string;
  873. begin
  874. Result := UnitInfo^.UnitName
  875. end;
  876. { ---------------------------------------------------------------------
  877. Auxiliary methods
  878. ---------------------------------------------------------------------}
  879. function aligntoptr(p : pointer) : pointer;inline;
  880. begin
  881. {$ifdef m68k}
  882. result:=AlignTypeData(p);
  883. {$else m68k}
  884. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  885. result:=align(p,sizeof(p));
  886. {$else FPC_REQUIRES_PROPER_ALIGNMENT}
  887. result:=p;
  888. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  889. {$endif m68k}
  890. end;
  891. function DerefTypeInfoPtr(Info: TypeInfoPtr): PTypeInfo; inline;
  892. begin
  893. {$ifdef ver3_0}
  894. Result := Info;
  895. {$else}
  896. if not Assigned(Info) then
  897. Result := Nil
  898. else
  899. Result := Info^;
  900. {$endif}
  901. end;
  902. {$ifdef FPC_HAS_UNIT_RTTI}
  903. var
  904. UnitList: TUnitInfoList; external name 'RTTIUNITLIST';
  905. {$endif FPC_HAS_UNIT_RTTI}
  906. function GetUnitList: PUnitInfoList;
  907. begin
  908. {$ifdef FPC_HAS_UNIT_RTTI}
  909. result := @UnitList;
  910. {$else FPC_HAS_UNIT_RTTI}
  911. result := nil;
  912. {$endif FPC_HAS_UNIT_RTTI}
  913. end;
  914. function GetAttributeData(TypeInfo: PTypeInfo): PAttributeData;
  915. var
  916. TD: PTypeData;
  917. begin
  918. if TypeInfo^.Kind<>tkClass then
  919. result := nil
  920. else
  921. begin
  922. TD := GetTypeData(TypeInfo);
  923. Result:=PAttributeData(PPointer(aligntoptr(pointer(@TD^.UnitInfo)+sizeof(TD^.UnitInfo)))^)
  924. end;
  925. end;
  926. function GetPropData(TypeInfo : PTypeInfo; TypeData: PTypeData) : PPropData;
  927. var
  928. p: PtrUInt;
  929. begin
  930. p := PtrUInt(@TypeData^.UnitInfo) + SizeOf(TypeData^.UnitInfo) + SizeOf(PAttributeData);
  931. Result := PPropData(aligntoptr(Pointer(p)));
  932. end;
  933. function GetFirstTypeinfoFromUnit(AUnitInfo: PUnitInfo): PTypeInfo;
  934. begin
  935. result := align(pointer(@AUnitInfo^.UnitName)+1+byte(AUnitInfo^.UnitName[0]), sizeof(Pointer));
  936. end;
  937. function GetNextTypeInfo(ATypeInfo: PTypeInfo): PTypeInfo;
  938. type
  939. TEnumTableMode=(lookup,search);
  940. var
  941. p: pointer;
  942. td: PTypeData;
  943. pd: ppropdata;
  944. i: longint;
  945. fc: longint;
  946. minv,maxv: longint;
  947. EnumTableMode: TEnumTableMode;
  948. count: pword;
  949. begin
  950. td := GetTypeData(ATypeInfo);
  951. p := GetTypeData(ATypeInfo);
  952. case ATypeInfo^.Kind of
  953. tkEnumeration:
  954. begin
  955. p := aligntoptr(p + 1); { OrdType }
  956. minv := PLongInt(p)^;
  957. p := p + SizeOf(LongInt); { MinValue }
  958. maxv := PLongInt(p)^;
  959. p := p + SizeOf(LongInt); { MaxValue }
  960. p := p + SizeOf(PTypeInfo); { basetype }
  961. for i := minv to maxv do
  962. p := p + 1 + pbyte(p)^; { NameList: shortstring length + length of string }
  963. p := p + 1 + pbyte(p)^; { UnitName: shortstring length + length of string }
  964. p := p + 1; { trailing zero }
  965. end;
  966. tkInteger,
  967. tkChar,
  968. tkWChar,
  969. tkBool : begin
  970. p := aligntoptr(p + 1); { OrdType }
  971. p := p + SizeOf(LongInt) + SizeOf(LongInt); { MinValue + MaxValue }
  972. end;
  973. tkSet : begin
  974. p := aligntoptr(p + 1); { OrdType }
  975. p := p + sizeof(PTypeInfo); { CompType }
  976. end;
  977. tkQWord : p := p + SizeOf(QWord) + SizeOf(QWord); { MinQWordValue, MaxQWordValue }
  978. tkInt64 : p := p + SizeOf(Int64) + SizeOf(Int64); { MinInt64Value, MaxInt64Value }
  979. tkSString: p := P + SizeOf(Byte); { MaxLength }
  980. tkArray : begin
  981. p := p + sizeof(Ptrint); { Element size }
  982. p := p + sizeof(PtrInt); { Element count }
  983. p := p + sizeof(pointer); { Element type }
  984. p := p + sizeof(longint); { Variant type }
  985. end;
  986. tkDynArray:begin
  987. p := p + sizeof(Ptrint); { Element size }
  988. p := p + sizeof(PtrInt); { Element type 2 }
  989. p := p + sizeof(longint); { Variant type }
  990. p := p + sizeof(pointer); { Element type }
  991. p := p + 1 + pbyte(p)^; { unitname: shortstring length + length of string }
  992. end;
  993. tkFloat : begin
  994. p := p + sizeof(TFloatType); { Float type }
  995. end;
  996. tkObject,
  997. tkRecord : begin
  998. p := p + 4; { Size }
  999. fc := plongint(p)^;
  1000. p := p + 4; { Fieldcount }
  1001. p := p + (fc * (sizeof(pointer) + 4)); { Fieldcount * (element type + field offset) }
  1002. end;
  1003. tkClass : begin
  1004. pd := GetPropData(ATypeInfo,td);
  1005. p:=@pd^.PropList;
  1006. for i:=1 to pd^.PropCount do
  1007. p:=aligntoptr(pointer(@ppropinfo(p)^.Name)+byte(ppropinfo(p)^.Name[0]));
  1008. end;
  1009. tkInterface :
  1010. begin
  1011. p := aligntoptr(pointer(@td^.IntfUnit)+byte(td^.IntfUnit[0])+1);
  1012. p := p+pbyte(p)^+1; { IIDStr }
  1013. end;
  1014. tkMethod : begin
  1015. p := @td^.ParamList[0];
  1016. for i := 0 to td^.ParamCount-1 do
  1017. begin
  1018. p := aligntoptr(p + sizeof(TParamFlags)); { TParamFlags }
  1019. p := aligntoptr(p +pbyte(p)^+1); { paramname }
  1020. p := aligntoptr(p +pbyte(p)^+1); { typename }
  1021. end;
  1022. if td^.MethodKind in [mkFunction, mkClassFunction] then
  1023. begin
  1024. p := aligntoptr(p +pbyte(p)^+1); { resulttype }
  1025. p := p + sizeof(PPTypeInfo); { resulttyperef }
  1026. end;
  1027. p := aligntoptr(p + sizeof(TCallConv)); { cc }
  1028. p := p + (td^.ParamCount * sizeof(PPTypeInfo));
  1029. end;
  1030. end;
  1031. result := PTypeInfo(align(p,sizeof(p)));
  1032. if PByte(result)^=255 then
  1033. result := nil;
  1034. end;
  1035. function GetPropAttribute(PropInfo: PPropInfo; AttributeNr: Word): TCustomAttribute;
  1036. var
  1037. attrtable: PAttributeData;
  1038. begin
  1039. attrtable := PropInfo^.AttributeTable;
  1040. if not Assigned(attrtable) or (AttributeNr >= attrtable^.AttributeCount) then
  1041. result := Nil
  1042. else
  1043. begin
  1044. result := attrtable^.AttributesList[AttributeNr]();
  1045. end;
  1046. end;
  1047. function GetAttribute(AttributeData: PAttributeData; AttributeNr: Word): TCustomAttribute;
  1048. var
  1049. AttributeProcList: TAttributeProcList;
  1050. begin
  1051. if (AttributeData=nil) or (AttributeNr>=AttributeData^.AttributeCount) then
  1052. result := nil
  1053. else
  1054. begin
  1055. result := AttributeData^.AttributesList[AttributeNr]();
  1056. end;
  1057. end;
  1058. Function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
  1059. Var PS : PShortString;
  1060. PT : PTypeData;
  1061. begin
  1062. PT:=GetTypeData(TypeInfo);
  1063. if TypeInfo^.Kind=tkBool then
  1064. begin
  1065. case Value of
  1066. 0,1:
  1067. Result:=BooleanIdents[Boolean(Value)];
  1068. else
  1069. Result:='';
  1070. end;
  1071. end
  1072. else
  1073. begin
  1074. PS:=@PT^.NameList;
  1075. dec(Value,PT^.MinValue);
  1076. While Value>0 Do
  1077. begin
  1078. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  1079. Dec(Value);
  1080. end;
  1081. Result:=PS^;
  1082. end;
  1083. end;
  1084. Function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
  1085. Var PS : PShortString;
  1086. PT : PTypeData;
  1087. Count : longint;
  1088. sName: shortstring;
  1089. begin
  1090. If Length(Name)=0 then
  1091. exit(-1);
  1092. sName := Name;
  1093. PT:=GetTypeData(TypeInfo);
  1094. Count:=0;
  1095. Result:=-1;
  1096. if TypeInfo^.Kind=tkBool then
  1097. begin
  1098. If CompareText(BooleanIdents[false],Name)=0 then
  1099. result:=0
  1100. else if CompareText(BooleanIdents[true],Name)=0 then
  1101. result:=1;
  1102. end
  1103. else
  1104. begin
  1105. PS:=@PT^.NameList;
  1106. While (Result=-1) and (PByte(PS)^<>0) do
  1107. begin
  1108. If ShortCompareText(PS^, sName) = 0 then
  1109. Result:=Count+PT^.MinValue;
  1110. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  1111. Inc(Count);
  1112. end;
  1113. if Result=-1 then
  1114. Result:=GetEnumeratedAliasValue(TypeInfo,Name);
  1115. end;
  1116. end;
  1117. function GetEnumNameCount(enum1: PTypeInfo): SizeInt;
  1118. var
  1119. PS: PShortString;
  1120. PT: PTypeData;
  1121. Count: SizeInt;
  1122. begin
  1123. PT:=GetTypeData(enum1);
  1124. if enum1^.Kind=tkBool then
  1125. Result:=2
  1126. else
  1127. begin
  1128. Count:=0;
  1129. Result:=0;
  1130. PS:=@PT^.NameList;
  1131. While (PByte(PS)^<>0) do
  1132. begin
  1133. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  1134. Inc(Count);
  1135. end;
  1136. { the last string is the unit name }
  1137. Result := Count - 1;
  1138. end;
  1139. end;
  1140. Function SetToString(PropInfo: PPropInfo; Value: LongInt; Brackets: Boolean) : String;
  1141. begin
  1142. Result:=SetToString(PropInfo^.PropType, @Value, Brackets);
  1143. end;
  1144. Function SetToString(TypeInfo: PTypeInfo; Value: LongInt; Brackets: Boolean) : String;
  1145. begin
  1146. Result := SetToString(TypeInfo, @Value, Brackets);
  1147. end;
  1148. function SetToString(TypeInfo: PTypeInfo; Value: Pointer; Brackets: Boolean): String;
  1149. type
  1150. tsetarr = bitpacked array[0..SizeOf(LongInt)*8-1] of 0..1;
  1151. Var
  1152. I,El,Els,Rem,V,Max : Integer;
  1153. PTI : PTypeInfo;
  1154. PTD : PTypeData;
  1155. ValueArr : PLongInt;
  1156. begin
  1157. PTD := GetTypeData(TypeInfo);
  1158. PTI:=PTD^.CompType;
  1159. ValueArr := PLongInt(Value);
  1160. Result:='';
  1161. {$ifdef ver3_0}
  1162. case PTD^.OrdType of
  1163. otSByte, otUByte: begin
  1164. Els := 0;
  1165. Rem := 1;
  1166. end;
  1167. otSWord, otUWord: begin
  1168. Els := 0;
  1169. Rem := 2;
  1170. end;
  1171. otSLong, otULong: begin
  1172. Els := 1;
  1173. Rem := 0;
  1174. end;
  1175. end;
  1176. {$else}
  1177. Els := PTD^.SetSize div SizeOf(LongInt);
  1178. Rem := PTD^.SetSize mod SizeOf(LongInt);
  1179. {$endif}
  1180. {$ifdef ver3_0}
  1181. El := 0;
  1182. {$else}
  1183. for El := 0 to (PTD^.SetSize - 1) div SizeOf(LongInt) do
  1184. {$endif}
  1185. begin
  1186. if El = Els then
  1187. Max := Rem
  1188. else
  1189. Max := SizeOf(LongInt);
  1190. For I:=0 to Max*8-1 do
  1191. begin
  1192. if (tsetarr(ValueArr[El])[i]<>0) then
  1193. begin
  1194. V := I + SizeOf(LongInt) * 8 * El;
  1195. If Result='' then
  1196. Result:=GetEnumName(PTI,V)
  1197. else
  1198. Result:=Result+','+GetEnumName(PTI,V);
  1199. end;
  1200. end;
  1201. end;
  1202. if Brackets then
  1203. Result:='['+Result+']';
  1204. end;
  1205. Function SetToString(PropInfo: PPropInfo; Value: LongInt) : String;
  1206. begin
  1207. Result:=SetToString(PropInfo,Value,False);
  1208. end;
  1209. function SetToString(PropInfo: PPropInfo; Value: Pointer; Brackets: Boolean): String;
  1210. begin
  1211. Result := SetToString(PropInfo^.PropType, Value, Brackets);
  1212. end;
  1213. Const
  1214. SetDelim = ['[',']',',',' '];
  1215. Function GetNextElement(Var S : String) : String;
  1216. Var
  1217. J : Integer;
  1218. begin
  1219. J:=1;
  1220. Result:='';
  1221. If Length(S)>0 then
  1222. begin
  1223. While (J<=Length(S)) and Not (S[j] in SetDelim) do
  1224. Inc(j);
  1225. Result:=Copy(S,1,j-1);
  1226. Delete(S,1,j);
  1227. end;
  1228. end;
  1229. Function StringToSet(PropInfo: PPropInfo; const Value: string): LongInt;
  1230. begin
  1231. StringToSet(PropInfo^.PropType,Value,@Result);
  1232. end;
  1233. Function StringToSet(TypeInfo: PTypeInfo; const Value: string): LongInt;
  1234. begin
  1235. StringToSet(TypeInfo, Value, @Result);
  1236. end;
  1237. procedure StringToSet(TypeInfo: PTypeInfo; const Value: String; Result: Pointer);
  1238. Var
  1239. S,T : String;
  1240. I, ElOfs, BitOfs : Integer;
  1241. PTD: PTypeData;
  1242. PTI : PTypeInfo;
  1243. ResArr: PLongWord;
  1244. begin
  1245. PTD:=GetTypeData(TypeInfo);
  1246. {$ifndef ver3_0}
  1247. FillChar(Result^, PTD^.SetSize, 0);
  1248. {$else}
  1249. PInteger(Result)^ := 0;
  1250. {$endif}
  1251. PTI:=PTD^.Comptype;
  1252. ResArr := PLongWord(Result);
  1253. S:=Value;
  1254. I:=1;
  1255. If Length(S)>0 then
  1256. begin
  1257. While (I<=Length(S)) and (S[i] in SetDelim) do
  1258. Inc(I);
  1259. Delete(S,1,i-1);
  1260. end;
  1261. While (S<>'') do
  1262. begin
  1263. T:=GetNextElement(S);
  1264. if T<>'' then
  1265. begin
  1266. I:=GetEnumValue(PTI,T);
  1267. if (I<0) then
  1268. raise EPropertyError.CreateFmt(SErrUnknownEnumValue, [T]);
  1269. ElOfs := I shr 5;
  1270. BitOfs := I and $1F;
  1271. {$ifdef FPC_BIG_ENDIAN}
  1272. { on Big Endian systems enum values start from the MSB, thus we need
  1273. to reverse the shift }
  1274. BitOfs := 31 - BitOfs;
  1275. {$endif}
  1276. ResArr[ElOfs] := ResArr[ElOfs] or (LongInt(1) shl BitOfs);
  1277. end;
  1278. end;
  1279. end;
  1280. procedure StringToSet(PropInfo: PPropInfo; const Value: String; Result: Pointer);
  1281. begin
  1282. StringToSet(PropInfo^.PropType, Value, Result);
  1283. end;
  1284. Function AlignTypeData(p : Pointer) : Pointer;
  1285. {$packrecords c}
  1286. type
  1287. TAlignCheck = record
  1288. b : byte;
  1289. q : qword;
  1290. end;
  1291. {$packrecords default}
  1292. begin
  1293. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  1294. {$ifdef VER3_0}
  1295. Result:=Pointer(align(p,SizeOf(Pointer)));
  1296. {$else VER3_0}
  1297. Result:=Pointer(align(p,PtrInt(@TAlignCheck(nil^).q)))
  1298. {$endif VER3_0}
  1299. {$else FPC_REQUIRES_PROPER_ALIGNMENT}
  1300. Result:=p;
  1301. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  1302. end;
  1303. Function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
  1304. begin
  1305. GetTypeData:=AlignTypeData(pointer(TypeInfo)+2+PByte(pointer(TypeInfo)+1)^);
  1306. end;
  1307. { ---------------------------------------------------------------------
  1308. Basic Type information functions.
  1309. ---------------------------------------------------------------------}
  1310. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string) : PPropInfo;
  1311. var
  1312. hp : PTypeData;
  1313. i : longint;
  1314. p : shortstring;
  1315. pd : PPropData;
  1316. begin
  1317. P:=PropName; // avoid Ansi<->short conversion in a loop
  1318. while Assigned(TypeInfo) do
  1319. begin
  1320. // skip the name
  1321. hp:=GetTypeData(Typeinfo);
  1322. // the class info rtti the property rtti follows immediatly
  1323. pd := GetPropData(TypeInfo,hp);
  1324. Result:=PPropInfo(@pd^.PropList);
  1325. for i:=1 to pd^.PropCount do
  1326. begin
  1327. // found a property of that name ?
  1328. if ShortCompareText(Result^.Name, P) = 0 then
  1329. exit;
  1330. // skip to next property
  1331. Result:=PPropInfo(aligntoptr(pointer(@Result^.Name)+byte(Result^.Name[0])+1));
  1332. end;
  1333. // parent class
  1334. Typeinfo:=hp^.ParentInfo;
  1335. end;
  1336. Result:=Nil;
  1337. end;
  1338. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string; Akinds : TTypeKinds) : PPropInfo;
  1339. begin
  1340. Result:=GetPropInfo(TypeInfo,PropName);
  1341. If (Akinds<>[]) then
  1342. If (Result<>Nil) then
  1343. If Not (Result^.PropType^.Kind in AKinds) then
  1344. Result:=Nil;
  1345. end;
  1346. Function GetPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
  1347. begin
  1348. Result:=GetPropInfo(PTypeInfo(AClass.ClassInfo),PropName,AKinds);
  1349. end;
  1350. Function GetPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
  1351. begin
  1352. Result:=GetPropInfo(Instance.ClassType,PropName,AKinds);
  1353. end;
  1354. Function GetPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  1355. begin
  1356. Result:=GetPropInfo(Instance,PropName,[]);
  1357. end;
  1358. Function GetPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  1359. begin
  1360. Result:=GetPropInfo(AClass,PropName,[]);
  1361. end;
  1362. Function FindPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  1363. begin
  1364. result:=GetPropInfo(Instance, PropName);
  1365. if Result=nil then
  1366. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  1367. end;
  1368. Function FindPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  1369. begin
  1370. result:=GetPropInfo(Instance, PropName, AKinds);
  1371. if Result=nil then
  1372. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  1373. end;
  1374. Function FindPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  1375. begin
  1376. result:=GetPropInfo(AClass, PropName);
  1377. if result=nil then
  1378. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  1379. end;
  1380. Function FindPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  1381. begin
  1382. result:=GetPropInfo(AClass, PropName, AKinds);
  1383. if result=nil then
  1384. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  1385. end;
  1386. function IsReadableProp(PropInfo: PPropInfo): Boolean;
  1387. begin
  1388. Result:=(((PropInfo^.PropProcs) and 3) in [ptField,ptStatic,ptVirtual]);
  1389. end;
  1390. function IsReadableProp(Instance: TObject; const PropName: string): Boolean;
  1391. begin
  1392. Result:=IsReadableProp(FindPropInfo(Instance,PropName));
  1393. end;
  1394. function IsReadableProp(AClass: TClass; const PropName: string): Boolean;
  1395. begin
  1396. Result:=IsReadableProp(FindPropInfo(AClass,PropName));
  1397. end;
  1398. function IsWriteableProp(PropInfo: PPropInfo): Boolean;
  1399. begin
  1400. Result:=(((PropInfo^.PropProcs shr 2) and 3) in [ptField,ptStatic,ptVirtual]);
  1401. end;
  1402. function IsWriteableProp(Instance: TObject; const PropName: string): Boolean;
  1403. begin
  1404. Result:=IsWriteableProp(FindPropInfo(Instance,PropName));
  1405. end;
  1406. function IsWriteableProp(AClass: TClass; const PropName: string): Boolean;
  1407. begin
  1408. Result:=IsWriteableProp(FindPropInfo(AClass,PropName));
  1409. end;
  1410. Function IsStoredProp(Instance : TObject;PropInfo : PPropInfo) : Boolean;
  1411. type
  1412. TBooleanIndexFunc=function(Index:integer):boolean of object;
  1413. TBooleanFunc=function:boolean of object;
  1414. var
  1415. AMethod : TMethod;
  1416. begin
  1417. case (PropInfo^.PropProcs shr 4) and 3 of
  1418. ptField:
  1419. Result:=PBoolean(Pointer(Instance)+PtrUInt(PropInfo^.StoredProc))^;
  1420. ptConst:
  1421. Result:=LongBool(PropInfo^.StoredProc);
  1422. ptStatic,
  1423. ptVirtual:
  1424. begin
  1425. if (PropInfo^.PropProcs shr 4) and 3=ptstatic then
  1426. AMethod.Code:=PropInfo^.StoredProc
  1427. else
  1428. AMethod.Code:=pcodepointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.StoredProc))^;
  1429. AMethod.Data:=Instance;
  1430. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1431. Result:=TBooleanIndexFunc(AMethod)(PropInfo^.Index)
  1432. else
  1433. Result:=TBooleanFunc(AMethod)();
  1434. end;
  1435. end;
  1436. end;
  1437. Procedure GetPropInfos(TypeInfo : PTypeInfo;PropList : PPropList);
  1438. {
  1439. Store Pointers to property information in the list pointed
  1440. to by proplist. PRopList must contain enough space to hold ALL
  1441. properties.
  1442. }
  1443. Var
  1444. TD : PTypeData;
  1445. TP : PPropInfo;
  1446. Count : Longint;
  1447. begin
  1448. // Get this objects TOTAL published properties count
  1449. TD:=GetTypeData(TypeInfo);
  1450. // Clear list
  1451. FillChar(PropList^,TD^.PropCount*sizeof(Pointer),0);
  1452. repeat
  1453. TD:=GetTypeData(TypeInfo);
  1454. // published properties count for this object
  1455. TP:=PPropInfo(GetPropData(TypeInfo, TD));
  1456. Count:=PWord(TP)^;
  1457. // Now point TP to first propinfo record.
  1458. Inc(Pointer(TP),SizeOF(Word));
  1459. tp:=aligntoptr(tp);
  1460. While Count>0 do
  1461. begin
  1462. // Don't overwrite properties with the same name
  1463. if PropList^[TP^.NameIndex]=nil then
  1464. PropList^[TP^.NameIndex]:=TP;
  1465. // Point to TP next propinfo record.
  1466. // Located at Name[Length(Name)+1] !
  1467. TP:=aligntoptr(PPropInfo(pointer(@TP^.Name)+PByte(@TP^.Name)^+1));
  1468. Dec(Count);
  1469. end;
  1470. TypeInfo:=TD^.Parentinfo;
  1471. until TypeInfo=nil;
  1472. end;
  1473. Procedure InsertProp (PL : PProplist;PI : PPropInfo; Count : longint);
  1474. Var
  1475. I : Longint;
  1476. begin
  1477. I:=0;
  1478. While (I<Count) and (PI^.Name>PL^[I]^.Name) do
  1479. Inc(I);
  1480. If I<Count then
  1481. Move(PL^[I], PL^[I+1], (Count - I) * SizeOf(Pointer));
  1482. PL^[I]:=PI;
  1483. end;
  1484. Procedure InsertPropnosort (PL : PProplist;PI : PPropInfo; Count : longint);
  1485. begin
  1486. PL^[Count]:=PI;
  1487. end;
  1488. Type TInsertProp = Procedure (PL : PProplist;PI : PPropInfo; Count : longint);
  1489. //Const InsertProps : array[false..boolean] of TInsertProp = (InsertPropNoSort,InsertProp);
  1490. Function GetPropList(TypeInfo : PTypeInfo;TypeKinds : TTypeKinds; PropList : PPropList;Sorted : boolean = true):longint;
  1491. {
  1492. Store Pointers to property information OF A CERTAIN KIND in the list pointed
  1493. to by proplist. PRopList must contain enough space to hold ALL
  1494. properties.
  1495. }
  1496. Var
  1497. TempList : PPropList;
  1498. PropInfo : PPropinfo;
  1499. I,Count : longint;
  1500. DoInsertProp : TInsertProp;
  1501. begin
  1502. if sorted then
  1503. DoInsertProp:=@InsertProp
  1504. else
  1505. DoInsertProp:=@InsertPropnosort;
  1506. Result:=0;
  1507. Count:=GetTypeData(TypeInfo)^.Propcount;
  1508. If Count>0 then
  1509. begin
  1510. GetMem(TempList,Count*SizeOf(Pointer));
  1511. Try
  1512. GetPropInfos(TypeInfo,TempList);
  1513. For I:=0 to Count-1 do
  1514. begin
  1515. PropInfo:=TempList^[i];
  1516. If PropInfo^.PropType^.Kind in TypeKinds then
  1517. begin
  1518. If (PropList<>Nil) then
  1519. DoInsertProp(PropList,PropInfo,Result);
  1520. Inc(Result);
  1521. end;
  1522. end;
  1523. finally
  1524. FreeMem(TempList,Count*SizeOf(Pointer));
  1525. end;
  1526. end;
  1527. end;
  1528. Function GetPropList(TypeInfo: PTypeInfo; out PropList: PPropList): SizeInt;
  1529. begin
  1530. result:=GetTypeData(TypeInfo)^.Propcount;
  1531. if result>0 then
  1532. begin
  1533. getmem(PropList,result*sizeof(pointer));
  1534. GetPropInfos(TypeInfo,PropList);
  1535. end
  1536. else
  1537. PropList:=Nil;
  1538. end;
  1539. function GetPropList(AClass: TClass; out PropList: PPropList): Integer;
  1540. begin
  1541. Result := GetPropList(PTypeInfo(AClass.ClassInfo), PropList);
  1542. end;
  1543. function GetPropList(Instance: TObject; out PropList: PPropList): Integer;
  1544. begin
  1545. Result := GetPropList(Instance.ClassType, PropList);
  1546. end;
  1547. { ---------------------------------------------------------------------
  1548. Property access functions
  1549. ---------------------------------------------------------------------}
  1550. { ---------------------------------------------------------------------
  1551. Ordinal properties
  1552. ---------------------------------------------------------------------}
  1553. Function GetOrdProp(Instance : TObject;PropInfo : PPropInfo) : Int64;
  1554. type
  1555. TGetInt64ProcIndex=function(index:longint):Int64 of object;
  1556. TGetInt64Proc=function():Int64 of object;
  1557. TGetIntegerProcIndex=function(index:longint):longint of object;
  1558. TGetIntegerProc=function:longint of object;
  1559. TGetWordProcIndex=function(index:longint):word of object;
  1560. TGetWordProc=function:word of object;
  1561. TGetByteProcIndex=function(index:longint):Byte of object;
  1562. TGetByteProc=function:Byte of object;
  1563. var
  1564. TypeInfo: PTypeInfo;
  1565. AMethod : TMethod;
  1566. DataSize: Integer;
  1567. OrdType: TOrdType;
  1568. Signed: Boolean;
  1569. begin
  1570. Result:=0;
  1571. TypeInfo := PropInfo^.PropType;
  1572. Signed := false;
  1573. DataSize := 4;
  1574. case TypeInfo^.Kind of
  1575. // We keep this for backwards compatibility, but internally it is no longer used.
  1576. {$ifdef cpu64}
  1577. tkInterface,
  1578. tkInterfaceRaw,
  1579. tkDynArray,
  1580. tkClass:
  1581. DataSize:=8;
  1582. {$endif cpu64}
  1583. tkChar, tkBool:
  1584. DataSize:=1;
  1585. tkWChar:
  1586. DataSize:=2;
  1587. tkSet,
  1588. tkEnumeration,
  1589. tkInteger:
  1590. begin
  1591. OrdType:=GetTypeData(TypeInfo)^.OrdType;
  1592. case OrdType of
  1593. otSByte,otUByte: DataSize := 1;
  1594. otSWord,otUWord: DataSize := 2;
  1595. end;
  1596. Signed := OrdType in [otSByte,otSWord,otSLong];
  1597. end;
  1598. tkInt64 :
  1599. begin
  1600. DataSize:=8;
  1601. Signed:=true;
  1602. end;
  1603. tkQword :
  1604. begin
  1605. DataSize:=8;
  1606. Signed:=false;
  1607. end;
  1608. end;
  1609. case (PropInfo^.PropProcs) and 3 of
  1610. ptField:
  1611. if Signed then begin
  1612. case DataSize of
  1613. 1: Result:=PShortInt(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1614. 2: Result:=PSmallInt(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1615. 4: Result:=PLongint(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1616. 8: Result:=PInt64(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1617. end;
  1618. end else begin
  1619. case DataSize of
  1620. 1: Result:=PByte(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1621. 2: Result:=PWord(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1622. 4: Result:=PLongint(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1623. 8: Result:=PInt64(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1624. end;
  1625. end;
  1626. ptStatic,
  1627. ptVirtual:
  1628. begin
  1629. if (PropInfo^.PropProcs and 3)=ptStatic then
  1630. AMethod.Code:=PropInfo^.GetProc
  1631. else
  1632. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1633. AMethod.Data:=Instance;
  1634. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then begin
  1635. case DataSize of
  1636. 1: Result:=TGetByteProcIndex(AMethod)(PropInfo^.Index);
  1637. 2: Result:=TGetWordProcIndex(AMethod)(PropInfo^.Index);
  1638. 4: Result:=TGetIntegerProcIndex(AMethod)(PropInfo^.Index);
  1639. 8: result:=TGetInt64ProcIndex(AMethod)(PropInfo^.Index)
  1640. end;
  1641. end else begin
  1642. case DataSize of
  1643. 1: Result:=TGetByteProc(AMethod)();
  1644. 2: Result:=TGetWordProc(AMethod)();
  1645. 4: Result:=TGetIntegerProc(AMethod)();
  1646. 8: result:=TGetInt64Proc(AMethod)();
  1647. end;
  1648. end;
  1649. if Signed then begin
  1650. case DataSize of
  1651. 1: Result:=ShortInt(Result);
  1652. 2: Result:=SmallInt(Result);
  1653. end;
  1654. end;
  1655. end;
  1656. else
  1657. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  1658. end;
  1659. end;
  1660. Procedure SetOrdProp(Instance : TObject;PropInfo : PPropInfo;Value : Int64);
  1661. type
  1662. TSetInt64ProcIndex=procedure(index:longint;i:Int64) of object;
  1663. TSetInt64Proc=procedure(i:Int64) of object;
  1664. TSetIntegerProcIndex=procedure(index,i:longint) of object;
  1665. TSetIntegerProc=procedure(i:longint) of object;
  1666. var
  1667. DataSize: Integer;
  1668. AMethod : TMethod;
  1669. begin
  1670. if PropInfo^.PropType^.Kind in [tkInt64,tkQword
  1671. { why do we have to handle classes here, see also below? (FK) }
  1672. {$ifdef cpu64}
  1673. ,tkInterface
  1674. ,tkInterfaceRaw
  1675. ,tkDynArray
  1676. ,tkClass
  1677. {$endif cpu64}
  1678. ] then
  1679. DataSize := 8
  1680. else
  1681. DataSize := 4;
  1682. if not(PropInfo^.PropType^.Kind in [tkInt64,tkQword,tkClass,tkInterface,tkInterfaceRaw,tkDynArray]) then
  1683. begin
  1684. { cut off unnecessary stuff }
  1685. case GetTypeData(PropInfo^.PropType)^.OrdType of
  1686. otSWord,otUWord:
  1687. begin
  1688. Value:=Value and $ffff;
  1689. DataSize := 2;
  1690. end;
  1691. otSByte,otUByte:
  1692. begin
  1693. Value:=Value and $ff;
  1694. DataSize := 1;
  1695. end;
  1696. end;
  1697. end;
  1698. case (PropInfo^.PropProcs shr 2) and 3 of
  1699. ptField:
  1700. case DataSize of
  1701. 1: PByte(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Byte(Value);
  1702. 2: PWord(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Word(Value);
  1703. 4: PLongint(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Longint(Value);
  1704. 8: PInt64(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1705. end;
  1706. ptStatic,
  1707. ptVirtual:
  1708. begin
  1709. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1710. AMethod.Code:=PropInfo^.SetProc
  1711. else
  1712. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1713. AMethod.Data:=Instance;
  1714. if datasize=8 then
  1715. begin
  1716. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1717. TSetInt64ProcIndex(AMethod)(PropInfo^.Index,Value)
  1718. else
  1719. TSetInt64Proc(AMethod)(Value);
  1720. end
  1721. else
  1722. begin
  1723. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1724. TSetIntegerProcIndex(AMethod)(PropInfo^.Index,Value)
  1725. else
  1726. TSetIntegerProc(AMethod)(Value);
  1727. end;
  1728. end;
  1729. else
  1730. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  1731. end;
  1732. end;
  1733. Function GetOrdProp(Instance: TObject; const PropName: string): Int64;
  1734. begin
  1735. Result:=GetOrdProp(Instance,FindPropInfo(Instance,PropName));
  1736. end;
  1737. Procedure SetOrdProp(Instance: TObject; const PropName: string; Value: Int64);
  1738. begin
  1739. SetOrdProp(Instance,FindPropInfo(Instance,PropName),Value);
  1740. end;
  1741. Function GetEnumProp(Instance: TObject; Const PropInfo: PPropInfo): string;
  1742. begin
  1743. Result:=GetEnumName(PropInfo^.PropType, GetOrdProp(Instance, PropInfo));
  1744. end;
  1745. Function GetEnumProp(Instance: TObject; const PropName: string): string;
  1746. begin
  1747. Result:=GetEnumProp(Instance,FindPropInfo(Instance,PropName));
  1748. end;
  1749. Procedure SetEnumProp(Instance: TObject; const PropName: string; const Value: string);
  1750. begin
  1751. SetEnumProp(Instance,FindPropInfo(Instance,PropName),Value);
  1752. end;
  1753. Procedure SetEnumProp(Instance: TObject; Const PropInfo : PPropInfo; const Value: string);
  1754. Var
  1755. PV : Longint;
  1756. begin
  1757. If PropInfo<>Nil then
  1758. begin
  1759. PV:=GetEnumValue(PropInfo^.PropType, Value);
  1760. if (PV<0) then
  1761. raise EPropertyError.CreateFmt(SErrUnknownEnumValue, [Value]);
  1762. SetOrdProp(Instance, PropInfo,PV);
  1763. end;
  1764. end;
  1765. { ---------------------------------------------------------------------
  1766. Int64 wrappers
  1767. ---------------------------------------------------------------------}
  1768. Function GetInt64Prop(Instance: TObject; PropInfo: PPropInfo): Int64;
  1769. begin
  1770. Result:=GetOrdProp(Instance,PropInfo);
  1771. end;
  1772. procedure SetInt64Prop(Instance: TObject; PropInfo: PPropInfo; const Value: Int64);
  1773. begin
  1774. SetOrdProp(Instance,PropInfo,Value);
  1775. end;
  1776. Function GetInt64Prop(Instance: TObject; const PropName: string): Int64;
  1777. begin
  1778. Result:=GetInt64Prop(Instance,FindPropInfo(Instance,PropName));
  1779. end;
  1780. Procedure SetInt64Prop(Instance: TObject; const PropName: string; const Value: Int64);
  1781. begin
  1782. SetInt64Prop(Instance,FindPropInfo(Instance,PropName),Value);
  1783. end;
  1784. { ---------------------------------------------------------------------
  1785. Set properties
  1786. ---------------------------------------------------------------------}
  1787. Function GetSetProp(Instance: TObject; const PropName: string): string;
  1788. begin
  1789. Result:=GetSetProp(Instance,PropName,False);
  1790. end;
  1791. Function GetSetProp(Instance: TObject; const PropName: string; Brackets: Boolean): string;
  1792. begin
  1793. Result:=GetSetProp(Instance,FindPropInfo(Instance,PropName),Brackets);
  1794. end;
  1795. Function GetSetProp(Instance: TObject; const PropInfo: PPropInfo; Brackets: Boolean): string;
  1796. begin
  1797. Result:=SetToString(PropInfo,GetOrdProp(Instance,PropInfo),Brackets);
  1798. end;
  1799. Procedure SetSetProp(Instance: TObject; const PropName: string; const Value: string);
  1800. begin
  1801. SetSetProp(Instance,FindPropInfo(Instance,PropName),Value);
  1802. end;
  1803. Procedure SetSetProp(Instance: TObject; const PropInfo: PPropInfo; const Value: string);
  1804. begin
  1805. SetOrdProp(Instance,PropInfo,StringToSet(PropInfo,Value));
  1806. end;
  1807. { ---------------------------------------------------------------------
  1808. Pointer properties - internal only
  1809. ---------------------------------------------------------------------}
  1810. Function GetPointerProp(Instance: TObject; PropInfo : PPropInfo): Pointer;
  1811. Type
  1812. TGetPointerProcIndex = function (index:longint): Pointer of object;
  1813. TGetPointerProc = function (): Pointer of object;
  1814. var
  1815. AMethod : TMethod;
  1816. begin
  1817. case (PropInfo^.PropProcs) and 3 of
  1818. ptField:
  1819. Result := PPointer(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  1820. ptStatic,
  1821. ptVirtual:
  1822. begin
  1823. if (PropInfo^.PropProcs and 3)=ptStatic then
  1824. AMethod.Code:=PropInfo^.GetProc
  1825. else
  1826. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1827. AMethod.Data:=Instance;
  1828. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1829. Result:=TGetPointerProcIndex(AMethod)(PropInfo^.Index)
  1830. else
  1831. Result:=TGetPointerProc(AMethod)();
  1832. end;
  1833. else
  1834. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  1835. end;
  1836. end;
  1837. Procedure SetPointerProp(Instance: TObject; PropInfo : PPropInfo; Value: Pointer);
  1838. type
  1839. TSetPointerProcIndex = procedure(index: longint; p: pointer) of object;
  1840. TSetPointerProc = procedure(p: pointer) of object;
  1841. var
  1842. AMethod : TMethod;
  1843. begin
  1844. case (PropInfo^.PropProcs shr 2) and 3 of
  1845. ptField:
  1846. PPointer(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  1847. ptStatic,
  1848. ptVirtual:
  1849. begin
  1850. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1851. AMethod.Code:=PropInfo^.SetProc
  1852. else
  1853. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1854. AMethod.Data:=Instance;
  1855. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1856. TSetPointerProcIndex(AMethod)(PropInfo^.Index,Value)
  1857. else
  1858. TSetPointerProc(AMethod)(Value);
  1859. end;
  1860. else
  1861. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  1862. end;
  1863. end;
  1864. { ---------------------------------------------------------------------
  1865. Object properties
  1866. ---------------------------------------------------------------------}
  1867. Function GetObjectProp(Instance: TObject; const PropName: string): TObject;
  1868. begin
  1869. Result:=GetObjectProp(Instance,PropName,Nil);
  1870. end;
  1871. Function GetObjectProp(Instance: TObject; const PropName: string; MinClass: TClass): TObject;
  1872. begin
  1873. Result:=GetObjectProp(Instance,FindPropInfo(Instance,PropName),MinClass);
  1874. end;
  1875. Function GetObjectProp(Instance: TObject; PropInfo : PPropInfo): TObject;
  1876. begin
  1877. Result:=GetObjectProp(Instance,PropInfo,Nil);
  1878. end;
  1879. Function GetObjectProp(Instance: TObject; PropInfo : PPropInfo; MinClass: TClass): TObject;
  1880. begin
  1881. Result:=TObject(GetPointerProp(Instance,PropInfo));
  1882. If (MinClass<>Nil) and (Result<>Nil) Then
  1883. If Not Result.InheritsFrom(MinClass) then
  1884. Result:=Nil;
  1885. end;
  1886. Procedure SetObjectProp(Instance: TObject; const PropName: string; Value: TObject);
  1887. begin
  1888. SetObjectProp(Instance,FindPropInfo(Instance,PropName),Value);
  1889. end;
  1890. Procedure SetObjectProp(Instance: TObject; PropInfo : PPropInfo; Value: TObject);
  1891. begin
  1892. SetPointerProp(Instance,PropInfo,Pointer(Value));
  1893. end;
  1894. Function GetObjectPropClass(Instance: TObject; const PropName: string): TClass;
  1895. begin
  1896. Result:=GetTypeData(FindPropInfo(Instance,PropName,[tkClass])^.PropType)^.ClassType;
  1897. end;
  1898. Function GetObjectPropClass(AClass: TClass; const PropName: string): TClass;
  1899. begin
  1900. Result:=GetTypeData(FindPropInfo(AClass,PropName,[tkClass])^.PropType)^.ClassType;
  1901. end;
  1902. { ---------------------------------------------------------------------
  1903. Interface wrapprers
  1904. ---------------------------------------------------------------------}
  1905. function GetInterfaceProp(Instance: TObject; const PropName: string): IInterface;
  1906. begin
  1907. Result:=GetInterfaceProp(Instance,FindPropInfo(Instance,PropName));
  1908. end;
  1909. function GetInterfaceProp(Instance: TObject; PropInfo: PPropInfo): IInterface;
  1910. type
  1911. TGetInterfaceProc=function:IInterface of object;
  1912. TGetInterfaceProcIndex=function(index:longint):IInterface of object;
  1913. var
  1914. AMethod : TMethod;
  1915. begin
  1916. Result:=nil;
  1917. case (PropInfo^.PropProcs) and 3 of
  1918. ptField:
  1919. Result:=IInterface(PPointer(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^);
  1920. ptStatic,
  1921. ptVirtual:
  1922. begin
  1923. if (PropInfo^.PropProcs and 3)=ptStatic then
  1924. AMethod.Code:=PropInfo^.GetProc
  1925. else
  1926. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1927. AMethod.Data:=Instance;
  1928. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1929. Result:=TGetInterfaceProcIndex(AMethod)(PropInfo^.Index)
  1930. else
  1931. Result:=TGetInterfaceProc(AMethod)();
  1932. end;
  1933. else
  1934. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  1935. end;
  1936. end;
  1937. procedure SetInterfaceProp(Instance: TObject; const PropName: string; const Value: IInterface);
  1938. begin
  1939. SetInterfaceProp(Instance,FindPropInfo(Instance,PropName),Value);
  1940. end;
  1941. procedure SetInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: IInterface);
  1942. type
  1943. TSetIntfStrProcIndex=procedure(index:longint;const i:IInterface) of object;
  1944. TSetIntfStrProc=procedure(i:IInterface) of object;
  1945. var
  1946. AMethod : TMethod;
  1947. begin
  1948. case Propinfo^.PropType^.Kind of
  1949. tkInterface:
  1950. begin
  1951. case (PropInfo^.PropProcs shr 2) and 3 of
  1952. ptField:
  1953. PInterface(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1954. ptStatic,
  1955. ptVirtual:
  1956. begin
  1957. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1958. AMethod.Code:=PropInfo^.SetProc
  1959. else
  1960. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1961. AMethod.Data:=Instance;
  1962. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1963. TSetIntfStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1964. else
  1965. TSetIntfStrProc(AMethod)(Value);
  1966. end;
  1967. else
  1968. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  1969. end;
  1970. end;
  1971. tkInterfaceRaw:
  1972. Raise Exception.Create('Cannot set RAW interface from IUnknown interface');
  1973. end;
  1974. end;
  1975. { ---------------------------------------------------------------------
  1976. RAW (Corba) Interface wrapprers
  1977. ---------------------------------------------------------------------}
  1978. function GetRawInterfaceProp(Instance: TObject; const PropName: string): Pointer;
  1979. begin
  1980. Result:=GetRawInterfaceProp(Instance,FindPropInfo(Instance,PropName));
  1981. end;
  1982. function GetRawInterfaceProp(Instance: TObject; PropInfo: PPropInfo): Pointer;
  1983. begin
  1984. Result:=GetPointerProp(Instance,PropInfo);
  1985. end;
  1986. procedure SetRawInterfaceProp(Instance: TObject; const PropName: string; const Value: Pointer);
  1987. begin
  1988. SetRawInterfaceProp(Instance,FindPropInfo(Instance,PropName),Value);
  1989. end;
  1990. procedure SetRawInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: Pointer);
  1991. begin
  1992. SetPointerProp(Instance,PropInfo,Value);
  1993. end;
  1994. { ---------------------------------------------------------------------
  1995. Dynamic array properties
  1996. ---------------------------------------------------------------------}
  1997. function GetDynArrayProp(Instance: TObject; const PropName: string): Pointer;
  1998. begin
  1999. Result:=GetDynArrayProp(Instance,FindPropInfo(Instance,PropName));
  2000. end;
  2001. function GetDynArrayProp(Instance: TObject; PropInfo: PPropInfo): Pointer;
  2002. type
  2003. { we need a dynamic array as that type is usually passed differently from
  2004. a plain pointer }
  2005. TDynArray=array of Byte;
  2006. TGetDynArrayProc=function:TDynArray of object;
  2007. TGetDynArrayProcIndex=function(index:longint):TDynArray of object;
  2008. var
  2009. AMethod : TMethod;
  2010. begin
  2011. Result:=nil;
  2012. if PropInfo^.PropType^.Kind<>tkDynArray then
  2013. Exit;
  2014. case (PropInfo^.PropProcs) and 3 of
  2015. ptField:
  2016. Result:=PPointer(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2017. ptStatic,
  2018. ptVirtual:
  2019. begin
  2020. if (PropInfo^.PropProcs and 3)=ptStatic then
  2021. AMethod.Code:=PropInfo^.GetProc
  2022. else
  2023. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2024. AMethod.Data:=Instance;
  2025. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2026. Result:=Pointer(TGetDynArrayProcIndex(AMethod)(PropInfo^.Index))
  2027. else
  2028. Result:=Pointer(TGetDynArrayProc(AMethod)());
  2029. end;
  2030. else
  2031. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2032. end;
  2033. end;
  2034. procedure SetDynArrayProp(Instance: TObject; const PropName: string; const Value: Pointer);
  2035. begin
  2036. SetDynArrayProp(Instance,FindPropInfo(Instance,PropName),Value);
  2037. end;
  2038. procedure SetDynArrayProp(Instance: TObject; PropInfo: PPropInfo; const Value: Pointer);
  2039. type
  2040. { we need a dynamic array as that type is usually passed differently from
  2041. a plain pointer }
  2042. TDynArray=array of Byte;
  2043. TSetDynArrayProcIndex=procedure(index:longint;const i:TDynArray) of object;
  2044. TSetDynArrayProc=procedure(i:TDynArray) of object;
  2045. var
  2046. AMethod: TMethod;
  2047. begin
  2048. if PropInfo^.PropType^.Kind<>tkDynArray then
  2049. Exit;
  2050. case (PropInfo^.PropProcs shr 2) and 3 of
  2051. ptField:
  2052. CopyArray(PPointer(Pointer(Instance)+PtrUInt(PropInfo^.SetProc)), @Value, PropInfo^.PropType, 1);
  2053. ptStatic,
  2054. ptVirtual:
  2055. begin
  2056. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2057. AMethod.Code:=PropInfo^.SetProc
  2058. else
  2059. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2060. AMethod.Data:=Instance;
  2061. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2062. TSetDynArrayProcIndex(AMethod)(PropInfo^.Index,TDynArray(Value))
  2063. else
  2064. TSetDynArrayProc(AMethod)(TDynArray(Value));
  2065. end;
  2066. else
  2067. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2068. end;
  2069. end;
  2070. { ---------------------------------------------------------------------
  2071. String properties
  2072. ---------------------------------------------------------------------}
  2073. Function GetStrProp(Instance: TObject; PropInfo: PPropInfo): AnsiString;
  2074. type
  2075. TGetShortStrProcIndex=function(index:longint):ShortString of object;
  2076. TGetShortStrProc=function():ShortString of object;
  2077. TGetAnsiStrProcIndex=function(index:longint):AnsiString of object;
  2078. TGetAnsiStrProc=function():AnsiString of object;
  2079. var
  2080. AMethod : TMethod;
  2081. begin
  2082. Result:='';
  2083. case Propinfo^.PropType^.Kind of
  2084. tkWString:
  2085. Result:=AnsiString(GetWideStrProp(Instance,PropInfo));
  2086. tkUString:
  2087. Result := AnsiString(GetUnicodeStrProp(Instance,PropInfo));
  2088. tkSString:
  2089. begin
  2090. case (PropInfo^.PropProcs) and 3 of
  2091. ptField:
  2092. Result := PShortString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  2093. ptStatic,
  2094. ptVirtual:
  2095. begin
  2096. if (PropInfo^.PropProcs and 3)=ptStatic then
  2097. AMethod.Code:=PropInfo^.GetProc
  2098. else
  2099. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2100. AMethod.Data:=Instance;
  2101. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2102. Result:=TGetShortStrProcIndex(AMethod)(PropInfo^.Index)
  2103. else
  2104. Result:=TGetShortStrProc(AMethod)();
  2105. end;
  2106. else
  2107. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2108. end;
  2109. end;
  2110. tkAString:
  2111. begin
  2112. case (PropInfo^.PropProcs) and 3 of
  2113. ptField:
  2114. Result := PAnsiString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  2115. ptStatic,
  2116. ptVirtual:
  2117. begin
  2118. if (PropInfo^.PropProcs and 3)=ptStatic then
  2119. AMethod.Code:=PropInfo^.GetProc
  2120. else
  2121. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2122. AMethod.Data:=Instance;
  2123. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2124. Result:=TGetAnsiStrProcIndex(AMethod)(PropInfo^.Index)
  2125. else
  2126. Result:=TGetAnsiStrProc(AMethod)();
  2127. end;
  2128. else
  2129. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2130. end;
  2131. end;
  2132. end;
  2133. end;
  2134. Procedure SetStrProp(Instance : TObject;PropInfo : PPropInfo; const Value : AnsiString);
  2135. type
  2136. TSetShortStrProcIndex=procedure(index:longint;const s:ShortString) of object;
  2137. TSetShortStrProc=procedure(const s:ShortString) of object;
  2138. TSetAnsiStrProcIndex=procedure(index:longint;s:AnsiString) of object;
  2139. TSetAnsiStrProc=procedure(s:AnsiString) of object;
  2140. var
  2141. AMethod : TMethod;
  2142. begin
  2143. case Propinfo^.PropType^.Kind of
  2144. tkWString:
  2145. SetWideStrProp(Instance,PropInfo,WideString(Value));
  2146. tkUString:
  2147. SetUnicodeStrProp(Instance,PropInfo,UnicodeString(Value));
  2148. tkSString:
  2149. begin
  2150. case (PropInfo^.PropProcs shr 2) and 3 of
  2151. ptField:
  2152. PShortString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  2153. ptStatic,
  2154. ptVirtual:
  2155. begin
  2156. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2157. AMethod.Code:=PropInfo^.SetProc
  2158. else
  2159. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2160. AMethod.Data:=Instance;
  2161. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2162. TSetShortStrProcIndex(AMethod)(PropInfo^.Index,Value)
  2163. else
  2164. TSetShortStrProc(AMethod)(Value);
  2165. end;
  2166. else
  2167. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2168. end;
  2169. end;
  2170. tkAString:
  2171. begin
  2172. case (PropInfo^.PropProcs shr 2) and 3 of
  2173. ptField:
  2174. PAnsiString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  2175. ptStatic,
  2176. ptVirtual:
  2177. begin
  2178. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2179. AMethod.Code:=PropInfo^.SetProc
  2180. else
  2181. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2182. AMethod.Data:=Instance;
  2183. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2184. TSetAnsiStrProcIndex(AMethod)(PropInfo^.Index,Value)
  2185. else
  2186. TSetAnsiStrProc(AMethod)(Value);
  2187. end;
  2188. else
  2189. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2190. end;
  2191. end;
  2192. end;
  2193. end;
  2194. Function GetStrProp(Instance: TObject; const PropName: string): string;
  2195. begin
  2196. Result:=GetStrProp(Instance,FindPropInfo(Instance,PropName));
  2197. end;
  2198. Procedure SetStrProp(Instance: TObject; const PropName: string; const Value: AnsiString);
  2199. begin
  2200. SetStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  2201. end;
  2202. Function GetWideStrProp(Instance: TObject; const PropName: string): WideString;
  2203. begin
  2204. Result:=GetWideStrProp(Instance, FindPropInfo(Instance, PropName));
  2205. end;
  2206. procedure SetWideStrProp(Instance: TObject; const PropName: string; const Value: WideString);
  2207. begin
  2208. SetWideStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  2209. end;
  2210. Function GetWideStrProp(Instance: TObject; PropInfo: PPropInfo): WideString;
  2211. type
  2212. TGetWideStrProcIndex=function(index:longint):WideString of object;
  2213. TGetWideStrProc=function():WideString of object;
  2214. var
  2215. AMethod : TMethod;
  2216. begin
  2217. Result:='';
  2218. case Propinfo^.PropType^.Kind of
  2219. tkSString,tkAString:
  2220. Result:=WideString(GetStrProp(Instance,PropInfo));
  2221. tkUString :
  2222. Result := GetUnicodeStrProp(Instance,PropInfo);
  2223. tkWString:
  2224. begin
  2225. case (PropInfo^.PropProcs) and 3 of
  2226. ptField:
  2227. Result := PWideString(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2228. ptStatic,
  2229. ptVirtual:
  2230. begin
  2231. if (PropInfo^.PropProcs and 3)=ptStatic then
  2232. AMethod.Code:=PropInfo^.GetProc
  2233. else
  2234. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2235. AMethod.Data:=Instance;
  2236. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2237. Result:=TGetWideStrProcIndex(AMethod)(PropInfo^.Index)
  2238. else
  2239. Result:=TGetWideStrProc(AMethod)();
  2240. end;
  2241. else
  2242. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2243. end;
  2244. end;
  2245. end;
  2246. end;
  2247. Procedure SetWideStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: WideString);
  2248. type
  2249. TSetWideStrProcIndex=procedure(index:longint;s:WideString) of object;
  2250. TSetWideStrProc=procedure(s:WideString) of object;
  2251. var
  2252. AMethod : TMethod;
  2253. begin
  2254. case Propinfo^.PropType^.Kind of
  2255. tkSString,tkAString:
  2256. SetStrProp(Instance,PropInfo,AnsiString(Value));
  2257. tkUString:
  2258. SetUnicodeStrProp(Instance,PropInfo,Value);
  2259. tkWString:
  2260. begin
  2261. case (PropInfo^.PropProcs shr 2) and 3 of
  2262. ptField:
  2263. PWideString(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2264. ptStatic,
  2265. ptVirtual:
  2266. begin
  2267. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2268. AMethod.Code:=PropInfo^.SetProc
  2269. else
  2270. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2271. AMethod.Data:=Instance;
  2272. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2273. TSetWideStrProcIndex(AMethod)(PropInfo^.Index,Value)
  2274. else
  2275. TSetWideStrProc(AMethod)(Value);
  2276. end;
  2277. else
  2278. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2279. end;
  2280. end;
  2281. end;
  2282. end;
  2283. Function GetUnicodeStrProp(Instance: TObject; const PropName: string): UnicodeString;
  2284. begin
  2285. Result:=GetUnicodeStrProp(Instance, FindPropInfo(Instance, PropName));
  2286. end;
  2287. procedure SetUnicodeStrProp(Instance: TObject; const PropName: string; const Value: UnicodeString);
  2288. begin
  2289. SetUnicodeStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  2290. end;
  2291. Function GetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo): UnicodeString;
  2292. type
  2293. TGetUnicodeStrProcIndex=function(index:longint):UnicodeString of object;
  2294. TGetUnicodeStrProc=function():UnicodeString of object;
  2295. var
  2296. AMethod : TMethod;
  2297. begin
  2298. Result:='';
  2299. case Propinfo^.PropType^.Kind of
  2300. tkSString,tkAString:
  2301. Result:=UnicodeString(GetStrProp(Instance,PropInfo));
  2302. tkWString:
  2303. Result:=GetWideStrProp(Instance,PropInfo);
  2304. tkUString:
  2305. begin
  2306. case (PropInfo^.PropProcs) and 3 of
  2307. ptField:
  2308. Result := PUnicodeString(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2309. ptStatic,
  2310. ptVirtual:
  2311. begin
  2312. if (PropInfo^.PropProcs and 3)=ptStatic then
  2313. AMethod.Code:=PropInfo^.GetProc
  2314. else
  2315. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2316. AMethod.Data:=Instance;
  2317. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2318. Result:=TGetUnicodeStrProcIndex(AMethod)(PropInfo^.Index)
  2319. else
  2320. Result:=TGetUnicodeStrProc(AMethod)();
  2321. end;
  2322. else
  2323. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2324. end;
  2325. end;
  2326. end;
  2327. end;
  2328. Procedure SetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: UnicodeString);
  2329. type
  2330. TSetUnicodeStrProcIndex=procedure(index:longint;s:UnicodeString) of object;
  2331. TSetUnicodeStrProc=procedure(s:UnicodeString) of object;
  2332. var
  2333. AMethod : TMethod;
  2334. begin
  2335. case Propinfo^.PropType^.Kind of
  2336. tkSString,tkAString:
  2337. SetStrProp(Instance,PropInfo,AnsiString(Value));
  2338. tkWString:
  2339. SetWideStrProp(Instance,PropInfo,Value);
  2340. tkUString:
  2341. begin
  2342. case (PropInfo^.PropProcs shr 2) and 3 of
  2343. ptField:
  2344. PUnicodeString(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2345. ptStatic,
  2346. ptVirtual:
  2347. begin
  2348. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2349. AMethod.Code:=PropInfo^.SetProc
  2350. else
  2351. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2352. AMethod.Data:=Instance;
  2353. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2354. TSetUnicodeStrProcIndex(AMethod)(PropInfo^.Index,Value)
  2355. else
  2356. TSetUnicodeStrProc(AMethod)(Value);
  2357. end;
  2358. else
  2359. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2360. end;
  2361. end;
  2362. end;
  2363. end;
  2364. function GetRawbyteStrProp(Instance: TObject; PropInfo: PPropInfo): RawByteString;
  2365. type
  2366. TGetRawByteStrProcIndex=function(index:longint): RawByteString of object;
  2367. TGetRawByteStrProc=function():RawByteString of object;
  2368. var
  2369. AMethod : TMethod;
  2370. begin
  2371. Result:='';
  2372. case Propinfo^.PropType^.Kind of
  2373. tkWString:
  2374. Result:=RawByteString(GetWideStrProp(Instance,PropInfo));
  2375. tkUString:
  2376. Result:=RawByteString(GetUnicodeStrProp(Instance,PropInfo));
  2377. tkSString:
  2378. Result:=RawByteString(GetStrProp(Instance,PropInfo));
  2379. tkAString:
  2380. begin
  2381. case (PropInfo^.PropProcs) and 3 of
  2382. ptField:
  2383. Result := PAnsiString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  2384. ptStatic,
  2385. ptVirtual:
  2386. begin
  2387. if (PropInfo^.PropProcs and 3)=ptStatic then
  2388. AMethod.Code:=PropInfo^.GetProc
  2389. else
  2390. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2391. AMethod.Data:=Instance;
  2392. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2393. Result:=TGetRawByteStrProcIndex(AMethod)(PropInfo^.Index)
  2394. else
  2395. Result:=TGetRawByteStrProc(AMethod)();
  2396. end;
  2397. else
  2398. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2399. end;
  2400. end;
  2401. end;
  2402. end;
  2403. function GetRawByteStrProp(Instance: TObject; const PropName: string): RawByteString;
  2404. begin
  2405. Result:=GetRawByteStrProp(Instance,FindPropInfo(Instance,PropName));
  2406. end;
  2407. procedure SetRawByteStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: RawByteString);
  2408. type
  2409. TSetRawByteStrProcIndex=procedure(index:longint;s:RawByteString) of object;
  2410. TSetRawByteStrProc=procedure(s:RawByteString) of object;
  2411. var
  2412. AMethod : TMethod;
  2413. begin
  2414. case Propinfo^.PropType^.Kind of
  2415. tkWString:
  2416. SetWideStrProp(Instance,PropInfo,WideString(Value));
  2417. tkUString:
  2418. SetUnicodeStrProp(Instance,PropInfo,UnicodeString(Value));
  2419. tkSString:
  2420. SetStrProp(Instance,PropInfo,Value); // Not 100% sure about this.
  2421. tkAString:
  2422. begin
  2423. case (PropInfo^.PropProcs shr 2) and 3 of
  2424. ptField:
  2425. PAnsiString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  2426. ptStatic,
  2427. ptVirtual:
  2428. begin
  2429. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2430. AMethod.Code:=PropInfo^.SetProc
  2431. else
  2432. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2433. AMethod.Data:=Instance;
  2434. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2435. TSetRawByteStrProcIndex(AMethod)(PropInfo^.Index,Value)
  2436. else
  2437. TSetRawByteStrProc(AMethod)(Value);
  2438. end;
  2439. else
  2440. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2441. end;
  2442. end;
  2443. end;
  2444. end;
  2445. procedure SetRawByteStrProp(Instance: TObject; const PropName: string; const Value: RawByteString);
  2446. begin
  2447. SetRawByteStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  2448. end;
  2449. {$ifndef FPUNONE}
  2450. { ---------------------------------------------------------------------
  2451. Float properties
  2452. ---------------------------------------------------------------------}
  2453. function GetFloatProp(Instance : TObject;PropInfo : PPropInfo) : Extended;
  2454. type
  2455. TGetExtendedProc = function:Extended of object;
  2456. TGetExtendedProcIndex = function(Index: integer): Extended of object;
  2457. TGetDoubleProc = function:Double of object;
  2458. TGetDoubleProcIndex = function(Index: integer): Double of object;
  2459. TGetSingleProc = function:Single of object;
  2460. TGetSingleProcIndex = function(Index: integer):Single of object;
  2461. TGetCurrencyProc = function : Currency of object;
  2462. TGetCurrencyProcIndex = function(Index: integer) : Currency of object;
  2463. var
  2464. AMethod : TMethod;
  2465. begin
  2466. Result:=0.0;
  2467. case PropInfo^.PropProcs and 3 of
  2468. ptField:
  2469. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  2470. ftSingle:
  2471. Result:=PSingle(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2472. ftDouble:
  2473. Result:=PDouble(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2474. ftExtended:
  2475. Result:=PExtended(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2476. ftcomp:
  2477. Result:=PComp(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2478. ftcurr:
  2479. Result:=PCurrency(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2480. end;
  2481. ptStatic,
  2482. ptVirtual:
  2483. begin
  2484. if (PropInfo^.PropProcs and 3)=ptStatic then
  2485. AMethod.Code:=PropInfo^.GetProc
  2486. else
  2487. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2488. AMethod.Data:=Instance;
  2489. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  2490. ftSingle:
  2491. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2492. Result:=TGetSingleProc(AMethod)()
  2493. else
  2494. Result:=TGetSingleProcIndex(AMethod)(PropInfo^.Index);
  2495. ftDouble:
  2496. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2497. Result:=TGetDoubleProc(AMethod)()
  2498. else
  2499. Result:=TGetDoubleProcIndex(AMethod)(PropInfo^.Index);
  2500. ftExtended:
  2501. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2502. Result:=TGetExtendedProc(AMethod)()
  2503. else
  2504. Result:=TGetExtendedProcIndex(AMethod)(PropInfo^.Index);
  2505. ftCurr:
  2506. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2507. Result:=TGetCurrencyProc(AMethod)()
  2508. else
  2509. Result:=TGetCurrencyProcIndex(AMethod)(PropInfo^.Index);
  2510. end;
  2511. end;
  2512. else
  2513. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2514. end;
  2515. end;
  2516. Procedure SetFloatProp(Instance : TObject;PropInfo : PPropInfo; Value : Extended);
  2517. type
  2518. TSetExtendedProc = procedure(const AValue: Extended) of object;
  2519. TSetExtendedProcIndex = procedure(Index: integer; AValue: Extended) of object;
  2520. TSetDoubleProc = procedure(const AValue: Double) of object;
  2521. TSetDoubleProcIndex = procedure(Index: integer; AValue: Double) of object;
  2522. TSetSingleProc = procedure(const AValue: Single) of object;
  2523. TSetSingleProcIndex = procedure(Index: integer; AValue: Single) of object;
  2524. TSetCurrencyProc = procedure(const AValue: Currency) of object;
  2525. TSetCurrencyProcIndex = procedure(Index: integer; AValue: Currency) of object;
  2526. Var
  2527. AMethod : TMethod;
  2528. begin
  2529. case (PropInfo^.PropProcs shr 2) and 3 of
  2530. ptfield:
  2531. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  2532. ftSingle:
  2533. PSingle(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2534. ftDouble:
  2535. PDouble(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2536. ftExtended:
  2537. PExtended(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2538. {$ifdef FPC_COMP_IS_INT64}
  2539. ftComp:
  2540. PComp(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=trunc(Value);
  2541. {$else FPC_COMP_IS_INT64}
  2542. ftComp:
  2543. PComp(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Comp(Value);
  2544. {$endif FPC_COMP_IS_INT64}
  2545. ftCurr:
  2546. PCurrency(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2547. end;
  2548. ptStatic,
  2549. ptVirtual:
  2550. begin
  2551. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2552. AMethod.Code:=PropInfo^.SetProc
  2553. else
  2554. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2555. AMethod.Data:=Instance;
  2556. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  2557. ftSingle:
  2558. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2559. TSetSingleProc(AMethod)(Value)
  2560. else
  2561. TSetSingleProcIndex(AMethod)(PropInfo^.Index,Value);
  2562. ftDouble:
  2563. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2564. TSetDoubleProc(AMethod)(Value)
  2565. else
  2566. TSetDoubleProcIndex(AMethod)(PropInfo^.Index,Value);
  2567. ftExtended:
  2568. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2569. TSetExtendedProc(AMethod)(Value)
  2570. else
  2571. TSetExtendedProcIndex(AMethod)(PropInfo^.Index,Value);
  2572. ftCurr:
  2573. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2574. TSetCurrencyProc(AMethod)(Value)
  2575. else
  2576. TSetCurrencyProcIndex(AMethod)(PropInfo^.Index,Value);
  2577. end;
  2578. end;
  2579. else
  2580. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2581. end;
  2582. end;
  2583. function GetFloatProp(Instance: TObject; const PropName: string): Extended;
  2584. begin
  2585. Result:=GetFloatProp(Instance,FindPropInfo(Instance,PropName))
  2586. end;
  2587. Procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Extended);
  2588. begin
  2589. SetFloatProp(Instance,FindPropInfo(Instance,PropName),Value);
  2590. end;
  2591. {$endif}
  2592. { ---------------------------------------------------------------------
  2593. Method properties
  2594. ---------------------------------------------------------------------}
  2595. Function GetMethodProp(Instance : TObject;PropInfo : PPropInfo) : TMethod;
  2596. type
  2597. TGetMethodProcIndex=function(Index: Longint): TMethod of object;
  2598. TGetMethodProc=function(): TMethod of object;
  2599. var
  2600. value: PMethod;
  2601. AMethod : TMethod;
  2602. begin
  2603. Result.Code:=nil;
  2604. Result.Data:=nil;
  2605. case (PropInfo^.PropProcs) and 3 of
  2606. ptField:
  2607. begin
  2608. Value:=PMethod(Pointer(Instance)+PtrUInt(PropInfo^.GetProc));
  2609. if Value<>nil then
  2610. Result:=Value^;
  2611. end;
  2612. ptStatic,
  2613. ptVirtual:
  2614. begin
  2615. if (PropInfo^.PropProcs and 3)=ptStatic then
  2616. AMethod.Code:=PropInfo^.GetProc
  2617. else
  2618. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2619. AMethod.Data:=Instance;
  2620. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2621. Result:=TGetMethodProcIndex(AMethod)(PropInfo^.Index)
  2622. else
  2623. Result:=TGetMethodProc(AMethod)();
  2624. end;
  2625. else
  2626. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2627. end;
  2628. end;
  2629. Procedure SetMethodProp(Instance : TObject;PropInfo : PPropInfo; const Value : TMethod);
  2630. type
  2631. TSetMethodProcIndex=procedure(index:longint;p:TMethod) of object;
  2632. TSetMethodProc=procedure(p:TMethod) of object;
  2633. var
  2634. AMethod : TMethod;
  2635. begin
  2636. case (PropInfo^.PropProcs shr 2) and 3 of
  2637. ptField:
  2638. PMethod(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^ := Value;
  2639. ptStatic,
  2640. ptVirtual:
  2641. begin
  2642. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2643. AMethod.Code:=PropInfo^.SetProc
  2644. else
  2645. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2646. AMethod.Data:=Instance;
  2647. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2648. TSetMethodProcIndex(AMethod)(PropInfo^.Index,Value)
  2649. else
  2650. TSetMethodProc(AMethod)(Value);
  2651. end;
  2652. else
  2653. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2654. end;
  2655. end;
  2656. Function GetMethodProp(Instance: TObject; const PropName: string): TMethod;
  2657. begin
  2658. Result:=GetMethodProp(Instance,FindPropInfo(Instance,PropName));
  2659. end;
  2660. Procedure SetMethodProp(Instance: TObject; const PropName: string; const Value: TMethod);
  2661. begin
  2662. SetMethodProp(Instance,FindPropInfo(Instance,PropName),Value);
  2663. end;
  2664. { ---------------------------------------------------------------------
  2665. Variant properties
  2666. ---------------------------------------------------------------------}
  2667. Procedure CheckVariantEvent(P : CodePointer);
  2668. begin
  2669. If (P=Nil) then
  2670. Raise Exception.Create(SErrNoVariantSupport);
  2671. end;
  2672. Function GetVariantProp(Instance : TObject;PropInfo : PPropInfo): Variant;
  2673. begin
  2674. CheckVariantEvent(CodePointer(OnGetVariantProp));
  2675. Result:=OnGetVariantProp(Instance,PropInfo);
  2676. end;
  2677. Procedure SetVariantProp(Instance : TObject;PropInfo : PPropInfo; const Value: Variant);
  2678. begin
  2679. CheckVariantEvent(CodePointer(OnSetVariantProp));
  2680. OnSetVariantProp(Instance,PropInfo,Value);
  2681. end;
  2682. Function GetVariantProp(Instance: TObject; const PropName: string): Variant;
  2683. begin
  2684. Result:=GetVariantProp(Instance,FindPropInfo(Instance,PropName));
  2685. end;
  2686. Procedure SetVariantProp(Instance: TObject; const PropName: string; const Value: Variant);
  2687. begin
  2688. SetVariantprop(instance,FindpropInfo(Instance,PropName),Value);
  2689. end;
  2690. { ---------------------------------------------------------------------
  2691. All properties through variant.
  2692. ---------------------------------------------------------------------}
  2693. Function GetPropValue(Instance: TObject; const PropName: string): Variant;
  2694. begin
  2695. Result := GetPropValue(Instance,FindPropInfo(Instance, PropName));
  2696. end;
  2697. Function GetPropValue(Instance: TObject; const PropName: string; PreferStrings: Boolean): Variant;
  2698. begin
  2699. Result := GetPropValue(Instance,FindPropInfo(Instance, PropName),PreferStrings);
  2700. end;
  2701. Function GetPropValue(Instance: TObject; PropInfo: PPropInfo): Variant;
  2702. begin
  2703. Result := GetPropValue(Instance, PropInfo, True);
  2704. end;
  2705. Function GetPropValue(Instance: TObject; PropInfo: PPropInfo; PreferStrings: Boolean): Variant;
  2706. begin
  2707. CheckVariantEvent(CodePointer(OnGetPropValue));
  2708. Result:=OnGetPropValue(Instance,PropInfo,PreferStrings);
  2709. end;
  2710. Procedure SetPropValue(Instance: TObject; const PropName: string; const Value: Variant);
  2711. begin
  2712. SetPropValue(Instance, FindPropInfo(Instance, PropName), Value);
  2713. end;
  2714. Procedure SetPropValue(Instance: TObject; PropInfo: PPropInfo; const Value: Variant);
  2715. begin
  2716. CheckVariantEvent(CodePointer(OnSetPropValue));
  2717. OnSetPropValue(Instance,PropInfo,Value);
  2718. end;
  2719. { ---------------------------------------------------------------------
  2720. Easy access methods that appeared in Delphi 5
  2721. ---------------------------------------------------------------------}
  2722. Function IsPublishedProp(Instance: TObject; const PropName: string): Boolean;
  2723. begin
  2724. Result:=GetPropInfo(Instance,PropName)<>Nil;
  2725. end;
  2726. Function IsPublishedProp(AClass: TClass; const PropName: string): Boolean;
  2727. begin
  2728. Result:=GetPropInfo(AClass,PropName)<>Nil;
  2729. end;
  2730. Function PropIsType(Instance: TObject; const PropName: string; TypeKind: TTypeKind): Boolean;
  2731. begin
  2732. Result:=PropType(Instance,PropName)=TypeKind
  2733. end;
  2734. Function PropIsType(AClass: TClass; const PropName: string; TypeKind: TTypeKind): Boolean;
  2735. begin
  2736. Result:=PropType(AClass,PropName)=TypeKind
  2737. end;
  2738. Function PropType(Instance: TObject; const PropName: string): TTypeKind;
  2739. begin
  2740. Result:=FindPropInfo(Instance,PropName)^.PropType^.Kind;
  2741. end;
  2742. Function PropType(AClass: TClass; const PropName: string): TTypeKind;
  2743. begin
  2744. Result:=FindPropInfo(AClass,PropName)^.PropType^.Kind;
  2745. end;
  2746. Function IsStoredProp(Instance: TObject; const PropName: string): Boolean;
  2747. begin
  2748. Result:=IsStoredProp(instance,FindPropInfo(Instance,PropName));
  2749. end;
  2750. { TParameterLocation }
  2751. function TParameterLocation.GetReference: Boolean;
  2752. begin
  2753. Result := (LocType and $80) <> 0;
  2754. end;
  2755. function TParameterLocation.GetRegType: TRegisterType;
  2756. begin
  2757. Result := TRegisterType(LocType and $7F);
  2758. end;
  2759. function TParameterLocation.GetShiftVal: Int8;
  2760. begin
  2761. if GetReference then begin
  2762. if Offset < Low(Int8) then
  2763. Result := Low(Int8)
  2764. else if Offset > High(Int8) then
  2765. Result := High(Int8)
  2766. else
  2767. Result := Offset;
  2768. end else
  2769. Result := 0;
  2770. end;
  2771. { TParameterLocations }
  2772. function TParameterLocations.GetLocation(aIndex: Byte): PParameterLocation;
  2773. begin
  2774. if aIndex >= Count then
  2775. Result := Nil
  2776. else
  2777. Result := PParameterLocation(PByte(aligntoptr(PByte(@Count) + SizeOf(Count))) + SizeOf(TParameterLocation) * aIndex);
  2778. end;
  2779. function TParameterLocations.GetTail: Pointer;
  2780. begin
  2781. Result := PByte(aligntoptr(PByte(@Count) + SizeOf(Count))) + SizeOf(TParameterLocation) * Count;
  2782. end;
  2783. { TProcedureParam }
  2784. function TProcedureParam.GetParamType: PTypeInfo;
  2785. begin
  2786. Result := DerefTypeInfoPtr(ParamTypeRef);
  2787. end;
  2788. function TProcedureParam.GetFlags: Byte;
  2789. begin
  2790. Result := PByte(@ParamFlags)^;
  2791. end;
  2792. { TManagedField }
  2793. function TManagedField.GetTypeRef: PTypeInfo;
  2794. begin
  2795. Result := DerefTypeInfoPtr(TypeRefRef);
  2796. end;
  2797. { TArrayTypeData }
  2798. function TArrayTypeData.GetElType: PTypeInfo;
  2799. begin
  2800. Result := DerefTypeInfoPtr(ElTypeRef);
  2801. end;
  2802. function TArrayTypeData.GetDims(aIndex: Byte): PTypeInfo;
  2803. begin
  2804. Result := DerefTypeInfoPtr(DimsRef[aIndex]);
  2805. end;
  2806. { TProcedureSignature }
  2807. function TProcedureSignature.GetResultType: PTypeInfo;
  2808. begin
  2809. Result := DerefTypeInfoPtr(ResultTypeRef);
  2810. end;
  2811. function TProcedureSignature.GetParam(ParamIndex: Integer): PProcedureParam;
  2812. begin
  2813. if (ParamIndex<0)or(ParamIndex>=ParamCount) then
  2814. Exit(nil);
  2815. Result := PProcedureParam(PByte(@Flags) + SizeOf(Self));
  2816. while ParamIndex > 0 do
  2817. begin
  2818. Result := PProcedureParam(aligntoptr((PByte(@Result^.Name) + (Length(Result^.Name) + 1) * SizeOf(AnsiChar))));
  2819. dec(ParamIndex);
  2820. end;
  2821. end;
  2822. { TVmtMethodParam }
  2823. function TVmtMethodParam.GetTail: Pointer;
  2824. begin
  2825. Result := PByte(@ParaLocs) + SizeOf(ParaLocs);
  2826. end;
  2827. function TVmtMethodParam.GetNext: PVmtMethodParam;
  2828. begin
  2829. Result := PVmtMethodParam(aligntoptr(Tail));
  2830. end;
  2831. function TVmtMethodParam.GetName: ShortString;
  2832. begin
  2833. Result := NamePtr^;
  2834. end;
  2835. { TIntfMethodEntry }
  2836. function TIntfMethodEntry.GetParam(Index: Word): PVmtMethodParam;
  2837. begin
  2838. if Index >= ParamCount then
  2839. Result := Nil
  2840. else
  2841. Result := PVmtMethodParam(PByte(aligntoptr(PByte(@NamePtr) + SizeOf(NamePtr))) + Index * PtrUInt(aligntoptr(Pointer(SizeOf(TVmtMethodParam)))));
  2842. end;
  2843. function TIntfMethodEntry.GetResultLocs: PParameterLocations;
  2844. begin
  2845. if not Assigned(ResultType) then
  2846. Result := Nil
  2847. else
  2848. Result := PParameterLocations(PByte(aligntoptr(PByte(@NamePtr) + SizeOf(NamePtr))) + ParamCount * PtrUInt(aligntoptr(Pointer(SizeOf(TVmtMethodParam)))));
  2849. end;
  2850. function TIntfMethodEntry.GetTail: Pointer;
  2851. begin
  2852. Result := PByte(@NamePtr) + SizeOf(NamePtr);
  2853. if ParamCount > 0 then
  2854. Result := PByte(aligntoptr(Result)) + ParamCount * PtrUInt(aligntoptr(Pointer(SizeOf(TVmtMethodParam))));
  2855. if Assigned(ResultType) then
  2856. Result := PByte(aligntoptr(Result)) + SizeOf(PParameterLocations);
  2857. end;
  2858. function TIntfMethodEntry.GetNext: PIntfMethodEntry;
  2859. begin
  2860. Result := PIntfMethodEntry(aligntoptr(Tail));
  2861. end;
  2862. function TIntfMethodEntry.GetName: ShortString;
  2863. begin
  2864. Result := NamePtr^;
  2865. end;
  2866. { TIntfMethodTable }
  2867. function TIntfMethodTable.GetMethod(Index: Word): PIntfMethodEntry;
  2868. begin
  2869. if (RTTICount = $FFFF) or (Index >= RTTICount) then
  2870. Result := Nil
  2871. else
  2872. begin
  2873. Result := aligntoptr(PIntfMethodEntry(PByte(@RTTICount) + SizeOf(RTTICount)));
  2874. while Index > 0 do
  2875. begin
  2876. Result := Result^.Next;
  2877. Dec(Index);
  2878. end;
  2879. end;
  2880. end;
  2881. { TVmtMethodTable }
  2882. function TVmtMethodTable.GetEntry(Index: LongWord): PVmtMethodEntry;
  2883. begin
  2884. Result := PVmtMethodEntry(@Entries[0]) + Index;
  2885. end;
  2886. { TVmtFieldTable }
  2887. function TVmtFieldTable.GetField(aIndex: Word): PVmtFieldEntry;
  2888. var
  2889. c: Word;
  2890. begin
  2891. if aIndex >= Count then
  2892. Exit(Nil);
  2893. c := aIndex;
  2894. Result := @Fields;
  2895. while c > 0 do begin
  2896. Result := Result^.Next;
  2897. Dec(c);
  2898. end;
  2899. end;
  2900. { TVmtFieldEntry }
  2901. function TVmtFieldEntry.GetNext: PVmtFieldEntry;
  2902. begin
  2903. Result := aligntoptr(Tail);
  2904. end;
  2905. function TVmtFieldEntry.GetTail: Pointer;
  2906. begin
  2907. Result := PByte(@Name) + Length(Name) + SizeOf(Byte);
  2908. end;
  2909. { TInterfaceData }
  2910. function TInterfaceData.GetUnitName: ShortString;
  2911. begin
  2912. Result := UnitNameField;
  2913. end;
  2914. function TInterfaceData.GetPropertyTable: PPropData;
  2915. var
  2916. p: PByte;
  2917. begin
  2918. p := PByte(@UnitNameField[0]) + SizeOf(UnitNameField[0]) + Length(UnitNameField);
  2919. Result := AlignTypeData(p);
  2920. end;
  2921. function TInterfaceData.GetMethodTable: PIntfMethodTable;
  2922. begin
  2923. Result := aligntoptr(PropertyTable^.Tail);
  2924. end;
  2925. { TInterfaceRawData }
  2926. function TInterfaceRawData.GetUnitName: ShortString;
  2927. begin
  2928. Result := UnitNameField;
  2929. end;
  2930. function TInterfaceRawData.GetIIDStr: ShortString;
  2931. begin
  2932. Result := PShortString(AlignTypeData(PByte(@UnitNameField[0]) + SizeOf(UnitNameField[0]) + Length(UnitNameField)))^;
  2933. end;
  2934. function TInterfaceRawData.GetPropertyTable: PPropData;
  2935. var
  2936. p: PByte;
  2937. begin
  2938. p := AlignTypeData(PByte(@UnitNameField[0]) + SizeOf(UnitNameField[0]) + Length(UnitNameField));
  2939. p := p + SizeOf(p^) + p^;
  2940. Result := aligntoptr(p);
  2941. end;
  2942. function TInterfaceRawData.GetMethodTable: PIntfMethodTable;
  2943. begin
  2944. Result := aligntoptr(PropertyTable^.Tail);
  2945. end;
  2946. { TClassData }
  2947. function TClassData.GetUnitName: ShortString;
  2948. begin
  2949. Result := UnitNameField;
  2950. end;
  2951. function TClassData.GetPropertyTable: PPropData;
  2952. var
  2953. p: PByte;
  2954. begin
  2955. p := PByte(@UnitNameField[0]) + SizeOf(UnitNameField[0]) + Length(UnitNameField);
  2956. Result := AlignTypeData(p);
  2957. end;
  2958. { TTypeData }
  2959. function TTypeData.GetBaseType: PTypeInfo;
  2960. begin
  2961. Result := DerefTypeInfoPtr(BaseTypeRef);
  2962. end;
  2963. function TTypeData.GetCompType: PTypeInfo;
  2964. begin
  2965. Result := DerefTypeInfoPtr(CompTypeRef);
  2966. end;
  2967. function TTypeData.GetParentInfo: PTypeInfo;
  2968. begin
  2969. Result := DerefTypeInfoPtr(ParentInfoRef);
  2970. end;
  2971. {$ifndef VER3_0}
  2972. function TTypeData.GetRecInitData: PRecInitData;
  2973. begin
  2974. Result := PRecInitData(aligntoptr(PTypeData(RecInitInfo+2+PByte(RecInitInfo+1)^)));
  2975. end;
  2976. {$endif}
  2977. function TTypeData.GetHelperParent: PTypeInfo;
  2978. begin
  2979. Result := DerefTypeInfoPtr(HelperParentRef);
  2980. end;
  2981. function TTypeData.GetExtendedInfo: PTypeInfo;
  2982. begin
  2983. Result := DerefTypeInfoPtr(ExtendedInfoRef);
  2984. end;
  2985. function TTypeData.GetIntfParent: PTypeInfo;
  2986. begin
  2987. Result := DerefTypeInfoPtr(IntfParentRef);
  2988. end;
  2989. function TTypeData.GetRawIntfParent: PTypeInfo;
  2990. begin
  2991. Result := DerefTypeInfoPtr(RawIntfParentRef);
  2992. end;
  2993. function TTypeData.GetIIDStr: ShortString;
  2994. begin
  2995. Result := PShortString(AlignTypeData(Pointer(@RawIntfUnit) + Length(RawIntfUnit) + 1))^;
  2996. end;
  2997. function TTypeData.GetElType: PTypeInfo;
  2998. begin
  2999. Result := DerefTypeInfoPtr(elTypeRef);
  3000. end;
  3001. function TTypeData.GetElType2: PTypeInfo;
  3002. begin
  3003. Result := DerefTypeInfoPtr(elType2Ref);
  3004. end;
  3005. function TTypeData.GetInstanceType: PTypeInfo;
  3006. begin
  3007. Result := DerefTypeInfoPtr(InstanceTypeRef);
  3008. end;
  3009. function TTypeData.GetRefType: PTypeInfo;
  3010. begin
  3011. Result := DerefTypeInfoPtr(RefTypeRef);
  3012. end;
  3013. { TPropData }
  3014. function TPropData.GetProp(Index: Word): PPropInfo;
  3015. begin
  3016. if Index >= PropCount then
  3017. Result := Nil
  3018. else
  3019. begin
  3020. Result := PPropInfo(aligntoptr(PByte(@PropCount) + SizeOf(PropCount)));
  3021. while Index > 0 do
  3022. begin
  3023. Result := aligntoptr(Result^.Tail);
  3024. Dec(Index);
  3025. end;
  3026. end;
  3027. end;
  3028. function TPropData.GetTail: Pointer;
  3029. begin
  3030. if PropCount = 0 then
  3031. Result := PByte(@PropCount) + SizeOf(PropCount)
  3032. else
  3033. Result := Prop[PropCount - 1]^.Tail;
  3034. end;
  3035. { TPropInfo }
  3036. function TPropInfo.GetPropType: PTypeInfo;
  3037. begin
  3038. Result := DerefTypeInfoPtr(PropTypeRef);
  3039. end;
  3040. function TPropInfo.GetTail: Pointer;
  3041. begin
  3042. Result := PByte(@Name[0]) + SizeOf(Name[0]) + Length(Name);
  3043. end;
  3044. function TPropInfo.GetNext: PPropInfo;
  3045. begin
  3046. Result := PPropInfo(aligntoptr(Tail));
  3047. end;
  3048. type
  3049. TElementAlias = record
  3050. Ordinal : Integer;
  3051. Alias : string;
  3052. end;
  3053. TElementAliasArray = Array of TElementAlias;
  3054. PElementAliasArray = ^TElementAliasArray;
  3055. TEnumeratedAliases = record
  3056. TypeInfo: PTypeInfo;
  3057. Aliases: TElementAliasArray;
  3058. end;
  3059. TEnumeratedAliasesArray = Array of TEnumeratedAliases;
  3060. Var
  3061. EnumeratedAliases : TEnumeratedAliasesArray;
  3062. Function IndexOfEnumeratedAliases(aTypeInfo : PTypeInfo) : integer;
  3063. begin
  3064. Result:=Length(EnumeratedAliases)-1;
  3065. while (Result>=0) and (EnumeratedAliases[Result].TypeInfo<>aTypeInfo) do
  3066. Dec(Result);
  3067. end;
  3068. Function GetEnumeratedAliases(aTypeInfo : PTypeInfo) : PElementAliasArray;
  3069. Var
  3070. I : integer;
  3071. begin
  3072. I:=IndexOfEnumeratedAliases(aTypeInfo);
  3073. if I=-1 then
  3074. Result:=Nil
  3075. else
  3076. Result:=@EnumeratedAliases[i].Aliases
  3077. end;
  3078. Function AddEnumeratedAliases(aTypeInfo : PTypeInfo) : PElementAliasArray;
  3079. Var
  3080. L : Integer;
  3081. begin
  3082. L:=Length(EnumeratedAliases);
  3083. SetLength(EnumeratedAliases,L+1);
  3084. EnumeratedAliases[L].TypeInfo:=aTypeInfo;
  3085. Result:=@EnumeratedAliases[L].Aliases;
  3086. end;
  3087. procedure RemoveEnumElementAliases(aTypeInfo: PTypeInfo);
  3088. Var
  3089. I,L : integer;
  3090. A : TEnumeratedAliases;
  3091. begin
  3092. I:=IndexOfEnumeratedAliases(aTypeInfo);
  3093. if I=-1 then
  3094. exit;
  3095. A:=EnumeratedAliases[i];
  3096. A.Aliases:=Nil;
  3097. A.TypeInfo:=Nil;
  3098. L:=Length(EnumeratedAliases)-1;
  3099. EnumeratedAliases[i]:=EnumeratedAliases[L];
  3100. EnumeratedAliases[L]:=A;
  3101. SetLength(EnumeratedAliases,L);
  3102. end;
  3103. Resourcestring
  3104. SErrNotAnEnumerated = 'Type information points to non-enumerated type';
  3105. SErrInvalidEnumeratedCount = 'Invalid number of enumerated values';
  3106. SErrDuplicateEnumerated = 'Duplicate alias for enumerated value';
  3107. procedure AddEnumElementAliases(aTypeInfo: PTypeInfo; const aNames: array of string; aStartValue: Integer = 0);
  3108. var
  3109. Aliases: PElementAliasArray;
  3110. A : TElementAliasArray;
  3111. L, I, J : Integer;
  3112. N : String;
  3113. PT : PTypeData;
  3114. begin
  3115. if (aTypeInfo^.Kind<>tkEnumeration) then
  3116. raise EArgumentException.Create(SErrNotAnEnumerated);
  3117. PT:=GetTypeData(aTypeInfo);
  3118. if (High(aNames)=-1) or ((aStartValue+High(aNames))> PT^.MaxValue) then
  3119. raise EArgumentException.Create(SErrInvalidEnumeratedCount);
  3120. Aliases:=GetEnumeratedAliases(aTypeInfo);
  3121. if (Aliases=Nil) then
  3122. Aliases:=AddEnumeratedAliases(aTypeInfo);
  3123. A:=Aliases^;
  3124. I:=0;
  3125. L:=Length(a);
  3126. SetLength(a,L+High(aNames)+1);
  3127. try
  3128. for N in aNames do
  3129. begin
  3130. for J:=0 to (L+I)-1 do
  3131. if SameText(N,A[J].Alias) then
  3132. raise EArgumentException.Create(SErrDuplicateEnumerated);
  3133. with A[L+I] do
  3134. begin
  3135. Ordinal:=aStartValue+I;
  3136. alias:=N;
  3137. end;
  3138. Inc(I);
  3139. end;
  3140. finally
  3141. // In case of exception, we need to correct the length.
  3142. if Length(A)<>I+L then
  3143. SetLength(A,I+L);
  3144. Aliases^:=A;
  3145. end;
  3146. end;
  3147. function GetEnumeratedAliasValue(aTypeInfo: PTypeInfo; const aName: string): Integer;
  3148. var
  3149. I : Integer;
  3150. Aliases: PElementAliasArray;
  3151. begin
  3152. Result:=-1;
  3153. Aliases:=GetEnumeratedAliases(aTypeInfo);
  3154. if (Aliases=Nil) then
  3155. Exit;
  3156. I:=Length(Aliases^)-1;
  3157. While (Result=-1) and (I>=0) do
  3158. begin
  3159. if SameText(Aliases^[I].Alias, aName) then
  3160. Result:=Aliases^[I].Ordinal;
  3161. Dec(I);
  3162. end;
  3163. end;
  3164. end.