typinfo.pp 108 KB

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