typinfo.pp 101 KB

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