typinfo.pp 105 KB

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