typinfo.pp 110 KB

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