typinfo.pp 107 KB

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