typinfo.pp 90 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921
  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. // if you change one of the following enumeration types
  29. // you have also to change the compiler in an appropriate way !
  30. TTypeKind = (tkUnknown,tkInteger,tkChar,tkEnumeration,tkFloat,
  31. tkSet,tkMethod,tkSString,tkLString,tkAString,
  32. tkWString,tkVariant,tkArray,tkRecord,tkInterface,
  33. tkClass,tkObject,tkWChar,tkBool,tkInt64,tkQWord,
  34. tkDynArray,tkInterfaceRaw,tkProcVar,tkUString,tkUChar,
  35. tkHelper,tkFile,tkClassRef,tkPointer);
  36. TOrdType = (otSByte,otUByte,otSWord,otUWord,otSLong,otULong,otSQWord,otUQWord);
  37. {$ifndef FPUNONE}
  38. TFloatType = (ftSingle,ftDouble,ftExtended,ftComp,ftCurr);
  39. {$endif}
  40. TMethodKind = (mkProcedure,mkFunction,mkConstructor,mkDestructor,
  41. mkClassProcedure,mkClassFunction,mkClassConstructor,
  42. mkClassDestructor,mkOperatorOverload);
  43. TParamFlag = (pfVar,pfConst,pfArray,pfAddress,pfReference,pfOut,pfConstRef
  44. {$ifndef VER3_0},pfHidden,pfHigh,pfSelf,pfVmt,pfResult{$endif VER3_0}
  45. );
  46. TParamFlags = set of TParamFlag;
  47. TIntfFlag = (ifHasGuid,ifDispInterface,ifDispatch,ifHasStrGUID);
  48. TIntfFlags = set of TIntfFlag;
  49. TIntfFlagsBase = set of TIntfFlag;
  50. // don't rely on integer values of TCallConv since it includes all conventions
  51. // which both delphi and fpc support. In the future delphi can support more and
  52. // fpc own conventions will be shifted/reordered accordinly
  53. TCallConv = (ccReg, ccCdecl, ccPascal, ccStdCall, ccSafeCall,
  54. ccCppdecl, ccFar16, ccOldFPCCall, ccInternProc,
  55. ccSysCall, ccSoftFloat, ccMWPascal);
  56. {$push}
  57. {$scopedenums on}
  58. TSubRegister = (
  59. None,
  60. Lo,
  61. Hi,
  62. Word,
  63. DWord,
  64. QWord,
  65. FloatSingle,
  66. FloatDouble,
  67. FloatQuad,
  68. MultiMediaSingle,
  69. MultiMediaDouble,
  70. MultiMediaWhole,
  71. MultiMediaX,
  72. MultiMediaY
  73. );
  74. TRegisterType = (
  75. Invalid,
  76. Int,
  77. FP,
  78. MMX,
  79. MultiMedia,
  80. Special,
  81. Address
  82. );
  83. {$pop}
  84. {$MINENUMSIZE DEFAULT}
  85. const
  86. ptField = 0;
  87. ptStatic = 1;
  88. ptVirtual = 2;
  89. ptConst = 3;
  90. type
  91. TTypeKinds = set of TTypeKind;
  92. ShortStringBase = string[255];
  93. PParameterLocation = ^TParameterLocation;
  94. TParameterLocation =
  95. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  96. packed
  97. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  98. record
  99. private
  100. LocType: Byte;
  101. function GetRegType: TRegisterType; inline;
  102. function GetReference: Boolean; inline;
  103. function GetShiftVal: Int8; inline;
  104. public
  105. RegSub: TSubRegister;
  106. RegNumber: Word;
  107. { Stack offset if Reference, ShiftVal if not }
  108. Offset: SizeInt;
  109. { if Reference then the register is the index register otherwise the
  110. register in wihch (part of) the parameter resides }
  111. property Reference: Boolean read GetReference;
  112. property RegType: TRegisterType read GetRegType;
  113. { if Reference, otherwise 0 }
  114. property ShiftVal: Int8 read GetShiftVal;
  115. end;
  116. PParameterLocations = ^TParameterLocations;
  117. TParameterLocations =
  118. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  119. packed
  120. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  121. record
  122. private
  123. function GetLocation(aIndex: Byte): PParameterLocation; inline;
  124. function GetTail: Pointer; inline;
  125. public
  126. Count: Byte;
  127. property Location[Index: Byte]: PParameterLocation read GetLocation;
  128. property Tail: Pointer read GetTail;
  129. end;
  130. PVmtFieldEntry = ^TVmtFieldEntry;
  131. TVmtFieldEntry =
  132. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  133. packed
  134. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  135. record
  136. FieldOffset: PtrUInt;
  137. TypeIndex: Word;
  138. Name: ShortString;
  139. end;
  140. PVmtFieldTable = ^TVmtFieldTable;
  141. TVmtFieldTable =
  142. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  143. packed
  144. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  145. record
  146. Count: Word;
  147. ClassTab: Pointer;
  148. { should be array[Word] of TFieldInfo; but
  149. Elements have variant size! force at least proper alignment }
  150. Fields: array[0..0] of TVmtFieldEntry
  151. end;
  152. {$PACKRECORDS 1}
  153. TTypeInfo = record
  154. Kind : TTypeKind;
  155. Name : ShortString;
  156. // here the type data follows as TTypeData record
  157. end;
  158. PTypeInfo = ^TTypeInfo;
  159. PPTypeInfo = ^PTypeInfo;
  160. PPropData = ^TPropData;
  161. { Note: these are only for backwards compatibility. New type references should
  162. only use PPTypeInfo directly! }
  163. {$ifdef ver3_0}
  164. {$define TypeInfoPtr := PTypeInfo}
  165. {$else}
  166. {$define TypeInfoPtr := PPTypeInfo}
  167. {$endif}
  168. {$PACKRECORDS C}
  169. // members of TTypeData
  170. TArrayTypeData =
  171. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  172. packed
  173. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  174. record
  175. private
  176. function GetElType: PTypeInfo; inline;
  177. function GetDims(aIndex: Byte): PTypeInfo; inline;
  178. public
  179. property ElType: PTypeInfo read GetElType;
  180. property Dims[Index: Byte]: PTypeInfo read GetDims;
  181. public
  182. Size: SizeInt;
  183. ElCount: SizeInt;
  184. ElTypeRef: TypeInfoPtr;
  185. DimCount: Byte;
  186. DimsRef: array[0..255] of TypeInfoPtr;
  187. end;
  188. PManagedField = ^TManagedField;
  189. TManagedField =
  190. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  191. packed
  192. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  193. record
  194. private
  195. function GetTypeRef: PTypeInfo; inline;
  196. public
  197. property TypeRef: PTypeInfo read GetTypeRef;
  198. public
  199. TypeRefRef: TypeInfoPtr;
  200. FldOffset: SizeInt;
  201. end;
  202. PInitManagedField = ^TInitManagedField;
  203. TInitManagedField = TManagedField;
  204. PProcedureParam = ^TProcedureParam;
  205. TProcedureParam =
  206. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  207. packed
  208. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  209. record
  210. private
  211. function GetParamType: PTypeInfo; inline;
  212. function GetFlags: Byte; inline;
  213. public
  214. property ParamType: PTypeInfo read GetParamType;
  215. property Flags: Byte read GetFlags;
  216. public
  217. ParamFlags: TParamFlags;
  218. ParamTypeRef: TypeInfoPtr;
  219. Name: ShortString;
  220. end;
  221. TProcedureSignature =
  222. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  223. packed
  224. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  225. record
  226. private
  227. function GetResultType: PTypeInfo; inline;
  228. public
  229. property ResultType: PTypeInfo read GetResultType;
  230. public
  231. Flags: Byte;
  232. CC: TCallConv;
  233. ResultTypeRef: TypeInfoPtr;
  234. ParamCount: Byte;
  235. {Params: array[0..ParamCount - 1] of TProcedureParam;}
  236. function GetParam(ParamIndex: Integer): PProcedureParam;
  237. end;
  238. PVmtMethodParam = ^TVmtMethodParam;
  239. TVmtMethodParam =
  240. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  241. packed
  242. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  243. record
  244. private
  245. function GetParaLocs: PParameterLocations; inline;
  246. function GetTail: Pointer; inline;
  247. function GetNext: PVmtMethodParam; inline;
  248. public
  249. ParamType: PPTypeInfo;
  250. Flags: TParamFlags;
  251. Name: ShortString;
  252. { ParaLocs: TParameterLocations; }
  253. property ParaLocs: PParameterLocations read GetParaLocs;
  254. property Tail: Pointer read GetTail;
  255. property Next: PVmtMethodParam read GetNext;
  256. end;
  257. PIntfMethodEntry = ^TIntfMethodEntry;
  258. TIntfMethodEntry =
  259. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  260. packed
  261. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  262. record
  263. private
  264. function GetParam(Index: Word): PVmtMethodParam;
  265. function GetResultLocs: PParameterLocations; inline;
  266. function GetTail: Pointer; inline;
  267. function GetNext: PIntfMethodEntry; inline;
  268. public
  269. ResultType: PPTypeInfo;
  270. CC: TCallConv;
  271. Kind: TMethodKind;
  272. ParamCount: Word;
  273. StackSize: SizeInt;
  274. Name: ShortString;
  275. { Params: array[0..ParamCount - 1] of TVmtMethodParam }
  276. { ResultLocs: TParameterLocations (if ResultType != Nil) }
  277. property Param[Index: Word]: PVmtMethodParam read GetParam;
  278. property ResultLocs: PParameterLocations read GetResultLocs;
  279. property Tail: Pointer read GetTail;
  280. property Next: PIntfMethodEntry read GetNext;
  281. end;
  282. PIntfMethodTable = ^TIntfMethodTable;
  283. TIntfMethodTable =
  284. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  285. packed
  286. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  287. record
  288. private
  289. function GetMethod(Index: Word): PIntfMethodEntry;
  290. public
  291. Count: Word;
  292. { $FFFF if there is no further info, or the value of Count }
  293. RTTICount: Word;
  294. { Entry: array[0..Count - 1] of TIntfMethodEntry }
  295. property Method[Index: Word]: PIntfMethodEntry read GetMethod;
  296. end;
  297. PRecInitData = ^TRecInitData;
  298. TRecInitData =
  299. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  300. packed
  301. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  302. record
  303. Terminator: Pointer;
  304. Size: Integer;
  305. {$ifdef FPC_HAS_MANAGEMENT_OPERATORS}
  306. ManagementOp: Pointer;
  307. {$endif}
  308. ManagedFieldCount: Integer;
  309. { ManagedFields: array[0..ManagedFieldCount - 1] of TInitManagedField ; }
  310. end;
  311. PInterfaceData = ^TInterfaceData;
  312. TInterfaceData =
  313. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  314. packed
  315. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  316. record
  317. private
  318. function GetUnitName: ShortString; inline;
  319. function GetPropertyTable: PPropData; inline;
  320. function GetMethodTable: PIntfMethodTable; inline;
  321. public
  322. Parent: PPTypeInfo;
  323. Flags: TIntfFlagsBase;
  324. GUID: TGUID;
  325. property UnitName: ShortString read GetUnitName;
  326. property PropertyTable: PPropData read GetPropertyTable;
  327. property MethodTable: PIntfMethodTable read GetMethodTable;
  328. private
  329. UnitNameField: ShortString;
  330. { PropertyTable: TPropData }
  331. { MethodTable: TIntfMethodTable }
  332. end;
  333. PInterfaceRawData = ^TInterfaceRawData;
  334. TInterfaceRawData =
  335. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  336. packed
  337. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  338. record
  339. private
  340. function GetUnitName: ShortString; inline;
  341. function GetIIDStr: ShortString; inline;
  342. function GetPropertyTable: PPropData; inline;
  343. function GetMethodTable: PIntfMethodTable; inline;
  344. public
  345. Parent: PPTypeInfo;
  346. Flags : TIntfFlagsBase;
  347. IID: TGUID;
  348. property UnitName: ShortString read GetUnitName;
  349. property IIDStr: ShortString read GetIIDStr;
  350. property PropertyTable: PPropData read GetPropertyTable;
  351. property MethodTable: PIntfMethodTable read GetMethodTable;
  352. private
  353. UnitNameField: ShortString;
  354. { IIDStr: ShortString; }
  355. { PropertyTable: TPropData }
  356. end;
  357. PTypeData = ^TTypeData;
  358. TTypeData =
  359. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  360. packed
  361. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  362. record
  363. private
  364. function GetBaseType: PTypeInfo; inline;
  365. function GetCompType: PTypeInfo; inline;
  366. function GetParentInfo: PTypeInfo; inline;
  367. {$ifndef VER3_0}
  368. function GetRecInitData: PRecInitData; inline;
  369. {$endif}
  370. function GetHelperParent: PTypeInfo; inline;
  371. function GetExtendedInfo: PTypeInfo; inline;
  372. function GetIntfParent: PTypeInfo; inline;
  373. function GetRawIntfParent: PTypeInfo; inline;
  374. function GetIIDStr: ShortString; inline;
  375. function GetElType: PTypeInfo; inline;
  376. function GetElType2: PTypeInfo; inline;
  377. function GetInstanceType: PTypeInfo; inline;
  378. function GetRefType: PTypeInfo; inline;
  379. public
  380. { tkEnumeration }
  381. property BaseType: PTypeInfo read GetBaseType;
  382. { tkSet }
  383. property CompType: PTypeInfo read GetCompType;
  384. { tkClass }
  385. property ParentInfo: PTypeInfo read GetParentInfo;
  386. { tkRecord }
  387. {$ifndef VER3_0}
  388. property RecInitData: PRecInitData read GetRecInitData;
  389. {$endif}
  390. { tkHelper }
  391. property HelperParent: PTypeInfo read GetHelperParent;
  392. property ExtendedInfo: PTypeInfo read GetExtendedInfo;
  393. { tkInterface }
  394. property IntfParent: PTypeInfo read GetIntfParent;
  395. { tkInterfaceRaw }
  396. property RawIntfParent: PTypeInfo read GetRawIntfParent;
  397. property IIDStr: ShortString read GetIIDStr;
  398. { tkDynArray }
  399. property ElType2: PTypeInfo read GetElType2;
  400. property ElType: PTypeInfo read GetElType;
  401. { tkClassRef }
  402. property InstanceType: PTypeInfo read GetInstanceType;
  403. { tkPointer }
  404. property RefType: PTypeInfo read GetRefType;
  405. public
  406. case TTypeKind of
  407. tkUnKnown,tkLString,tkWString,tkVariant,tkUString:
  408. ();
  409. tkAString:
  410. (CodePage: Word);
  411. {$ifndef VER3_0}
  412. tkInt64,tkQWord,
  413. {$endif VER3_0}
  414. tkInteger,tkChar,tkEnumeration,tkBool,tkWChar,tkSet:
  415. (OrdType : TOrdType;
  416. case TTypeKind of
  417. tkInteger,tkChar,tkEnumeration,tkBool,tkWChar : (
  418. MinValue,MaxValue : Longint;
  419. case TTypeKind of
  420. tkEnumeration:
  421. (
  422. BaseTypeRef : TypeInfoPtr;
  423. NameList : ShortString;
  424. {EnumUnitName: ShortString;})
  425. );
  426. {$ifndef VER3_0}
  427. {tkBool with OrdType=otSQWord }
  428. tkInt64:
  429. (MinInt64Value, MaxInt64Value: Int64);
  430. {tkBool with OrdType=otUQWord }
  431. tkQWord:
  432. (MinQWordValue, MaxQWordValue: QWord);
  433. {$endif VER3_0}
  434. tkSet:
  435. (CompTypeRef : TypeInfoPtr)
  436. );
  437. {$ifndef FPUNONE}
  438. tkFloat:
  439. (FloatType : TFloatType);
  440. {$endif}
  441. tkSString:
  442. (MaxLength : Byte);
  443. tkClass:
  444. (ClassType : TClass;
  445. ParentInfoRef : TypeInfoPtr;
  446. PropCount : SmallInt;
  447. UnitName : ShortString
  448. // here the properties follow as array of TPropInfo
  449. );
  450. tkRecord:
  451. (
  452. {$ifndef VER3_0}
  453. RecInitInfo: Pointer; { points to TTypeInfo followed by init table }
  454. {$endif VER3_0}
  455. RecSize: Integer;
  456. case Boolean of
  457. False: (ManagedFldCount: Integer deprecated 'Use RecInitData^.ManagedFieldCount or TotalFieldCount depending on your use case');
  458. True: (TotalFieldCount: Integer);
  459. {ManagedFields: array[1..TotalFieldCount] of TManagedField}
  460. );
  461. tkHelper:
  462. (HelperParentRef : TypeInfoPtr;
  463. ExtendedInfoRef : TypeInfoPtr;
  464. HelperProps : SmallInt;
  465. HelperUnit : ShortString
  466. // here the properties follow as array of TPropInfo
  467. );
  468. tkMethod:
  469. (MethodKind : TMethodKind;
  470. ParamCount : Byte;
  471. ParamList : array[0..1023] of Char
  472. {in reality ParamList is a array[1..ParamCount] of:
  473. record
  474. Flags : TParamFlags;
  475. ParamName : ShortString;
  476. TypeName : ShortString;
  477. end;
  478. followed by
  479. ResultType : ShortString // for mkFunction, mkClassFunction only
  480. ResultTypeRef : PPTypeInfo; // for mkFunction, mkClassFunction only
  481. CC : TCallConv;
  482. ParamTypeRefs : array[1..ParamCount] of PPTypeInfo;}
  483. );
  484. tkProcVar:
  485. (ProcSig: TProcedureSignature);
  486. {$ifdef VER3_0}
  487. tkInt64:
  488. (MinInt64Value, MaxInt64Value: Int64);
  489. tkQWord:
  490. (MinQWordValue, MaxQWordValue: QWord);
  491. {$endif VER3_0}
  492. tkInterface:
  493. (
  494. IntfParentRef: TypeInfoPtr;
  495. IntfFlags : TIntfFlagsBase;
  496. GUID: TGUID;
  497. IntfUnit: ShortString;
  498. { PropertyTable: TPropData }
  499. { MethodTable: TIntfMethodTable }
  500. );
  501. tkInterfaceRaw:
  502. (
  503. RawIntfParentRef: TypeInfoPtr;
  504. RawIntfFlags : TIntfFlagsBase;
  505. IID: TGUID;
  506. RawIntfUnit: ShortString;
  507. { IIDStr: ShortString; }
  508. { PropertyTable: TPropData }
  509. );
  510. tkArray:
  511. (ArrayData: TArrayTypeData);
  512. tkDynArray:
  513. (
  514. elSize : PtrUInt;
  515. elType2Ref : TypeInfoPtr;
  516. varType : Longint;
  517. elTypeRef : TypeInfoPtr;
  518. DynUnitName: ShortStringBase
  519. );
  520. tkClassRef:
  521. (InstanceTypeRef: TypeInfoPtr);
  522. tkPointer:
  523. (RefTypeRef: TypeInfoPtr);
  524. end;
  525. PPropInfo = ^TPropInfo;
  526. TPropData =
  527. {$ifndef FPC_REQUIRES_PROPER_ALIGNMENT}
  528. packed
  529. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  530. record
  531. private
  532. function GetProp(Index: Word): PPropInfo;
  533. function GetTail: Pointer; inline;
  534. public
  535. PropCount : Word;
  536. PropList : record _alignmentdummy : ptrint; end;
  537. property Prop[Index: Word]: PPropInfo read GetProp;
  538. property Tail: Pointer read GetTail;
  539. end;
  540. {$PACKRECORDS 1}
  541. TPropInfo = packed record
  542. private
  543. function GetPropType: PTypeInfo; inline;
  544. function GetTail: Pointer; inline;
  545. function GetNext: PPropInfo; inline;
  546. public
  547. PropTypeRef : TypeInfoPtr;
  548. GetProc : CodePointer;
  549. SetProc : CodePointer;
  550. StoredProc : CodePointer;
  551. Index : Integer;
  552. Default : Longint;
  553. NameIndex : SmallInt;
  554. // contains the type of the Get/Set/Storedproc, see also ptxxx
  555. // bit 0..1 GetProc
  556. // 2..3 SetProc
  557. // 4..5 StoredProc
  558. // 6 : true, constant index property
  559. PropProcs : Byte;
  560. Name : ShortString;
  561. property PropType: PTypeInfo read GetPropType;
  562. property Tail: Pointer read GetTail;
  563. property Next: PPropInfo read GetNext;
  564. end;
  565. TProcInfoProc = Procedure(PropInfo : PPropInfo) of object;
  566. PPropList = ^TPropList;
  567. TPropList = array[0..{$ifdef cpu16}(32768 div sizeof(PPropInfo))-2{$else}65535{$endif}] of PPropInfo;
  568. const
  569. tkString = tkSString;
  570. tkProcedure = tkProcVar; // for compatibility with Delphi
  571. tkAny = [Low(TTypeKind)..High(TTypeKind)];
  572. tkMethods = [tkMethod];
  573. tkProperties = tkAny-tkMethods-[tkUnknown];
  574. // general property handling
  575. Function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
  576. Function AlignTypeData(p : Pointer) : Pointer; inline;
  577. Function GetPropInfo(TypeInfo: PTypeInfo;const PropName: string): PPropInfo;
  578. Function GetPropInfo(TypeInfo: PTypeInfo;const PropName: string; AKinds: TTypeKinds): PPropInfo;
  579. Function GetPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  580. Function GetPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  581. Function GetPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  582. Function GetPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  583. Function FindPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  584. Function FindPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  585. Function FindPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  586. Function FindPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  587. Procedure GetPropInfos(TypeInfo: PTypeInfo; PropList: PPropList);
  588. Function GetPropList(TypeInfo: PTypeInfo; TypeKinds: TTypeKinds; PropList: PPropList; Sorted: boolean = true): longint;
  589. Function GetPropList(TypeInfo: PTypeInfo; out PropList: PPropList): SizeInt;
  590. function GetPropList(AClass: TClass; out PropList: PPropList): Integer;
  591. function GetPropList(Instance: TObject; out PropList: PPropList): Integer;
  592. // Property information routines.
  593. Function IsStoredProp(Instance: TObject;PropInfo : PPropInfo) : Boolean;
  594. Function IsStoredProp(Instance: TObject; const PropName: string): Boolean;
  595. Function IsPublishedProp(Instance: TObject; const PropName: string): Boolean;
  596. Function IsPublishedProp(AClass: TClass; const PropName: string): Boolean;
  597. Function PropType(Instance: TObject; const PropName: string): TTypeKind;
  598. Function PropType(AClass: TClass; const PropName: string): TTypeKind;
  599. Function PropIsType(Instance: TObject; const PropName: string; TypeKind: TTypeKind): Boolean;
  600. Function PropIsType(AClass: TClass; const PropName: string; TypeKind: TTypeKind): Boolean;
  601. // subroutines to read/write properties
  602. Function GetOrdProp(Instance: TObject; PropInfo : PPropInfo) : Int64;
  603. Function GetOrdProp(Instance: TObject; const PropName: string): Int64;
  604. Procedure SetOrdProp(Instance: TObject; PropInfo : PPropInfo; Value : Int64);
  605. Procedure SetOrdProp(Instance: TObject; const PropName: string; Value: Int64);
  606. Function GetEnumProp(Instance: TObject; const PropName: string): string;
  607. Function GetEnumProp(Instance: TObject; const PropInfo: PPropInfo): string;
  608. Procedure SetEnumProp(Instance: TObject; const PropName: string;const Value: string);
  609. Procedure SetEnumProp(Instance: TObject; const PropInfo: PPropInfo;const Value: string);
  610. Function GetSetProp(Instance: TObject; const PropName: string): string;
  611. Function GetSetProp(Instance: TObject; const PropName: string; Brackets: Boolean): string;
  612. Function GetSetProp(Instance: TObject; const PropInfo: PPropInfo; Brackets: Boolean): string;
  613. Procedure SetSetProp(Instance: TObject; const PropName: string; const Value: string);
  614. Procedure SetSetProp(Instance: TObject; const PropInfo: PPropInfo; const Value: string);
  615. Function GetStrProp(Instance: TObject; PropInfo : PPropInfo) : Ansistring;
  616. Function GetStrProp(Instance: TObject; const PropName: string): string;
  617. Procedure SetStrProp(Instance: TObject; const PropName: string; const Value: AnsiString);
  618. Procedure SetStrProp(Instance: TObject; PropInfo : PPropInfo; const Value : Ansistring);
  619. Function GetWideStrProp(Instance: TObject; PropInfo: PPropInfo): WideString;
  620. Function GetWideStrProp(Instance: TObject; const PropName: string): WideString;
  621. Procedure SetWideStrProp(Instance: TObject; const PropName: string; const Value: WideString);
  622. Procedure SetWideStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: WideString);
  623. Function GetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo): UnicodeString;
  624. Function GetUnicodeStrProp(Instance: TObject; const PropName: string): UnicodeString;
  625. Procedure SetUnicodeStrProp(Instance: TObject; const PropName: string; const Value: UnicodeString);
  626. Procedure SetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: UnicodeString);
  627. Function GetRawbyteStrProp(Instance: TObject; PropInfo: PPropInfo): RawByteString;
  628. Function GetRawByteStrProp(Instance: TObject; const PropName: string): RawByteString;
  629. Procedure SetRawByteStrProp(Instance: TObject; const PropName: string; const Value: RawByteString);
  630. Procedure SetRawByteStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: RawByteString);
  631. {$ifndef FPUNONE}
  632. Function GetFloatProp(Instance: TObject; PropInfo : PPropInfo) : Extended;
  633. Function GetFloatProp(Instance: TObject; const PropName: string): Extended;
  634. Procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Extended);
  635. Procedure SetFloatProp(Instance: TObject; PropInfo : PPropInfo; Value : Extended);
  636. {$endif}
  637. Function GetObjectProp(Instance: TObject; const PropName: string): TObject;
  638. Function GetObjectProp(Instance: TObject; const PropName: string; MinClass: TClass): TObject;
  639. Function GetObjectProp(Instance: TObject; PropInfo: PPropInfo): TObject;
  640. Function GetObjectProp(Instance: TObject; PropInfo: PPropInfo; MinClass: TClass): TObject;
  641. Procedure SetObjectProp(Instance: TObject; const PropName: string; Value: TObject);
  642. Procedure SetObjectProp(Instance: TObject; PropInfo: PPropInfo; Value: TObject);
  643. Function GetObjectPropClass(Instance: TObject; const PropName: string): TClass;
  644. Function GetObjectPropClass(AClass: TClass; const PropName: string): TClass;
  645. Function GetMethodProp(Instance: TObject; PropInfo: PPropInfo) : TMethod;
  646. Function GetMethodProp(Instance: TObject; const PropName: string): TMethod;
  647. Procedure SetMethodProp(Instance: TObject; PropInfo: PPropInfo; const Value : TMethod);
  648. Procedure SetMethodProp(Instance: TObject; const PropName: string; const Value: TMethod);
  649. Function GetInt64Prop(Instance: TObject; PropInfo: PPropInfo): Int64;
  650. Function GetInt64Prop(Instance: TObject; const PropName: string): Int64;
  651. Procedure SetInt64Prop(Instance: TObject; PropInfo: PPropInfo; const Value: Int64);
  652. Procedure SetInt64Prop(Instance: TObject; const PropName: string; const Value: Int64);
  653. Function GetPropValue(Instance: TObject; const PropName: string): Variant;
  654. Function GetPropValue(Instance: TObject; const PropName: string; PreferStrings: Boolean): Variant;
  655. Function GetPropValue(Instance: TObject; PropInfo: PPropInfo): Variant;
  656. Function GetPropValue(Instance: TObject; PropInfo: PPropInfo; PreferStrings: Boolean): Variant;
  657. Procedure SetPropValue(Instance: TObject; const PropName: string; const Value: Variant);
  658. Procedure SetPropValue(Instance: TObject; PropInfo: PPropInfo; const Value: Variant);
  659. Function GetVariantProp(Instance: TObject; PropInfo : PPropInfo): Variant;
  660. Function GetVariantProp(Instance: TObject; const PropName: string): Variant;
  661. Procedure SetVariantProp(Instance: TObject; const PropName: string; const Value: Variant);
  662. Procedure SetVariantProp(Instance: TObject; PropInfo : PPropInfo; const Value: Variant);
  663. function GetInterfaceProp(Instance: TObject; const PropName: string): IInterface;
  664. function GetInterfaceProp(Instance: TObject; PropInfo: PPropInfo): IInterface;
  665. procedure SetInterfaceProp(Instance: TObject; const PropName: string; const Value: IInterface);
  666. procedure SetInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: IInterface);
  667. function GetRawInterfaceProp(Instance: TObject; const PropName: string): Pointer;
  668. function GetRawInterfaceProp(Instance: TObject; PropInfo: PPropInfo): Pointer;
  669. procedure SetRawInterfaceProp(Instance: TObject; const PropName: string; const Value: Pointer);
  670. procedure SetRawInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: Pointer);
  671. function GetDynArrayProp(Instance: TObject; const PropName: string): Pointer;
  672. function GetDynArrayProp(Instance: TObject; PropInfo: PPropInfo): Pointer;
  673. procedure SetDynArrayProp(Instance: TObject; const PropName: string; const Value: Pointer);
  674. procedure SetDynArrayProp(Instance: TObject; PropInfo: PPropInfo; const Value: Pointer);
  675. // Auxiliary routines, which may be useful
  676. Function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
  677. Function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
  678. function GetEnumNameCount(enum1: PTypeInfo): SizeInt;
  679. function SetToString(TypeInfo: PTypeInfo; Value: Integer; Brackets: Boolean) : String;
  680. function SetToString(PropInfo: PPropInfo; Value: Integer; Brackets: Boolean) : String;
  681. function SetToString(PropInfo: PPropInfo; Value: Integer) : String;
  682. function StringToSet(PropInfo: PPropInfo; const Value: string): Integer;
  683. function StringToSet(TypeInfo: PTypeInfo; const Value: string): Integer;
  684. const
  685. BooleanIdents: array[Boolean] of String = ('False', 'True');
  686. DotSep: String = '.';
  687. Type
  688. EPropertyError = Class(Exception);
  689. TGetPropValue = Function (Instance: TObject; PropInfo: PPropInfo; PreferStrings: Boolean) : Variant;
  690. TSetPropValue = Procedure (Instance: TObject; PropInfo: PPropInfo; const Value: Variant);
  691. TGetVariantProp = Function (Instance: TObject; PropInfo : PPropInfo): Variant;
  692. TSetVariantProp = Procedure (Instance: TObject; PropInfo : PPropInfo; const Value: Variant);
  693. EPropertyConvertError = class(Exception); // Not used (yet), but defined for compatibility.
  694. Const
  695. OnGetPropValue : TGetPropValue = Nil;
  696. OnSetPropValue : TSetPropValue = Nil;
  697. OnGetVariantprop : TGetVariantProp = Nil;
  698. OnSetVariantprop : TSetVariantProp = Nil;
  699. { for inlining }
  700. function DerefTypeInfoPtr(Info: TypeInfoPtr): PTypeInfo; inline;
  701. Implementation
  702. uses rtlconsts;
  703. type
  704. PMethod = ^TMethod;
  705. { ---------------------------------------------------------------------
  706. Auxiliary methods
  707. ---------------------------------------------------------------------}
  708. function aligntoptr(p : pointer) : pointer;inline;
  709. begin
  710. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  711. result:=align(p,sizeof(p));
  712. {$else FPC_REQUIRES_PROPER_ALIGNMENT}
  713. result:=p;
  714. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  715. end;
  716. function DerefTypeInfoPtr(Info: TypeInfoPtr): PTypeInfo; inline;
  717. begin
  718. {$ifdef ver3_0}
  719. Result := Info;
  720. {$else}
  721. if not Assigned(Info) then
  722. Result := Nil
  723. else
  724. Result := Info^;
  725. {$endif}
  726. end;
  727. Function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
  728. Var PS : PShortString;
  729. PT : PTypeData;
  730. begin
  731. PT:=GetTypeData(TypeInfo);
  732. if TypeInfo^.Kind=tkBool then
  733. begin
  734. case Value of
  735. 0,1:
  736. Result:=BooleanIdents[Boolean(Value)];
  737. else
  738. Result:='';
  739. end;
  740. end
  741. else
  742. begin
  743. PS:=@PT^.NameList;
  744. dec(Value,PT^.MinValue);
  745. While Value>0 Do
  746. begin
  747. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  748. Dec(Value);
  749. end;
  750. Result:=PS^;
  751. end;
  752. end;
  753. Function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
  754. Var PS : PShortString;
  755. PT : PTypeData;
  756. Count : longint;
  757. sName: shortstring;
  758. begin
  759. If Length(Name)=0 then
  760. exit(-1);
  761. sName := Name;
  762. PT:=GetTypeData(TypeInfo);
  763. Count:=0;
  764. Result:=-1;
  765. if TypeInfo^.Kind=tkBool then
  766. begin
  767. If CompareText(BooleanIdents[false],Name)=0 then
  768. result:=0
  769. else if CompareText(BooleanIdents[true],Name)=0 then
  770. result:=1;
  771. end
  772. else
  773. begin
  774. PS:=@PT^.NameList;
  775. While (Result=-1) and (PByte(PS)^<>0) do
  776. begin
  777. If ShortCompareText(PS^, sName) = 0 then
  778. Result:=Count+PT^.MinValue;
  779. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  780. Inc(Count);
  781. end;
  782. end;
  783. end;
  784. function GetEnumNameCount(enum1: PTypeInfo): SizeInt;
  785. var
  786. PS: PShortString;
  787. PT: PTypeData;
  788. Count: SizeInt;
  789. begin
  790. PT:=GetTypeData(enum1);
  791. if enum1^.Kind=tkBool then
  792. Result:=2
  793. else
  794. begin
  795. Count:=0;
  796. Result:=0;
  797. PS:=@PT^.NameList;
  798. While (PByte(PS)^<>0) do
  799. begin
  800. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  801. Inc(Count);
  802. end;
  803. { the last string is the unit name }
  804. Result := Count - 1;
  805. end;
  806. end;
  807. Function SetToString(PropInfo: PPropInfo; Value: Integer; Brackets: Boolean) : String;
  808. begin
  809. Result:=SetToString(PropInfo^.PropType,Value,Brackets);
  810. end;
  811. Function SetToString(TypeInfo: PTypeInfo; Value: Integer; Brackets: Boolean) : String;
  812. type
  813. tsetarr = bitpacked array[0..SizeOf(Integer)*8-1] of 0..1;
  814. Var
  815. I : Integer;
  816. PTI : PTypeInfo;
  817. begin
  818. {$if defined(FPC_BIG_ENDIAN)}
  819. { On big endian systems, set element 0 is in the most significant bit,
  820. and the same goes for the elements of bitpacked arrays there. }
  821. case GetTypeData(TypeInfo)^.OrdType of
  822. otSByte,otUByte: Value:=Value shl (SizeOf(Integer)*8-8);
  823. otSWord,otUWord: Value:=Value shl (SizeOf(Integer)*8-16);
  824. end;
  825. {$endif}
  826. PTI:=GetTypeData(TypeInfo)^.CompType;
  827. Result:='';
  828. For I:=0 to SizeOf(Integer)*8-1 do
  829. begin
  830. if (tsetarr(Value)[i]<>0) then
  831. begin
  832. If Result='' then
  833. Result:=GetEnumName(PTI,i)
  834. else
  835. Result:=Result+','+GetEnumName(PTI,I);
  836. end;
  837. end;
  838. if Brackets then
  839. Result:='['+Result+']';
  840. end;
  841. Function SetToString(PropInfo: PPropInfo; Value: Integer) : String;
  842. begin
  843. Result:=SetToString(PropInfo,Value,False);
  844. end;
  845. Const
  846. SetDelim = ['[',']',',',' '];
  847. Function GetNextElement(Var S : String) : String;
  848. Var
  849. J : Integer;
  850. begin
  851. J:=1;
  852. Result:='';
  853. If Length(S)>0 then
  854. begin
  855. While (J<=Length(S)) and Not (S[j] in SetDelim) do
  856. Inc(j);
  857. Result:=Copy(S,1,j-1);
  858. Delete(S,1,j);
  859. end;
  860. end;
  861. Function StringToSet(PropInfo: PPropInfo; const Value: string): Integer;
  862. begin
  863. Result:=StringToSet(PropInfo^.PropType,Value);
  864. end;
  865. Function StringToSet(TypeInfo: PTypeInfo; const Value: string): Integer;
  866. Var
  867. S,T : String;
  868. I : Integer;
  869. PTI : PTypeInfo;
  870. begin
  871. Result:=0;
  872. PTI:=GetTypeData(TypeInfo)^.Comptype;
  873. S:=Value;
  874. I:=1;
  875. If Length(S)>0 then
  876. begin
  877. While (I<=Length(S)) and (S[i] in SetDelim) do
  878. Inc(I);
  879. Delete(S,1,i-1);
  880. end;
  881. While (S<>'') do
  882. begin
  883. T:=GetNextElement(S);
  884. if T<>'' then
  885. begin
  886. I:=GetEnumValue(PTI,T);
  887. if (I<0) then
  888. raise EPropertyError.CreateFmt(SErrUnknownEnumValue, [T]);
  889. Result:=Result or (1 shl i);
  890. end;
  891. end;
  892. end;
  893. Function AlignTypeData(p : Pointer) : Pointer;
  894. {$push}
  895. {$packrecords c}
  896. type
  897. TAlignCheck = record
  898. b : byte;
  899. q : qword;
  900. end;
  901. {$pop}
  902. begin
  903. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  904. {$ifdef VER3_0}
  905. Result:=Pointer(align(p,SizeOf(Pointer)));
  906. {$else VER3_0}
  907. Result:=Pointer(align(p,PtrInt(@TAlignCheck(nil^).q)))
  908. {$endif VER3_0}
  909. {$else FPC_REQUIRES_PROPER_ALIGNMENT}
  910. Result:=p;
  911. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  912. end;
  913. Function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
  914. begin
  915. GetTypeData:=AlignTypeData(pointer(TypeInfo)+2+PByte(pointer(TypeInfo)+1)^);
  916. end;
  917. { ---------------------------------------------------------------------
  918. Basic Type information functions.
  919. ---------------------------------------------------------------------}
  920. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string) : PPropInfo;
  921. var
  922. hp : PTypeData;
  923. i : longint;
  924. p : shortstring;
  925. pd : ^TPropData;
  926. begin
  927. P:=PropName; // avoid Ansi<->short conversion in a loop
  928. while Assigned(TypeInfo) do
  929. begin
  930. // skip the name
  931. hp:=GetTypeData(Typeinfo);
  932. // the class info rtti the property rtti follows immediatly
  933. pd:=aligntoptr(pointer(pointer(@hp^.UnitName)+Length(hp^.UnitName)+1));
  934. Result:=PPropInfo(@pd^.PropList);
  935. for i:=1 to pd^.PropCount do
  936. begin
  937. // found a property of that name ?
  938. if ShortCompareText(Result^.Name, P) = 0 then
  939. exit;
  940. // skip to next property
  941. Result:=PPropInfo(aligntoptr(pointer(@Result^.Name)+byte(Result^.Name[0])+1));
  942. end;
  943. // parent class
  944. Typeinfo:=hp^.ParentInfo;
  945. end;
  946. Result:=Nil;
  947. end;
  948. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string; Akinds : TTypeKinds) : PPropInfo;
  949. begin
  950. Result:=GetPropInfo(TypeInfo,PropName);
  951. If (Akinds<>[]) then
  952. If (Result<>Nil) then
  953. If Not (Result^.PropType^.Kind in AKinds) then
  954. Result:=Nil;
  955. end;
  956. Function GetPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
  957. begin
  958. Result:=GetPropInfo(PTypeInfo(AClass.ClassInfo),PropName,AKinds);
  959. end;
  960. Function GetPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
  961. begin
  962. Result:=GetPropInfo(Instance.ClassType,PropName,AKinds);
  963. end;
  964. Function GetPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  965. begin
  966. Result:=GetPropInfo(Instance,PropName,[]);
  967. end;
  968. Function GetPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  969. begin
  970. Result:=GetPropInfo(AClass,PropName,[]);
  971. end;
  972. Function FindPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  973. begin
  974. result:=GetPropInfo(Instance, PropName);
  975. if Result=nil then
  976. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  977. end;
  978. Function FindPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  979. begin
  980. result:=GetPropInfo(Instance, PropName, AKinds);
  981. if Result=nil then
  982. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  983. end;
  984. Function FindPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  985. begin
  986. result:=GetPropInfo(AClass, PropName);
  987. if result=nil then
  988. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  989. end;
  990. Function FindPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  991. begin
  992. result:=GetPropInfo(AClass, PropName, AKinds);
  993. if result=nil then
  994. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  995. end;
  996. Function IsStoredProp(Instance : TObject;PropInfo : PPropInfo) : Boolean;
  997. type
  998. TBooleanIndexFunc=function(Index:integer):boolean of object;
  999. TBooleanFunc=function:boolean of object;
  1000. var
  1001. AMethod : TMethod;
  1002. begin
  1003. case (PropInfo^.PropProcs shr 4) and 3 of
  1004. ptField:
  1005. Result:=PBoolean(Pointer(Instance)+PtrUInt(PropInfo^.StoredProc))^;
  1006. ptConst:
  1007. Result:=LongBool(PropInfo^.StoredProc);
  1008. ptStatic,
  1009. ptVirtual:
  1010. begin
  1011. if (PropInfo^.PropProcs shr 4) and 3=ptstatic then
  1012. AMethod.Code:=PropInfo^.StoredProc
  1013. else
  1014. AMethod.Code:=pcodepointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.StoredProc))^;
  1015. AMethod.Data:=Instance;
  1016. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1017. Result:=TBooleanIndexFunc(AMethod)(PropInfo^.Index)
  1018. else
  1019. Result:=TBooleanFunc(AMethod)();
  1020. end;
  1021. end;
  1022. end;
  1023. Procedure GetPropInfos(TypeInfo : PTypeInfo;PropList : PPropList);
  1024. {
  1025. Store Pointers to property information in the list pointed
  1026. to by proplist. PRopList must contain enough space to hold ALL
  1027. properties.
  1028. }
  1029. Var
  1030. TD : PTypeData;
  1031. TP : PPropInfo;
  1032. Count : Longint;
  1033. begin
  1034. // Get this objects TOTAL published properties count
  1035. TD:=GetTypeData(TypeInfo);
  1036. // Clear list
  1037. FillChar(PropList^,TD^.PropCount*sizeof(Pointer),0);
  1038. repeat
  1039. TD:=GetTypeData(TypeInfo);
  1040. // published properties count for this object
  1041. TP:=aligntoptr(PPropInfo(aligntoptr((Pointer(@TD^.UnitName)+Length(TD^.UnitName)+1))));
  1042. Count:=PWord(TP)^;
  1043. // Now point TP to first propinfo record.
  1044. Inc(Pointer(TP),SizeOF(Word));
  1045. tp:=aligntoptr(tp);
  1046. While Count>0 do
  1047. begin
  1048. // Don't overwrite properties with the same name
  1049. if PropList^[TP^.NameIndex]=nil then
  1050. PropList^[TP^.NameIndex]:=TP;
  1051. // Point to TP next propinfo record.
  1052. // Located at Name[Length(Name)+1] !
  1053. TP:=aligntoptr(PPropInfo(pointer(@TP^.Name)+PByte(@TP^.Name)^+1));
  1054. Dec(Count);
  1055. end;
  1056. TypeInfo:=TD^.Parentinfo;
  1057. until TypeInfo=nil;
  1058. end;
  1059. Procedure InsertProp (PL : PProplist;PI : PPropInfo; Count : longint);
  1060. Var
  1061. I : Longint;
  1062. begin
  1063. I:=0;
  1064. While (I<Count) and (PI^.Name>PL^[I]^.Name) do
  1065. Inc(I);
  1066. If I<Count then
  1067. Move(PL^[I], PL^[I+1], (Count - I) * SizeOf(Pointer));
  1068. PL^[I]:=PI;
  1069. end;
  1070. Procedure InsertPropnosort (PL : PProplist;PI : PPropInfo; Count : longint);
  1071. begin
  1072. PL^[Count]:=PI;
  1073. end;
  1074. Type TInsertProp = Procedure (PL : PProplist;PI : PPropInfo; Count : longint);
  1075. //Const InsertProps : array[false..boolean] of TInsertProp = (InsertPropNoSort,InsertProp);
  1076. Function GetPropList(TypeInfo : PTypeInfo;TypeKinds : TTypeKinds; PropList : PPropList;Sorted : boolean = true):longint;
  1077. {
  1078. Store Pointers to property information OF A CERTAIN KIND in the list pointed
  1079. to by proplist. PRopList must contain enough space to hold ALL
  1080. properties.
  1081. }
  1082. Var
  1083. TempList : PPropList;
  1084. PropInfo : PPropinfo;
  1085. I,Count : longint;
  1086. DoInsertProp : TInsertProp;
  1087. begin
  1088. if sorted then
  1089. DoInsertProp:=@InsertProp
  1090. else
  1091. DoInsertProp:=@InsertPropnosort;
  1092. Result:=0;
  1093. Count:=GetTypeData(TypeInfo)^.Propcount;
  1094. If Count>0 then
  1095. begin
  1096. GetMem(TempList,Count*SizeOf(Pointer));
  1097. Try
  1098. GetPropInfos(TypeInfo,TempList);
  1099. For I:=0 to Count-1 do
  1100. begin
  1101. PropInfo:=TempList^[i];
  1102. If PropInfo^.PropType^.Kind in TypeKinds then
  1103. begin
  1104. If (PropList<>Nil) then
  1105. DoInsertProp(PropList,PropInfo,Result);
  1106. Inc(Result);
  1107. end;
  1108. end;
  1109. finally
  1110. FreeMem(TempList,Count*SizeOf(Pointer));
  1111. end;
  1112. end;
  1113. end;
  1114. Function GetPropList(TypeInfo: PTypeInfo; out PropList: PPropList): SizeInt;
  1115. begin
  1116. result:=GetTypeData(TypeInfo)^.Propcount;
  1117. if result>0 then
  1118. begin
  1119. getmem(PropList,result*sizeof(pointer));
  1120. GetPropInfos(TypeInfo,PropList);
  1121. end
  1122. else
  1123. PropList:=Nil;
  1124. end;
  1125. function GetPropList(AClass: TClass; out PropList: PPropList): Integer;
  1126. begin
  1127. Result := GetPropList(PTypeInfo(AClass.ClassInfo), PropList);
  1128. end;
  1129. function GetPropList(Instance: TObject; out PropList: PPropList): Integer;
  1130. begin
  1131. Result := GetPropList(Instance.ClassType, PropList);
  1132. end;
  1133. { ---------------------------------------------------------------------
  1134. Property access functions
  1135. ---------------------------------------------------------------------}
  1136. { ---------------------------------------------------------------------
  1137. Ordinal properties
  1138. ---------------------------------------------------------------------}
  1139. Function GetOrdProp(Instance : TObject;PropInfo : PPropInfo) : Int64;
  1140. type
  1141. TGetInt64ProcIndex=function(index:longint):Int64 of object;
  1142. TGetInt64Proc=function():Int64 of object;
  1143. TGetIntegerProcIndex=function(index:longint):longint of object;
  1144. TGetIntegerProc=function:longint of object;
  1145. TGetWordProcIndex=function(index:longint):word of object;
  1146. TGetWordProc=function:word of object;
  1147. TGetByteProcIndex=function(index:longint):Byte of object;
  1148. TGetByteProc=function:Byte of object;
  1149. var
  1150. TypeInfo: PTypeInfo;
  1151. AMethod : TMethod;
  1152. DataSize: Integer;
  1153. OrdType: TOrdType;
  1154. Signed: Boolean;
  1155. begin
  1156. Result:=0;
  1157. TypeInfo := PropInfo^.PropType;
  1158. Signed := false;
  1159. DataSize := 4;
  1160. case TypeInfo^.Kind of
  1161. {$ifdef cpu64}
  1162. tkInterface,
  1163. tkInterfaceRaw,
  1164. tkDynArray,
  1165. tkClass:
  1166. DataSize:=8;
  1167. {$endif cpu64}
  1168. tkChar, tkBool:
  1169. DataSize:=1;
  1170. tkWChar:
  1171. DataSize:=2;
  1172. tkSet,
  1173. tkEnumeration,
  1174. tkInteger:
  1175. begin
  1176. OrdType:=GetTypeData(TypeInfo)^.OrdType;
  1177. case OrdType of
  1178. otSByte,otUByte: DataSize := 1;
  1179. otSWord,otUWord: DataSize := 2;
  1180. end;
  1181. Signed := OrdType in [otSByte,otSWord,otSLong];
  1182. end;
  1183. tkInt64 :
  1184. begin
  1185. DataSize:=8;
  1186. Signed:=true;
  1187. end;
  1188. tkQword :
  1189. begin
  1190. DataSize:=8;
  1191. Signed:=false;
  1192. end;
  1193. end;
  1194. case (PropInfo^.PropProcs) and 3 of
  1195. ptField:
  1196. if Signed then begin
  1197. case DataSize of
  1198. 1: Result:=PShortInt(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1199. 2: Result:=PSmallInt(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1200. 4: Result:=PLongint(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1201. 8: Result:=PInt64(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1202. end;
  1203. end else begin
  1204. case DataSize of
  1205. 1: Result:=PByte(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1206. 2: Result:=PWord(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1207. 4: Result:=PLongint(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1208. 8: Result:=PInt64(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1209. end;
  1210. end;
  1211. ptStatic,
  1212. ptVirtual:
  1213. begin
  1214. if (PropInfo^.PropProcs and 3)=ptStatic then
  1215. AMethod.Code:=PropInfo^.GetProc
  1216. else
  1217. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1218. AMethod.Data:=Instance;
  1219. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then begin
  1220. case DataSize of
  1221. 1: Result:=TGetByteProcIndex(AMethod)(PropInfo^.Index);
  1222. 2: Result:=TGetWordProcIndex(AMethod)(PropInfo^.Index);
  1223. 4: Result:=TGetIntegerProcIndex(AMethod)(PropInfo^.Index);
  1224. 8: result:=TGetInt64ProcIndex(AMethod)(PropInfo^.Index)
  1225. end;
  1226. end else begin
  1227. case DataSize of
  1228. 1: Result:=TGetByteProc(AMethod)();
  1229. 2: Result:=TGetWordProc(AMethod)();
  1230. 4: Result:=TGetIntegerProc(AMethod)();
  1231. 8: result:=TGetInt64Proc(AMethod)();
  1232. end;
  1233. end;
  1234. if Signed then begin
  1235. case DataSize of
  1236. 1: Result:=ShortInt(Result);
  1237. 2: Result:=SmallInt(Result);
  1238. end;
  1239. end;
  1240. end;
  1241. end;
  1242. end;
  1243. Procedure SetOrdProp(Instance : TObject;PropInfo : PPropInfo;Value : Int64);
  1244. type
  1245. TSetInt64ProcIndex=procedure(index:longint;i:Int64) of object;
  1246. TSetInt64Proc=procedure(i:Int64) of object;
  1247. TSetIntegerProcIndex=procedure(index,i:longint) of object;
  1248. TSetIntegerProc=procedure(i:longint) of object;
  1249. var
  1250. DataSize: Integer;
  1251. AMethod : TMethod;
  1252. begin
  1253. if PropInfo^.PropType^.Kind in [tkInt64,tkQword
  1254. { why do we have to handle classes here, see also below? (FK) }
  1255. {$ifdef cpu64}
  1256. ,tkInterface
  1257. ,tkInterfaceRaw
  1258. ,tkDynArray
  1259. ,tkClass
  1260. {$endif cpu64}
  1261. ] then
  1262. DataSize := 8
  1263. else
  1264. DataSize := 4;
  1265. if not(PropInfo^.PropType^.Kind in [tkInt64,tkQword,tkClass,tkInterface,tkInterfaceRaw,tkDynArray]) then
  1266. begin
  1267. { cut off unnecessary stuff }
  1268. case GetTypeData(PropInfo^.PropType)^.OrdType of
  1269. otSWord,otUWord:
  1270. begin
  1271. Value:=Value and $ffff;
  1272. DataSize := 2;
  1273. end;
  1274. otSByte,otUByte:
  1275. begin
  1276. Value:=Value and $ff;
  1277. DataSize := 1;
  1278. end;
  1279. end;
  1280. end;
  1281. case (PropInfo^.PropProcs shr 2) and 3 of
  1282. ptField:
  1283. case DataSize of
  1284. 1: PByte(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Byte(Value);
  1285. 2: PWord(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Word(Value);
  1286. 4: PLongint(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Longint(Value);
  1287. 8: PInt64(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1288. end;
  1289. ptStatic,
  1290. ptVirtual:
  1291. begin
  1292. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1293. AMethod.Code:=PropInfo^.SetProc
  1294. else
  1295. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1296. AMethod.Data:=Instance;
  1297. if datasize=8 then
  1298. begin
  1299. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1300. TSetInt64ProcIndex(AMethod)(PropInfo^.Index,Value)
  1301. else
  1302. TSetInt64Proc(AMethod)(Value);
  1303. end
  1304. else
  1305. begin
  1306. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1307. TSetIntegerProcIndex(AMethod)(PropInfo^.Index,Value)
  1308. else
  1309. TSetIntegerProc(AMethod)(Value);
  1310. end;
  1311. end;
  1312. end;
  1313. end;
  1314. Function GetOrdProp(Instance: TObject; const PropName: string): Int64;
  1315. begin
  1316. Result:=GetOrdProp(Instance,FindPropInfo(Instance,PropName));
  1317. end;
  1318. Procedure SetOrdProp(Instance: TObject; const PropName: string; Value: Int64);
  1319. begin
  1320. SetOrdProp(Instance,FindPropInfo(Instance,PropName),Value);
  1321. end;
  1322. Function GetEnumProp(Instance: TObject; Const PropInfo: PPropInfo): string;
  1323. begin
  1324. Result:=GetEnumName(PropInfo^.PropType, GetOrdProp(Instance, PropInfo));
  1325. end;
  1326. Function GetEnumProp(Instance: TObject; const PropName: string): string;
  1327. begin
  1328. Result:=GetEnumProp(Instance,FindPropInfo(Instance,PropName));
  1329. end;
  1330. Procedure SetEnumProp(Instance: TObject; const PropName: string; const Value: string);
  1331. begin
  1332. SetEnumProp(Instance,FindPropInfo(Instance,PropName),Value);
  1333. end;
  1334. Procedure SetEnumProp(Instance: TObject; Const PropInfo : PPropInfo; const Value: string);
  1335. Var
  1336. PV : Longint;
  1337. begin
  1338. If PropInfo<>Nil then
  1339. begin
  1340. PV:=GetEnumValue(PropInfo^.PropType, Value);
  1341. if (PV<0) then
  1342. raise EPropertyError.CreateFmt(SErrUnknownEnumValue, [Value]);
  1343. SetOrdProp(Instance, PropInfo,PV);
  1344. end;
  1345. end;
  1346. { ---------------------------------------------------------------------
  1347. Int64 wrappers
  1348. ---------------------------------------------------------------------}
  1349. Function GetInt64Prop(Instance: TObject; PropInfo: PPropInfo): Int64;
  1350. begin
  1351. Result:=GetOrdProp(Instance,PropInfo);
  1352. end;
  1353. procedure SetInt64Prop(Instance: TObject; PropInfo: PPropInfo; const Value: Int64);
  1354. begin
  1355. SetOrdProp(Instance,PropInfo,Value);
  1356. end;
  1357. Function GetInt64Prop(Instance: TObject; const PropName: string): Int64;
  1358. begin
  1359. Result:=GetInt64Prop(Instance,FindPropInfo(Instance,PropName));
  1360. end;
  1361. Procedure SetInt64Prop(Instance: TObject; const PropName: string; const Value: Int64);
  1362. begin
  1363. SetInt64Prop(Instance,FindPropInfo(Instance,PropName),Value);
  1364. end;
  1365. { ---------------------------------------------------------------------
  1366. Set properties
  1367. ---------------------------------------------------------------------}
  1368. Function GetSetProp(Instance: TObject; const PropName: string): string;
  1369. begin
  1370. Result:=GetSetProp(Instance,PropName,False);
  1371. end;
  1372. Function GetSetProp(Instance: TObject; const PropName: string; Brackets: Boolean): string;
  1373. begin
  1374. Result:=GetSetProp(Instance,FindPropInfo(Instance,PropName),Brackets);
  1375. end;
  1376. Function GetSetProp(Instance: TObject; const PropInfo: PPropInfo; Brackets: Boolean): string;
  1377. begin
  1378. Result:=SetToString(PropInfo,GetOrdProp(Instance,PropInfo),Brackets);
  1379. end;
  1380. Procedure SetSetProp(Instance: TObject; const PropName: string; const Value: string);
  1381. begin
  1382. SetSetProp(Instance,FindPropInfo(Instance,PropName),Value);
  1383. end;
  1384. Procedure SetSetProp(Instance: TObject; const PropInfo: PPropInfo; const Value: string);
  1385. begin
  1386. SetOrdProp(Instance,PropInfo,StringToSet(PropInfo,Value));
  1387. end;
  1388. { ---------------------------------------------------------------------
  1389. Object properties
  1390. ---------------------------------------------------------------------}
  1391. Function GetObjectProp(Instance: TObject; const PropName: string): TObject;
  1392. begin
  1393. Result:=GetObjectProp(Instance,PropName,Nil);
  1394. end;
  1395. Function GetObjectProp(Instance: TObject; const PropName: string; MinClass: TClass): TObject;
  1396. begin
  1397. Result:=GetObjectProp(Instance,FindPropInfo(Instance,PropName),MinClass);
  1398. end;
  1399. Function GetObjectProp(Instance: TObject; PropInfo : PPropInfo): TObject;
  1400. begin
  1401. Result:=GetObjectProp(Instance,PropInfo,Nil);
  1402. end;
  1403. Function GetObjectProp(Instance: TObject; PropInfo : PPropInfo; MinClass: TClass): TObject;
  1404. begin
  1405. {$ifdef cpu64}
  1406. Result:=TObject(GetInt64Prop(Instance,PropInfo));
  1407. {$else cpu64}
  1408. Result:=TObject(PtrInt(GetOrdProp(Instance,PropInfo)));
  1409. {$endif cpu64}
  1410. If (MinClass<>Nil) and (Result<>Nil) Then
  1411. If Not Result.InheritsFrom(MinClass) then
  1412. Result:=Nil;
  1413. end;
  1414. Procedure SetObjectProp(Instance: TObject; const PropName: string; Value: TObject);
  1415. begin
  1416. SetObjectProp(Instance,FindPropInfo(Instance,PropName),Value);
  1417. end;
  1418. Procedure SetObjectProp(Instance: TObject; PropInfo : PPropInfo; Value: TObject);
  1419. begin
  1420. {$ifdef cpu64}
  1421. SetInt64Prop(Instance,PropInfo,Int64(Value));
  1422. {$else cpu64}
  1423. SetOrdProp(Instance,PropInfo,PtrInt(Value));
  1424. {$endif cpu64}
  1425. end;
  1426. Function GetObjectPropClass(Instance: TObject; const PropName: string): TClass;
  1427. begin
  1428. Result:=GetTypeData(FindPropInfo(Instance,PropName,[tkClass])^.PropType)^.ClassType;
  1429. end;
  1430. Function GetObjectPropClass(AClass: TClass; const PropName: string): TClass;
  1431. begin
  1432. Result:=GetTypeData(FindPropInfo(AClass,PropName,[tkClass])^.PropType)^.ClassType;
  1433. end;
  1434. { ---------------------------------------------------------------------
  1435. Interface wrapprers
  1436. ---------------------------------------------------------------------}
  1437. function GetInterfaceProp(Instance: TObject; const PropName: string): IInterface;
  1438. begin
  1439. Result:=GetInterfaceProp(Instance,FindPropInfo(Instance,PropName));
  1440. end;
  1441. function GetInterfaceProp(Instance: TObject; PropInfo: PPropInfo): IInterface;
  1442. type
  1443. TGetInterfaceProc=function:IInterface of object;
  1444. TGetInterfaceProcIndex=function(index:longint):IInterface of object;
  1445. var
  1446. AMethod : TMethod;
  1447. begin
  1448. Result:=nil;
  1449. case (PropInfo^.PropProcs) and 3 of
  1450. ptField:
  1451. Result:=IInterface(PPointer(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^);
  1452. ptStatic,
  1453. ptVirtual:
  1454. begin
  1455. if (PropInfo^.PropProcs and 3)=ptStatic then
  1456. AMethod.Code:=PropInfo^.GetProc
  1457. else
  1458. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1459. AMethod.Data:=Instance;
  1460. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1461. Result:=TGetInterfaceProcIndex(AMethod)(PropInfo^.Index)
  1462. else
  1463. Result:=TGetInterfaceProc(AMethod)();
  1464. end;
  1465. end;
  1466. end;
  1467. procedure SetInterfaceProp(Instance: TObject; const PropName: string; const Value: IInterface);
  1468. begin
  1469. SetInterfaceProp(Instance,FindPropInfo(Instance,PropName),Value);
  1470. end;
  1471. procedure SetInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: IInterface);
  1472. type
  1473. TSetIntfStrProcIndex=procedure(index:longint;const i:IInterface) of object;
  1474. TSetIntfStrProc=procedure(i:IInterface) of object;
  1475. var
  1476. AMethod : TMethod;
  1477. begin
  1478. case Propinfo^.PropType^.Kind of
  1479. tkInterface:
  1480. begin
  1481. case (PropInfo^.PropProcs shr 2) and 3 of
  1482. ptField:
  1483. PInterface(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1484. ptStatic,
  1485. ptVirtual:
  1486. begin
  1487. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1488. AMethod.Code:=PropInfo^.SetProc
  1489. else
  1490. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1491. AMethod.Data:=Instance;
  1492. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1493. TSetIntfStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1494. else
  1495. TSetIntfStrProc(AMethod)(Value);
  1496. end;
  1497. end;
  1498. end;
  1499. tkInterfaceRaw:
  1500. Raise Exception.Create('Cannot set RAW interface from IUnknown interface');
  1501. end;
  1502. end;
  1503. { ---------------------------------------------------------------------
  1504. RAW (Corba) Interface wrapprers
  1505. ---------------------------------------------------------------------}
  1506. function GetRawInterfaceProp(Instance: TObject; const PropName: string): Pointer;
  1507. begin
  1508. Result:=GetRawInterfaceProp(Instance,FindPropInfo(Instance,PropName));
  1509. end;
  1510. function GetRawInterfaceProp(Instance: TObject; PropInfo: PPropInfo): Pointer;
  1511. begin
  1512. {$ifdef cpu64}
  1513. Result:=Pointer(GetInt64Prop(Instance,PropInfo));
  1514. {$else cpu64}
  1515. Result:=Pointer(PtrInt(GetOrdProp(Instance,PropInfo)));
  1516. {$endif cpu64}
  1517. end;
  1518. procedure SetRawInterfaceProp(Instance: TObject; const PropName: string; const Value: Pointer);
  1519. begin
  1520. SetRawInterfaceProp(Instance,FindPropInfo(Instance,PropName),Value);
  1521. end;
  1522. procedure SetRawInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: Pointer);
  1523. type
  1524. TSetPointerProcIndex=procedure(index:longint;const i:Pointer) of object;
  1525. TSetPointerProc=procedure(i:Pointer) of object;
  1526. var
  1527. AMethod : TMethod;
  1528. begin
  1529. case Propinfo^.PropType^.Kind of
  1530. tkInterfaceRaw:
  1531. begin
  1532. case (PropInfo^.PropProcs shr 2) and 3 of
  1533. ptField:
  1534. PPointer(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1535. ptStatic,
  1536. ptVirtual:
  1537. begin
  1538. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1539. AMethod.Code:=PropInfo^.SetProc
  1540. else
  1541. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1542. AMethod.Data:=Instance;
  1543. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1544. TSetPointerProcIndex(AMethod)(PropInfo^.Index,Value)
  1545. else
  1546. TSetPointerProc(AMethod)(Value);
  1547. end;
  1548. end;
  1549. end;
  1550. tkInterface:
  1551. Raise Exception.Create('Cannot set interface from RAW interface');
  1552. end;
  1553. end;
  1554. { ---------------------------------------------------------------------
  1555. Dynamic array properties
  1556. ---------------------------------------------------------------------}
  1557. function GetDynArrayProp(Instance: TObject; const PropName: string): Pointer;
  1558. begin
  1559. Result:=GetDynArrayProp(Instance,FindPropInfo(Instance,PropName));
  1560. end;
  1561. function GetDynArrayProp(Instance: TObject; PropInfo: PPropInfo): Pointer;
  1562. type
  1563. { we need a dynamic array as that type is usually passed differently from
  1564. a plain pointer }
  1565. TDynArray=array of Byte;
  1566. TGetDynArrayProc=function:TDynArray of object;
  1567. TGetDynArrayProcIndex=function(index:longint):TDynArray of object;
  1568. var
  1569. AMethod : TMethod;
  1570. begin
  1571. Result:=nil;
  1572. if PropInfo^.PropType^.Kind<>tkDynArray then
  1573. Exit;
  1574. case (PropInfo^.PropProcs) and 3 of
  1575. ptField:
  1576. Result:=PPointer(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1577. ptStatic,
  1578. ptVirtual:
  1579. begin
  1580. if (PropInfo^.PropProcs and 3)=ptStatic then
  1581. AMethod.Code:=PropInfo^.GetProc
  1582. else
  1583. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1584. AMethod.Data:=Instance;
  1585. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1586. Result:=Pointer(TGetDynArrayProcIndex(AMethod)(PropInfo^.Index))
  1587. else
  1588. Result:=Pointer(TGetDynArrayProc(AMethod)());
  1589. end;
  1590. end;
  1591. end;
  1592. procedure SetDynArrayProp(Instance: TObject; const PropName: string; const Value: Pointer);
  1593. begin
  1594. SetDynArrayProp(Instance,FindPropInfo(Instance,PropName),Value);
  1595. end;
  1596. procedure SetDynArrayProp(Instance: TObject; PropInfo: PPropInfo; const Value: Pointer);
  1597. type
  1598. { we need a dynamic array as that type is usually passed differently from
  1599. a plain pointer }
  1600. TDynArray=array of Byte;
  1601. TSetDynArrayProcIndex=procedure(index:longint;const i:TDynArray) of object;
  1602. TSetDynArrayProc=procedure(i:TDynArray) of object;
  1603. var
  1604. AMethod: TMethod;
  1605. begin
  1606. if PropInfo^.PropType^.Kind<>tkDynArray then
  1607. Exit;
  1608. case (PropInfo^.PropProcs shr 2) and 3 of
  1609. ptField:
  1610. CopyArray(PPointer(Pointer(Instance)+PtrUInt(PropInfo^.SetProc)), @Value, PropInfo^.PropType, 1);
  1611. ptStatic,
  1612. ptVirtual:
  1613. begin
  1614. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1615. AMethod.Code:=PropInfo^.SetProc
  1616. else
  1617. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1618. AMethod.Data:=Instance;
  1619. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1620. TSetDynArrayProcIndex(AMethod)(PropInfo^.Index,TDynArray(Value))
  1621. else
  1622. TSetDynArrayProc(AMethod)(TDynArray(Value));
  1623. end;
  1624. end;
  1625. end;
  1626. { ---------------------------------------------------------------------
  1627. String properties
  1628. ---------------------------------------------------------------------}
  1629. Function GetStrProp(Instance: TObject; PropInfo: PPropInfo): AnsiString;
  1630. type
  1631. TGetShortStrProcIndex=function(index:longint):ShortString of object;
  1632. TGetShortStrProc=function():ShortString of object;
  1633. TGetAnsiStrProcIndex=function(index:longint):AnsiString of object;
  1634. TGetAnsiStrProc=function():AnsiString of object;
  1635. var
  1636. AMethod : TMethod;
  1637. begin
  1638. Result:='';
  1639. case Propinfo^.PropType^.Kind of
  1640. tkWString:
  1641. Result:=AnsiString(GetWideStrProp(Instance,PropInfo));
  1642. tkUString:
  1643. Result := AnsiString(GetUnicodeStrProp(Instance,PropInfo));
  1644. tkSString:
  1645. begin
  1646. case (PropInfo^.PropProcs) and 3 of
  1647. ptField:
  1648. Result := PShortString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  1649. ptStatic,
  1650. ptVirtual:
  1651. begin
  1652. if (PropInfo^.PropProcs and 3)=ptStatic then
  1653. AMethod.Code:=PropInfo^.GetProc
  1654. else
  1655. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1656. AMethod.Data:=Instance;
  1657. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1658. Result:=TGetShortStrProcIndex(AMethod)(PropInfo^.Index)
  1659. else
  1660. Result:=TGetShortStrProc(AMethod)();
  1661. end;
  1662. end;
  1663. end;
  1664. tkAString:
  1665. begin
  1666. case (PropInfo^.PropProcs) and 3 of
  1667. ptField:
  1668. Result := PAnsiString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  1669. ptStatic,
  1670. ptVirtual:
  1671. begin
  1672. if (PropInfo^.PropProcs and 3)=ptStatic then
  1673. AMethod.Code:=PropInfo^.GetProc
  1674. else
  1675. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1676. AMethod.Data:=Instance;
  1677. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1678. Result:=TGetAnsiStrProcIndex(AMethod)(PropInfo^.Index)
  1679. else
  1680. Result:=TGetAnsiStrProc(AMethod)();
  1681. end;
  1682. end;
  1683. end;
  1684. end;
  1685. end;
  1686. Procedure SetStrProp(Instance : TObject;PropInfo : PPropInfo; const Value : AnsiString);
  1687. type
  1688. TSetShortStrProcIndex=procedure(index:longint;const s:ShortString) of object;
  1689. TSetShortStrProc=procedure(const s:ShortString) of object;
  1690. TSetAnsiStrProcIndex=procedure(index:longint;s:AnsiString) of object;
  1691. TSetAnsiStrProc=procedure(s:AnsiString) of object;
  1692. var
  1693. AMethod : TMethod;
  1694. begin
  1695. case Propinfo^.PropType^.Kind of
  1696. tkWString:
  1697. SetWideStrProp(Instance,PropInfo,WideString(Value));
  1698. tkUString:
  1699. SetUnicodeStrProp(Instance,PropInfo,UnicodeString(Value));
  1700. tkSString:
  1701. begin
  1702. case (PropInfo^.PropProcs shr 2) and 3 of
  1703. ptField:
  1704. PShortString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  1705. ptStatic,
  1706. ptVirtual:
  1707. begin
  1708. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1709. AMethod.Code:=PropInfo^.SetProc
  1710. else
  1711. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1712. AMethod.Data:=Instance;
  1713. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1714. TSetShortStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1715. else
  1716. TSetShortStrProc(AMethod)(Value);
  1717. end;
  1718. end;
  1719. end;
  1720. tkAString:
  1721. begin
  1722. case (PropInfo^.PropProcs shr 2) and 3 of
  1723. ptField:
  1724. PAnsiString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  1725. ptStatic,
  1726. ptVirtual:
  1727. begin
  1728. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1729. AMethod.Code:=PropInfo^.SetProc
  1730. else
  1731. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1732. AMethod.Data:=Instance;
  1733. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1734. TSetAnsiStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1735. else
  1736. TSetAnsiStrProc(AMethod)(Value);
  1737. end;
  1738. end;
  1739. end;
  1740. end;
  1741. end;
  1742. Function GetStrProp(Instance: TObject; const PropName: string): string;
  1743. begin
  1744. Result:=GetStrProp(Instance,FindPropInfo(Instance,PropName));
  1745. end;
  1746. Procedure SetStrProp(Instance: TObject; const PropName: string; const Value: AnsiString);
  1747. begin
  1748. SetStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  1749. end;
  1750. Function GetWideStrProp(Instance: TObject; const PropName: string): WideString;
  1751. begin
  1752. Result:=GetWideStrProp(Instance, FindPropInfo(Instance, PropName));
  1753. end;
  1754. procedure SetWideStrProp(Instance: TObject; const PropName: string; const Value: WideString);
  1755. begin
  1756. SetWideStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  1757. end;
  1758. Function GetWideStrProp(Instance: TObject; PropInfo: PPropInfo): WideString;
  1759. type
  1760. TGetWideStrProcIndex=function(index:longint):WideString of object;
  1761. TGetWideStrProc=function():WideString of object;
  1762. var
  1763. AMethod : TMethod;
  1764. begin
  1765. Result:='';
  1766. case Propinfo^.PropType^.Kind of
  1767. tkSString,tkAString:
  1768. Result:=WideString(GetStrProp(Instance,PropInfo));
  1769. tkUString :
  1770. Result := GetUnicodeStrProp(Instance,PropInfo);
  1771. tkWString:
  1772. begin
  1773. case (PropInfo^.PropProcs) and 3 of
  1774. ptField:
  1775. Result := PWideString(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1776. ptStatic,
  1777. ptVirtual:
  1778. begin
  1779. if (PropInfo^.PropProcs and 3)=ptStatic then
  1780. AMethod.Code:=PropInfo^.GetProc
  1781. else
  1782. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1783. AMethod.Data:=Instance;
  1784. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1785. Result:=TGetWideStrProcIndex(AMethod)(PropInfo^.Index)
  1786. else
  1787. Result:=TGetWideStrProc(AMethod)();
  1788. end;
  1789. end;
  1790. end;
  1791. end;
  1792. end;
  1793. Procedure SetWideStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: WideString);
  1794. type
  1795. TSetWideStrProcIndex=procedure(index:longint;s:WideString) of object;
  1796. TSetWideStrProc=procedure(s:WideString) of object;
  1797. var
  1798. AMethod : TMethod;
  1799. begin
  1800. case Propinfo^.PropType^.Kind of
  1801. tkSString,tkAString:
  1802. SetStrProp(Instance,PropInfo,AnsiString(Value));
  1803. tkUString:
  1804. SetUnicodeStrProp(Instance,PropInfo,Value);
  1805. tkWString:
  1806. begin
  1807. case (PropInfo^.PropProcs shr 2) and 3 of
  1808. ptField:
  1809. PWideString(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1810. ptStatic,
  1811. ptVirtual:
  1812. begin
  1813. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1814. AMethod.Code:=PropInfo^.SetProc
  1815. else
  1816. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1817. AMethod.Data:=Instance;
  1818. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1819. TSetWideStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1820. else
  1821. TSetWideStrProc(AMethod)(Value);
  1822. end;
  1823. end;
  1824. end;
  1825. end;
  1826. end;
  1827. Function GetUnicodeStrProp(Instance: TObject; const PropName: string): UnicodeString;
  1828. begin
  1829. Result:=GetUnicodeStrProp(Instance, FindPropInfo(Instance, PropName));
  1830. end;
  1831. procedure SetUnicodeStrProp(Instance: TObject; const PropName: string; const Value: UnicodeString);
  1832. begin
  1833. SetUnicodeStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  1834. end;
  1835. Function GetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo): UnicodeString;
  1836. type
  1837. TGetUnicodeStrProcIndex=function(index:longint):UnicodeString of object;
  1838. TGetUnicodeStrProc=function():UnicodeString of object;
  1839. var
  1840. AMethod : TMethod;
  1841. begin
  1842. Result:='';
  1843. case Propinfo^.PropType^.Kind of
  1844. tkSString,tkAString:
  1845. Result:=UnicodeString(GetStrProp(Instance,PropInfo));
  1846. tkWString:
  1847. Result:=GetWideStrProp(Instance,PropInfo);
  1848. tkUString:
  1849. begin
  1850. case (PropInfo^.PropProcs) and 3 of
  1851. ptField:
  1852. Result := PUnicodeString(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1853. ptStatic,
  1854. ptVirtual:
  1855. begin
  1856. if (PropInfo^.PropProcs and 3)=ptStatic then
  1857. AMethod.Code:=PropInfo^.GetProc
  1858. else
  1859. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1860. AMethod.Data:=Instance;
  1861. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1862. Result:=TGetUnicodeStrProcIndex(AMethod)(PropInfo^.Index)
  1863. else
  1864. Result:=TGetUnicodeStrProc(AMethod)();
  1865. end;
  1866. end;
  1867. end;
  1868. end;
  1869. end;
  1870. Procedure SetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: UnicodeString);
  1871. type
  1872. TSetUnicodeStrProcIndex=procedure(index:longint;s:UnicodeString) of object;
  1873. TSetUnicodeStrProc=procedure(s:UnicodeString) of object;
  1874. var
  1875. AMethod : TMethod;
  1876. begin
  1877. case Propinfo^.PropType^.Kind of
  1878. tkSString,tkAString:
  1879. SetStrProp(Instance,PropInfo,AnsiString(Value));
  1880. tkWString:
  1881. SetWideStrProp(Instance,PropInfo,Value);
  1882. tkUString:
  1883. begin
  1884. case (PropInfo^.PropProcs shr 2) and 3 of
  1885. ptField:
  1886. PUnicodeString(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1887. ptStatic,
  1888. ptVirtual:
  1889. begin
  1890. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1891. AMethod.Code:=PropInfo^.SetProc
  1892. else
  1893. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1894. AMethod.Data:=Instance;
  1895. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1896. TSetUnicodeStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1897. else
  1898. TSetUnicodeStrProc(AMethod)(Value);
  1899. end;
  1900. end;
  1901. end;
  1902. end;
  1903. end;
  1904. function GetRawbyteStrProp(Instance: TObject; PropInfo: PPropInfo): RawByteString;
  1905. type
  1906. TGetRawByteStrProcIndex=function(index:longint): RawByteString of object;
  1907. TGetRawByteStrProc=function():RawByteString of object;
  1908. var
  1909. AMethod : TMethod;
  1910. begin
  1911. Result:='';
  1912. case Propinfo^.PropType^.Kind of
  1913. tkWString:
  1914. Result:=RawByteString(GetWideStrProp(Instance,PropInfo));
  1915. tkUString:
  1916. Result:=RawByteString(GetUnicodeStrProp(Instance,PropInfo));
  1917. tkSString:
  1918. Result:=RawByteString(GetStrProp(Instance,PropInfo));
  1919. tkAString:
  1920. begin
  1921. case (PropInfo^.PropProcs) and 3 of
  1922. ptField:
  1923. Result := PAnsiString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  1924. ptStatic,
  1925. ptVirtual:
  1926. begin
  1927. if (PropInfo^.PropProcs and 3)=ptStatic then
  1928. AMethod.Code:=PropInfo^.GetProc
  1929. else
  1930. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1931. AMethod.Data:=Instance;
  1932. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1933. Result:=TGetRawByteStrProcIndex(AMethod)(PropInfo^.Index)
  1934. else
  1935. Result:=TGetRawByteStrProc(AMethod)();
  1936. end;
  1937. end;
  1938. end;
  1939. end;
  1940. end;
  1941. function GetRawByteStrProp(Instance: TObject; const PropName: string): RawByteString;
  1942. begin
  1943. Result:=GetRawByteStrProp(Instance,FindPropInfo(Instance,PropName));
  1944. end;
  1945. procedure SetRawByteStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: RawByteString);
  1946. type
  1947. TSetRawByteStrProcIndex=procedure(index:longint;s:RawByteString) of object;
  1948. TSetRawByteStrProc=procedure(s:RawByteString) of object;
  1949. var
  1950. AMethod : TMethod;
  1951. begin
  1952. case Propinfo^.PropType^.Kind of
  1953. tkWString:
  1954. SetWideStrProp(Instance,PropInfo,WideString(Value));
  1955. tkUString:
  1956. SetUnicodeStrProp(Instance,PropInfo,UnicodeString(Value));
  1957. tkSString:
  1958. SetStrProp(Instance,PropInfo,Value); // Not 100% sure about this.
  1959. tkAString:
  1960. begin
  1961. case (PropInfo^.PropProcs shr 2) and 3 of
  1962. ptField:
  1963. PAnsiString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  1964. ptStatic,
  1965. ptVirtual:
  1966. begin
  1967. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1968. AMethod.Code:=PropInfo^.SetProc
  1969. else
  1970. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1971. AMethod.Data:=Instance;
  1972. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1973. TSetRawByteStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1974. else
  1975. TSetRawByteStrProc(AMethod)(Value);
  1976. end;
  1977. end;
  1978. end;
  1979. end;
  1980. end;
  1981. procedure SetRawByteStrProp(Instance: TObject; const PropName: string; const Value: RawByteString);
  1982. begin
  1983. SetRawByteStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  1984. end;
  1985. {$ifndef FPUNONE}
  1986. { ---------------------------------------------------------------------
  1987. Float properties
  1988. ---------------------------------------------------------------------}
  1989. function GetFloatProp(Instance : TObject;PropInfo : PPropInfo) : Extended;
  1990. type
  1991. TGetExtendedProc = function:Extended of object;
  1992. TGetExtendedProcIndex = function(Index: integer): Extended of object;
  1993. TGetDoubleProc = function:Double of object;
  1994. TGetDoubleProcIndex = function(Index: integer): Double of object;
  1995. TGetSingleProc = function:Single of object;
  1996. TGetSingleProcIndex = function(Index: integer):Single of object;
  1997. TGetCurrencyProc = function : Currency of object;
  1998. TGetCurrencyProcIndex = function(Index: integer) : Currency of object;
  1999. var
  2000. AMethod : TMethod;
  2001. begin
  2002. Result:=0.0;
  2003. case PropInfo^.PropProcs and 3 of
  2004. ptField:
  2005. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  2006. ftSingle:
  2007. Result:=PSingle(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2008. ftDouble:
  2009. Result:=PDouble(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2010. ftExtended:
  2011. Result:=PExtended(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2012. ftcomp:
  2013. Result:=PComp(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2014. ftcurr:
  2015. Result:=PCurrency(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2016. end;
  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. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  2026. ftSingle:
  2027. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2028. Result:=TGetSingleProc(AMethod)()
  2029. else
  2030. Result:=TGetSingleProcIndex(AMethod)(PropInfo^.Index);
  2031. ftDouble:
  2032. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2033. Result:=TGetDoubleProc(AMethod)()
  2034. else
  2035. Result:=TGetDoubleProcIndex(AMethod)(PropInfo^.Index);
  2036. ftExtended:
  2037. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2038. Result:=TGetExtendedProc(AMethod)()
  2039. else
  2040. Result:=TGetExtendedProcIndex(AMethod)(PropInfo^.Index);
  2041. ftCurr:
  2042. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2043. Result:=TGetCurrencyProc(AMethod)()
  2044. else
  2045. Result:=TGetCurrencyProcIndex(AMethod)(PropInfo^.Index);
  2046. end;
  2047. end;
  2048. end;
  2049. end;
  2050. Procedure SetFloatProp(Instance : TObject;PropInfo : PPropInfo; Value : Extended);
  2051. type
  2052. TSetExtendedProc = procedure(const AValue: Extended) of object;
  2053. TSetExtendedProcIndex = procedure(Index: integer; AValue: Extended) of object;
  2054. TSetDoubleProc = procedure(const AValue: Double) of object;
  2055. TSetDoubleProcIndex = procedure(Index: integer; AValue: Double) of object;
  2056. TSetSingleProc = procedure(const AValue: Single) of object;
  2057. TSetSingleProcIndex = procedure(Index: integer; AValue: Single) of object;
  2058. TSetCurrencyProc = procedure(const AValue: Currency) of object;
  2059. TSetCurrencyProcIndex = procedure(Index: integer; AValue: Currency) of object;
  2060. Var
  2061. AMethod : TMethod;
  2062. begin
  2063. case (PropInfo^.PropProcs shr 2) and 3 of
  2064. ptfield:
  2065. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  2066. ftSingle:
  2067. PSingle(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2068. ftDouble:
  2069. PDouble(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2070. ftExtended:
  2071. PExtended(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2072. {$ifdef FPC_COMP_IS_INT64}
  2073. ftComp:
  2074. PComp(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=trunc(Value);
  2075. {$else FPC_COMP_IS_INT64}
  2076. ftComp:
  2077. PComp(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Comp(Value);
  2078. {$endif FPC_COMP_IS_INT64}
  2079. ftCurr:
  2080. PCurrency(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2081. end;
  2082. ptStatic,
  2083. ptVirtual:
  2084. begin
  2085. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2086. AMethod.Code:=PropInfo^.SetProc
  2087. else
  2088. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2089. AMethod.Data:=Instance;
  2090. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  2091. ftSingle:
  2092. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2093. TSetSingleProc(AMethod)(Value)
  2094. else
  2095. TSetSingleProcIndex(AMethod)(PropInfo^.Index,Value);
  2096. ftDouble:
  2097. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2098. TSetDoubleProc(AMethod)(Value)
  2099. else
  2100. TSetDoubleProcIndex(AMethod)(PropInfo^.Index,Value);
  2101. ftExtended:
  2102. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2103. TSetExtendedProc(AMethod)(Value)
  2104. else
  2105. TSetExtendedProcIndex(AMethod)(PropInfo^.Index,Value);
  2106. ftCurr:
  2107. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2108. TSetCurrencyProc(AMethod)(Value)
  2109. else
  2110. TSetCurrencyProcIndex(AMethod)(PropInfo^.Index,Value);
  2111. end;
  2112. end;
  2113. end;
  2114. end;
  2115. function GetFloatProp(Instance: TObject; const PropName: string): Extended;
  2116. begin
  2117. Result:=GetFloatProp(Instance,FindPropInfo(Instance,PropName))
  2118. end;
  2119. Procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Extended);
  2120. begin
  2121. SetFloatProp(Instance,FindPropInfo(Instance,PropName),Value);
  2122. end;
  2123. {$endif}
  2124. { ---------------------------------------------------------------------
  2125. Method properties
  2126. ---------------------------------------------------------------------}
  2127. Function GetMethodProp(Instance : TObject;PropInfo : PPropInfo) : TMethod;
  2128. type
  2129. TGetMethodProcIndex=function(Index: Longint): TMethod of object;
  2130. TGetMethodProc=function(): TMethod of object;
  2131. var
  2132. value: PMethod;
  2133. AMethod : TMethod;
  2134. begin
  2135. Result.Code:=nil;
  2136. Result.Data:=nil;
  2137. case (PropInfo^.PropProcs) and 3 of
  2138. ptField:
  2139. begin
  2140. Value:=PMethod(Pointer(Instance)+PtrUInt(PropInfo^.GetProc));
  2141. if Value<>nil then
  2142. Result:=Value^;
  2143. end;
  2144. ptStatic,
  2145. ptVirtual:
  2146. begin
  2147. if (PropInfo^.PropProcs and 3)=ptStatic then
  2148. AMethod.Code:=PropInfo^.GetProc
  2149. else
  2150. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2151. AMethod.Data:=Instance;
  2152. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2153. Result:=TGetMethodProcIndex(AMethod)(PropInfo^.Index)
  2154. else
  2155. Result:=TGetMethodProc(AMethod)();
  2156. end;
  2157. end;
  2158. end;
  2159. Procedure SetMethodProp(Instance : TObject;PropInfo : PPropInfo; const Value : TMethod);
  2160. type
  2161. TSetMethodProcIndex=procedure(index:longint;p:TMethod) of object;
  2162. TSetMethodProc=procedure(p:TMethod) of object;
  2163. var
  2164. AMethod : TMethod;
  2165. begin
  2166. case (PropInfo^.PropProcs shr 2) and 3 of
  2167. ptField:
  2168. PMethod(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^ := Value;
  2169. ptStatic,
  2170. ptVirtual:
  2171. begin
  2172. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2173. AMethod.Code:=PropInfo^.SetProc
  2174. else
  2175. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2176. AMethod.Data:=Instance;
  2177. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2178. TSetMethodProcIndex(AMethod)(PropInfo^.Index,Value)
  2179. else
  2180. TSetMethodProc(AMethod)(Value);
  2181. end;
  2182. end;
  2183. end;
  2184. Function GetMethodProp(Instance: TObject; const PropName: string): TMethod;
  2185. begin
  2186. Result:=GetMethodProp(Instance,FindPropInfo(Instance,PropName));
  2187. end;
  2188. Procedure SetMethodProp(Instance: TObject; const PropName: string; const Value: TMethod);
  2189. begin
  2190. SetMethodProp(Instance,FindPropInfo(Instance,PropName),Value);
  2191. end;
  2192. { ---------------------------------------------------------------------
  2193. Variant properties
  2194. ---------------------------------------------------------------------}
  2195. Procedure CheckVariantEvent(P : CodePointer);
  2196. begin
  2197. If (P=Nil) then
  2198. Raise Exception.Create(SErrNoVariantSupport);
  2199. end;
  2200. Function GetVariantProp(Instance : TObject;PropInfo : PPropInfo): Variant;
  2201. begin
  2202. CheckVariantEvent(CodePointer(OnGetVariantProp));
  2203. Result:=OnGetVariantProp(Instance,PropInfo);
  2204. end;
  2205. Procedure SetVariantProp(Instance : TObject;PropInfo : PPropInfo; const Value: Variant);
  2206. begin
  2207. CheckVariantEvent(CodePointer(OnSetVariantProp));
  2208. OnSetVariantProp(Instance,PropInfo,Value);
  2209. end;
  2210. Function GetVariantProp(Instance: TObject; const PropName: string): Variant;
  2211. begin
  2212. Result:=GetVariantProp(Instance,FindPropInfo(Instance,PropName));
  2213. end;
  2214. Procedure SetVariantProp(Instance: TObject; const PropName: string; const Value: Variant);
  2215. begin
  2216. SetVariantprop(instance,FindpropInfo(Instance,PropName),Value);
  2217. end;
  2218. { ---------------------------------------------------------------------
  2219. All properties through variant.
  2220. ---------------------------------------------------------------------}
  2221. Function GetPropValue(Instance: TObject; const PropName: string): Variant;
  2222. begin
  2223. Result := GetPropValue(Instance,FindPropInfo(Instance, PropName));
  2224. end;
  2225. Function GetPropValue(Instance: TObject; const PropName: string; PreferStrings: Boolean): Variant;
  2226. begin
  2227. Result := GetPropValue(Instance,FindPropInfo(Instance, PropName),PreferStrings);
  2228. end;
  2229. Function GetPropValue(Instance: TObject; PropInfo: PPropInfo): Variant;
  2230. begin
  2231. Result := GetPropValue(Instance, PropInfo, True);
  2232. end;
  2233. Function GetPropValue(Instance: TObject; PropInfo: PPropInfo; PreferStrings: Boolean): Variant;
  2234. begin
  2235. CheckVariantEvent(CodePointer(OnGetPropValue));
  2236. Result:=OnGetPropValue(Instance,PropInfo,PreferStrings);
  2237. end;
  2238. Procedure SetPropValue(Instance: TObject; const PropName: string; const Value: Variant);
  2239. begin
  2240. SetPropValue(Instance, FindPropInfo(Instance, PropName), Value);
  2241. end;
  2242. Procedure SetPropValue(Instance: TObject; PropInfo: PPropInfo; const Value: Variant);
  2243. begin
  2244. CheckVariantEvent(CodePointer(OnSetPropValue));
  2245. OnSetPropValue(Instance,PropInfo,Value);
  2246. end;
  2247. { ---------------------------------------------------------------------
  2248. Easy access methods that appeared in Delphi 5
  2249. ---------------------------------------------------------------------}
  2250. Function IsPublishedProp(Instance: TObject; const PropName: string): Boolean;
  2251. begin
  2252. Result:=GetPropInfo(Instance,PropName)<>Nil;
  2253. end;
  2254. Function IsPublishedProp(AClass: TClass; const PropName: string): Boolean;
  2255. begin
  2256. Result:=GetPropInfo(AClass,PropName)<>Nil;
  2257. end;
  2258. Function PropIsType(Instance: TObject; const PropName: string; TypeKind: TTypeKind): Boolean;
  2259. begin
  2260. Result:=PropType(Instance,PropName)=TypeKind
  2261. end;
  2262. Function PropIsType(AClass: TClass; const PropName: string; TypeKind: TTypeKind): Boolean;
  2263. begin
  2264. Result:=PropType(AClass,PropName)=TypeKind
  2265. end;
  2266. Function PropType(Instance: TObject; const PropName: string): TTypeKind;
  2267. begin
  2268. Result:=FindPropInfo(Instance,PropName)^.PropType^.Kind;
  2269. end;
  2270. Function PropType(AClass: TClass; const PropName: string): TTypeKind;
  2271. begin
  2272. Result:=FindPropInfo(AClass,PropName)^.PropType^.Kind;
  2273. end;
  2274. Function IsStoredProp(Instance: TObject; const PropName: string): Boolean;
  2275. begin
  2276. Result:=IsStoredProp(instance,FindPropInfo(Instance,PropName));
  2277. end;
  2278. { TParameterLocation }
  2279. function TParameterLocation.GetReference: Boolean;
  2280. begin
  2281. Result := (LocType and $80) <> 0;
  2282. end;
  2283. function TParameterLocation.GetRegType: TRegisterType;
  2284. begin
  2285. Result := TRegisterType(LocType and $7F);
  2286. end;
  2287. function TParameterLocation.GetShiftVal: Int8;
  2288. begin
  2289. if GetReference then begin
  2290. if Offset < Low(Int8) then
  2291. Result := Low(Int8)
  2292. else if Offset > High(Int8) then
  2293. Result := High(Int8)
  2294. else
  2295. Result := Offset;
  2296. end else
  2297. Result := 0;
  2298. end;
  2299. { TParameterLocations }
  2300. function TParameterLocations.GetLocation(aIndex: Byte): PParameterLocation;
  2301. begin
  2302. if aIndex >= Count then
  2303. Result := Nil
  2304. else
  2305. Result := PParameterLocation(PByte(aligntoptr(PByte(@Count) + SizeOf(Count))) + SizeOf(TParameterLocation) * aIndex);
  2306. end;
  2307. function TParameterLocations.GetTail: Pointer;
  2308. begin
  2309. Result := PByte(aligntoptr(PByte(@Count) + SizeOf(Count))) + SizeOf(TParameterLocation) * Count;
  2310. end;
  2311. { TProcedureParam }
  2312. function TProcedureParam.GetParamType: PTypeInfo;
  2313. begin
  2314. Result := DerefTypeInfoPtr(ParamTypeRef);
  2315. end;
  2316. function TProcedureParam.GetFlags: Byte;
  2317. begin
  2318. Result := PByte(@ParamFlags)^;
  2319. end;
  2320. { TManagedField }
  2321. function TManagedField.GetTypeRef: PTypeInfo;
  2322. begin
  2323. Result := DerefTypeInfoPtr(TypeRefRef);
  2324. end;
  2325. { TArrayTypeData }
  2326. function TArrayTypeData.GetElType: PTypeInfo;
  2327. begin
  2328. Result := DerefTypeInfoPtr(ElTypeRef);
  2329. end;
  2330. function TArrayTypeData.GetDims(aIndex: Byte): PTypeInfo;
  2331. begin
  2332. Result := DerefTypeInfoPtr(DimsRef[aIndex]);
  2333. end;
  2334. { TProcedureSignature }
  2335. function TProcedureSignature.GetResultType: PTypeInfo;
  2336. begin
  2337. Result := DerefTypeInfoPtr(ResultTypeRef);
  2338. end;
  2339. function TProcedureSignature.GetParam(ParamIndex: Integer): PProcedureParam;
  2340. begin
  2341. if (ParamIndex<0)or(ParamIndex>=ParamCount) then
  2342. Exit(nil);
  2343. Result := PProcedureParam(PByte(@Flags) + SizeOf(Self));
  2344. while ParamIndex > 0 do
  2345. begin
  2346. Result := PProcedureParam(aligntoptr((PByte(@Result^.Name) + (Length(Result^.Name) + 1) * SizeOf(AnsiChar))));
  2347. dec(ParamIndex);
  2348. end;
  2349. end;
  2350. { TVmtMethodParam }
  2351. function TVmtMethodParam.GetParaLocs: PParameterLocations;
  2352. begin
  2353. Result := PParameterLocations(aligntoptr(PByte(@Name[0]) + Length(Name) + Sizeof(Name[0])));
  2354. end;
  2355. function TVmtMethodParam.GetTail: Pointer;
  2356. begin
  2357. Result := ParaLocs^.Tail;
  2358. end;
  2359. function TVmtMethodParam.GetNext: PVmtMethodParam;
  2360. begin
  2361. Result := PVmtMethodParam(aligntoptr(Tail));
  2362. end;
  2363. { TIntfMethodEntry }
  2364. function TIntfMethodEntry.GetParam(Index: Word): PVmtMethodParam;
  2365. begin
  2366. if Index >= ParamCount then
  2367. Result := Nil
  2368. else
  2369. begin
  2370. Result := PVmtMethodParam(aligntoptr(PByte(@Name[0]) + SizeOf(Name[0]) + Length(Name)));
  2371. while Index > 0 do
  2372. begin
  2373. Result := Result^.Next;
  2374. Dec(Index);
  2375. end;
  2376. end;
  2377. end;
  2378. function TIntfMethodEntry.GetResultLocs: PParameterLocations;
  2379. begin
  2380. if not Assigned(ResultType) then
  2381. Result := Nil
  2382. else if ParamCount = 0 then
  2383. Result := PParameterLocations(aligntoptr(PByte(@Name[0]) + SizeOf(Name[0]) + Length(Name)))
  2384. else
  2385. Result := PParameterLocations(aligntoptr(Param[ParamCount - 1]^.Tail));
  2386. end;
  2387. function TIntfMethodEntry.GetTail: Pointer;
  2388. var
  2389. retloc: PParameterLocations;
  2390. begin
  2391. if Assigned(ResultType) then
  2392. begin
  2393. retloc := ResultLocs;
  2394. Result := PByte(@retloc^.Count) + SizeOf(retloc^.Count) + SizeOf(TParameterLocation) * retloc^.Count;
  2395. end
  2396. else if ParamCount = 0 then
  2397. Result := PByte(@Name[0]) + Length(Name) + SizeOf(Byte)
  2398. else
  2399. Result := Param[ParamCount - 1]^.Tail;
  2400. end;
  2401. function TIntfMethodEntry.GetNext: PIntfMethodEntry;
  2402. begin
  2403. Result := PIntfMethodEntry(aligntoptr(Tail));
  2404. end;
  2405. { TIntfMethodTable }
  2406. function TIntfMethodTable.GetMethod(Index: Word): PIntfMethodEntry;
  2407. begin
  2408. if (RTTICount = $FFFF) or (Index >= RTTICount) then
  2409. Result := Nil
  2410. else
  2411. begin
  2412. Result := aligntoptr(PIntfMethodEntry(PByte(@RTTICount) + SizeOf(RTTICount)));
  2413. while Index > 0 do
  2414. begin
  2415. Result := Result^.Next;
  2416. Dec(Index);
  2417. end;
  2418. end;
  2419. end;
  2420. { TInterfaceData }
  2421. function TInterfaceData.GetUnitName: ShortString;
  2422. begin
  2423. Result := UnitNameField;
  2424. end;
  2425. function TInterfaceData.GetPropertyTable: PPropData;
  2426. var
  2427. p: PByte;
  2428. begin
  2429. p := PByte(@UnitNameField[0]) + SizeOf(UnitNameField[0]) + Length(UnitNameField);
  2430. Result := AlignTypeData(p);
  2431. end;
  2432. function TInterfaceData.GetMethodTable: PIntfMethodTable;
  2433. begin
  2434. Result := aligntoptr(PropertyTable^.Tail);
  2435. end;
  2436. { TInterfaceRawData }
  2437. function TInterfaceRawData.GetUnitName: ShortString;
  2438. begin
  2439. Result := UnitNameField;
  2440. end;
  2441. function TInterfaceRawData.GetIIDStr: ShortString;
  2442. begin
  2443. Result := PShortString(AlignTypeData(PByte(@UnitNameField[0]) + SizeOf(UnitNameField[0]) + Length(UnitNameField)))^;
  2444. end;
  2445. function TInterfaceRawData.GetPropertyTable: PPropData;
  2446. var
  2447. p: PByte;
  2448. begin
  2449. p := AlignTypeData(PByte(@UnitNameField[0]) + SizeOf(UnitNameField[0]) + Length(UnitNameField));
  2450. p := p + SizeOf(p^) + p^;
  2451. Result := aligntoptr(p);
  2452. end;
  2453. function TInterfaceRawData.GetMethodTable: PIntfMethodTable;
  2454. begin
  2455. Result := aligntoptr(PropertyTable^.Tail);
  2456. end;
  2457. { TTypeData }
  2458. function TTypeData.GetBaseType: PTypeInfo;
  2459. begin
  2460. Result := DerefTypeInfoPtr(BaseTypeRef);
  2461. end;
  2462. function TTypeData.GetCompType: PTypeInfo;
  2463. begin
  2464. Result := DerefTypeInfoPtr(CompTypeRef);
  2465. end;
  2466. function TTypeData.GetParentInfo: PTypeInfo;
  2467. begin
  2468. Result := DerefTypeInfoPtr(ParentInfoRef);
  2469. end;
  2470. {$ifndef VER3_0}
  2471. function TTypeData.GetRecInitData: PRecInitData;
  2472. begin
  2473. Result := PRecInitData(aligntoptr(PTypeData(RecInitInfo+2+PByte(RecInitInfo+1)^)));
  2474. end;
  2475. {$endif}
  2476. function TTypeData.GetHelperParent: PTypeInfo;
  2477. begin
  2478. Result := DerefTypeInfoPtr(HelperParentRef);
  2479. end;
  2480. function TTypeData.GetExtendedInfo: PTypeInfo;
  2481. begin
  2482. Result := DerefTypeInfoPtr(ExtendedInfoRef);
  2483. end;
  2484. function TTypeData.GetIntfParent: PTypeInfo;
  2485. begin
  2486. Result := DerefTypeInfoPtr(IntfParentRef);
  2487. end;
  2488. function TTypeData.GetRawIntfParent: PTypeInfo;
  2489. begin
  2490. Result := DerefTypeInfoPtr(RawIntfParentRef);
  2491. end;
  2492. function TTypeData.GetIIDStr: ShortString;
  2493. begin
  2494. Result := PShortString(AlignTypeData(Pointer(@RawIntfUnit) + Length(RawIntfUnit) + 1))^;
  2495. end;
  2496. function TTypeData.GetElType: PTypeInfo;
  2497. begin
  2498. Result := DerefTypeInfoPtr(elTypeRef);
  2499. end;
  2500. function TTypeData.GetElType2: PTypeInfo;
  2501. begin
  2502. Result := DerefTypeInfoPtr(elType2Ref);
  2503. end;
  2504. function TTypeData.GetInstanceType: PTypeInfo;
  2505. begin
  2506. Result := DerefTypeInfoPtr(InstanceTypeRef);
  2507. end;
  2508. function TTypeData.GetRefType: PTypeInfo;
  2509. begin
  2510. Result := DerefTypeInfoPtr(RefTypeRef);
  2511. end;
  2512. { TPropData }
  2513. function TPropData.GetProp(Index: Word): PPropInfo;
  2514. begin
  2515. if Index >= PropCount then
  2516. Result := Nil
  2517. else
  2518. begin
  2519. Result := PPropInfo(aligntoptr(PByte(@PropCount) + SizeOf(PropCount)));
  2520. while Index > 0 do
  2521. begin
  2522. Result := aligntoptr(Result^.Tail);
  2523. Dec(Index);
  2524. end;
  2525. end;
  2526. end;
  2527. function TPropData.GetTail: Pointer;
  2528. begin
  2529. if PropCount = 0 then
  2530. Result := PByte(@PropCount) + SizeOf(PropCount)
  2531. else
  2532. Result := Prop[PropCount - 1]^.Tail;
  2533. end;
  2534. { TPropInfo }
  2535. function TPropInfo.GetPropType: PTypeInfo;
  2536. begin
  2537. Result := DerefTypeInfoPtr(PropTypeRef);
  2538. end;
  2539. function TPropInfo.GetTail: Pointer;
  2540. begin
  2541. Result := PByte(@Name[0]) + SizeOf(Name[0]) + Length(Name);
  2542. end;
  2543. function TPropInfo.GetNext: PPropInfo;
  2544. begin
  2545. Result := PPropInfo(aligntoptr(Tail));
  2546. end;
  2547. end.