typinfo.pp 94 KB

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