typinfo.pp 108 KB

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