typinfo.pp 111 KB

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