typinfo.pp 101 KB

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