typinfo.pp 93 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068
  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. procedure AddEnumElementAliases(aTypeInfo: PTypeInfo; const aNames: array of string; aStartValue: Integer = 0);
  680. procedure RemoveEnumElementAliases(aTypeInfo: PTypeInfo);
  681. function GetEnumeratedAliasValue(aTypeInfo: PTypeInfo; const aName: string): Integer;
  682. function SetToString(TypeInfo: PTypeInfo; Value: Integer; Brackets: Boolean) : String;
  683. function SetToString(PropInfo: PPropInfo; Value: Integer; Brackets: Boolean) : String;
  684. function SetToString(PropInfo: PPropInfo; Value: Integer) : String;
  685. function StringToSet(PropInfo: PPropInfo; const Value: string): Integer;
  686. function StringToSet(TypeInfo: PTypeInfo; const Value: string): Integer;
  687. const
  688. BooleanIdents: array[Boolean] of String = ('False', 'True');
  689. DotSep: String = '.';
  690. Type
  691. EPropertyError = Class(Exception);
  692. TGetPropValue = Function (Instance: TObject; PropInfo: PPropInfo; PreferStrings: Boolean) : Variant;
  693. TSetPropValue = Procedure (Instance: TObject; PropInfo: PPropInfo; const Value: Variant);
  694. TGetVariantProp = Function (Instance: TObject; PropInfo : PPropInfo): Variant;
  695. TSetVariantProp = Procedure (Instance: TObject; PropInfo : PPropInfo; const Value: Variant);
  696. EPropertyConvertError = class(Exception); // Not used (yet), but defined for compatibility.
  697. Const
  698. OnGetPropValue : TGetPropValue = Nil;
  699. OnSetPropValue : TSetPropValue = Nil;
  700. OnGetVariantprop : TGetVariantProp = Nil;
  701. OnSetVariantprop : TSetVariantProp = Nil;
  702. { for inlining }
  703. function DerefTypeInfoPtr(Info: TypeInfoPtr): PTypeInfo; inline;
  704. Implementation
  705. uses rtlconsts;
  706. type
  707. PMethod = ^TMethod;
  708. { ---------------------------------------------------------------------
  709. Auxiliary methods
  710. ---------------------------------------------------------------------}
  711. function aligntoptr(p : pointer) : pointer;inline;
  712. begin
  713. {$ifdef m68k}
  714. result:=AlignTypeData(p);
  715. {$else m68k}
  716. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  717. result:=align(p,sizeof(p));
  718. {$else FPC_REQUIRES_PROPER_ALIGNMENT}
  719. result:=p;
  720. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  721. {$endif m68k}
  722. end;
  723. function DerefTypeInfoPtr(Info: TypeInfoPtr): PTypeInfo; inline;
  724. begin
  725. {$ifdef ver3_0}
  726. Result := Info;
  727. {$else}
  728. if not Assigned(Info) then
  729. Result := Nil
  730. else
  731. Result := Info^;
  732. {$endif}
  733. end;
  734. Function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
  735. Var PS : PShortString;
  736. PT : PTypeData;
  737. begin
  738. PT:=GetTypeData(TypeInfo);
  739. if TypeInfo^.Kind=tkBool then
  740. begin
  741. case Value of
  742. 0,1:
  743. Result:=BooleanIdents[Boolean(Value)];
  744. else
  745. Result:='';
  746. end;
  747. end
  748. else
  749. begin
  750. PS:=@PT^.NameList;
  751. dec(Value,PT^.MinValue);
  752. While Value>0 Do
  753. begin
  754. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  755. Dec(Value);
  756. end;
  757. Result:=PS^;
  758. end;
  759. end;
  760. Function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
  761. Var PS : PShortString;
  762. PT : PTypeData;
  763. Count : longint;
  764. sName: shortstring;
  765. begin
  766. If Length(Name)=0 then
  767. exit(-1);
  768. sName := Name;
  769. PT:=GetTypeData(TypeInfo);
  770. Count:=0;
  771. Result:=-1;
  772. if TypeInfo^.Kind=tkBool then
  773. begin
  774. If CompareText(BooleanIdents[false],Name)=0 then
  775. result:=0
  776. else if CompareText(BooleanIdents[true],Name)=0 then
  777. result:=1;
  778. end
  779. else
  780. begin
  781. PS:=@PT^.NameList;
  782. While (Result=-1) and (PByte(PS)^<>0) do
  783. begin
  784. If ShortCompareText(PS^, sName) = 0 then
  785. Result:=Count+PT^.MinValue;
  786. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  787. Inc(Count);
  788. end;
  789. if Result=-1 then
  790. Result:=GetEnumeratedAliasValue(TypeInfo,Name);
  791. end;
  792. end;
  793. function GetEnumNameCount(enum1: PTypeInfo): SizeInt;
  794. var
  795. PS: PShortString;
  796. PT: PTypeData;
  797. Count: SizeInt;
  798. begin
  799. PT:=GetTypeData(enum1);
  800. if enum1^.Kind=tkBool then
  801. Result:=2
  802. else
  803. begin
  804. Count:=0;
  805. Result:=0;
  806. PS:=@PT^.NameList;
  807. While (PByte(PS)^<>0) do
  808. begin
  809. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  810. Inc(Count);
  811. end;
  812. { the last string is the unit name }
  813. Result := Count - 1;
  814. end;
  815. end;
  816. Function SetToString(PropInfo: PPropInfo; Value: Integer; Brackets: Boolean) : String;
  817. begin
  818. Result:=SetToString(PropInfo^.PropType,Value,Brackets);
  819. end;
  820. Function SetToString(TypeInfo: PTypeInfo; Value: Integer; Brackets: Boolean) : String;
  821. type
  822. tsetarr = bitpacked array[0..SizeOf(Integer)*8-1] of 0..1;
  823. Var
  824. I : Integer;
  825. PTI : PTypeInfo;
  826. begin
  827. {$if defined(FPC_BIG_ENDIAN)}
  828. { On big endian systems, set element 0 is in the most significant bit,
  829. and the same goes for the elements of bitpacked arrays there. }
  830. case GetTypeData(TypeInfo)^.OrdType of
  831. otSByte,otUByte: Value:=Value shl (SizeOf(Integer)*8-8);
  832. otSWord,otUWord: Value:=Value shl (SizeOf(Integer)*8-16);
  833. end;
  834. {$endif}
  835. PTI:=GetTypeData(TypeInfo)^.CompType;
  836. Result:='';
  837. For I:=0 to SizeOf(Integer)*8-1 do
  838. begin
  839. if (tsetarr(Value)[i]<>0) then
  840. begin
  841. If Result='' then
  842. Result:=GetEnumName(PTI,i)
  843. else
  844. Result:=Result+','+GetEnumName(PTI,I);
  845. end;
  846. end;
  847. if Brackets then
  848. Result:='['+Result+']';
  849. end;
  850. Function SetToString(PropInfo: PPropInfo; Value: Integer) : String;
  851. begin
  852. Result:=SetToString(PropInfo,Value,False);
  853. end;
  854. Const
  855. SetDelim = ['[',']',',',' '];
  856. Function GetNextElement(Var S : String) : String;
  857. Var
  858. J : Integer;
  859. begin
  860. J:=1;
  861. Result:='';
  862. If Length(S)>0 then
  863. begin
  864. While (J<=Length(S)) and Not (S[j] in SetDelim) do
  865. Inc(j);
  866. Result:=Copy(S,1,j-1);
  867. Delete(S,1,j);
  868. end;
  869. end;
  870. Function StringToSet(PropInfo: PPropInfo; const Value: string): Integer;
  871. begin
  872. Result:=StringToSet(PropInfo^.PropType,Value);
  873. end;
  874. Function StringToSet(TypeInfo: PTypeInfo; const Value: string): Integer;
  875. Var
  876. S,T : String;
  877. I : Integer;
  878. PTI : PTypeInfo;
  879. begin
  880. Result:=0;
  881. PTI:=GetTypeData(TypeInfo)^.Comptype;
  882. S:=Value;
  883. I:=1;
  884. If Length(S)>0 then
  885. begin
  886. While (I<=Length(S)) and (S[i] in SetDelim) do
  887. Inc(I);
  888. Delete(S,1,i-1);
  889. end;
  890. While (S<>'') do
  891. begin
  892. T:=GetNextElement(S);
  893. if T<>'' then
  894. begin
  895. I:=GetEnumValue(PTI,T);
  896. if (I<0) then
  897. raise EPropertyError.CreateFmt(SErrUnknownEnumValue, [T]);
  898. Result:=Result or (1 shl i);
  899. end;
  900. end;
  901. end;
  902. Function AlignTypeData(p : Pointer) : Pointer;
  903. {$packrecords c}
  904. type
  905. TAlignCheck = record
  906. b : byte;
  907. q : qword;
  908. end;
  909. {$packrecords default}
  910. begin
  911. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  912. {$ifdef VER3_0}
  913. Result:=Pointer(align(p,SizeOf(Pointer)));
  914. {$else VER3_0}
  915. Result:=Pointer(align(p,PtrInt(@TAlignCheck(nil^).q)))
  916. {$endif VER3_0}
  917. {$else FPC_REQUIRES_PROPER_ALIGNMENT}
  918. Result:=p;
  919. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  920. end;
  921. Function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
  922. begin
  923. GetTypeData:=AlignTypeData(pointer(TypeInfo)+2+PByte(pointer(TypeInfo)+1)^);
  924. end;
  925. { ---------------------------------------------------------------------
  926. Basic Type information functions.
  927. ---------------------------------------------------------------------}
  928. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string) : PPropInfo;
  929. var
  930. hp : PTypeData;
  931. i : longint;
  932. p : shortstring;
  933. pd : ^TPropData;
  934. begin
  935. P:=PropName; // avoid Ansi<->short conversion in a loop
  936. while Assigned(TypeInfo) do
  937. begin
  938. // skip the name
  939. hp:=GetTypeData(Typeinfo);
  940. // the class info rtti the property rtti follows immediatly
  941. pd:=aligntoptr(pointer(pointer(@hp^.UnitName)+Length(hp^.UnitName)+1));
  942. Result:=PPropInfo(@pd^.PropList);
  943. for i:=1 to pd^.PropCount do
  944. begin
  945. // found a property of that name ?
  946. if ShortCompareText(Result^.Name, P) = 0 then
  947. exit;
  948. // skip to next property
  949. Result:=PPropInfo(aligntoptr(pointer(@Result^.Name)+byte(Result^.Name[0])+1));
  950. end;
  951. // parent class
  952. Typeinfo:=hp^.ParentInfo;
  953. end;
  954. Result:=Nil;
  955. end;
  956. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string; Akinds : TTypeKinds) : PPropInfo;
  957. begin
  958. Result:=GetPropInfo(TypeInfo,PropName);
  959. If (Akinds<>[]) then
  960. If (Result<>Nil) then
  961. If Not (Result^.PropType^.Kind in AKinds) then
  962. Result:=Nil;
  963. end;
  964. Function GetPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
  965. begin
  966. Result:=GetPropInfo(PTypeInfo(AClass.ClassInfo),PropName,AKinds);
  967. end;
  968. Function GetPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
  969. begin
  970. Result:=GetPropInfo(Instance.ClassType,PropName,AKinds);
  971. end;
  972. Function GetPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  973. begin
  974. Result:=GetPropInfo(Instance,PropName,[]);
  975. end;
  976. Function GetPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  977. begin
  978. Result:=GetPropInfo(AClass,PropName,[]);
  979. end;
  980. Function FindPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  981. begin
  982. result:=GetPropInfo(Instance, PropName);
  983. if Result=nil then
  984. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  985. end;
  986. Function FindPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  987. begin
  988. result:=GetPropInfo(Instance, PropName, AKinds);
  989. if Result=nil then
  990. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  991. end;
  992. Function FindPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  993. begin
  994. result:=GetPropInfo(AClass, PropName);
  995. if result=nil then
  996. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  997. end;
  998. Function FindPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  999. begin
  1000. result:=GetPropInfo(AClass, PropName, AKinds);
  1001. if result=nil then
  1002. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  1003. end;
  1004. Function IsStoredProp(Instance : TObject;PropInfo : PPropInfo) : Boolean;
  1005. type
  1006. TBooleanIndexFunc=function(Index:integer):boolean of object;
  1007. TBooleanFunc=function:boolean of object;
  1008. var
  1009. AMethod : TMethod;
  1010. begin
  1011. case (PropInfo^.PropProcs shr 4) and 3 of
  1012. ptField:
  1013. Result:=PBoolean(Pointer(Instance)+PtrUInt(PropInfo^.StoredProc))^;
  1014. ptConst:
  1015. Result:=LongBool(PropInfo^.StoredProc);
  1016. ptStatic,
  1017. ptVirtual:
  1018. begin
  1019. if (PropInfo^.PropProcs shr 4) and 3=ptstatic then
  1020. AMethod.Code:=PropInfo^.StoredProc
  1021. else
  1022. AMethod.Code:=pcodepointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.StoredProc))^;
  1023. AMethod.Data:=Instance;
  1024. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1025. Result:=TBooleanIndexFunc(AMethod)(PropInfo^.Index)
  1026. else
  1027. Result:=TBooleanFunc(AMethod)();
  1028. end;
  1029. end;
  1030. end;
  1031. Procedure GetPropInfos(TypeInfo : PTypeInfo;PropList : PPropList);
  1032. {
  1033. Store Pointers to property information in the list pointed
  1034. to by proplist. PRopList must contain enough space to hold ALL
  1035. properties.
  1036. }
  1037. Var
  1038. TD : PTypeData;
  1039. TP : PPropInfo;
  1040. Count : Longint;
  1041. begin
  1042. // Get this objects TOTAL published properties count
  1043. TD:=GetTypeData(TypeInfo);
  1044. // Clear list
  1045. FillChar(PropList^,TD^.PropCount*sizeof(Pointer),0);
  1046. repeat
  1047. TD:=GetTypeData(TypeInfo);
  1048. // published properties count for this object
  1049. TP:=aligntoptr(PPropInfo(aligntoptr((Pointer(@TD^.UnitName)+Length(TD^.UnitName)+1))));
  1050. Count:=PWord(TP)^;
  1051. // Now point TP to first propinfo record.
  1052. Inc(Pointer(TP),SizeOF(Word));
  1053. tp:=aligntoptr(tp);
  1054. While Count>0 do
  1055. begin
  1056. // Don't overwrite properties with the same name
  1057. if PropList^[TP^.NameIndex]=nil then
  1058. PropList^[TP^.NameIndex]:=TP;
  1059. // Point to TP next propinfo record.
  1060. // Located at Name[Length(Name)+1] !
  1061. TP:=aligntoptr(PPropInfo(pointer(@TP^.Name)+PByte(@TP^.Name)^+1));
  1062. Dec(Count);
  1063. end;
  1064. TypeInfo:=TD^.Parentinfo;
  1065. until TypeInfo=nil;
  1066. end;
  1067. Procedure InsertProp (PL : PProplist;PI : PPropInfo; Count : longint);
  1068. Var
  1069. I : Longint;
  1070. begin
  1071. I:=0;
  1072. While (I<Count) and (PI^.Name>PL^[I]^.Name) do
  1073. Inc(I);
  1074. If I<Count then
  1075. Move(PL^[I], PL^[I+1], (Count - I) * SizeOf(Pointer));
  1076. PL^[I]:=PI;
  1077. end;
  1078. Procedure InsertPropnosort (PL : PProplist;PI : PPropInfo; Count : longint);
  1079. begin
  1080. PL^[Count]:=PI;
  1081. end;
  1082. Type TInsertProp = Procedure (PL : PProplist;PI : PPropInfo; Count : longint);
  1083. //Const InsertProps : array[false..boolean] of TInsertProp = (InsertPropNoSort,InsertProp);
  1084. Function GetPropList(TypeInfo : PTypeInfo;TypeKinds : TTypeKinds; PropList : PPropList;Sorted : boolean = true):longint;
  1085. {
  1086. Store Pointers to property information OF A CERTAIN KIND in the list pointed
  1087. to by proplist. PRopList must contain enough space to hold ALL
  1088. properties.
  1089. }
  1090. Var
  1091. TempList : PPropList;
  1092. PropInfo : PPropinfo;
  1093. I,Count : longint;
  1094. DoInsertProp : TInsertProp;
  1095. begin
  1096. if sorted then
  1097. DoInsertProp:=@InsertProp
  1098. else
  1099. DoInsertProp:=@InsertPropnosort;
  1100. Result:=0;
  1101. Count:=GetTypeData(TypeInfo)^.Propcount;
  1102. If Count>0 then
  1103. begin
  1104. GetMem(TempList,Count*SizeOf(Pointer));
  1105. Try
  1106. GetPropInfos(TypeInfo,TempList);
  1107. For I:=0 to Count-1 do
  1108. begin
  1109. PropInfo:=TempList^[i];
  1110. If PropInfo^.PropType^.Kind in TypeKinds then
  1111. begin
  1112. If (PropList<>Nil) then
  1113. DoInsertProp(PropList,PropInfo,Result);
  1114. Inc(Result);
  1115. end;
  1116. end;
  1117. finally
  1118. FreeMem(TempList,Count*SizeOf(Pointer));
  1119. end;
  1120. end;
  1121. end;
  1122. Function GetPropList(TypeInfo: PTypeInfo; out PropList: PPropList): SizeInt;
  1123. begin
  1124. result:=GetTypeData(TypeInfo)^.Propcount;
  1125. if result>0 then
  1126. begin
  1127. getmem(PropList,result*sizeof(pointer));
  1128. GetPropInfos(TypeInfo,PropList);
  1129. end
  1130. else
  1131. PropList:=Nil;
  1132. end;
  1133. function GetPropList(AClass: TClass; out PropList: PPropList): Integer;
  1134. begin
  1135. Result := GetPropList(PTypeInfo(AClass.ClassInfo), PropList);
  1136. end;
  1137. function GetPropList(Instance: TObject; out PropList: PPropList): Integer;
  1138. begin
  1139. Result := GetPropList(Instance.ClassType, PropList);
  1140. end;
  1141. { ---------------------------------------------------------------------
  1142. Property access functions
  1143. ---------------------------------------------------------------------}
  1144. { ---------------------------------------------------------------------
  1145. Ordinal properties
  1146. ---------------------------------------------------------------------}
  1147. Function GetOrdProp(Instance : TObject;PropInfo : PPropInfo) : Int64;
  1148. type
  1149. TGetInt64ProcIndex=function(index:longint):Int64 of object;
  1150. TGetInt64Proc=function():Int64 of object;
  1151. TGetIntegerProcIndex=function(index:longint):longint of object;
  1152. TGetIntegerProc=function:longint of object;
  1153. TGetWordProcIndex=function(index:longint):word of object;
  1154. TGetWordProc=function:word of object;
  1155. TGetByteProcIndex=function(index:longint):Byte of object;
  1156. TGetByteProc=function:Byte of object;
  1157. var
  1158. TypeInfo: PTypeInfo;
  1159. AMethod : TMethod;
  1160. DataSize: Integer;
  1161. OrdType: TOrdType;
  1162. Signed: Boolean;
  1163. begin
  1164. Result:=0;
  1165. TypeInfo := PropInfo^.PropType;
  1166. Signed := false;
  1167. DataSize := 4;
  1168. case TypeInfo^.Kind of
  1169. {$ifdef cpu64}
  1170. tkInterface,
  1171. tkInterfaceRaw,
  1172. tkDynArray,
  1173. tkClass:
  1174. DataSize:=8;
  1175. {$endif cpu64}
  1176. tkChar, tkBool:
  1177. DataSize:=1;
  1178. tkWChar:
  1179. DataSize:=2;
  1180. tkSet,
  1181. tkEnumeration,
  1182. tkInteger:
  1183. begin
  1184. OrdType:=GetTypeData(TypeInfo)^.OrdType;
  1185. case OrdType of
  1186. otSByte,otUByte: DataSize := 1;
  1187. otSWord,otUWord: DataSize := 2;
  1188. end;
  1189. Signed := OrdType in [otSByte,otSWord,otSLong];
  1190. end;
  1191. tkInt64 :
  1192. begin
  1193. DataSize:=8;
  1194. Signed:=true;
  1195. end;
  1196. tkQword :
  1197. begin
  1198. DataSize:=8;
  1199. Signed:=false;
  1200. end;
  1201. end;
  1202. case (PropInfo^.PropProcs) and 3 of
  1203. ptField:
  1204. if Signed then begin
  1205. case DataSize of
  1206. 1: Result:=PShortInt(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1207. 2: Result:=PSmallInt(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1208. 4: Result:=PLongint(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1209. 8: Result:=PInt64(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1210. end;
  1211. end else begin
  1212. case DataSize of
  1213. 1: Result:=PByte(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1214. 2: Result:=PWord(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1215. 4: Result:=PLongint(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1216. 8: Result:=PInt64(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1217. end;
  1218. end;
  1219. ptStatic,
  1220. ptVirtual:
  1221. begin
  1222. if (PropInfo^.PropProcs and 3)=ptStatic then
  1223. AMethod.Code:=PropInfo^.GetProc
  1224. else
  1225. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1226. AMethod.Data:=Instance;
  1227. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then begin
  1228. case DataSize of
  1229. 1: Result:=TGetByteProcIndex(AMethod)(PropInfo^.Index);
  1230. 2: Result:=TGetWordProcIndex(AMethod)(PropInfo^.Index);
  1231. 4: Result:=TGetIntegerProcIndex(AMethod)(PropInfo^.Index);
  1232. 8: result:=TGetInt64ProcIndex(AMethod)(PropInfo^.Index)
  1233. end;
  1234. end else begin
  1235. case DataSize of
  1236. 1: Result:=TGetByteProc(AMethod)();
  1237. 2: Result:=TGetWordProc(AMethod)();
  1238. 4: Result:=TGetIntegerProc(AMethod)();
  1239. 8: result:=TGetInt64Proc(AMethod)();
  1240. end;
  1241. end;
  1242. if Signed then begin
  1243. case DataSize of
  1244. 1: Result:=ShortInt(Result);
  1245. 2: Result:=SmallInt(Result);
  1246. end;
  1247. end;
  1248. end;
  1249. end;
  1250. end;
  1251. Procedure SetOrdProp(Instance : TObject;PropInfo : PPropInfo;Value : Int64);
  1252. type
  1253. TSetInt64ProcIndex=procedure(index:longint;i:Int64) of object;
  1254. TSetInt64Proc=procedure(i:Int64) of object;
  1255. TSetIntegerProcIndex=procedure(index,i:longint) of object;
  1256. TSetIntegerProc=procedure(i:longint) of object;
  1257. var
  1258. DataSize: Integer;
  1259. AMethod : TMethod;
  1260. begin
  1261. if PropInfo^.PropType^.Kind in [tkInt64,tkQword
  1262. { why do we have to handle classes here, see also below? (FK) }
  1263. {$ifdef cpu64}
  1264. ,tkInterface
  1265. ,tkInterfaceRaw
  1266. ,tkDynArray
  1267. ,tkClass
  1268. {$endif cpu64}
  1269. ] then
  1270. DataSize := 8
  1271. else
  1272. DataSize := 4;
  1273. if not(PropInfo^.PropType^.Kind in [tkInt64,tkQword,tkClass,tkInterface,tkInterfaceRaw,tkDynArray]) then
  1274. begin
  1275. { cut off unnecessary stuff }
  1276. case GetTypeData(PropInfo^.PropType)^.OrdType of
  1277. otSWord,otUWord:
  1278. begin
  1279. Value:=Value and $ffff;
  1280. DataSize := 2;
  1281. end;
  1282. otSByte,otUByte:
  1283. begin
  1284. Value:=Value and $ff;
  1285. DataSize := 1;
  1286. end;
  1287. end;
  1288. end;
  1289. case (PropInfo^.PropProcs shr 2) and 3 of
  1290. ptField:
  1291. case DataSize of
  1292. 1: PByte(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Byte(Value);
  1293. 2: PWord(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Word(Value);
  1294. 4: PLongint(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Longint(Value);
  1295. 8: PInt64(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1296. end;
  1297. ptStatic,
  1298. ptVirtual:
  1299. begin
  1300. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1301. AMethod.Code:=PropInfo^.SetProc
  1302. else
  1303. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1304. AMethod.Data:=Instance;
  1305. if datasize=8 then
  1306. begin
  1307. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1308. TSetInt64ProcIndex(AMethod)(PropInfo^.Index,Value)
  1309. else
  1310. TSetInt64Proc(AMethod)(Value);
  1311. end
  1312. else
  1313. begin
  1314. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1315. TSetIntegerProcIndex(AMethod)(PropInfo^.Index,Value)
  1316. else
  1317. TSetIntegerProc(AMethod)(Value);
  1318. end;
  1319. end;
  1320. end;
  1321. end;
  1322. Function GetOrdProp(Instance: TObject; const PropName: string): Int64;
  1323. begin
  1324. Result:=GetOrdProp(Instance,FindPropInfo(Instance,PropName));
  1325. end;
  1326. Procedure SetOrdProp(Instance: TObject; const PropName: string; Value: Int64);
  1327. begin
  1328. SetOrdProp(Instance,FindPropInfo(Instance,PropName),Value);
  1329. end;
  1330. Function GetEnumProp(Instance: TObject; Const PropInfo: PPropInfo): string;
  1331. begin
  1332. Result:=GetEnumName(PropInfo^.PropType, GetOrdProp(Instance, PropInfo));
  1333. end;
  1334. Function GetEnumProp(Instance: TObject; const PropName: string): string;
  1335. begin
  1336. Result:=GetEnumProp(Instance,FindPropInfo(Instance,PropName));
  1337. end;
  1338. Procedure SetEnumProp(Instance: TObject; const PropName: string; const Value: string);
  1339. begin
  1340. SetEnumProp(Instance,FindPropInfo(Instance,PropName),Value);
  1341. end;
  1342. Procedure SetEnumProp(Instance: TObject; Const PropInfo : PPropInfo; const Value: string);
  1343. Var
  1344. PV : Longint;
  1345. begin
  1346. If PropInfo<>Nil then
  1347. begin
  1348. PV:=GetEnumValue(PropInfo^.PropType, Value);
  1349. if (PV<0) then
  1350. raise EPropertyError.CreateFmt(SErrUnknownEnumValue, [Value]);
  1351. SetOrdProp(Instance, PropInfo,PV);
  1352. end;
  1353. end;
  1354. { ---------------------------------------------------------------------
  1355. Int64 wrappers
  1356. ---------------------------------------------------------------------}
  1357. Function GetInt64Prop(Instance: TObject; PropInfo: PPropInfo): Int64;
  1358. begin
  1359. Result:=GetOrdProp(Instance,PropInfo);
  1360. end;
  1361. procedure SetInt64Prop(Instance: TObject; PropInfo: PPropInfo; const Value: Int64);
  1362. begin
  1363. SetOrdProp(Instance,PropInfo,Value);
  1364. end;
  1365. Function GetInt64Prop(Instance: TObject; const PropName: string): Int64;
  1366. begin
  1367. Result:=GetInt64Prop(Instance,FindPropInfo(Instance,PropName));
  1368. end;
  1369. Procedure SetInt64Prop(Instance: TObject; const PropName: string; const Value: Int64);
  1370. begin
  1371. SetInt64Prop(Instance,FindPropInfo(Instance,PropName),Value);
  1372. end;
  1373. { ---------------------------------------------------------------------
  1374. Set properties
  1375. ---------------------------------------------------------------------}
  1376. Function GetSetProp(Instance: TObject; const PropName: string): string;
  1377. begin
  1378. Result:=GetSetProp(Instance,PropName,False);
  1379. end;
  1380. Function GetSetProp(Instance: TObject; const PropName: string; Brackets: Boolean): string;
  1381. begin
  1382. Result:=GetSetProp(Instance,FindPropInfo(Instance,PropName),Brackets);
  1383. end;
  1384. Function GetSetProp(Instance: TObject; const PropInfo: PPropInfo; Brackets: Boolean): string;
  1385. begin
  1386. Result:=SetToString(PropInfo,GetOrdProp(Instance,PropInfo),Brackets);
  1387. end;
  1388. Procedure SetSetProp(Instance: TObject; const PropName: string; const Value: string);
  1389. begin
  1390. SetSetProp(Instance,FindPropInfo(Instance,PropName),Value);
  1391. end;
  1392. Procedure SetSetProp(Instance: TObject; const PropInfo: PPropInfo; const Value: string);
  1393. begin
  1394. SetOrdProp(Instance,PropInfo,StringToSet(PropInfo,Value));
  1395. end;
  1396. { ---------------------------------------------------------------------
  1397. Object properties
  1398. ---------------------------------------------------------------------}
  1399. Function GetObjectProp(Instance: TObject; const PropName: string): TObject;
  1400. begin
  1401. Result:=GetObjectProp(Instance,PropName,Nil);
  1402. end;
  1403. Function GetObjectProp(Instance: TObject; const PropName: string; MinClass: TClass): TObject;
  1404. begin
  1405. Result:=GetObjectProp(Instance,FindPropInfo(Instance,PropName),MinClass);
  1406. end;
  1407. Function GetObjectProp(Instance: TObject; PropInfo : PPropInfo): TObject;
  1408. begin
  1409. Result:=GetObjectProp(Instance,PropInfo,Nil);
  1410. end;
  1411. Function GetObjectProp(Instance: TObject; PropInfo : PPropInfo; MinClass: TClass): TObject;
  1412. begin
  1413. {$ifdef cpu64}
  1414. Result:=TObject(GetInt64Prop(Instance,PropInfo));
  1415. {$else cpu64}
  1416. Result:=TObject(PtrInt(GetOrdProp(Instance,PropInfo)));
  1417. {$endif cpu64}
  1418. If (MinClass<>Nil) and (Result<>Nil) Then
  1419. If Not Result.InheritsFrom(MinClass) then
  1420. Result:=Nil;
  1421. end;
  1422. Procedure SetObjectProp(Instance: TObject; const PropName: string; Value: TObject);
  1423. begin
  1424. SetObjectProp(Instance,FindPropInfo(Instance,PropName),Value);
  1425. end;
  1426. Procedure SetObjectProp(Instance: TObject; PropInfo : PPropInfo; Value: TObject);
  1427. begin
  1428. {$ifdef cpu64}
  1429. SetInt64Prop(Instance,PropInfo,Int64(Value));
  1430. {$else cpu64}
  1431. SetOrdProp(Instance,PropInfo,PtrInt(Value));
  1432. {$endif cpu64}
  1433. end;
  1434. Function GetObjectPropClass(Instance: TObject; const PropName: string): TClass;
  1435. begin
  1436. Result:=GetTypeData(FindPropInfo(Instance,PropName,[tkClass])^.PropType)^.ClassType;
  1437. end;
  1438. Function GetObjectPropClass(AClass: TClass; const PropName: string): TClass;
  1439. begin
  1440. Result:=GetTypeData(FindPropInfo(AClass,PropName,[tkClass])^.PropType)^.ClassType;
  1441. end;
  1442. { ---------------------------------------------------------------------
  1443. Interface wrapprers
  1444. ---------------------------------------------------------------------}
  1445. function GetInterfaceProp(Instance: TObject; const PropName: string): IInterface;
  1446. begin
  1447. Result:=GetInterfaceProp(Instance,FindPropInfo(Instance,PropName));
  1448. end;
  1449. function GetInterfaceProp(Instance: TObject; PropInfo: PPropInfo): IInterface;
  1450. type
  1451. TGetInterfaceProc=function:IInterface of object;
  1452. TGetInterfaceProcIndex=function(index:longint):IInterface of object;
  1453. var
  1454. AMethod : TMethod;
  1455. begin
  1456. Result:=nil;
  1457. case (PropInfo^.PropProcs) and 3 of
  1458. ptField:
  1459. Result:=IInterface(PPointer(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^);
  1460. ptStatic,
  1461. ptVirtual:
  1462. begin
  1463. if (PropInfo^.PropProcs and 3)=ptStatic then
  1464. AMethod.Code:=PropInfo^.GetProc
  1465. else
  1466. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1467. AMethod.Data:=Instance;
  1468. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1469. Result:=TGetInterfaceProcIndex(AMethod)(PropInfo^.Index)
  1470. else
  1471. Result:=TGetInterfaceProc(AMethod)();
  1472. end;
  1473. end;
  1474. end;
  1475. procedure SetInterfaceProp(Instance: TObject; const PropName: string; const Value: IInterface);
  1476. begin
  1477. SetInterfaceProp(Instance,FindPropInfo(Instance,PropName),Value);
  1478. end;
  1479. procedure SetInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: IInterface);
  1480. type
  1481. TSetIntfStrProcIndex=procedure(index:longint;const i:IInterface) of object;
  1482. TSetIntfStrProc=procedure(i:IInterface) of object;
  1483. var
  1484. AMethod : TMethod;
  1485. begin
  1486. case Propinfo^.PropType^.Kind of
  1487. tkInterface:
  1488. begin
  1489. case (PropInfo^.PropProcs shr 2) and 3 of
  1490. ptField:
  1491. PInterface(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1492. ptStatic,
  1493. ptVirtual:
  1494. begin
  1495. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1496. AMethod.Code:=PropInfo^.SetProc
  1497. else
  1498. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1499. AMethod.Data:=Instance;
  1500. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1501. TSetIntfStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1502. else
  1503. TSetIntfStrProc(AMethod)(Value);
  1504. end;
  1505. end;
  1506. end;
  1507. tkInterfaceRaw:
  1508. Raise Exception.Create('Cannot set RAW interface from IUnknown interface');
  1509. end;
  1510. end;
  1511. { ---------------------------------------------------------------------
  1512. RAW (Corba) Interface wrapprers
  1513. ---------------------------------------------------------------------}
  1514. function GetRawInterfaceProp(Instance: TObject; const PropName: string): Pointer;
  1515. begin
  1516. Result:=GetRawInterfaceProp(Instance,FindPropInfo(Instance,PropName));
  1517. end;
  1518. function GetRawInterfaceProp(Instance: TObject; PropInfo: PPropInfo): Pointer;
  1519. begin
  1520. {$ifdef cpu64}
  1521. Result:=Pointer(GetInt64Prop(Instance,PropInfo));
  1522. {$else cpu64}
  1523. Result:=Pointer(PtrInt(GetOrdProp(Instance,PropInfo)));
  1524. {$endif cpu64}
  1525. end;
  1526. procedure SetRawInterfaceProp(Instance: TObject; const PropName: string; const Value: Pointer);
  1527. begin
  1528. SetRawInterfaceProp(Instance,FindPropInfo(Instance,PropName),Value);
  1529. end;
  1530. procedure SetRawInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: Pointer);
  1531. type
  1532. TSetPointerProcIndex=procedure(index:longint;const i:Pointer) of object;
  1533. TSetPointerProc=procedure(i:Pointer) of object;
  1534. var
  1535. AMethod : TMethod;
  1536. begin
  1537. case Propinfo^.PropType^.Kind of
  1538. tkInterfaceRaw:
  1539. begin
  1540. case (PropInfo^.PropProcs shr 2) and 3 of
  1541. ptField:
  1542. PPointer(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1543. ptStatic,
  1544. ptVirtual:
  1545. begin
  1546. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1547. AMethod.Code:=PropInfo^.SetProc
  1548. else
  1549. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1550. AMethod.Data:=Instance;
  1551. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1552. TSetPointerProcIndex(AMethod)(PropInfo^.Index,Value)
  1553. else
  1554. TSetPointerProc(AMethod)(Value);
  1555. end;
  1556. end;
  1557. end;
  1558. tkInterface:
  1559. Raise Exception.Create('Cannot set interface from RAW interface');
  1560. end;
  1561. end;
  1562. { ---------------------------------------------------------------------
  1563. Dynamic array properties
  1564. ---------------------------------------------------------------------}
  1565. function GetDynArrayProp(Instance: TObject; const PropName: string): Pointer;
  1566. begin
  1567. Result:=GetDynArrayProp(Instance,FindPropInfo(Instance,PropName));
  1568. end;
  1569. function GetDynArrayProp(Instance: TObject; PropInfo: PPropInfo): Pointer;
  1570. type
  1571. { we need a dynamic array as that type is usually passed differently from
  1572. a plain pointer }
  1573. TDynArray=array of Byte;
  1574. TGetDynArrayProc=function:TDynArray of object;
  1575. TGetDynArrayProcIndex=function(index:longint):TDynArray of object;
  1576. var
  1577. AMethod : TMethod;
  1578. begin
  1579. Result:=nil;
  1580. if PropInfo^.PropType^.Kind<>tkDynArray then
  1581. Exit;
  1582. case (PropInfo^.PropProcs) and 3 of
  1583. ptField:
  1584. Result:=PPointer(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1585. ptStatic,
  1586. ptVirtual:
  1587. begin
  1588. if (PropInfo^.PropProcs and 3)=ptStatic then
  1589. AMethod.Code:=PropInfo^.GetProc
  1590. else
  1591. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1592. AMethod.Data:=Instance;
  1593. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1594. Result:=Pointer(TGetDynArrayProcIndex(AMethod)(PropInfo^.Index))
  1595. else
  1596. Result:=Pointer(TGetDynArrayProc(AMethod)());
  1597. end;
  1598. end;
  1599. end;
  1600. procedure SetDynArrayProp(Instance: TObject; const PropName: string; const Value: Pointer);
  1601. begin
  1602. SetDynArrayProp(Instance,FindPropInfo(Instance,PropName),Value);
  1603. end;
  1604. procedure SetDynArrayProp(Instance: TObject; PropInfo: PPropInfo; const Value: Pointer);
  1605. type
  1606. { we need a dynamic array as that type is usually passed differently from
  1607. a plain pointer }
  1608. TDynArray=array of Byte;
  1609. TSetDynArrayProcIndex=procedure(index:longint;const i:TDynArray) of object;
  1610. TSetDynArrayProc=procedure(i:TDynArray) of object;
  1611. var
  1612. AMethod: TMethod;
  1613. begin
  1614. if PropInfo^.PropType^.Kind<>tkDynArray then
  1615. Exit;
  1616. case (PropInfo^.PropProcs shr 2) and 3 of
  1617. ptField:
  1618. CopyArray(PPointer(Pointer(Instance)+PtrUInt(PropInfo^.SetProc)), @Value, PropInfo^.PropType, 1);
  1619. ptStatic,
  1620. ptVirtual:
  1621. begin
  1622. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1623. AMethod.Code:=PropInfo^.SetProc
  1624. else
  1625. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1626. AMethod.Data:=Instance;
  1627. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1628. TSetDynArrayProcIndex(AMethod)(PropInfo^.Index,TDynArray(Value))
  1629. else
  1630. TSetDynArrayProc(AMethod)(TDynArray(Value));
  1631. end;
  1632. end;
  1633. end;
  1634. { ---------------------------------------------------------------------
  1635. String properties
  1636. ---------------------------------------------------------------------}
  1637. Function GetStrProp(Instance: TObject; PropInfo: PPropInfo): AnsiString;
  1638. type
  1639. TGetShortStrProcIndex=function(index:longint):ShortString of object;
  1640. TGetShortStrProc=function():ShortString of object;
  1641. TGetAnsiStrProcIndex=function(index:longint):AnsiString of object;
  1642. TGetAnsiStrProc=function():AnsiString of object;
  1643. var
  1644. AMethod : TMethod;
  1645. begin
  1646. Result:='';
  1647. case Propinfo^.PropType^.Kind of
  1648. tkWString:
  1649. Result:=AnsiString(GetWideStrProp(Instance,PropInfo));
  1650. tkUString:
  1651. Result := AnsiString(GetUnicodeStrProp(Instance,PropInfo));
  1652. tkSString:
  1653. begin
  1654. case (PropInfo^.PropProcs) and 3 of
  1655. ptField:
  1656. Result := PShortString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  1657. ptStatic,
  1658. ptVirtual:
  1659. begin
  1660. if (PropInfo^.PropProcs and 3)=ptStatic then
  1661. AMethod.Code:=PropInfo^.GetProc
  1662. else
  1663. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1664. AMethod.Data:=Instance;
  1665. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1666. Result:=TGetShortStrProcIndex(AMethod)(PropInfo^.Index)
  1667. else
  1668. Result:=TGetShortStrProc(AMethod)();
  1669. end;
  1670. end;
  1671. end;
  1672. tkAString:
  1673. begin
  1674. case (PropInfo^.PropProcs) and 3 of
  1675. ptField:
  1676. Result := PAnsiString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  1677. ptStatic,
  1678. ptVirtual:
  1679. begin
  1680. if (PropInfo^.PropProcs and 3)=ptStatic then
  1681. AMethod.Code:=PropInfo^.GetProc
  1682. else
  1683. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1684. AMethod.Data:=Instance;
  1685. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1686. Result:=TGetAnsiStrProcIndex(AMethod)(PropInfo^.Index)
  1687. else
  1688. Result:=TGetAnsiStrProc(AMethod)();
  1689. end;
  1690. end;
  1691. end;
  1692. end;
  1693. end;
  1694. Procedure SetStrProp(Instance : TObject;PropInfo : PPropInfo; const Value : AnsiString);
  1695. type
  1696. TSetShortStrProcIndex=procedure(index:longint;const s:ShortString) of object;
  1697. TSetShortStrProc=procedure(const s:ShortString) of object;
  1698. TSetAnsiStrProcIndex=procedure(index:longint;s:AnsiString) of object;
  1699. TSetAnsiStrProc=procedure(s:AnsiString) of object;
  1700. var
  1701. AMethod : TMethod;
  1702. begin
  1703. case Propinfo^.PropType^.Kind of
  1704. tkWString:
  1705. SetWideStrProp(Instance,PropInfo,WideString(Value));
  1706. tkUString:
  1707. SetUnicodeStrProp(Instance,PropInfo,UnicodeString(Value));
  1708. tkSString:
  1709. begin
  1710. case (PropInfo^.PropProcs shr 2) and 3 of
  1711. ptField:
  1712. PShortString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  1713. ptStatic,
  1714. ptVirtual:
  1715. begin
  1716. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1717. AMethod.Code:=PropInfo^.SetProc
  1718. else
  1719. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1720. AMethod.Data:=Instance;
  1721. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1722. TSetShortStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1723. else
  1724. TSetShortStrProc(AMethod)(Value);
  1725. end;
  1726. end;
  1727. end;
  1728. tkAString:
  1729. begin
  1730. case (PropInfo^.PropProcs shr 2) and 3 of
  1731. ptField:
  1732. PAnsiString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  1733. ptStatic,
  1734. ptVirtual:
  1735. begin
  1736. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1737. AMethod.Code:=PropInfo^.SetProc
  1738. else
  1739. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1740. AMethod.Data:=Instance;
  1741. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1742. TSetAnsiStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1743. else
  1744. TSetAnsiStrProc(AMethod)(Value);
  1745. end;
  1746. end;
  1747. end;
  1748. end;
  1749. end;
  1750. Function GetStrProp(Instance: TObject; const PropName: string): string;
  1751. begin
  1752. Result:=GetStrProp(Instance,FindPropInfo(Instance,PropName));
  1753. end;
  1754. Procedure SetStrProp(Instance: TObject; const PropName: string; const Value: AnsiString);
  1755. begin
  1756. SetStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  1757. end;
  1758. Function GetWideStrProp(Instance: TObject; const PropName: string): WideString;
  1759. begin
  1760. Result:=GetWideStrProp(Instance, FindPropInfo(Instance, PropName));
  1761. end;
  1762. procedure SetWideStrProp(Instance: TObject; const PropName: string; const Value: WideString);
  1763. begin
  1764. SetWideStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  1765. end;
  1766. Function GetWideStrProp(Instance: TObject; PropInfo: PPropInfo): WideString;
  1767. type
  1768. TGetWideStrProcIndex=function(index:longint):WideString of object;
  1769. TGetWideStrProc=function():WideString of object;
  1770. var
  1771. AMethod : TMethod;
  1772. begin
  1773. Result:='';
  1774. case Propinfo^.PropType^.Kind of
  1775. tkSString,tkAString:
  1776. Result:=WideString(GetStrProp(Instance,PropInfo));
  1777. tkUString :
  1778. Result := GetUnicodeStrProp(Instance,PropInfo);
  1779. tkWString:
  1780. begin
  1781. case (PropInfo^.PropProcs) and 3 of
  1782. ptField:
  1783. Result := PWideString(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1784. ptStatic,
  1785. ptVirtual:
  1786. begin
  1787. if (PropInfo^.PropProcs and 3)=ptStatic then
  1788. AMethod.Code:=PropInfo^.GetProc
  1789. else
  1790. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1791. AMethod.Data:=Instance;
  1792. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1793. Result:=TGetWideStrProcIndex(AMethod)(PropInfo^.Index)
  1794. else
  1795. Result:=TGetWideStrProc(AMethod)();
  1796. end;
  1797. end;
  1798. end;
  1799. end;
  1800. end;
  1801. Procedure SetWideStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: WideString);
  1802. type
  1803. TSetWideStrProcIndex=procedure(index:longint;s:WideString) of object;
  1804. TSetWideStrProc=procedure(s:WideString) of object;
  1805. var
  1806. AMethod : TMethod;
  1807. begin
  1808. case Propinfo^.PropType^.Kind of
  1809. tkSString,tkAString:
  1810. SetStrProp(Instance,PropInfo,AnsiString(Value));
  1811. tkUString:
  1812. SetUnicodeStrProp(Instance,PropInfo,Value);
  1813. tkWString:
  1814. begin
  1815. case (PropInfo^.PropProcs shr 2) and 3 of
  1816. ptField:
  1817. PWideString(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1818. ptStatic,
  1819. ptVirtual:
  1820. begin
  1821. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1822. AMethod.Code:=PropInfo^.SetProc
  1823. else
  1824. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1825. AMethod.Data:=Instance;
  1826. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1827. TSetWideStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1828. else
  1829. TSetWideStrProc(AMethod)(Value);
  1830. end;
  1831. end;
  1832. end;
  1833. end;
  1834. end;
  1835. Function GetUnicodeStrProp(Instance: TObject; const PropName: string): UnicodeString;
  1836. begin
  1837. Result:=GetUnicodeStrProp(Instance, FindPropInfo(Instance, PropName));
  1838. end;
  1839. procedure SetUnicodeStrProp(Instance: TObject; const PropName: string; const Value: UnicodeString);
  1840. begin
  1841. SetUnicodeStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  1842. end;
  1843. Function GetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo): UnicodeString;
  1844. type
  1845. TGetUnicodeStrProcIndex=function(index:longint):UnicodeString of object;
  1846. TGetUnicodeStrProc=function():UnicodeString of object;
  1847. var
  1848. AMethod : TMethod;
  1849. begin
  1850. Result:='';
  1851. case Propinfo^.PropType^.Kind of
  1852. tkSString,tkAString:
  1853. Result:=UnicodeString(GetStrProp(Instance,PropInfo));
  1854. tkWString:
  1855. Result:=GetWideStrProp(Instance,PropInfo);
  1856. tkUString:
  1857. begin
  1858. case (PropInfo^.PropProcs) and 3 of
  1859. ptField:
  1860. Result := PUnicodeString(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1861. ptStatic,
  1862. ptVirtual:
  1863. begin
  1864. if (PropInfo^.PropProcs and 3)=ptStatic then
  1865. AMethod.Code:=PropInfo^.GetProc
  1866. else
  1867. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1868. AMethod.Data:=Instance;
  1869. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1870. Result:=TGetUnicodeStrProcIndex(AMethod)(PropInfo^.Index)
  1871. else
  1872. Result:=TGetUnicodeStrProc(AMethod)();
  1873. end;
  1874. end;
  1875. end;
  1876. end;
  1877. end;
  1878. Procedure SetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: UnicodeString);
  1879. type
  1880. TSetUnicodeStrProcIndex=procedure(index:longint;s:UnicodeString) of object;
  1881. TSetUnicodeStrProc=procedure(s:UnicodeString) of object;
  1882. var
  1883. AMethod : TMethod;
  1884. begin
  1885. case Propinfo^.PropType^.Kind of
  1886. tkSString,tkAString:
  1887. SetStrProp(Instance,PropInfo,AnsiString(Value));
  1888. tkWString:
  1889. SetWideStrProp(Instance,PropInfo,Value);
  1890. tkUString:
  1891. begin
  1892. case (PropInfo^.PropProcs shr 2) and 3 of
  1893. ptField:
  1894. PUnicodeString(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1895. ptStatic,
  1896. ptVirtual:
  1897. begin
  1898. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1899. AMethod.Code:=PropInfo^.SetProc
  1900. else
  1901. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1902. AMethod.Data:=Instance;
  1903. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1904. TSetUnicodeStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1905. else
  1906. TSetUnicodeStrProc(AMethod)(Value);
  1907. end;
  1908. end;
  1909. end;
  1910. end;
  1911. end;
  1912. function GetRawbyteStrProp(Instance: TObject; PropInfo: PPropInfo): RawByteString;
  1913. type
  1914. TGetRawByteStrProcIndex=function(index:longint): RawByteString of object;
  1915. TGetRawByteStrProc=function():RawByteString of object;
  1916. var
  1917. AMethod : TMethod;
  1918. begin
  1919. Result:='';
  1920. case Propinfo^.PropType^.Kind of
  1921. tkWString:
  1922. Result:=RawByteString(GetWideStrProp(Instance,PropInfo));
  1923. tkUString:
  1924. Result:=RawByteString(GetUnicodeStrProp(Instance,PropInfo));
  1925. tkSString:
  1926. Result:=RawByteString(GetStrProp(Instance,PropInfo));
  1927. tkAString:
  1928. begin
  1929. case (PropInfo^.PropProcs) and 3 of
  1930. ptField:
  1931. Result := PAnsiString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  1932. ptStatic,
  1933. ptVirtual:
  1934. begin
  1935. if (PropInfo^.PropProcs and 3)=ptStatic then
  1936. AMethod.Code:=PropInfo^.GetProc
  1937. else
  1938. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1939. AMethod.Data:=Instance;
  1940. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1941. Result:=TGetRawByteStrProcIndex(AMethod)(PropInfo^.Index)
  1942. else
  1943. Result:=TGetRawByteStrProc(AMethod)();
  1944. end;
  1945. end;
  1946. end;
  1947. end;
  1948. end;
  1949. function GetRawByteStrProp(Instance: TObject; const PropName: string): RawByteString;
  1950. begin
  1951. Result:=GetRawByteStrProp(Instance,FindPropInfo(Instance,PropName));
  1952. end;
  1953. procedure SetRawByteStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: RawByteString);
  1954. type
  1955. TSetRawByteStrProcIndex=procedure(index:longint;s:RawByteString) of object;
  1956. TSetRawByteStrProc=procedure(s:RawByteString) of object;
  1957. var
  1958. AMethod : TMethod;
  1959. begin
  1960. case Propinfo^.PropType^.Kind of
  1961. tkWString:
  1962. SetWideStrProp(Instance,PropInfo,WideString(Value));
  1963. tkUString:
  1964. SetUnicodeStrProp(Instance,PropInfo,UnicodeString(Value));
  1965. tkSString:
  1966. SetStrProp(Instance,PropInfo,Value); // Not 100% sure about this.
  1967. tkAString:
  1968. begin
  1969. case (PropInfo^.PropProcs shr 2) and 3 of
  1970. ptField:
  1971. PAnsiString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  1972. ptStatic,
  1973. ptVirtual:
  1974. begin
  1975. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1976. AMethod.Code:=PropInfo^.SetProc
  1977. else
  1978. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1979. AMethod.Data:=Instance;
  1980. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1981. TSetRawByteStrProcIndex(AMethod)(PropInfo^.Index,Value)
  1982. else
  1983. TSetRawByteStrProc(AMethod)(Value);
  1984. end;
  1985. end;
  1986. end;
  1987. end;
  1988. end;
  1989. procedure SetRawByteStrProp(Instance: TObject; const PropName: string; const Value: RawByteString);
  1990. begin
  1991. SetRawByteStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  1992. end;
  1993. {$ifndef FPUNONE}
  1994. { ---------------------------------------------------------------------
  1995. Float properties
  1996. ---------------------------------------------------------------------}
  1997. function GetFloatProp(Instance : TObject;PropInfo : PPropInfo) : Extended;
  1998. type
  1999. TGetExtendedProc = function:Extended of object;
  2000. TGetExtendedProcIndex = function(Index: integer): Extended of object;
  2001. TGetDoubleProc = function:Double of object;
  2002. TGetDoubleProcIndex = function(Index: integer): Double of object;
  2003. TGetSingleProc = function:Single of object;
  2004. TGetSingleProcIndex = function(Index: integer):Single of object;
  2005. TGetCurrencyProc = function : Currency of object;
  2006. TGetCurrencyProcIndex = function(Index: integer) : Currency of object;
  2007. var
  2008. AMethod : TMethod;
  2009. begin
  2010. Result:=0.0;
  2011. case PropInfo^.PropProcs and 3 of
  2012. ptField:
  2013. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  2014. ftSingle:
  2015. Result:=PSingle(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2016. ftDouble:
  2017. Result:=PDouble(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2018. ftExtended:
  2019. Result:=PExtended(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2020. ftcomp:
  2021. Result:=PComp(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2022. ftcurr:
  2023. Result:=PCurrency(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2024. end;
  2025. ptStatic,
  2026. ptVirtual:
  2027. begin
  2028. if (PropInfo^.PropProcs and 3)=ptStatic then
  2029. AMethod.Code:=PropInfo^.GetProc
  2030. else
  2031. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2032. AMethod.Data:=Instance;
  2033. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  2034. ftSingle:
  2035. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2036. Result:=TGetSingleProc(AMethod)()
  2037. else
  2038. Result:=TGetSingleProcIndex(AMethod)(PropInfo^.Index);
  2039. ftDouble:
  2040. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2041. Result:=TGetDoubleProc(AMethod)()
  2042. else
  2043. Result:=TGetDoubleProcIndex(AMethod)(PropInfo^.Index);
  2044. ftExtended:
  2045. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2046. Result:=TGetExtendedProc(AMethod)()
  2047. else
  2048. Result:=TGetExtendedProcIndex(AMethod)(PropInfo^.Index);
  2049. ftCurr:
  2050. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2051. Result:=TGetCurrencyProc(AMethod)()
  2052. else
  2053. Result:=TGetCurrencyProcIndex(AMethod)(PropInfo^.Index);
  2054. end;
  2055. end;
  2056. end;
  2057. end;
  2058. Procedure SetFloatProp(Instance : TObject;PropInfo : PPropInfo; Value : Extended);
  2059. type
  2060. TSetExtendedProc = procedure(const AValue: Extended) of object;
  2061. TSetExtendedProcIndex = procedure(Index: integer; AValue: Extended) of object;
  2062. TSetDoubleProc = procedure(const AValue: Double) of object;
  2063. TSetDoubleProcIndex = procedure(Index: integer; AValue: Double) of object;
  2064. TSetSingleProc = procedure(const AValue: Single) of object;
  2065. TSetSingleProcIndex = procedure(Index: integer; AValue: Single) of object;
  2066. TSetCurrencyProc = procedure(const AValue: Currency) of object;
  2067. TSetCurrencyProcIndex = procedure(Index: integer; AValue: Currency) of object;
  2068. Var
  2069. AMethod : TMethod;
  2070. begin
  2071. case (PropInfo^.PropProcs shr 2) and 3 of
  2072. ptfield:
  2073. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  2074. ftSingle:
  2075. PSingle(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2076. ftDouble:
  2077. PDouble(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2078. ftExtended:
  2079. PExtended(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2080. {$ifdef FPC_COMP_IS_INT64}
  2081. ftComp:
  2082. PComp(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=trunc(Value);
  2083. {$else FPC_COMP_IS_INT64}
  2084. ftComp:
  2085. PComp(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Comp(Value);
  2086. {$endif FPC_COMP_IS_INT64}
  2087. ftCurr:
  2088. PCurrency(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2089. end;
  2090. ptStatic,
  2091. ptVirtual:
  2092. begin
  2093. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2094. AMethod.Code:=PropInfo^.SetProc
  2095. else
  2096. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2097. AMethod.Data:=Instance;
  2098. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  2099. ftSingle:
  2100. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2101. TSetSingleProc(AMethod)(Value)
  2102. else
  2103. TSetSingleProcIndex(AMethod)(PropInfo^.Index,Value);
  2104. ftDouble:
  2105. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2106. TSetDoubleProc(AMethod)(Value)
  2107. else
  2108. TSetDoubleProcIndex(AMethod)(PropInfo^.Index,Value);
  2109. ftExtended:
  2110. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2111. TSetExtendedProc(AMethod)(Value)
  2112. else
  2113. TSetExtendedProcIndex(AMethod)(PropInfo^.Index,Value);
  2114. ftCurr:
  2115. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2116. TSetCurrencyProc(AMethod)(Value)
  2117. else
  2118. TSetCurrencyProcIndex(AMethod)(PropInfo^.Index,Value);
  2119. end;
  2120. end;
  2121. end;
  2122. end;
  2123. function GetFloatProp(Instance: TObject; const PropName: string): Extended;
  2124. begin
  2125. Result:=GetFloatProp(Instance,FindPropInfo(Instance,PropName))
  2126. end;
  2127. Procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Extended);
  2128. begin
  2129. SetFloatProp(Instance,FindPropInfo(Instance,PropName),Value);
  2130. end;
  2131. {$endif}
  2132. { ---------------------------------------------------------------------
  2133. Method properties
  2134. ---------------------------------------------------------------------}
  2135. Function GetMethodProp(Instance : TObject;PropInfo : PPropInfo) : TMethod;
  2136. type
  2137. TGetMethodProcIndex=function(Index: Longint): TMethod of object;
  2138. TGetMethodProc=function(): TMethod of object;
  2139. var
  2140. value: PMethod;
  2141. AMethod : TMethod;
  2142. begin
  2143. Result.Code:=nil;
  2144. Result.Data:=nil;
  2145. case (PropInfo^.PropProcs) and 3 of
  2146. ptField:
  2147. begin
  2148. Value:=PMethod(Pointer(Instance)+PtrUInt(PropInfo^.GetProc));
  2149. if Value<>nil then
  2150. Result:=Value^;
  2151. end;
  2152. ptStatic,
  2153. ptVirtual:
  2154. begin
  2155. if (PropInfo^.PropProcs and 3)=ptStatic then
  2156. AMethod.Code:=PropInfo^.GetProc
  2157. else
  2158. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2159. AMethod.Data:=Instance;
  2160. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2161. Result:=TGetMethodProcIndex(AMethod)(PropInfo^.Index)
  2162. else
  2163. Result:=TGetMethodProc(AMethod)();
  2164. end;
  2165. end;
  2166. end;
  2167. Procedure SetMethodProp(Instance : TObject;PropInfo : PPropInfo; const Value : TMethod);
  2168. type
  2169. TSetMethodProcIndex=procedure(index:longint;p:TMethod) of object;
  2170. TSetMethodProc=procedure(p:TMethod) of object;
  2171. var
  2172. AMethod : TMethod;
  2173. begin
  2174. case (PropInfo^.PropProcs shr 2) and 3 of
  2175. ptField:
  2176. PMethod(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^ := Value;
  2177. ptStatic,
  2178. ptVirtual:
  2179. begin
  2180. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2181. AMethod.Code:=PropInfo^.SetProc
  2182. else
  2183. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2184. AMethod.Data:=Instance;
  2185. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2186. TSetMethodProcIndex(AMethod)(PropInfo^.Index,Value)
  2187. else
  2188. TSetMethodProc(AMethod)(Value);
  2189. end;
  2190. end;
  2191. end;
  2192. Function GetMethodProp(Instance: TObject; const PropName: string): TMethod;
  2193. begin
  2194. Result:=GetMethodProp(Instance,FindPropInfo(Instance,PropName));
  2195. end;
  2196. Procedure SetMethodProp(Instance: TObject; const PropName: string; const Value: TMethod);
  2197. begin
  2198. SetMethodProp(Instance,FindPropInfo(Instance,PropName),Value);
  2199. end;
  2200. { ---------------------------------------------------------------------
  2201. Variant properties
  2202. ---------------------------------------------------------------------}
  2203. Procedure CheckVariantEvent(P : CodePointer);
  2204. begin
  2205. If (P=Nil) then
  2206. Raise Exception.Create(SErrNoVariantSupport);
  2207. end;
  2208. Function GetVariantProp(Instance : TObject;PropInfo : PPropInfo): Variant;
  2209. begin
  2210. CheckVariantEvent(CodePointer(OnGetVariantProp));
  2211. Result:=OnGetVariantProp(Instance,PropInfo);
  2212. end;
  2213. Procedure SetVariantProp(Instance : TObject;PropInfo : PPropInfo; const Value: Variant);
  2214. begin
  2215. CheckVariantEvent(CodePointer(OnSetVariantProp));
  2216. OnSetVariantProp(Instance,PropInfo,Value);
  2217. end;
  2218. Function GetVariantProp(Instance: TObject; const PropName: string): Variant;
  2219. begin
  2220. Result:=GetVariantProp(Instance,FindPropInfo(Instance,PropName));
  2221. end;
  2222. Procedure SetVariantProp(Instance: TObject; const PropName: string; const Value: Variant);
  2223. begin
  2224. SetVariantprop(instance,FindpropInfo(Instance,PropName),Value);
  2225. end;
  2226. { ---------------------------------------------------------------------
  2227. All properties through variant.
  2228. ---------------------------------------------------------------------}
  2229. Function GetPropValue(Instance: TObject; const PropName: string): Variant;
  2230. begin
  2231. Result := GetPropValue(Instance,FindPropInfo(Instance, PropName));
  2232. end;
  2233. Function GetPropValue(Instance: TObject; const PropName: string; PreferStrings: Boolean): Variant;
  2234. begin
  2235. Result := GetPropValue(Instance,FindPropInfo(Instance, PropName),PreferStrings);
  2236. end;
  2237. Function GetPropValue(Instance: TObject; PropInfo: PPropInfo): Variant;
  2238. begin
  2239. Result := GetPropValue(Instance, PropInfo, True);
  2240. end;
  2241. Function GetPropValue(Instance: TObject; PropInfo: PPropInfo; PreferStrings: Boolean): Variant;
  2242. begin
  2243. CheckVariantEvent(CodePointer(OnGetPropValue));
  2244. Result:=OnGetPropValue(Instance,PropInfo,PreferStrings);
  2245. end;
  2246. Procedure SetPropValue(Instance: TObject; const PropName: string; const Value: Variant);
  2247. begin
  2248. SetPropValue(Instance, FindPropInfo(Instance, PropName), Value);
  2249. end;
  2250. Procedure SetPropValue(Instance: TObject; PropInfo: PPropInfo; const Value: Variant);
  2251. begin
  2252. CheckVariantEvent(CodePointer(OnSetPropValue));
  2253. OnSetPropValue(Instance,PropInfo,Value);
  2254. end;
  2255. { ---------------------------------------------------------------------
  2256. Easy access methods that appeared in Delphi 5
  2257. ---------------------------------------------------------------------}
  2258. Function IsPublishedProp(Instance: TObject; const PropName: string): Boolean;
  2259. begin
  2260. Result:=GetPropInfo(Instance,PropName)<>Nil;
  2261. end;
  2262. Function IsPublishedProp(AClass: TClass; const PropName: string): Boolean;
  2263. begin
  2264. Result:=GetPropInfo(AClass,PropName)<>Nil;
  2265. end;
  2266. Function PropIsType(Instance: TObject; const PropName: string; TypeKind: TTypeKind): Boolean;
  2267. begin
  2268. Result:=PropType(Instance,PropName)=TypeKind
  2269. end;
  2270. Function PropIsType(AClass: TClass; const PropName: string; TypeKind: TTypeKind): Boolean;
  2271. begin
  2272. Result:=PropType(AClass,PropName)=TypeKind
  2273. end;
  2274. Function PropType(Instance: TObject; const PropName: string): TTypeKind;
  2275. begin
  2276. Result:=FindPropInfo(Instance,PropName)^.PropType^.Kind;
  2277. end;
  2278. Function PropType(AClass: TClass; const PropName: string): TTypeKind;
  2279. begin
  2280. Result:=FindPropInfo(AClass,PropName)^.PropType^.Kind;
  2281. end;
  2282. Function IsStoredProp(Instance: TObject; const PropName: string): Boolean;
  2283. begin
  2284. Result:=IsStoredProp(instance,FindPropInfo(Instance,PropName));
  2285. end;
  2286. { TParameterLocation }
  2287. function TParameterLocation.GetReference: Boolean;
  2288. begin
  2289. Result := (LocType and $80) <> 0;
  2290. end;
  2291. function TParameterLocation.GetRegType: TRegisterType;
  2292. begin
  2293. Result := TRegisterType(LocType and $7F);
  2294. end;
  2295. function TParameterLocation.GetShiftVal: Int8;
  2296. begin
  2297. if GetReference then begin
  2298. if Offset < Low(Int8) then
  2299. Result := Low(Int8)
  2300. else if Offset > High(Int8) then
  2301. Result := High(Int8)
  2302. else
  2303. Result := Offset;
  2304. end else
  2305. Result := 0;
  2306. end;
  2307. { TParameterLocations }
  2308. function TParameterLocations.GetLocation(aIndex: Byte): PParameterLocation;
  2309. begin
  2310. if aIndex >= Count then
  2311. Result := Nil
  2312. else
  2313. Result := PParameterLocation(PByte(aligntoptr(PByte(@Count) + SizeOf(Count))) + SizeOf(TParameterLocation) * aIndex);
  2314. end;
  2315. function TParameterLocations.GetTail: Pointer;
  2316. begin
  2317. Result := PByte(aligntoptr(PByte(@Count) + SizeOf(Count))) + SizeOf(TParameterLocation) * Count;
  2318. end;
  2319. { TProcedureParam }
  2320. function TProcedureParam.GetParamType: PTypeInfo;
  2321. begin
  2322. Result := DerefTypeInfoPtr(ParamTypeRef);
  2323. end;
  2324. function TProcedureParam.GetFlags: Byte;
  2325. begin
  2326. Result := PByte(@ParamFlags)^;
  2327. end;
  2328. { TManagedField }
  2329. function TManagedField.GetTypeRef: PTypeInfo;
  2330. begin
  2331. Result := DerefTypeInfoPtr(TypeRefRef);
  2332. end;
  2333. { TArrayTypeData }
  2334. function TArrayTypeData.GetElType: PTypeInfo;
  2335. begin
  2336. Result := DerefTypeInfoPtr(ElTypeRef);
  2337. end;
  2338. function TArrayTypeData.GetDims(aIndex: Byte): PTypeInfo;
  2339. begin
  2340. Result := DerefTypeInfoPtr(DimsRef[aIndex]);
  2341. end;
  2342. { TProcedureSignature }
  2343. function TProcedureSignature.GetResultType: PTypeInfo;
  2344. begin
  2345. Result := DerefTypeInfoPtr(ResultTypeRef);
  2346. end;
  2347. function TProcedureSignature.GetParam(ParamIndex: Integer): PProcedureParam;
  2348. begin
  2349. if (ParamIndex<0)or(ParamIndex>=ParamCount) then
  2350. Exit(nil);
  2351. Result := PProcedureParam(PByte(@Flags) + SizeOf(Self));
  2352. while ParamIndex > 0 do
  2353. begin
  2354. Result := PProcedureParam(aligntoptr((PByte(@Result^.Name) + (Length(Result^.Name) + 1) * SizeOf(AnsiChar))));
  2355. dec(ParamIndex);
  2356. end;
  2357. end;
  2358. { TVmtMethodParam }
  2359. function TVmtMethodParam.GetParaLocs: PParameterLocations;
  2360. begin
  2361. Result := PParameterLocations(aligntoptr(PByte(@Name[0]) + Length(Name) + Sizeof(Name[0])));
  2362. end;
  2363. function TVmtMethodParam.GetTail: Pointer;
  2364. begin
  2365. Result := ParaLocs^.Tail;
  2366. end;
  2367. function TVmtMethodParam.GetNext: PVmtMethodParam;
  2368. begin
  2369. Result := PVmtMethodParam(aligntoptr(Tail));
  2370. end;
  2371. { TIntfMethodEntry }
  2372. function TIntfMethodEntry.GetParam(Index: Word): PVmtMethodParam;
  2373. begin
  2374. if Index >= ParamCount then
  2375. Result := Nil
  2376. else
  2377. begin
  2378. Result := PVmtMethodParam(aligntoptr(PByte(@Name[0]) + SizeOf(Name[0]) + Length(Name)));
  2379. while Index > 0 do
  2380. begin
  2381. Result := Result^.Next;
  2382. Dec(Index);
  2383. end;
  2384. end;
  2385. end;
  2386. function TIntfMethodEntry.GetResultLocs: PParameterLocations;
  2387. begin
  2388. if not Assigned(ResultType) then
  2389. Result := Nil
  2390. else if ParamCount = 0 then
  2391. Result := PParameterLocations(aligntoptr(PByte(@Name[0]) + SizeOf(Name[0]) + Length(Name)))
  2392. else
  2393. Result := PParameterLocations(aligntoptr(Param[ParamCount - 1]^.Tail));
  2394. end;
  2395. function TIntfMethodEntry.GetTail: Pointer;
  2396. var
  2397. retloc: PParameterLocations;
  2398. begin
  2399. if Assigned(ResultType) then
  2400. begin
  2401. retloc := ResultLocs;
  2402. Result := PByte(@retloc^.Count) + SizeOf(retloc^.Count) + SizeOf(TParameterLocation) * retloc^.Count;
  2403. end
  2404. else if ParamCount = 0 then
  2405. Result := PByte(@Name[0]) + Length(Name) + SizeOf(Byte)
  2406. else
  2407. Result := Param[ParamCount - 1]^.Tail;
  2408. end;
  2409. function TIntfMethodEntry.GetNext: PIntfMethodEntry;
  2410. begin
  2411. Result := PIntfMethodEntry(aligntoptr(Tail));
  2412. end;
  2413. { TIntfMethodTable }
  2414. function TIntfMethodTable.GetMethod(Index: Word): PIntfMethodEntry;
  2415. begin
  2416. if (RTTICount = $FFFF) or (Index >= RTTICount) then
  2417. Result := Nil
  2418. else
  2419. begin
  2420. Result := aligntoptr(PIntfMethodEntry(PByte(@RTTICount) + SizeOf(RTTICount)));
  2421. while Index > 0 do
  2422. begin
  2423. Result := Result^.Next;
  2424. Dec(Index);
  2425. end;
  2426. end;
  2427. end;
  2428. { TInterfaceData }
  2429. function TInterfaceData.GetUnitName: ShortString;
  2430. begin
  2431. Result := UnitNameField;
  2432. end;
  2433. function TInterfaceData.GetPropertyTable: PPropData;
  2434. var
  2435. p: PByte;
  2436. begin
  2437. p := PByte(@UnitNameField[0]) + SizeOf(UnitNameField[0]) + Length(UnitNameField);
  2438. Result := AlignTypeData(p);
  2439. end;
  2440. function TInterfaceData.GetMethodTable: PIntfMethodTable;
  2441. begin
  2442. Result := aligntoptr(PropertyTable^.Tail);
  2443. end;
  2444. { TInterfaceRawData }
  2445. function TInterfaceRawData.GetUnitName: ShortString;
  2446. begin
  2447. Result := UnitNameField;
  2448. end;
  2449. function TInterfaceRawData.GetIIDStr: ShortString;
  2450. begin
  2451. Result := PShortString(AlignTypeData(PByte(@UnitNameField[0]) + SizeOf(UnitNameField[0]) + Length(UnitNameField)))^;
  2452. end;
  2453. function TInterfaceRawData.GetPropertyTable: PPropData;
  2454. var
  2455. p: PByte;
  2456. begin
  2457. p := AlignTypeData(PByte(@UnitNameField[0]) + SizeOf(UnitNameField[0]) + Length(UnitNameField));
  2458. p := p + SizeOf(p^) + p^;
  2459. Result := aligntoptr(p);
  2460. end;
  2461. function TInterfaceRawData.GetMethodTable: PIntfMethodTable;
  2462. begin
  2463. Result := aligntoptr(PropertyTable^.Tail);
  2464. end;
  2465. { TTypeData }
  2466. function TTypeData.GetBaseType: PTypeInfo;
  2467. begin
  2468. Result := DerefTypeInfoPtr(BaseTypeRef);
  2469. end;
  2470. function TTypeData.GetCompType: PTypeInfo;
  2471. begin
  2472. Result := DerefTypeInfoPtr(CompTypeRef);
  2473. end;
  2474. function TTypeData.GetParentInfo: PTypeInfo;
  2475. begin
  2476. Result := DerefTypeInfoPtr(ParentInfoRef);
  2477. end;
  2478. {$ifndef VER3_0}
  2479. function TTypeData.GetRecInitData: PRecInitData;
  2480. begin
  2481. Result := PRecInitData(aligntoptr(PTypeData(RecInitInfo+2+PByte(RecInitInfo+1)^)));
  2482. end;
  2483. {$endif}
  2484. function TTypeData.GetHelperParent: PTypeInfo;
  2485. begin
  2486. Result := DerefTypeInfoPtr(HelperParentRef);
  2487. end;
  2488. function TTypeData.GetExtendedInfo: PTypeInfo;
  2489. begin
  2490. Result := DerefTypeInfoPtr(ExtendedInfoRef);
  2491. end;
  2492. function TTypeData.GetIntfParent: PTypeInfo;
  2493. begin
  2494. Result := DerefTypeInfoPtr(IntfParentRef);
  2495. end;
  2496. function TTypeData.GetRawIntfParent: PTypeInfo;
  2497. begin
  2498. Result := DerefTypeInfoPtr(RawIntfParentRef);
  2499. end;
  2500. function TTypeData.GetIIDStr: ShortString;
  2501. begin
  2502. Result := PShortString(AlignTypeData(Pointer(@RawIntfUnit) + Length(RawIntfUnit) + 1))^;
  2503. end;
  2504. function TTypeData.GetElType: PTypeInfo;
  2505. begin
  2506. Result := DerefTypeInfoPtr(elTypeRef);
  2507. end;
  2508. function TTypeData.GetElType2: PTypeInfo;
  2509. begin
  2510. Result := DerefTypeInfoPtr(elType2Ref);
  2511. end;
  2512. function TTypeData.GetInstanceType: PTypeInfo;
  2513. begin
  2514. Result := DerefTypeInfoPtr(InstanceTypeRef);
  2515. end;
  2516. function TTypeData.GetRefType: PTypeInfo;
  2517. begin
  2518. Result := DerefTypeInfoPtr(RefTypeRef);
  2519. end;
  2520. { TPropData }
  2521. function TPropData.GetProp(Index: Word): PPropInfo;
  2522. begin
  2523. if Index >= PropCount then
  2524. Result := Nil
  2525. else
  2526. begin
  2527. Result := PPropInfo(aligntoptr(PByte(@PropCount) + SizeOf(PropCount)));
  2528. while Index > 0 do
  2529. begin
  2530. Result := aligntoptr(Result^.Tail);
  2531. Dec(Index);
  2532. end;
  2533. end;
  2534. end;
  2535. function TPropData.GetTail: Pointer;
  2536. begin
  2537. if PropCount = 0 then
  2538. Result := PByte(@PropCount) + SizeOf(PropCount)
  2539. else
  2540. Result := Prop[PropCount - 1]^.Tail;
  2541. end;
  2542. { TPropInfo }
  2543. function TPropInfo.GetPropType: PTypeInfo;
  2544. begin
  2545. Result := DerefTypeInfoPtr(PropTypeRef);
  2546. end;
  2547. function TPropInfo.GetTail: Pointer;
  2548. begin
  2549. Result := PByte(@Name[0]) + SizeOf(Name[0]) + Length(Name);
  2550. end;
  2551. function TPropInfo.GetNext: PPropInfo;
  2552. begin
  2553. Result := PPropInfo(aligntoptr(Tail));
  2554. end;
  2555. type
  2556. TElementAlias = record
  2557. Ordinal : Integer;
  2558. Alias : string;
  2559. end;
  2560. TElementAliasArray = Array of TElementAlias;
  2561. PElementAliasArray = ^TElementAliasArray;
  2562. TEnumeratedAliases = record
  2563. TypeInfo: PTypeInfo;
  2564. Aliases: TElementAliasArray;
  2565. end;
  2566. TEnumeratedAliasesArray = Array of TEnumeratedAliases;
  2567. Var
  2568. EnumeratedAliases : TEnumeratedAliasesArray;
  2569. Function IndexOfEnumeratedAliases(aTypeInfo : PTypeInfo) : integer;
  2570. begin
  2571. Result:=Length(EnumeratedAliases)-1;
  2572. while (Result>=0) and (EnumeratedAliases[Result].TypeInfo<>aTypeInfo) do
  2573. Dec(Result);
  2574. end;
  2575. Function GetEnumeratedAliases(aTypeInfo : PTypeInfo) : PElementAliasArray;
  2576. Var
  2577. I : integer;
  2578. begin
  2579. I:=IndexOfEnumeratedAliases(aTypeInfo);
  2580. if I=-1 then
  2581. Result:=Nil
  2582. else
  2583. Result:=@EnumeratedAliases[i].Aliases
  2584. end;
  2585. Function AddEnumeratedAliases(aTypeInfo : PTypeInfo) : PElementAliasArray;
  2586. Var
  2587. L : Integer;
  2588. begin
  2589. L:=Length(EnumeratedAliases);
  2590. SetLength(EnumeratedAliases,L+1);
  2591. EnumeratedAliases[L].TypeInfo:=aTypeInfo;
  2592. Result:=@EnumeratedAliases[L].Aliases;
  2593. end;
  2594. procedure RemoveEnumElementAliases(aTypeInfo: PTypeInfo);
  2595. Var
  2596. I,L : integer;
  2597. A : TEnumeratedAliases;
  2598. begin
  2599. I:=IndexOfEnumeratedAliases(aTypeInfo);
  2600. if I=-1 then
  2601. exit;
  2602. A:=EnumeratedAliases[i];
  2603. A.Aliases:=Nil;
  2604. A.TypeInfo:=Nil;
  2605. L:=Length(EnumeratedAliases)-1;
  2606. EnumeratedAliases[i]:=EnumeratedAliases[L];
  2607. EnumeratedAliases[L]:=A;
  2608. SetLength(EnumeratedAliases,L);
  2609. end;
  2610. Resourcestring
  2611. SErrNotAnEnumerated = 'Type information points to non-enumerated type';
  2612. SErrInvalidEnumeratedCount = 'Invalid number of enumerated values';
  2613. SErrDuplicateEnumerated = 'Duplicate alias for enumerated value';
  2614. procedure AddEnumElementAliases(aTypeInfo: PTypeInfo; const aNames: array of string; aStartValue: Integer = 0);
  2615. var
  2616. Aliases: PElementAliasArray;
  2617. A : TElementAliasArray;
  2618. L, I, J : Integer;
  2619. N : String;
  2620. PT : PTypeData;
  2621. begin
  2622. if (aTypeInfo^.Kind<>tkEnumeration) then
  2623. raise EArgumentException.Create(SErrNotAnEnumerated);
  2624. PT:=GetTypeData(aTypeInfo);
  2625. if (High(aNames)=-1) or ((aStartValue+High(aNames))> PT^.MaxValue) then
  2626. raise EArgumentException.Create(SErrInvalidEnumeratedCount);
  2627. Aliases:=GetEnumeratedAliases(aTypeInfo);
  2628. if (Aliases=Nil) then
  2629. Aliases:=AddEnumeratedAliases(aTypeInfo);
  2630. A:=Aliases^;
  2631. I:=0;
  2632. L:=Length(a);
  2633. SetLength(a,L+High(aNames)+1);
  2634. try
  2635. for N in aNames do
  2636. begin
  2637. for J:=0 to (L+I)-1 do
  2638. if SameText(N,A[J].Alias) then
  2639. raise EArgumentException.Create(SErrDuplicateEnumerated);
  2640. with A[L+I] do
  2641. begin
  2642. Ordinal:=aStartValue+I;
  2643. alias:=N;
  2644. end;
  2645. Inc(I);
  2646. end;
  2647. finally
  2648. // In case of exception, we need to correct the length.
  2649. if Length(A)<>I+L then
  2650. SetLength(A,I+L);
  2651. Aliases^:=A;
  2652. end;
  2653. end;
  2654. function GetEnumeratedAliasValue(aTypeInfo: PTypeInfo; const aName: string): Integer;
  2655. var
  2656. I : Integer;
  2657. Aliases: PElementAliasArray;
  2658. begin
  2659. Result:=-1;
  2660. Aliases:=GetEnumeratedAliases(aTypeInfo);
  2661. if (Aliases=Nil) then
  2662. Exit;
  2663. I:=Length(Aliases^)-1;
  2664. While (Result=-1) and (I>=0) do
  2665. begin
  2666. if SameText(Aliases^[I].Alias, aName) then
  2667. Result:=Aliases^[I].Ordinal;
  2668. Dec(I);
  2669. end;
  2670. end;
  2671. end.