typinfo.pp 82 KB

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