typinfo.pp 110 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711
  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 SetToArray(TypeInfo: PTypeInfo; Value: Pointer) : TBytes;
  901. function SetToArray(PropInfo: PPropInfo; Value: Pointer) : TBytes;
  902. function SetToArray(TypeInfo: PTypeInfo; Value: LongInt) : TBytes;
  903. function SetToArray(PropInfo: PPropInfo; Value: LongInt) : TBytes;
  904. function SetToString(TypeInfo: PTypeInfo; Value: LongInt; Brackets: Boolean) : String;
  905. function SetToString(PropInfo: PPropInfo; Value: LongInt; Brackets: Boolean) : String;
  906. function SetToString(PropInfo: PPropInfo; Value: LongInt) : String;
  907. function SetToString(TypeInfo: PTypeInfo; Value: Pointer; Brackets: Boolean = False) : String;
  908. function SetToString(PropInfo: PPropInfo; Value: Pointer; Brackets: Boolean = False) : String;
  909. function ArrayToSet(PropInfo: PPropInfo; const Value: array of Byte): LongInt;
  910. function ArrayToSet(TypeInfo: PTypeInfo; const Value: array of Byte): LongInt;
  911. procedure ArrayToSet(PropInfo: PPropInfo; const Value: array of Byte; Result: Pointer);
  912. procedure ArrayToSet(TypeInfo: PTypeInfo; const Value: array of Byte; Result: Pointer);
  913. function StringToSet(PropInfo: PPropInfo; const Value: string): LongInt;
  914. function StringToSet(TypeInfo: PTypeInfo; const Value: string): LongInt;
  915. procedure StringToSet(PropInfo: PPropInfo; const Value: String; Result: Pointer);
  916. procedure StringToSet(TypeInfo: PTypeInfo; const Value: String; Result: Pointer);
  917. const
  918. BooleanIdents: array[Boolean] of String = ('False', 'True');
  919. DotSep: String = '.';
  920. Type
  921. EPropertyError = Class(Exception);
  922. TGetPropValue = Function (Instance: TObject; PropInfo: PPropInfo; PreferStrings: Boolean) : Variant;
  923. TSetPropValue = Procedure (Instance: TObject; PropInfo: PPropInfo; const Value: Variant);
  924. TGetVariantProp = Function (Instance: TObject; PropInfo : PPropInfo): Variant;
  925. TSetVariantProp = Procedure (Instance: TObject; PropInfo : PPropInfo; const Value: Variant);
  926. EPropertyConvertError = class(Exception); // Not used (yet), but defined for compatibility.
  927. Const
  928. OnGetPropValue : TGetPropValue = Nil;
  929. OnSetPropValue : TSetPropValue = Nil;
  930. OnGetVariantprop : TGetVariantProp = Nil;
  931. OnSetVariantprop : TSetVariantProp = Nil;
  932. { for inlining }
  933. function DerefTypeInfoPtr(Info: TypeInfoPtr): PTypeInfo; inline;
  934. Implementation
  935. uses rtlconsts;
  936. type
  937. PMethod = ^TMethod;
  938. { ---------------------------------------------------------------------
  939. Auxiliary methods
  940. ---------------------------------------------------------------------}
  941. function aligntoptr(p : pointer) : pointer;inline;
  942. begin
  943. {$ifdef CPUM68K}
  944. result:=AlignTypeData(p);
  945. {$else CPUM68K}
  946. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  947. result:=align(p,sizeof(p));
  948. {$else FPC_REQUIRES_PROPER_ALIGNMENT}
  949. result:=p;
  950. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  951. {$endif CPUM68K}
  952. end;
  953. function DerefTypeInfoPtr(Info: TypeInfoPtr): PTypeInfo; inline;
  954. begin
  955. {$ifdef ver3_0}
  956. Result := Info;
  957. {$else}
  958. if not Assigned(Info) then
  959. Result := Nil
  960. else
  961. Result := Info^;
  962. {$endif}
  963. end;
  964. function GetAttributeTable(TypeInfo: PTypeInfo): PAttributeTable;
  965. {$ifdef PROVIDE_ATTR_TABLE}
  966. var
  967. TD: PTypeData;
  968. begin
  969. TD := GetTypeData(TypeInfo);
  970. Result:=TD^.AttributeTable;
  971. {$else}
  972. begin
  973. Result:=Nil;
  974. {$endif}
  975. end;
  976. function GetPropData(TypeInfo : PTypeInfo; TypeData: PTypeData) : PPropData; inline;
  977. var
  978. p: PtrUInt;
  979. begin
  980. p := PtrUInt(@TypeData^.UnitName) + SizeOf(TypeData^.UnitName[0]) + Length(TypeData^.UnitName);
  981. Result := PPropData(aligntoptr(Pointer(p)));
  982. end;
  983. function GetAttribute(AttributeTable: PAttributeTable; AttributeNr: Word): TCustomAttribute;
  984. begin
  985. if (AttributeTable=nil) or (AttributeNr>=AttributeTable^.AttributeCount) then
  986. result := nil
  987. else
  988. begin
  989. result := AttributeTable^.AttributesList[AttributeNr].AttrProc();
  990. end;
  991. end;
  992. function GetPropAttribute(PropInfo: PPropInfo; AttributeNr: Word): TCustomAttribute;
  993. begin
  994. {$ifdef PROVIDE_ATTR_TABLE}
  995. Result := GetAttribute(PropInfo^.AttributeTable, AttributeNr);
  996. {$else}
  997. Result := Nil;
  998. {$endif}
  999. end;
  1000. Function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
  1001. Var PS : PShortString;
  1002. PT : PTypeData;
  1003. begin
  1004. PT:=GetTypeData(TypeInfo);
  1005. if TypeInfo^.Kind=tkBool then
  1006. begin
  1007. case Value of
  1008. 0,1:
  1009. Result:=BooleanIdents[Boolean(Value)];
  1010. else
  1011. Result:='';
  1012. end;
  1013. end
  1014. else
  1015. begin
  1016. PS:=@PT^.NameList;
  1017. dec(Value,PT^.MinValue);
  1018. While Value>0 Do
  1019. begin
  1020. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  1021. Dec(Value);
  1022. end;
  1023. Result:=PS^;
  1024. end;
  1025. end;
  1026. Function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
  1027. Var PS : PShortString;
  1028. PT : PTypeData;
  1029. Count : longint;
  1030. sName: shortstring;
  1031. begin
  1032. If Length(Name)=0 then
  1033. exit(-1);
  1034. sName := Name;
  1035. PT:=GetTypeData(TypeInfo);
  1036. Count:=0;
  1037. Result:=-1;
  1038. if TypeInfo^.Kind=tkBool then
  1039. begin
  1040. If CompareText(BooleanIdents[false],Name)=0 then
  1041. result:=0
  1042. else if CompareText(BooleanIdents[true],Name)=0 then
  1043. result:=1;
  1044. end
  1045. else
  1046. begin
  1047. PS:=@PT^.NameList;
  1048. While (Result=-1) and (PByte(PS)^<>0) do
  1049. begin
  1050. If ShortCompareText(PS^, sName) = 0 then
  1051. Result:=Count+PT^.MinValue;
  1052. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  1053. Inc(Count);
  1054. end;
  1055. if Result=-1 then
  1056. Result:=GetEnumeratedAliasValue(TypeInfo,Name);
  1057. end;
  1058. end;
  1059. function GetEnumNameCount(enum1: PTypeInfo): SizeInt;
  1060. var
  1061. PS: PShortString;
  1062. PT: PTypeData;
  1063. Count: SizeInt;
  1064. begin
  1065. PT:=GetTypeData(enum1);
  1066. if enum1^.Kind=tkBool then
  1067. Result:=2
  1068. else
  1069. begin
  1070. Count:=0;
  1071. Result:=0;
  1072. PS:=@PT^.NameList;
  1073. While (PByte(PS)^<>0) do
  1074. begin
  1075. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  1076. Inc(Count);
  1077. end;
  1078. { the last string is the unit name }
  1079. Result := Count - 1;
  1080. end;
  1081. end;
  1082. Function SetToString(PropInfo: PPropInfo; Value: LongInt; Brackets: Boolean) : String;
  1083. begin
  1084. Result:=SetToString(PropInfo^.PropType, Value, Brackets);
  1085. end;
  1086. Function SetToString(TypeInfo: PTypeInfo; Value: LongInt; Brackets: Boolean) : String;
  1087. begin
  1088. {$if defined(FPC_BIG_ENDIAN)}
  1089. { correctly adjust packed sets that are smaller than 32-bit }
  1090. case GetTypeData(TypeInfo)^.OrdType of
  1091. otSByte,otUByte: Value := Value shl (SizeOf(Integer)*8-8);
  1092. otSWord,otUWord: Value := Value shl (SizeOf(Integer)*8-16);
  1093. end;
  1094. {$endif}
  1095. Result := SetToString(TypeInfo, @Value, Brackets);
  1096. end;
  1097. function SetToString(TypeInfo: PTypeInfo; Value: Pointer; Brackets: Boolean): String;
  1098. var
  1099. A: TBytes;
  1100. B: Byte;
  1101. PTI : PTypeInfo;
  1102. begin
  1103. PTI:=GetTypeData(TypeInfo)^.CompType;
  1104. A:=SetToArray(TypeInfo, Value);
  1105. Result := '';
  1106. for B in A do
  1107. If Result='' then
  1108. Result:=GetEnumName(PTI,B)
  1109. else
  1110. Result:=Result+','+GetEnumName(PTI,B);
  1111. if Brackets then
  1112. Result:='['+Result+']';
  1113. end;
  1114. Function SetToString(PropInfo: PPropInfo; Value: LongInt) : String;
  1115. begin
  1116. Result:=SetToString(PropInfo,Value,False);
  1117. end;
  1118. function SetToString(PropInfo: PPropInfo; Value: Pointer; Brackets: Boolean): String;
  1119. begin
  1120. Result := SetToString(PropInfo^.PropType, Value, Brackets);
  1121. end;
  1122. function SetToArray(TypeInfo: PTypeInfo; Value: Pointer) : TBytes;
  1123. type
  1124. tsetarr = bitpacked array[0..SizeOf(LongInt)*8-1] of 0..1;
  1125. Var
  1126. I,El,Els,Rem,V,Max : Integer;
  1127. PTD : PTypeData;
  1128. ValueArr : PLongInt;
  1129. begin
  1130. PTD := GetTypeData(TypeInfo);
  1131. ValueArr := PLongInt(Value);
  1132. Result:=[];
  1133. {$ifdef ver3_0}
  1134. case PTD^.OrdType of
  1135. otSByte, otUByte: begin
  1136. Els := 0;
  1137. Rem := 1;
  1138. end;
  1139. otSWord, otUWord: begin
  1140. Els := 0;
  1141. Rem := 2;
  1142. end;
  1143. otSLong, otULong: begin
  1144. Els := 1;
  1145. Rem := 0;
  1146. end;
  1147. end;
  1148. {$else}
  1149. Els := PTD^.SetSize div SizeOf(LongInt);
  1150. Rem := PTD^.SetSize mod SizeOf(LongInt);
  1151. {$endif}
  1152. {$ifdef ver3_0}
  1153. El := 0;
  1154. {$else}
  1155. for El := 0 to (PTD^.SetSize - 1) div SizeOf(LongInt) do
  1156. {$endif}
  1157. begin
  1158. if El = Els then
  1159. Max := Rem
  1160. else
  1161. Max := SizeOf(LongInt);
  1162. For I:=0 to Max*8-1 do
  1163. begin
  1164. if (tsetarr(ValueArr[El])[i]<>0) then
  1165. begin
  1166. V := I + SizeOf(LongInt) * 8 * El;
  1167. SetLength(Result, Length(Result)+1);
  1168. Result[High(Result)]:=V;
  1169. end;
  1170. end;
  1171. end;
  1172. end;
  1173. function SetToArray(PropInfo: PPropInfo; Value: Pointer) : TBytes;
  1174. begin
  1175. Result:=SetToArray(PropInfo^.PropType,Value);
  1176. end;
  1177. function SetToArray(TypeInfo: PTypeInfo; Value: LongInt) : TBytes;
  1178. begin
  1179. Result:=SetToArray(TypeInfo,@Value);
  1180. end;
  1181. function SetToArray(PropInfo: PPropInfo; Value: LongInt) : TBytes;
  1182. begin
  1183. Result:=SetToArray(PropInfo^.PropType,@Value);
  1184. end;
  1185. Const
  1186. SetDelim = ['[',']',',',' '];
  1187. Function GetNextElement(Var S : String) : String;
  1188. Var
  1189. J : Integer;
  1190. begin
  1191. J:=1;
  1192. Result:='';
  1193. If Length(S)>0 then
  1194. begin
  1195. While (J<=Length(S)) and Not (S[j] in SetDelim) do
  1196. Inc(j);
  1197. Result:=Copy(S,1,j-1);
  1198. Delete(S,1,j);
  1199. end;
  1200. end;
  1201. Function StringToSet(PropInfo: PPropInfo; const Value: string): LongInt;
  1202. begin
  1203. Result:=StringToSet(PropInfo^.PropType,Value);
  1204. end;
  1205. Function StringToSet(TypeInfo: PTypeInfo; const Value: string): LongInt;
  1206. begin
  1207. StringToSet(TypeInfo, Value, @Result);
  1208. {$if defined(FPC_BIG_ENDIAN)}
  1209. { correctly adjust packed sets that are smaller than 32-bit }
  1210. case GetTypeData(TypeInfo)^.OrdType of
  1211. otSByte,otUByte: Result := Result shr (SizeOf(Integer)*8-8);
  1212. otSWord,otUWord: Result := Result shr (SizeOf(Integer)*8-16);
  1213. end;
  1214. {$endif}
  1215. end;
  1216. procedure StringToSet(TypeInfo: PTypeInfo; const Value: String; Result: Pointer);
  1217. Var
  1218. S,T : String;
  1219. I, ElOfs, BitOfs : Integer;
  1220. PTD: PTypeData;
  1221. PTI : PTypeInfo;
  1222. A: TBytes;
  1223. begin
  1224. PTD:=GetTypeData(TypeInfo);
  1225. PTI:=PTD^.Comptype;
  1226. S:=Value;
  1227. I:=1;
  1228. If Length(S)>0 then
  1229. begin
  1230. While (I<=Length(S)) and (S[i] in SetDelim) do
  1231. Inc(I);
  1232. Delete(S,1,i-1);
  1233. end;
  1234. A:=[];
  1235. While (S<>'') do
  1236. begin
  1237. T:=GetNextElement(S);
  1238. if T<>'' then
  1239. begin
  1240. I:=GetEnumValue(PTI,T);
  1241. if (I<0) then
  1242. raise EPropertyError.CreateFmt(SErrUnknownEnumValue, [T]);
  1243. SetLength(A, Length(A)+1);
  1244. A[High(A)]:=I;
  1245. end;
  1246. end;
  1247. ArrayToSet(TypeInfo,A,Result);
  1248. end;
  1249. procedure StringToSet(PropInfo: PPropInfo; const Value: String; Result: Pointer);
  1250. begin
  1251. StringToSet(PropInfo^.PropType, Value, Result);
  1252. end;
  1253. Function ArrayToSet(PropInfo: PPropInfo; const Value: array of Byte): LongInt;
  1254. begin
  1255. Result:=ArrayToSet(PropInfo^.PropType,Value);
  1256. end;
  1257. Function ArrayToSet(TypeInfo: PTypeInfo; const Value: array of Byte): LongInt;
  1258. begin
  1259. ArrayToSet(TypeInfo, Value, @Result);
  1260. {$if defined(FPC_BIG_ENDIAN)}
  1261. { correctly adjust packed sets that are smaller than 32-bit }
  1262. case GetTypeData(TypeInfo)^.OrdType of
  1263. otSByte,otUByte: Result := Result shr (SizeOf(Integer)*8-8);
  1264. otSWord,otUWord: Result := Result shr (SizeOf(Integer)*8-16);
  1265. end;
  1266. {$endif}
  1267. end;
  1268. procedure ArrayToSet(TypeInfo: PTypeInfo; const Value: array of Byte; Result: Pointer);
  1269. Var
  1270. ElOfs, BitOfs : Integer;
  1271. PTD: PTypeData;
  1272. ResArr: PLongWord;
  1273. B: Byte;
  1274. begin
  1275. PTD:=GetTypeData(TypeInfo);
  1276. {$ifndef ver3_0}
  1277. FillChar(Result^, PTD^.SetSize, 0);
  1278. {$else}
  1279. PInteger(Result)^ := 0;
  1280. {$endif}
  1281. ResArr := PLongWord(Result);
  1282. for B in Value do
  1283. begin
  1284. ElOfs := B shr 5;
  1285. BitOfs := B and $1F;
  1286. {$ifdef FPC_BIG_ENDIAN}
  1287. { on Big Endian systems enum values start from the MSB, thus we need
  1288. to reverse the shift }
  1289. BitOfs := 31 - BitOfs;
  1290. {$endif}
  1291. ResArr[ElOfs] := ResArr[ElOfs] or (LongInt(1) shl BitOfs);
  1292. end;
  1293. end;
  1294. procedure ArrayToSet(PropInfo: PPropInfo; const Value: array of Byte; Result: Pointer);
  1295. begin
  1296. ArrayToSet(PropInfo^.PropType, Value, Result);
  1297. end;
  1298. Function AlignTypeData(p : Pointer) : Pointer;
  1299. {$packrecords c}
  1300. type
  1301. TAlignCheck = record
  1302. b : byte;
  1303. q : qword;
  1304. end;
  1305. {$packrecords default}
  1306. begin
  1307. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  1308. {$ifdef VER3_0}
  1309. Result:=Pointer(align(p,SizeOf(Pointer)));
  1310. {$else VER3_0}
  1311. Result:=Pointer(align(p,PtrInt(@TAlignCheck(nil^).q)))
  1312. {$endif VER3_0}
  1313. {$else FPC_REQUIRES_PROPER_ALIGNMENT}
  1314. Result:=p;
  1315. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  1316. end;
  1317. Function AlignTParamFlags(p : Pointer) : Pointer; inline;
  1318. {$packrecords c}
  1319. type
  1320. TAlignCheck = record
  1321. b : byte;
  1322. w : word;
  1323. end;
  1324. {$packrecords default}
  1325. begin
  1326. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  1327. Result:=Pointer(align(p,PtrInt(@TAlignCheck(nil^).w)))
  1328. {$else FPC_REQUIRES_PROPER_ALIGNMENT}
  1329. Result:=p;
  1330. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  1331. end;
  1332. Function AlignPTypeInfo(p : Pointer) : Pointer; inline;
  1333. {$packrecords c}
  1334. type
  1335. TAlignCheck = record
  1336. b : byte;
  1337. p : pointer;
  1338. end;
  1339. {$packrecords default}
  1340. begin
  1341. {$ifdef FPC_REQUIRES_PROPER_ALIGNMENT}
  1342. Result:=Pointer(align(p,PtrInt(@TAlignCheck(nil^).p)))
  1343. {$else FPC_REQUIRES_PROPER_ALIGNMENT}
  1344. Result:=p;
  1345. {$endif FPC_REQUIRES_PROPER_ALIGNMENT}
  1346. end;
  1347. Function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
  1348. begin
  1349. GetTypeData:=AlignTypeData(pointer(TypeInfo)+2+PByte(pointer(TypeInfo)+1)^);
  1350. end;
  1351. { ---------------------------------------------------------------------
  1352. Basic Type information functions.
  1353. ---------------------------------------------------------------------}
  1354. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string) : PPropInfo;
  1355. var
  1356. hp : PTypeData;
  1357. i : longint;
  1358. p : shortstring;
  1359. pd : PPropData;
  1360. begin
  1361. P:=PropName; // avoid Ansi<->short conversion in a loop
  1362. while Assigned(TypeInfo) do
  1363. begin
  1364. // skip the name
  1365. hp:=GetTypeData(Typeinfo);
  1366. // the class info rtti the property rtti follows immediatly
  1367. pd := GetPropData(TypeInfo,hp);
  1368. Result:=PPropInfo(@pd^.PropList);
  1369. for i:=1 to pd^.PropCount do
  1370. begin
  1371. // found a property of that name ?
  1372. if ShortCompareText(Result^.Name, P) = 0 then
  1373. exit;
  1374. // skip to next property
  1375. Result:=PPropInfo(aligntoptr(pointer(@Result^.Name)+byte(Result^.Name[0])+1));
  1376. end;
  1377. // parent class
  1378. Typeinfo:=hp^.ParentInfo;
  1379. end;
  1380. Result:=Nil;
  1381. end;
  1382. Function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string; Akinds : TTypeKinds) : PPropInfo;
  1383. begin
  1384. Result:=GetPropInfo(TypeInfo,PropName);
  1385. If (Akinds<>[]) then
  1386. If (Result<>Nil) then
  1387. If Not (Result^.PropType^.Kind in AKinds) then
  1388. Result:=Nil;
  1389. end;
  1390. Function GetPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
  1391. begin
  1392. Result:=GetPropInfo(PTypeInfo(AClass.ClassInfo),PropName,AKinds);
  1393. end;
  1394. Function GetPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds) : PPropInfo;
  1395. begin
  1396. Result:=GetPropInfo(Instance.ClassType,PropName,AKinds);
  1397. end;
  1398. Function GetPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  1399. begin
  1400. Result:=GetPropInfo(Instance,PropName,[]);
  1401. end;
  1402. Function GetPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  1403. begin
  1404. Result:=GetPropInfo(AClass,PropName,[]);
  1405. end;
  1406. Function FindPropInfo(Instance: TObject; const PropName: string): PPropInfo;
  1407. begin
  1408. result:=GetPropInfo(Instance, PropName);
  1409. if Result=nil then
  1410. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  1411. end;
  1412. Function FindPropInfo(Instance: TObject; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  1413. begin
  1414. result:=GetPropInfo(Instance, PropName, AKinds);
  1415. if Result=nil then
  1416. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  1417. end;
  1418. Function FindPropInfo(AClass: TClass; const PropName: string): PPropInfo;
  1419. begin
  1420. result:=GetPropInfo(AClass, PropName);
  1421. if result=nil then
  1422. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  1423. end;
  1424. Function FindPropInfo(AClass: TClass; const PropName: string; AKinds: TTypeKinds): PPropInfo;
  1425. begin
  1426. result:=GetPropInfo(AClass, PropName, AKinds);
  1427. if result=nil then
  1428. Raise EPropertyError.CreateFmt(SErrPropertyNotFound, [PropName]);
  1429. end;
  1430. function IsReadableProp(PropInfo: PPropInfo): Boolean;
  1431. begin
  1432. Result:=(((PropInfo^.PropProcs) and 3) in [ptField,ptStatic,ptVirtual]);
  1433. end;
  1434. function IsReadableProp(Instance: TObject; const PropName: string): Boolean;
  1435. begin
  1436. Result:=IsReadableProp(FindPropInfo(Instance,PropName));
  1437. end;
  1438. function IsReadableProp(AClass: TClass; const PropName: string): Boolean;
  1439. begin
  1440. Result:=IsReadableProp(FindPropInfo(AClass,PropName));
  1441. end;
  1442. function IsWriteableProp(PropInfo: PPropInfo): Boolean;
  1443. begin
  1444. Result:=(((PropInfo^.PropProcs shr 2) and 3) in [ptField,ptStatic,ptVirtual]);
  1445. end;
  1446. function IsWriteableProp(Instance: TObject; const PropName: string): Boolean;
  1447. begin
  1448. Result:=IsWriteableProp(FindPropInfo(Instance,PropName));
  1449. end;
  1450. function IsWriteableProp(AClass: TClass; const PropName: string): Boolean;
  1451. begin
  1452. Result:=IsWriteableProp(FindPropInfo(AClass,PropName));
  1453. end;
  1454. Function IsStoredProp(Instance : TObject;PropInfo : PPropInfo) : Boolean;
  1455. type
  1456. TBooleanIndexFunc=function(Index:integer):boolean of object;
  1457. TBooleanFunc=function:boolean of object;
  1458. var
  1459. AMethod : TMethod;
  1460. begin
  1461. case (PropInfo^.PropProcs shr 4) and 3 of
  1462. ptField:
  1463. Result:=PBoolean(Pointer(Instance)+PtrUInt(PropInfo^.StoredProc))^;
  1464. ptConst:
  1465. Result:=LongBool(PropInfo^.StoredProc);
  1466. ptStatic,
  1467. ptVirtual:
  1468. begin
  1469. if (PropInfo^.PropProcs shr 4) and 3=ptstatic then
  1470. AMethod.Code:=PropInfo^.StoredProc
  1471. else
  1472. AMethod.Code:=pcodepointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.StoredProc))^;
  1473. AMethod.Data:=Instance;
  1474. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1475. Result:=TBooleanIndexFunc(AMethod)(PropInfo^.Index)
  1476. else
  1477. Result:=TBooleanFunc(AMethod)();
  1478. end;
  1479. end;
  1480. end;
  1481. Procedure GetPropInfos(TypeInfo : PTypeInfo;PropList : PPropList);
  1482. {
  1483. Store Pointers to property information in the list pointed
  1484. to by proplist. PRopList must contain enough space to hold ALL
  1485. properties.
  1486. }
  1487. Var
  1488. TD : PTypeData;
  1489. TP : PPropInfo;
  1490. Count : Longint;
  1491. begin
  1492. // Get this objects TOTAL published properties count
  1493. TD:=GetTypeData(TypeInfo);
  1494. // Clear list
  1495. FillChar(PropList^,TD^.PropCount*sizeof(Pointer),0);
  1496. repeat
  1497. TD:=GetTypeData(TypeInfo);
  1498. // published properties count for this object
  1499. TP:=PPropInfo(GetPropData(TypeInfo, TD));
  1500. Count:=PWord(TP)^;
  1501. // Now point TP to first propinfo record.
  1502. Inc(Pointer(TP),SizeOF(Word));
  1503. tp:=aligntoptr(tp);
  1504. While Count>0 do
  1505. begin
  1506. // Don't overwrite properties with the same name
  1507. if PropList^[TP^.NameIndex]=nil then
  1508. PropList^[TP^.NameIndex]:=TP;
  1509. // Point to TP next propinfo record.
  1510. // Located at Name[Length(Name)+1] !
  1511. TP:=aligntoptr(PPropInfo(pointer(@TP^.Name)+PByte(@TP^.Name)^+1));
  1512. Dec(Count);
  1513. end;
  1514. TypeInfo:=TD^.Parentinfo;
  1515. until TypeInfo=nil;
  1516. end;
  1517. Procedure InsertProp (PL : PProplist;PI : PPropInfo; Count : longint);
  1518. Var
  1519. I : Longint;
  1520. begin
  1521. I:=0;
  1522. While (I<Count) and (PI^.Name>PL^[I]^.Name) do
  1523. Inc(I);
  1524. If I<Count then
  1525. Move(PL^[I], PL^[I+1], (Count - I) * SizeOf(Pointer));
  1526. PL^[I]:=PI;
  1527. end;
  1528. Procedure InsertPropnosort (PL : PProplist;PI : PPropInfo; Count : longint);
  1529. begin
  1530. PL^[Count]:=PI;
  1531. end;
  1532. Type TInsertProp = Procedure (PL : PProplist;PI : PPropInfo; Count : longint);
  1533. //Const InsertProps : array[false..boolean] of TInsertProp = (InsertPropNoSort,InsertProp);
  1534. Function GetPropList(TypeInfo : PTypeInfo;TypeKinds : TTypeKinds; PropList : PPropList;Sorted : boolean = true):longint;
  1535. {
  1536. Store Pointers to property information OF A CERTAIN KIND in the list pointed
  1537. to by proplist. PRopList must contain enough space to hold ALL
  1538. properties.
  1539. }
  1540. Var
  1541. TempList : PPropList;
  1542. PropInfo : PPropinfo;
  1543. I,Count : longint;
  1544. DoInsertProp : TInsertProp;
  1545. begin
  1546. if sorted then
  1547. DoInsertProp:=@InsertProp
  1548. else
  1549. DoInsertProp:=@InsertPropnosort;
  1550. Result:=0;
  1551. Count:=GetTypeData(TypeInfo)^.Propcount;
  1552. If Count>0 then
  1553. begin
  1554. GetMem(TempList,Count*SizeOf(Pointer));
  1555. Try
  1556. GetPropInfos(TypeInfo,TempList);
  1557. For I:=0 to Count-1 do
  1558. begin
  1559. PropInfo:=TempList^[i];
  1560. If PropInfo^.PropType^.Kind in TypeKinds then
  1561. begin
  1562. If (PropList<>Nil) then
  1563. DoInsertProp(PropList,PropInfo,Result);
  1564. Inc(Result);
  1565. end;
  1566. end;
  1567. finally
  1568. FreeMem(TempList,Count*SizeOf(Pointer));
  1569. end;
  1570. end;
  1571. end;
  1572. Function GetPropList(TypeInfo: PTypeInfo; out PropList: PPropList): SizeInt;
  1573. begin
  1574. result:=GetTypeData(TypeInfo)^.Propcount;
  1575. if result>0 then
  1576. begin
  1577. getmem(PropList,result*sizeof(pointer));
  1578. GetPropInfos(TypeInfo,PropList);
  1579. end
  1580. else
  1581. PropList:=Nil;
  1582. end;
  1583. function GetPropList(AClass: TClass; out PropList: PPropList): Integer;
  1584. begin
  1585. Result := GetPropList(PTypeInfo(AClass.ClassInfo), PropList);
  1586. end;
  1587. function GetPropList(Instance: TObject; out PropList: PPropList): Integer;
  1588. begin
  1589. Result := GetPropList(Instance.ClassType, PropList);
  1590. end;
  1591. { ---------------------------------------------------------------------
  1592. Property access functions
  1593. ---------------------------------------------------------------------}
  1594. { ---------------------------------------------------------------------
  1595. Ordinal properties
  1596. ---------------------------------------------------------------------}
  1597. Function GetOrdProp(Instance : TObject;PropInfo : PPropInfo) : Int64;
  1598. type
  1599. TGetInt64ProcIndex=function(index:longint):Int64 of object;
  1600. TGetInt64Proc=function():Int64 of object;
  1601. TGetIntegerProcIndex=function(index:longint):longint of object;
  1602. TGetIntegerProc=function:longint of object;
  1603. TGetWordProcIndex=function(index:longint):word of object;
  1604. TGetWordProc=function:word of object;
  1605. TGetByteProcIndex=function(index:longint):Byte of object;
  1606. TGetByteProc=function:Byte of object;
  1607. var
  1608. TypeInfo: PTypeInfo;
  1609. AMethod : TMethod;
  1610. DataSize: Integer;
  1611. OrdType: TOrdType;
  1612. Signed: Boolean;
  1613. begin
  1614. Result:=0;
  1615. TypeInfo := PropInfo^.PropType;
  1616. Signed := false;
  1617. DataSize := 4;
  1618. case TypeInfo^.Kind of
  1619. // We keep this for backwards compatibility, but internally it is no longer used.
  1620. {$ifdef cpu64}
  1621. tkInterface,
  1622. tkInterfaceRaw,
  1623. tkDynArray,
  1624. tkClass:
  1625. DataSize:=8;
  1626. {$endif cpu64}
  1627. tkChar, tkBool:
  1628. DataSize:=1;
  1629. tkWChar:
  1630. DataSize:=2;
  1631. tkSet,
  1632. tkEnumeration,
  1633. tkInteger:
  1634. begin
  1635. OrdType:=GetTypeData(TypeInfo)^.OrdType;
  1636. case OrdType of
  1637. otSByte,otUByte: DataSize := 1;
  1638. otSWord,otUWord: DataSize := 2;
  1639. end;
  1640. Signed := OrdType in [otSByte,otSWord,otSLong];
  1641. end;
  1642. tkInt64 :
  1643. begin
  1644. DataSize:=8;
  1645. Signed:=true;
  1646. end;
  1647. tkQword :
  1648. begin
  1649. DataSize:=8;
  1650. Signed:=false;
  1651. end;
  1652. end;
  1653. case (PropInfo^.PropProcs) and 3 of
  1654. ptField:
  1655. if Signed then begin
  1656. case DataSize of
  1657. 1: Result:=PShortInt(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1658. 2: Result:=PSmallInt(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1659. 4: Result:=PLongint(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1660. 8: Result:=PInt64(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1661. end;
  1662. end else begin
  1663. case DataSize of
  1664. 1: Result:=PByte(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1665. 2: Result:=PWord(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1666. 4: Result:=PLongint(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1667. 8: Result:=PInt64(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  1668. end;
  1669. end;
  1670. ptStatic,
  1671. ptVirtual:
  1672. begin
  1673. if (PropInfo^.PropProcs and 3)=ptStatic then
  1674. AMethod.Code:=PropInfo^.GetProc
  1675. else
  1676. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1677. AMethod.Data:=Instance;
  1678. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then begin
  1679. case DataSize of
  1680. 1: Result:=TGetByteProcIndex(AMethod)(PropInfo^.Index);
  1681. 2: Result:=TGetWordProcIndex(AMethod)(PropInfo^.Index);
  1682. 4: Result:=TGetIntegerProcIndex(AMethod)(PropInfo^.Index);
  1683. 8: result:=TGetInt64ProcIndex(AMethod)(PropInfo^.Index)
  1684. end;
  1685. end else begin
  1686. case DataSize of
  1687. 1: Result:=TGetByteProc(AMethod)();
  1688. 2: Result:=TGetWordProc(AMethod)();
  1689. 4: Result:=TGetIntegerProc(AMethod)();
  1690. 8: result:=TGetInt64Proc(AMethod)();
  1691. end;
  1692. end;
  1693. if Signed then begin
  1694. case DataSize of
  1695. 1: Result:=ShortInt(Result);
  1696. 2: Result:=SmallInt(Result);
  1697. end;
  1698. end;
  1699. end;
  1700. else
  1701. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  1702. end;
  1703. end;
  1704. Procedure SetOrdProp(Instance : TObject;PropInfo : PPropInfo;Value : Int64);
  1705. type
  1706. TSetInt64ProcIndex=procedure(index:longint;i:Int64) of object;
  1707. TSetInt64Proc=procedure(i:Int64) of object;
  1708. TSetIntegerProcIndex=procedure(index,i:longint) of object;
  1709. TSetIntegerProc=procedure(i:longint) of object;
  1710. var
  1711. DataSize: Integer;
  1712. AMethod : TMethod;
  1713. begin
  1714. if PropInfo^.PropType^.Kind in [tkInt64,tkQword
  1715. { why do we have to handle classes here, see also below? (FK) }
  1716. {$ifdef cpu64}
  1717. ,tkInterface
  1718. ,tkInterfaceRaw
  1719. ,tkDynArray
  1720. ,tkClass
  1721. {$endif cpu64}
  1722. ] then
  1723. DataSize := 8
  1724. else
  1725. DataSize := 4;
  1726. if not(PropInfo^.PropType^.Kind in [tkInt64,tkQword,tkClass,tkInterface,tkInterfaceRaw,tkDynArray]) then
  1727. begin
  1728. { cut off unnecessary stuff }
  1729. case GetTypeData(PropInfo^.PropType)^.OrdType of
  1730. otSWord,otUWord:
  1731. begin
  1732. Value:=Value and $ffff;
  1733. DataSize := 2;
  1734. end;
  1735. otSByte,otUByte:
  1736. begin
  1737. Value:=Value and $ff;
  1738. DataSize := 1;
  1739. end;
  1740. end;
  1741. end;
  1742. case (PropInfo^.PropProcs shr 2) and 3 of
  1743. ptField:
  1744. case DataSize of
  1745. 1: PByte(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Byte(Value);
  1746. 2: PWord(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Word(Value);
  1747. 4: PLongint(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Longint(Value);
  1748. 8: PInt64(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1749. end;
  1750. ptStatic,
  1751. ptVirtual:
  1752. begin
  1753. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1754. AMethod.Code:=PropInfo^.SetProc
  1755. else
  1756. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1757. AMethod.Data:=Instance;
  1758. if datasize=8 then
  1759. begin
  1760. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1761. TSetInt64ProcIndex(AMethod)(PropInfo^.Index,Value)
  1762. else
  1763. TSetInt64Proc(AMethod)(Value);
  1764. end
  1765. else
  1766. begin
  1767. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1768. TSetIntegerProcIndex(AMethod)(PropInfo^.Index,Value)
  1769. else
  1770. TSetIntegerProc(AMethod)(Value);
  1771. end;
  1772. end;
  1773. else
  1774. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  1775. end;
  1776. end;
  1777. Function GetOrdProp(Instance: TObject; const PropName: string): Int64;
  1778. begin
  1779. Result:=GetOrdProp(Instance,FindPropInfo(Instance,PropName));
  1780. end;
  1781. Procedure SetOrdProp(Instance: TObject; const PropName: string; Value: Int64);
  1782. begin
  1783. SetOrdProp(Instance,FindPropInfo(Instance,PropName),Value);
  1784. end;
  1785. Function GetEnumProp(Instance: TObject; Const PropInfo: PPropInfo): string;
  1786. begin
  1787. Result:=GetEnumName(PropInfo^.PropType, GetOrdProp(Instance, PropInfo));
  1788. end;
  1789. Function GetEnumProp(Instance: TObject; const PropName: string): string;
  1790. begin
  1791. Result:=GetEnumProp(Instance,FindPropInfo(Instance,PropName));
  1792. end;
  1793. Procedure SetEnumProp(Instance: TObject; const PropName: string; const Value: string);
  1794. begin
  1795. SetEnumProp(Instance,FindPropInfo(Instance,PropName),Value);
  1796. end;
  1797. Procedure SetEnumProp(Instance: TObject; Const PropInfo : PPropInfo; const Value: string);
  1798. Var
  1799. PV : Longint;
  1800. begin
  1801. If PropInfo<>Nil then
  1802. begin
  1803. PV:=GetEnumValue(PropInfo^.PropType, Value);
  1804. if (PV<0) then
  1805. raise EPropertyError.CreateFmt(SErrUnknownEnumValue, [Value]);
  1806. SetOrdProp(Instance, PropInfo,PV);
  1807. end;
  1808. end;
  1809. { ---------------------------------------------------------------------
  1810. Int64 wrappers
  1811. ---------------------------------------------------------------------}
  1812. Function GetInt64Prop(Instance: TObject; PropInfo: PPropInfo): Int64;
  1813. begin
  1814. Result:=GetOrdProp(Instance,PropInfo);
  1815. end;
  1816. procedure SetInt64Prop(Instance: TObject; PropInfo: PPropInfo; const Value: Int64);
  1817. begin
  1818. SetOrdProp(Instance,PropInfo,Value);
  1819. end;
  1820. Function GetInt64Prop(Instance: TObject; const PropName: string): Int64;
  1821. begin
  1822. Result:=GetInt64Prop(Instance,FindPropInfo(Instance,PropName));
  1823. end;
  1824. Procedure SetInt64Prop(Instance: TObject; const PropName: string; const Value: Int64);
  1825. begin
  1826. SetInt64Prop(Instance,FindPropInfo(Instance,PropName),Value);
  1827. end;
  1828. { ---------------------------------------------------------------------
  1829. Set properties
  1830. ---------------------------------------------------------------------}
  1831. Function GetSetProp(Instance: TObject; const PropName: string): string;
  1832. begin
  1833. Result:=GetSetProp(Instance,PropName,False);
  1834. end;
  1835. Function GetSetProp(Instance: TObject; const PropName: string; Brackets: Boolean): string;
  1836. begin
  1837. Result:=GetSetProp(Instance,FindPropInfo(Instance,PropName),Brackets);
  1838. end;
  1839. Function GetSetProp(Instance: TObject; const PropInfo: PPropInfo; Brackets: Boolean): string;
  1840. begin
  1841. Result:=SetToString(PropInfo,GetOrdProp(Instance,PropInfo),Brackets);
  1842. end;
  1843. Procedure SetSetProp(Instance: TObject; const PropName: string; const Value: string);
  1844. begin
  1845. SetSetProp(Instance,FindPropInfo(Instance,PropName),Value);
  1846. end;
  1847. Procedure SetSetProp(Instance: TObject; const PropInfo: PPropInfo; const Value: string);
  1848. begin
  1849. SetOrdProp(Instance,PropInfo,StringToSet(PropInfo,Value));
  1850. end;
  1851. { ---------------------------------------------------------------------
  1852. Pointer properties - internal only
  1853. ---------------------------------------------------------------------}
  1854. Function GetPointerProp(Instance: TObject; PropInfo : PPropInfo): Pointer;
  1855. Type
  1856. TGetPointerProcIndex = function (index:longint): Pointer of object;
  1857. TGetPointerProc = function (): Pointer of object;
  1858. var
  1859. AMethod : TMethod;
  1860. begin
  1861. case (PropInfo^.PropProcs) and 3 of
  1862. ptField:
  1863. Result := PPointer(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  1864. ptStatic,
  1865. ptVirtual:
  1866. begin
  1867. if (PropInfo^.PropProcs and 3)=ptStatic then
  1868. AMethod.Code:=PropInfo^.GetProc
  1869. else
  1870. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1871. AMethod.Data:=Instance;
  1872. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1873. Result:=TGetPointerProcIndex(AMethod)(PropInfo^.Index)
  1874. else
  1875. Result:=TGetPointerProc(AMethod)();
  1876. end;
  1877. else
  1878. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  1879. end;
  1880. end;
  1881. Procedure SetPointerProp(Instance: TObject; PropInfo : PPropInfo; Value: Pointer);
  1882. type
  1883. TSetPointerProcIndex = procedure(index: longint; p: pointer) of object;
  1884. TSetPointerProc = procedure(p: pointer) of object;
  1885. var
  1886. AMethod : TMethod;
  1887. begin
  1888. case (PropInfo^.PropProcs shr 2) and 3 of
  1889. ptField:
  1890. PPointer(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  1891. ptStatic,
  1892. ptVirtual:
  1893. begin
  1894. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  1895. AMethod.Code:=PropInfo^.SetProc
  1896. else
  1897. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  1898. AMethod.Data:=Instance;
  1899. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1900. TSetPointerProcIndex(AMethod)(PropInfo^.Index,Value)
  1901. else
  1902. TSetPointerProc(AMethod)(Value);
  1903. end;
  1904. else
  1905. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  1906. end;
  1907. end;
  1908. { ---------------------------------------------------------------------
  1909. Object properties
  1910. ---------------------------------------------------------------------}
  1911. Function GetObjectProp(Instance: TObject; const PropName: string): TObject;
  1912. begin
  1913. Result:=GetObjectProp(Instance,PropName,Nil);
  1914. end;
  1915. Function GetObjectProp(Instance: TObject; const PropName: string; MinClass: TClass): TObject;
  1916. begin
  1917. Result:=GetObjectProp(Instance,FindPropInfo(Instance,PropName),MinClass);
  1918. end;
  1919. Function GetObjectProp(Instance: TObject; PropInfo : PPropInfo): TObject;
  1920. begin
  1921. Result:=GetObjectProp(Instance,PropInfo,Nil);
  1922. end;
  1923. Function GetObjectProp(Instance: TObject; PropInfo : PPropInfo; MinClass: TClass): TObject;
  1924. begin
  1925. Result:=TObject(GetPointerProp(Instance,PropInfo));
  1926. If (MinClass<>Nil) and (Result<>Nil) Then
  1927. If Not Result.InheritsFrom(MinClass) then
  1928. Result:=Nil;
  1929. end;
  1930. Procedure SetObjectProp(Instance: TObject; const PropName: string; Value: TObject);
  1931. begin
  1932. SetObjectProp(Instance,FindPropInfo(Instance,PropName),Value);
  1933. end;
  1934. Procedure SetObjectProp(Instance: TObject; PropInfo : PPropInfo; Value: TObject);
  1935. begin
  1936. SetPointerProp(Instance,PropInfo,Pointer(Value));
  1937. end;
  1938. Function GetObjectPropClass(Instance: TObject; const PropName: string): TClass;
  1939. begin
  1940. Result:=GetTypeData(FindPropInfo(Instance,PropName,[tkClass])^.PropType)^.ClassType;
  1941. end;
  1942. Function GetObjectPropClass(AClass: TClass; const PropName: string): TClass;
  1943. begin
  1944. Result:=GetTypeData(FindPropInfo(AClass,PropName,[tkClass])^.PropType)^.ClassType;
  1945. end;
  1946. { ---------------------------------------------------------------------
  1947. Interface wrapprers
  1948. ---------------------------------------------------------------------}
  1949. function GetInterfaceProp(Instance: TObject; const PropName: string): IInterface;
  1950. begin
  1951. Result:=GetInterfaceProp(Instance,FindPropInfo(Instance,PropName));
  1952. end;
  1953. function GetInterfaceProp(Instance: TObject; PropInfo: PPropInfo): IInterface;
  1954. type
  1955. TGetInterfaceProc=function:IInterface of object;
  1956. TGetInterfaceProcIndex=function(index:longint):IInterface of object;
  1957. var
  1958. AMethod : TMethod;
  1959. begin
  1960. Result:=nil;
  1961. case (PropInfo^.PropProcs) and 3 of
  1962. ptField:
  1963. Result:=IInterface(PPointer(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^);
  1964. ptStatic,
  1965. ptVirtual:
  1966. begin
  1967. if (PropInfo^.PropProcs and 3)=ptStatic then
  1968. AMethod.Code:=PropInfo^.GetProc
  1969. else
  1970. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  1971. AMethod.Data:=Instance;
  1972. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  1973. Result:=TGetInterfaceProcIndex(AMethod)(PropInfo^.Index)
  1974. else
  1975. Result:=TGetInterfaceProc(AMethod)();
  1976. end;
  1977. else
  1978. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  1979. end;
  1980. end;
  1981. procedure SetInterfaceProp(Instance: TObject; const PropName: string; const Value: IInterface);
  1982. begin
  1983. SetInterfaceProp(Instance,FindPropInfo(Instance,PropName),Value);
  1984. end;
  1985. procedure SetInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: IInterface);
  1986. type
  1987. TSetIntfStrProcIndex=procedure(index:longint;const i:IInterface) of object;
  1988. TSetIntfStrProc=procedure(i:IInterface) of object;
  1989. var
  1990. AMethod : TMethod;
  1991. begin
  1992. case Propinfo^.PropType^.Kind of
  1993. tkInterface:
  1994. begin
  1995. case (PropInfo^.PropProcs shr 2) and 3 of
  1996. ptField:
  1997. PInterface(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  1998. ptStatic,
  1999. ptVirtual:
  2000. begin
  2001. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2002. AMethod.Code:=PropInfo^.SetProc
  2003. else
  2004. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2005. AMethod.Data:=Instance;
  2006. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2007. TSetIntfStrProcIndex(AMethod)(PropInfo^.Index,Value)
  2008. else
  2009. TSetIntfStrProc(AMethod)(Value);
  2010. end;
  2011. else
  2012. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2013. end;
  2014. end;
  2015. tkInterfaceRaw:
  2016. Raise Exception.Create('Cannot set RAW interface from IUnknown interface');
  2017. end;
  2018. end;
  2019. { ---------------------------------------------------------------------
  2020. RAW (Corba) Interface wrapprers
  2021. ---------------------------------------------------------------------}
  2022. function GetRawInterfaceProp(Instance: TObject; const PropName: string): Pointer;
  2023. begin
  2024. Result:=GetRawInterfaceProp(Instance,FindPropInfo(Instance,PropName));
  2025. end;
  2026. function GetRawInterfaceProp(Instance: TObject; PropInfo: PPropInfo): Pointer;
  2027. begin
  2028. Result:=GetPointerProp(Instance,PropInfo);
  2029. end;
  2030. procedure SetRawInterfaceProp(Instance: TObject; const PropName: string; const Value: Pointer);
  2031. begin
  2032. SetRawInterfaceProp(Instance,FindPropInfo(Instance,PropName),Value);
  2033. end;
  2034. procedure SetRawInterfaceProp(Instance: TObject; PropInfo: PPropInfo; const Value: Pointer);
  2035. begin
  2036. SetPointerProp(Instance,PropInfo,Value);
  2037. end;
  2038. { ---------------------------------------------------------------------
  2039. Dynamic array properties
  2040. ---------------------------------------------------------------------}
  2041. function GetDynArrayProp(Instance: TObject; const PropName: string): Pointer;
  2042. begin
  2043. Result:=GetDynArrayProp(Instance,FindPropInfo(Instance,PropName));
  2044. end;
  2045. function GetDynArrayProp(Instance: TObject; PropInfo: PPropInfo): Pointer;
  2046. type
  2047. { we need a dynamic array as that type is usually passed differently from
  2048. a plain pointer }
  2049. TDynArray=array of Byte;
  2050. TGetDynArrayProc=function:TDynArray of object;
  2051. TGetDynArrayProcIndex=function(index:longint):TDynArray of object;
  2052. var
  2053. AMethod : TMethod;
  2054. begin
  2055. Result:=nil;
  2056. if PropInfo^.PropType^.Kind<>tkDynArray then
  2057. Exit;
  2058. case (PropInfo^.PropProcs) and 3 of
  2059. ptField:
  2060. Result:=PPointer(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2061. ptStatic,
  2062. ptVirtual:
  2063. begin
  2064. if (PropInfo^.PropProcs and 3)=ptStatic then
  2065. AMethod.Code:=PropInfo^.GetProc
  2066. else
  2067. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2068. AMethod.Data:=Instance;
  2069. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2070. Result:=Pointer(TGetDynArrayProcIndex(AMethod)(PropInfo^.Index))
  2071. else
  2072. Result:=Pointer(TGetDynArrayProc(AMethod)());
  2073. end;
  2074. else
  2075. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2076. end;
  2077. end;
  2078. procedure SetDynArrayProp(Instance: TObject; const PropName: string; const Value: Pointer);
  2079. begin
  2080. SetDynArrayProp(Instance,FindPropInfo(Instance,PropName),Value);
  2081. end;
  2082. procedure SetDynArrayProp(Instance: TObject; PropInfo: PPropInfo; const Value: Pointer);
  2083. type
  2084. { we need a dynamic array as that type is usually passed differently from
  2085. a plain pointer }
  2086. TDynArray=array of Byte;
  2087. TSetDynArrayProcIndex=procedure(index:longint;const i:TDynArray) of object;
  2088. TSetDynArrayProc=procedure(i:TDynArray) of object;
  2089. var
  2090. AMethod: TMethod;
  2091. begin
  2092. if PropInfo^.PropType^.Kind<>tkDynArray then
  2093. Exit;
  2094. case (PropInfo^.PropProcs shr 2) and 3 of
  2095. ptField:
  2096. CopyArray(PPointer(Pointer(Instance)+PtrUInt(PropInfo^.SetProc)), @Value, PropInfo^.PropType, 1);
  2097. ptStatic,
  2098. ptVirtual:
  2099. begin
  2100. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2101. AMethod.Code:=PropInfo^.SetProc
  2102. else
  2103. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2104. AMethod.Data:=Instance;
  2105. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2106. TSetDynArrayProcIndex(AMethod)(PropInfo^.Index,TDynArray(Value))
  2107. else
  2108. TSetDynArrayProc(AMethod)(TDynArray(Value));
  2109. end;
  2110. else
  2111. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2112. end;
  2113. end;
  2114. { ---------------------------------------------------------------------
  2115. String properties
  2116. ---------------------------------------------------------------------}
  2117. Function GetStrProp(Instance: TObject; PropInfo: PPropInfo): AnsiString;
  2118. type
  2119. TGetShortStrProcIndex=function(index:longint):ShortString of object;
  2120. TGetShortStrProc=function():ShortString of object;
  2121. TGetAnsiStrProcIndex=function(index:longint):AnsiString of object;
  2122. TGetAnsiStrProc=function():AnsiString of object;
  2123. var
  2124. AMethod : TMethod;
  2125. begin
  2126. Result:='';
  2127. case Propinfo^.PropType^.Kind of
  2128. tkWString:
  2129. Result:=AnsiString(GetWideStrProp(Instance,PropInfo));
  2130. tkUString:
  2131. Result := AnsiString(GetUnicodeStrProp(Instance,PropInfo));
  2132. tkSString:
  2133. begin
  2134. case (PropInfo^.PropProcs) and 3 of
  2135. ptField:
  2136. Result := PShortString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  2137. ptStatic,
  2138. ptVirtual:
  2139. begin
  2140. if (PropInfo^.PropProcs and 3)=ptStatic then
  2141. AMethod.Code:=PropInfo^.GetProc
  2142. else
  2143. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2144. AMethod.Data:=Instance;
  2145. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2146. Result:=TGetShortStrProcIndex(AMethod)(PropInfo^.Index)
  2147. else
  2148. Result:=TGetShortStrProc(AMethod)();
  2149. end;
  2150. else
  2151. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2152. end;
  2153. end;
  2154. tkAString:
  2155. begin
  2156. case (PropInfo^.PropProcs) and 3 of
  2157. ptField:
  2158. Result := PAnsiString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  2159. ptStatic,
  2160. ptVirtual:
  2161. begin
  2162. if (PropInfo^.PropProcs and 3)=ptStatic then
  2163. AMethod.Code:=PropInfo^.GetProc
  2164. else
  2165. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2166. AMethod.Data:=Instance;
  2167. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2168. Result:=TGetAnsiStrProcIndex(AMethod)(PropInfo^.Index)
  2169. else
  2170. Result:=TGetAnsiStrProc(AMethod)();
  2171. end;
  2172. else
  2173. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2174. end;
  2175. end;
  2176. end;
  2177. end;
  2178. Procedure SetStrProp(Instance : TObject;PropInfo : PPropInfo; const Value : AnsiString);
  2179. type
  2180. TSetShortStrProcIndex=procedure(index:longint;const s:ShortString) of object;
  2181. TSetShortStrProc=procedure(const s:ShortString) of object;
  2182. TSetAnsiStrProcIndex=procedure(index:longint;s:AnsiString) of object;
  2183. TSetAnsiStrProc=procedure(s:AnsiString) of object;
  2184. var
  2185. AMethod : TMethod;
  2186. begin
  2187. case Propinfo^.PropType^.Kind of
  2188. tkWString:
  2189. SetWideStrProp(Instance,PropInfo,WideString(Value));
  2190. tkUString:
  2191. SetUnicodeStrProp(Instance,PropInfo,UnicodeString(Value));
  2192. tkSString:
  2193. begin
  2194. case (PropInfo^.PropProcs shr 2) and 3 of
  2195. ptField:
  2196. PShortString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  2197. ptStatic,
  2198. ptVirtual:
  2199. begin
  2200. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2201. AMethod.Code:=PropInfo^.SetProc
  2202. else
  2203. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2204. AMethod.Data:=Instance;
  2205. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2206. TSetShortStrProcIndex(AMethod)(PropInfo^.Index,Value)
  2207. else
  2208. TSetShortStrProc(AMethod)(Value);
  2209. end;
  2210. else
  2211. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2212. end;
  2213. end;
  2214. tkAString:
  2215. begin
  2216. case (PropInfo^.PropProcs shr 2) and 3 of
  2217. ptField:
  2218. PAnsiString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  2219. ptStatic,
  2220. ptVirtual:
  2221. begin
  2222. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2223. AMethod.Code:=PropInfo^.SetProc
  2224. else
  2225. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2226. AMethod.Data:=Instance;
  2227. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2228. TSetAnsiStrProcIndex(AMethod)(PropInfo^.Index,Value)
  2229. else
  2230. TSetAnsiStrProc(AMethod)(Value);
  2231. end;
  2232. else
  2233. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2234. end;
  2235. end;
  2236. end;
  2237. end;
  2238. Function GetStrProp(Instance: TObject; const PropName: string): string;
  2239. begin
  2240. Result:=GetStrProp(Instance,FindPropInfo(Instance,PropName));
  2241. end;
  2242. Procedure SetStrProp(Instance: TObject; const PropName: string; const Value: AnsiString);
  2243. begin
  2244. SetStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  2245. end;
  2246. Function GetWideStrProp(Instance: TObject; const PropName: string): WideString;
  2247. begin
  2248. Result:=GetWideStrProp(Instance, FindPropInfo(Instance, PropName));
  2249. end;
  2250. procedure SetWideStrProp(Instance: TObject; const PropName: string; const Value: WideString);
  2251. begin
  2252. SetWideStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  2253. end;
  2254. Function GetWideStrProp(Instance: TObject; PropInfo: PPropInfo): WideString;
  2255. type
  2256. TGetWideStrProcIndex=function(index:longint):WideString of object;
  2257. TGetWideStrProc=function():WideString of object;
  2258. var
  2259. AMethod : TMethod;
  2260. begin
  2261. Result:='';
  2262. case Propinfo^.PropType^.Kind of
  2263. tkSString,tkAString:
  2264. Result:=WideString(GetStrProp(Instance,PropInfo));
  2265. tkUString :
  2266. Result := GetUnicodeStrProp(Instance,PropInfo);
  2267. tkWString:
  2268. begin
  2269. case (PropInfo^.PropProcs) and 3 of
  2270. ptField:
  2271. Result := PWideString(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2272. ptStatic,
  2273. ptVirtual:
  2274. begin
  2275. if (PropInfo^.PropProcs and 3)=ptStatic then
  2276. AMethod.Code:=PropInfo^.GetProc
  2277. else
  2278. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2279. AMethod.Data:=Instance;
  2280. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2281. Result:=TGetWideStrProcIndex(AMethod)(PropInfo^.Index)
  2282. else
  2283. Result:=TGetWideStrProc(AMethod)();
  2284. end;
  2285. else
  2286. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2287. end;
  2288. end;
  2289. end;
  2290. end;
  2291. Procedure SetWideStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: WideString);
  2292. type
  2293. TSetWideStrProcIndex=procedure(index:longint;s:WideString) of object;
  2294. TSetWideStrProc=procedure(s:WideString) of object;
  2295. var
  2296. AMethod : TMethod;
  2297. begin
  2298. case Propinfo^.PropType^.Kind of
  2299. tkSString,tkAString:
  2300. SetStrProp(Instance,PropInfo,AnsiString(Value));
  2301. tkUString:
  2302. SetUnicodeStrProp(Instance,PropInfo,Value);
  2303. tkWString:
  2304. begin
  2305. case (PropInfo^.PropProcs shr 2) and 3 of
  2306. ptField:
  2307. PWideString(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2308. ptStatic,
  2309. ptVirtual:
  2310. begin
  2311. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2312. AMethod.Code:=PropInfo^.SetProc
  2313. else
  2314. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2315. AMethod.Data:=Instance;
  2316. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2317. TSetWideStrProcIndex(AMethod)(PropInfo^.Index,Value)
  2318. else
  2319. TSetWideStrProc(AMethod)(Value);
  2320. end;
  2321. else
  2322. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2323. end;
  2324. end;
  2325. end;
  2326. end;
  2327. Function GetUnicodeStrProp(Instance: TObject; const PropName: string): UnicodeString;
  2328. begin
  2329. Result:=GetUnicodeStrProp(Instance, FindPropInfo(Instance, PropName));
  2330. end;
  2331. procedure SetUnicodeStrProp(Instance: TObject; const PropName: string; const Value: UnicodeString);
  2332. begin
  2333. SetUnicodeStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  2334. end;
  2335. Function GetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo): UnicodeString;
  2336. type
  2337. TGetUnicodeStrProcIndex=function(index:longint):UnicodeString of object;
  2338. TGetUnicodeStrProc=function():UnicodeString of object;
  2339. var
  2340. AMethod : TMethod;
  2341. begin
  2342. Result:='';
  2343. case Propinfo^.PropType^.Kind of
  2344. tkSString,tkAString:
  2345. Result:=UnicodeString(GetStrProp(Instance,PropInfo));
  2346. tkWString:
  2347. Result:=GetWideStrProp(Instance,PropInfo);
  2348. tkUString:
  2349. begin
  2350. case (PropInfo^.PropProcs) and 3 of
  2351. ptField:
  2352. Result := PUnicodeString(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2353. ptStatic,
  2354. ptVirtual:
  2355. begin
  2356. if (PropInfo^.PropProcs and 3)=ptStatic then
  2357. AMethod.Code:=PropInfo^.GetProc
  2358. else
  2359. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2360. AMethod.Data:=Instance;
  2361. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2362. Result:=TGetUnicodeStrProcIndex(AMethod)(PropInfo^.Index)
  2363. else
  2364. Result:=TGetUnicodeStrProc(AMethod)();
  2365. end;
  2366. else
  2367. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2368. end;
  2369. end;
  2370. end;
  2371. end;
  2372. Procedure SetUnicodeStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: UnicodeString);
  2373. type
  2374. TSetUnicodeStrProcIndex=procedure(index:longint;s:UnicodeString) of object;
  2375. TSetUnicodeStrProc=procedure(s:UnicodeString) of object;
  2376. var
  2377. AMethod : TMethod;
  2378. begin
  2379. case Propinfo^.PropType^.Kind of
  2380. tkSString,tkAString:
  2381. SetStrProp(Instance,PropInfo,AnsiString(Value));
  2382. tkWString:
  2383. SetWideStrProp(Instance,PropInfo,Value);
  2384. tkUString:
  2385. begin
  2386. case (PropInfo^.PropProcs shr 2) and 3 of
  2387. ptField:
  2388. PUnicodeString(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2389. ptStatic,
  2390. ptVirtual:
  2391. begin
  2392. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2393. AMethod.Code:=PropInfo^.SetProc
  2394. else
  2395. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2396. AMethod.Data:=Instance;
  2397. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2398. TSetUnicodeStrProcIndex(AMethod)(PropInfo^.Index,Value)
  2399. else
  2400. TSetUnicodeStrProc(AMethod)(Value);
  2401. end;
  2402. else
  2403. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2404. end;
  2405. end;
  2406. end;
  2407. end;
  2408. function GetRawbyteStrProp(Instance: TObject; PropInfo: PPropInfo): RawByteString;
  2409. type
  2410. TGetRawByteStrProcIndex=function(index:longint): RawByteString of object;
  2411. TGetRawByteStrProc=function():RawByteString of object;
  2412. var
  2413. AMethod : TMethod;
  2414. begin
  2415. Result:='';
  2416. case Propinfo^.PropType^.Kind of
  2417. tkWString:
  2418. Result:=RawByteString(GetWideStrProp(Instance,PropInfo));
  2419. tkUString:
  2420. Result:=RawByteString(GetUnicodeStrProp(Instance,PropInfo));
  2421. tkSString:
  2422. Result:=RawByteString(GetStrProp(Instance,PropInfo));
  2423. tkAString:
  2424. begin
  2425. case (PropInfo^.PropProcs) and 3 of
  2426. ptField:
  2427. Result := PAnsiString(Pointer(Instance) + LongWord(PropInfo^.GetProc))^;
  2428. ptStatic,
  2429. ptVirtual:
  2430. begin
  2431. if (PropInfo^.PropProcs and 3)=ptStatic then
  2432. AMethod.Code:=PropInfo^.GetProc
  2433. else
  2434. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2435. AMethod.Data:=Instance;
  2436. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2437. Result:=TGetRawByteStrProcIndex(AMethod)(PropInfo^.Index)
  2438. else
  2439. Result:=TGetRawByteStrProc(AMethod)();
  2440. end;
  2441. else
  2442. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2443. end;
  2444. end;
  2445. end;
  2446. end;
  2447. function GetRawByteStrProp(Instance: TObject; const PropName: string): RawByteString;
  2448. begin
  2449. Result:=GetRawByteStrProp(Instance,FindPropInfo(Instance,PropName));
  2450. end;
  2451. procedure SetRawByteStrProp(Instance: TObject; PropInfo: PPropInfo; const Value: RawByteString);
  2452. type
  2453. TSetRawByteStrProcIndex=procedure(index:longint;s:RawByteString) of object;
  2454. TSetRawByteStrProc=procedure(s:RawByteString) of object;
  2455. var
  2456. AMethod : TMethod;
  2457. begin
  2458. case Propinfo^.PropType^.Kind of
  2459. tkWString:
  2460. SetWideStrProp(Instance,PropInfo,WideString(Value));
  2461. tkUString:
  2462. SetUnicodeStrProp(Instance,PropInfo,UnicodeString(Value));
  2463. tkSString:
  2464. SetStrProp(Instance,PropInfo,Value); // Not 100% sure about this.
  2465. tkAString:
  2466. begin
  2467. case (PropInfo^.PropProcs shr 2) and 3 of
  2468. ptField:
  2469. PAnsiString(Pointer(Instance) + LongWord(PropInfo^.SetProc))^:=Value;
  2470. ptStatic,
  2471. ptVirtual:
  2472. begin
  2473. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2474. AMethod.Code:=PropInfo^.SetProc
  2475. else
  2476. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2477. AMethod.Data:=Instance;
  2478. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2479. TSetRawByteStrProcIndex(AMethod)(PropInfo^.Index,Value)
  2480. else
  2481. TSetRawByteStrProc(AMethod)(Value);
  2482. end;
  2483. else
  2484. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2485. end;
  2486. end;
  2487. end;
  2488. end;
  2489. procedure SetRawByteStrProp(Instance: TObject; const PropName: string; const Value: RawByteString);
  2490. begin
  2491. SetRawByteStrProp(Instance,FindPropInfo(Instance,PropName),Value);
  2492. end;
  2493. {$ifndef FPUNONE}
  2494. { ---------------------------------------------------------------------
  2495. Float properties
  2496. ---------------------------------------------------------------------}
  2497. function GetFloatProp(Instance : TObject;PropInfo : PPropInfo) : Extended;
  2498. type
  2499. TGetExtendedProc = function:Extended of object;
  2500. TGetExtendedProcIndex = function(Index: integer): Extended of object;
  2501. TGetDoubleProc = function:Double of object;
  2502. TGetDoubleProcIndex = function(Index: integer): Double of object;
  2503. TGetSingleProc = function:Single of object;
  2504. TGetSingleProcIndex = function(Index: integer):Single of object;
  2505. TGetCurrencyProc = function : Currency of object;
  2506. TGetCurrencyProcIndex = function(Index: integer) : Currency of object;
  2507. var
  2508. AMethod : TMethod;
  2509. begin
  2510. Result:=0.0;
  2511. case PropInfo^.PropProcs and 3 of
  2512. ptField:
  2513. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  2514. ftSingle:
  2515. Result:=PSingle(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2516. ftDouble:
  2517. Result:=PDouble(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2518. ftExtended:
  2519. Result:=PExtended(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2520. ftcomp:
  2521. Result:=PComp(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2522. ftcurr:
  2523. Result:=PCurrency(Pointer(Instance)+PtrUInt(PropInfo^.GetProc))^;
  2524. end;
  2525. ptStatic,
  2526. ptVirtual:
  2527. begin
  2528. if (PropInfo^.PropProcs and 3)=ptStatic then
  2529. AMethod.Code:=PropInfo^.GetProc
  2530. else
  2531. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2532. AMethod.Data:=Instance;
  2533. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  2534. ftSingle:
  2535. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2536. Result:=TGetSingleProc(AMethod)()
  2537. else
  2538. Result:=TGetSingleProcIndex(AMethod)(PropInfo^.Index);
  2539. ftDouble:
  2540. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2541. Result:=TGetDoubleProc(AMethod)()
  2542. else
  2543. Result:=TGetDoubleProcIndex(AMethod)(PropInfo^.Index);
  2544. ftExtended:
  2545. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2546. Result:=TGetExtendedProc(AMethod)()
  2547. else
  2548. Result:=TGetExtendedProcIndex(AMethod)(PropInfo^.Index);
  2549. ftCurr:
  2550. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2551. Result:=TGetCurrencyProc(AMethod)()
  2552. else
  2553. Result:=TGetCurrencyProcIndex(AMethod)(PropInfo^.Index);
  2554. end;
  2555. end;
  2556. else
  2557. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2558. end;
  2559. end;
  2560. Procedure SetFloatProp(Instance : TObject;PropInfo : PPropInfo; Value : Extended);
  2561. type
  2562. TSetExtendedProc = procedure(const AValue: Extended) of object;
  2563. TSetExtendedProcIndex = procedure(Index: integer; AValue: Extended) of object;
  2564. TSetDoubleProc = procedure(const AValue: Double) of object;
  2565. TSetDoubleProcIndex = procedure(Index: integer; AValue: Double) of object;
  2566. TSetSingleProc = procedure(const AValue: Single) of object;
  2567. TSetSingleProcIndex = procedure(Index: integer; AValue: Single) of object;
  2568. TSetCurrencyProc = procedure(const AValue: Currency) of object;
  2569. TSetCurrencyProcIndex = procedure(Index: integer; AValue: Currency) of object;
  2570. Var
  2571. AMethod : TMethod;
  2572. begin
  2573. case (PropInfo^.PropProcs shr 2) and 3 of
  2574. ptfield:
  2575. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  2576. ftSingle:
  2577. PSingle(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2578. ftDouble:
  2579. PDouble(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2580. ftExtended:
  2581. PExtended(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2582. {$ifdef FPC_COMP_IS_INT64}
  2583. ftComp:
  2584. PComp(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=trunc(Value);
  2585. {$else FPC_COMP_IS_INT64}
  2586. ftComp:
  2587. PComp(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Comp(Value);
  2588. {$endif FPC_COMP_IS_INT64}
  2589. ftCurr:
  2590. PCurrency(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^:=Value;
  2591. end;
  2592. ptStatic,
  2593. ptVirtual:
  2594. begin
  2595. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2596. AMethod.Code:=PropInfo^.SetProc
  2597. else
  2598. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2599. AMethod.Data:=Instance;
  2600. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  2601. ftSingle:
  2602. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2603. TSetSingleProc(AMethod)(Value)
  2604. else
  2605. TSetSingleProcIndex(AMethod)(PropInfo^.Index,Value);
  2606. ftDouble:
  2607. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2608. TSetDoubleProc(AMethod)(Value)
  2609. else
  2610. TSetDoubleProcIndex(AMethod)(PropInfo^.Index,Value);
  2611. ftExtended:
  2612. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2613. TSetExtendedProc(AMethod)(Value)
  2614. else
  2615. TSetExtendedProcIndex(AMethod)(PropInfo^.Index,Value);
  2616. ftCurr:
  2617. if ((PropInfo^.PropProcs shr 6) and 1)=0 then
  2618. TSetCurrencyProc(AMethod)(Value)
  2619. else
  2620. TSetCurrencyProcIndex(AMethod)(PropInfo^.Index,Value);
  2621. end;
  2622. end;
  2623. else
  2624. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2625. end;
  2626. end;
  2627. function GetFloatProp(Instance: TObject; const PropName: string): Extended;
  2628. begin
  2629. Result:=GetFloatProp(Instance,FindPropInfo(Instance,PropName))
  2630. end;
  2631. Procedure SetFloatProp(Instance: TObject; const PropName: string; Value: Extended);
  2632. begin
  2633. SetFloatProp(Instance,FindPropInfo(Instance,PropName),Value);
  2634. end;
  2635. {$endif}
  2636. { ---------------------------------------------------------------------
  2637. Method properties
  2638. ---------------------------------------------------------------------}
  2639. Function GetMethodProp(Instance : TObject;PropInfo : PPropInfo) : TMethod;
  2640. type
  2641. TGetMethodProcIndex=function(Index: Longint): TMethod of object;
  2642. TGetMethodProc=function(): TMethod of object;
  2643. var
  2644. value: PMethod;
  2645. AMethod : TMethod;
  2646. begin
  2647. Result.Code:=nil;
  2648. Result.Data:=nil;
  2649. case (PropInfo^.PropProcs) and 3 of
  2650. ptField:
  2651. begin
  2652. Value:=PMethod(Pointer(Instance)+PtrUInt(PropInfo^.GetProc));
  2653. if Value<>nil then
  2654. Result:=Value^;
  2655. end;
  2656. ptStatic,
  2657. ptVirtual:
  2658. begin
  2659. if (PropInfo^.PropProcs and 3)=ptStatic then
  2660. AMethod.Code:=PropInfo^.GetProc
  2661. else
  2662. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.GetProc))^;
  2663. AMethod.Data:=Instance;
  2664. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2665. Result:=TGetMethodProcIndex(AMethod)(PropInfo^.Index)
  2666. else
  2667. Result:=TGetMethodProc(AMethod)();
  2668. end;
  2669. else
  2670. raise EPropertyError.CreateFmt(SErrCannotReadProperty, [PropInfo^.Name]);
  2671. end;
  2672. end;
  2673. Procedure SetMethodProp(Instance : TObject;PropInfo : PPropInfo; const Value : TMethod);
  2674. type
  2675. TSetMethodProcIndex=procedure(index:longint;p:TMethod) of object;
  2676. TSetMethodProc=procedure(p:TMethod) of object;
  2677. var
  2678. AMethod : TMethod;
  2679. begin
  2680. case (PropInfo^.PropProcs shr 2) and 3 of
  2681. ptField:
  2682. PMethod(Pointer(Instance)+PtrUInt(PropInfo^.SetProc))^ := Value;
  2683. ptStatic,
  2684. ptVirtual:
  2685. begin
  2686. if ((PropInfo^.PropProcs shr 2) and 3)=ptStatic then
  2687. AMethod.Code:=PropInfo^.SetProc
  2688. else
  2689. AMethod.Code:=PCodePointer(Pointer(Instance.ClassType)+PtrUInt(PropInfo^.SetProc))^;
  2690. AMethod.Data:=Instance;
  2691. if ((PropInfo^.PropProcs shr 6) and 1)<>0 then
  2692. TSetMethodProcIndex(AMethod)(PropInfo^.Index,Value)
  2693. else
  2694. TSetMethodProc(AMethod)(Value);
  2695. end;
  2696. else
  2697. raise EPropertyError.CreateFmt(SErrCannotWriteToProperty, [PropInfo^.Name]);
  2698. end;
  2699. end;
  2700. Function GetMethodProp(Instance: TObject; const PropName: string): TMethod;
  2701. begin
  2702. Result:=GetMethodProp(Instance,FindPropInfo(Instance,PropName));
  2703. end;
  2704. Procedure SetMethodProp(Instance: TObject; const PropName: string; const Value: TMethod);
  2705. begin
  2706. SetMethodProp(Instance,FindPropInfo(Instance,PropName),Value);
  2707. end;
  2708. { ---------------------------------------------------------------------
  2709. Variant properties
  2710. ---------------------------------------------------------------------}
  2711. Procedure CheckVariantEvent(P : CodePointer);
  2712. begin
  2713. If (P=Nil) then
  2714. Raise Exception.Create(SErrNoVariantSupport);
  2715. end;
  2716. Function GetVariantProp(Instance : TObject;PropInfo : PPropInfo): Variant;
  2717. begin
  2718. CheckVariantEvent(CodePointer(OnGetVariantProp));
  2719. Result:=OnGetVariantProp(Instance,PropInfo);
  2720. end;
  2721. Procedure SetVariantProp(Instance : TObject;PropInfo : PPropInfo; const Value: Variant);
  2722. begin
  2723. CheckVariantEvent(CodePointer(OnSetVariantProp));
  2724. OnSetVariantProp(Instance,PropInfo,Value);
  2725. end;
  2726. Function GetVariantProp(Instance: TObject; const PropName: string): Variant;
  2727. begin
  2728. Result:=GetVariantProp(Instance,FindPropInfo(Instance,PropName));
  2729. end;
  2730. Procedure SetVariantProp(Instance: TObject; const PropName: string; const Value: Variant);
  2731. begin
  2732. SetVariantprop(instance,FindpropInfo(Instance,PropName),Value);
  2733. end;
  2734. { ---------------------------------------------------------------------
  2735. All properties through variant.
  2736. ---------------------------------------------------------------------}
  2737. Function GetPropValue(Instance: TObject; const PropName: string): Variant;
  2738. begin
  2739. Result := GetPropValue(Instance,FindPropInfo(Instance, PropName));
  2740. end;
  2741. Function GetPropValue(Instance: TObject; const PropName: string; PreferStrings: Boolean): Variant;
  2742. begin
  2743. Result := GetPropValue(Instance,FindPropInfo(Instance, PropName),PreferStrings);
  2744. end;
  2745. Function GetPropValue(Instance: TObject; PropInfo: PPropInfo): Variant;
  2746. begin
  2747. Result := GetPropValue(Instance, PropInfo, True);
  2748. end;
  2749. Function GetPropValue(Instance: TObject; PropInfo: PPropInfo; PreferStrings: Boolean): Variant;
  2750. begin
  2751. CheckVariantEvent(CodePointer(OnGetPropValue));
  2752. Result:=OnGetPropValue(Instance,PropInfo,PreferStrings);
  2753. end;
  2754. Procedure SetPropValue(Instance: TObject; const PropName: string; const Value: Variant);
  2755. begin
  2756. SetPropValue(Instance, FindPropInfo(Instance, PropName), Value);
  2757. end;
  2758. Procedure SetPropValue(Instance: TObject; PropInfo: PPropInfo; const Value: Variant);
  2759. begin
  2760. CheckVariantEvent(CodePointer(OnSetPropValue));
  2761. OnSetPropValue(Instance,PropInfo,Value);
  2762. end;
  2763. { ---------------------------------------------------------------------
  2764. Easy access methods that appeared in Delphi 5
  2765. ---------------------------------------------------------------------}
  2766. Function IsPublishedProp(Instance: TObject; const PropName: string): Boolean;
  2767. begin
  2768. Result:=GetPropInfo(Instance,PropName)<>Nil;
  2769. end;
  2770. Function IsPublishedProp(AClass: TClass; const PropName: string): Boolean;
  2771. begin
  2772. Result:=GetPropInfo(AClass,PropName)<>Nil;
  2773. end;
  2774. Function PropIsType(Instance: TObject; const PropName: string; TypeKind: TTypeKind): Boolean;
  2775. begin
  2776. Result:=PropType(Instance,PropName)=TypeKind
  2777. end;
  2778. Function PropIsType(AClass: TClass; const PropName: string; TypeKind: TTypeKind): Boolean;
  2779. begin
  2780. Result:=PropType(AClass,PropName)=TypeKind
  2781. end;
  2782. Function PropType(Instance: TObject; const PropName: string): TTypeKind;
  2783. begin
  2784. Result:=FindPropInfo(Instance,PropName)^.PropType^.Kind;
  2785. end;
  2786. Function PropType(AClass: TClass; const PropName: string): TTypeKind;
  2787. begin
  2788. Result:=FindPropInfo(AClass,PropName)^.PropType^.Kind;
  2789. end;
  2790. Function IsStoredProp(Instance: TObject; const PropName: string): Boolean;
  2791. begin
  2792. Result:=IsStoredProp(instance,FindPropInfo(Instance,PropName));
  2793. end;
  2794. { TParameterLocation }
  2795. function TParameterLocation.GetReference: Boolean;
  2796. begin
  2797. Result := (LocType and $80) <> 0;
  2798. end;
  2799. function TParameterLocation.GetRegType: TRegisterType;
  2800. begin
  2801. Result := TRegisterType(LocType and $7F);
  2802. end;
  2803. function TParameterLocation.GetShiftVal: Int8;
  2804. begin
  2805. if GetReference then begin
  2806. if Offset < Low(Int8) then
  2807. Result := Low(Int8)
  2808. else if Offset > High(Int8) then
  2809. Result := High(Int8)
  2810. else
  2811. Result := Offset;
  2812. end else
  2813. Result := 0;
  2814. end;
  2815. { TParameterLocations }
  2816. function TParameterLocations.GetLocation(aIndex: Byte): PParameterLocation;
  2817. begin
  2818. if aIndex >= Count then
  2819. Result := Nil
  2820. else
  2821. Result := PParameterLocation(PByte(aligntoptr(PByte(@Count) + SizeOf(Count))) + SizeOf(TParameterLocation) * aIndex);
  2822. end;
  2823. function TParameterLocations.GetTail: Pointer;
  2824. begin
  2825. Result := PByte(aligntoptr(PByte(@Count) + SizeOf(Count))) + SizeOf(TParameterLocation) * Count;
  2826. end;
  2827. { TProcedureParam }
  2828. function TProcedureParam.GetParamType: PTypeInfo;
  2829. begin
  2830. Result := DerefTypeInfoPtr(ParamTypeRef);
  2831. end;
  2832. function TProcedureParam.GetFlags: Byte;
  2833. begin
  2834. Result := PByte(@ParamFlags)^;
  2835. end;
  2836. { TManagedField }
  2837. function TManagedField.GetTypeRef: PTypeInfo;
  2838. begin
  2839. Result := DerefTypeInfoPtr(TypeRefRef);
  2840. end;
  2841. { TArrayTypeData }
  2842. function TArrayTypeData.GetElType: PTypeInfo;
  2843. begin
  2844. Result := DerefTypeInfoPtr(ElTypeRef);
  2845. end;
  2846. function TArrayTypeData.GetDims(aIndex: Byte): PTypeInfo;
  2847. begin
  2848. Result := DerefTypeInfoPtr(DimsRef[aIndex]);
  2849. end;
  2850. { TProcedureSignature }
  2851. function TProcedureSignature.GetResultType: PTypeInfo;
  2852. begin
  2853. Result := DerefTypeInfoPtr(ResultTypeRef);
  2854. end;
  2855. function TProcedureSignature.GetParam(ParamIndex: Integer): PProcedureParam;
  2856. begin
  2857. if (ParamIndex<0)or(ParamIndex>=ParamCount) then
  2858. Exit(nil);
  2859. Result := PProcedureParam(PByte(@Flags) + SizeOf(Self));
  2860. while ParamIndex > 0 do
  2861. begin
  2862. Result := PProcedureParam(aligntoptr((PByte(@Result^.Name) + (Length(Result^.Name) + 1) * SizeOf(AnsiChar))));
  2863. dec(ParamIndex);
  2864. end;
  2865. end;
  2866. { TVmtMethodParam }
  2867. function TVmtMethodParam.GetTail: Pointer;
  2868. begin
  2869. Result := PByte(@ParaLocs) + SizeOf(ParaLocs);
  2870. end;
  2871. function TVmtMethodParam.GetNext: PVmtMethodParam;
  2872. begin
  2873. Result := PVmtMethodParam(aligntoptr(Tail));
  2874. end;
  2875. function TVmtMethodParam.GetName: ShortString;
  2876. begin
  2877. Result := NamePtr^;
  2878. end;
  2879. { TIntfMethodEntry }
  2880. function TIntfMethodEntry.GetParam(Index: Word): PVmtMethodParam;
  2881. begin
  2882. if Index >= ParamCount then
  2883. Result := Nil
  2884. else
  2885. Result := PVmtMethodParam(PByte(aligntoptr(PByte(@NamePtr) + SizeOf(NamePtr))) + Index * PtrUInt(aligntoptr(Pointer(SizeOf(TVmtMethodParam)))));
  2886. end;
  2887. function TIntfMethodEntry.GetResultLocs: PParameterLocations;
  2888. begin
  2889. if not Assigned(ResultType) then
  2890. Result := Nil
  2891. else
  2892. Result := PParameterLocations(PByte(aligntoptr(PByte(@NamePtr) + SizeOf(NamePtr))) + ParamCount * PtrUInt(aligntoptr(Pointer(SizeOf(TVmtMethodParam)))));
  2893. end;
  2894. function TIntfMethodEntry.GetTail: Pointer;
  2895. begin
  2896. Result := PByte(@NamePtr) + SizeOf(NamePtr);
  2897. if ParamCount > 0 then
  2898. Result := PByte(aligntoptr(Result)) + ParamCount * PtrUInt(aligntoptr(Pointer(SizeOf(TVmtMethodParam))));
  2899. if Assigned(ResultType) then
  2900. Result := PByte(aligntoptr(Result)) + SizeOf(PParameterLocations);
  2901. end;
  2902. function TIntfMethodEntry.GetNext: PIntfMethodEntry;
  2903. begin
  2904. Result := PIntfMethodEntry(aligntoptr(Tail));
  2905. end;
  2906. function TIntfMethodEntry.GetName: ShortString;
  2907. begin
  2908. Result := NamePtr^;
  2909. end;
  2910. { TIntfMethodTable }
  2911. function TIntfMethodTable.GetMethod(Index: Word): PIntfMethodEntry;
  2912. begin
  2913. if (RTTICount = $FFFF) or (Index >= RTTICount) then
  2914. Result := Nil
  2915. else
  2916. begin
  2917. Result := aligntoptr(PIntfMethodEntry(PByte(@RTTICount) + SizeOf(RTTICount)));
  2918. while Index > 0 do
  2919. begin
  2920. Result := Result^.Next;
  2921. Dec(Index);
  2922. end;
  2923. end;
  2924. end;
  2925. { TVmtMethodTable }
  2926. function TVmtMethodTable.GetEntry(Index: LongWord): PVmtMethodEntry;
  2927. begin
  2928. Result := PVmtMethodEntry(@Entries[0]) + Index;
  2929. end;
  2930. { TVmtFieldTable }
  2931. function TVmtFieldTable.GetField(aIndex: Word): PVmtFieldEntry;
  2932. var
  2933. c: Word;
  2934. begin
  2935. if aIndex >= Count then
  2936. Exit(Nil);
  2937. c := aIndex;
  2938. Result := @Fields;
  2939. while c > 0 do begin
  2940. Result := Result^.Next;
  2941. Dec(c);
  2942. end;
  2943. end;
  2944. { TVmtFieldEntry }
  2945. function TVmtFieldEntry.GetNext: PVmtFieldEntry;
  2946. begin
  2947. Result := aligntoptr(Tail);
  2948. end;
  2949. function TVmtFieldEntry.GetTail: Pointer;
  2950. begin
  2951. Result := PByte(@Name) + Length(Name) + SizeOf(Byte);
  2952. end;
  2953. { TInterfaceData }
  2954. function TInterfaceData.GetUnitName: ShortString;
  2955. begin
  2956. Result := UnitNameField;
  2957. end;
  2958. function TInterfaceData.GetPropertyTable: PPropData;
  2959. var
  2960. p: PByte;
  2961. begin
  2962. p := PByte(@UnitNameField[0]) + SizeOf(UnitNameField[0]) + Length(UnitNameField);
  2963. Result := AlignTypeData(p);
  2964. end;
  2965. function TInterfaceData.GetMethodTable: PIntfMethodTable;
  2966. begin
  2967. Result := aligntoptr(PropertyTable^.Tail);
  2968. end;
  2969. { TInterfaceRawData }
  2970. function TInterfaceRawData.GetUnitName: ShortString;
  2971. begin
  2972. Result := UnitNameField;
  2973. end;
  2974. function TInterfaceRawData.GetIIDStr: ShortString;
  2975. begin
  2976. Result := PShortString(AlignTypeData(PByte(@UnitNameField[0]) + SizeOf(UnitNameField[0]) + Length(UnitNameField)))^;
  2977. end;
  2978. function TInterfaceRawData.GetPropertyTable: PPropData;
  2979. var
  2980. p: PByte;
  2981. begin
  2982. p := AlignTypeData(PByte(@UnitNameField[0]) + SizeOf(UnitNameField[0]) + Length(UnitNameField));
  2983. p := p + SizeOf(p^) + p^;
  2984. Result := aligntoptr(p);
  2985. end;
  2986. function TInterfaceRawData.GetMethodTable: PIntfMethodTable;
  2987. begin
  2988. Result := aligntoptr(PropertyTable^.Tail);
  2989. end;
  2990. { TClassData }
  2991. function TClassData.GetUnitName: ShortString;
  2992. begin
  2993. Result := UnitNameField;
  2994. end;
  2995. function TClassData.GetPropertyTable: PPropData;
  2996. var
  2997. p: PByte;
  2998. begin
  2999. p := PByte(@UnitNameField[0]) + SizeOf(UnitNameField[0]) + Length(UnitNameField);
  3000. Result := AlignToPtr(p);
  3001. end;
  3002. { TTypeData }
  3003. function TTypeData.GetBaseType: PTypeInfo;
  3004. begin
  3005. Result := DerefTypeInfoPtr(BaseTypeRef);
  3006. end;
  3007. function TTypeData.GetCompType: PTypeInfo;
  3008. begin
  3009. Result := DerefTypeInfoPtr(CompTypeRef);
  3010. end;
  3011. function TTypeData.GetParentInfo: PTypeInfo;
  3012. begin
  3013. Result := DerefTypeInfoPtr(ParentInfoRef);
  3014. end;
  3015. {$ifndef VER3_0}
  3016. function TTypeData.GetRecInitData: PRecInitData;
  3017. begin
  3018. Result := PRecInitData(aligntoptr(PTypeData(RecInitInfo+2+PByte(RecInitInfo+1)^)));
  3019. end;
  3020. {$endif}
  3021. function TTypeData.GetHelperParent: PTypeInfo;
  3022. begin
  3023. Result := DerefTypeInfoPtr(HelperParentRef);
  3024. end;
  3025. function TTypeData.GetExtendedInfo: PTypeInfo;
  3026. begin
  3027. Result := DerefTypeInfoPtr(ExtendedInfoRef);
  3028. end;
  3029. function TTypeData.GetIntfParent: PTypeInfo;
  3030. begin
  3031. Result := DerefTypeInfoPtr(IntfParentRef);
  3032. end;
  3033. function TTypeData.GetRawIntfParent: PTypeInfo;
  3034. begin
  3035. Result := DerefTypeInfoPtr(RawIntfParentRef);
  3036. end;
  3037. function TTypeData.GetIIDStr: ShortString;
  3038. begin
  3039. Result := PShortString(AlignTypeData(Pointer(@RawIntfUnit) + Length(RawIntfUnit) + 1))^;
  3040. end;
  3041. function TTypeData.GetElType: PTypeInfo;
  3042. begin
  3043. Result := DerefTypeInfoPtr(elTypeRef);
  3044. end;
  3045. function TTypeData.GetElType2: PTypeInfo;
  3046. begin
  3047. Result := DerefTypeInfoPtr(elType2Ref);
  3048. end;
  3049. function TTypeData.GetInstanceType: PTypeInfo;
  3050. begin
  3051. Result := DerefTypeInfoPtr(InstanceTypeRef);
  3052. end;
  3053. function TTypeData.GetRefType: PTypeInfo;
  3054. begin
  3055. Result := DerefTypeInfoPtr(RefTypeRef);
  3056. end;
  3057. { TPropData }
  3058. function TPropData.GetProp(Index: Word): PPropInfo;
  3059. begin
  3060. if Index >= PropCount then
  3061. Result := Nil
  3062. else
  3063. begin
  3064. Result := PPropInfo(aligntoptr(PByte(@PropCount) + SizeOf(PropCount)));
  3065. while Index > 0 do
  3066. begin
  3067. Result := aligntoptr(Result^.Tail);
  3068. Dec(Index);
  3069. end;
  3070. end;
  3071. end;
  3072. function TPropData.GetTail: Pointer;
  3073. begin
  3074. if PropCount = 0 then
  3075. Result := PByte(@PropCount) + SizeOf(PropCount)
  3076. else
  3077. Result := Prop[PropCount - 1]^.Tail;
  3078. end;
  3079. { TPropInfo }
  3080. function TPropInfo.GetPropType: PTypeInfo;
  3081. begin
  3082. Result := DerefTypeInfoPtr(PropTypeRef);
  3083. end;
  3084. function TPropInfo.GetTail: Pointer;
  3085. begin
  3086. Result := PByte(@Name[0]) + SizeOf(Name[0]) + Length(Name);
  3087. end;
  3088. function TPropInfo.GetNext: PPropInfo;
  3089. begin
  3090. Result := PPropInfo(aligntoptr(Tail));
  3091. end;
  3092. type
  3093. TElementAlias = record
  3094. Ordinal : Integer;
  3095. Alias : string;
  3096. end;
  3097. TElementAliasArray = Array of TElementAlias;
  3098. PElementAliasArray = ^TElementAliasArray;
  3099. TEnumeratedAliases = record
  3100. TypeInfo: PTypeInfo;
  3101. Aliases: TElementAliasArray;
  3102. end;
  3103. TEnumeratedAliasesArray = Array of TEnumeratedAliases;
  3104. Var
  3105. EnumeratedAliases : TEnumeratedAliasesArray;
  3106. Function IndexOfEnumeratedAliases(aTypeInfo : PTypeInfo) : integer;
  3107. begin
  3108. Result:=Length(EnumeratedAliases)-1;
  3109. while (Result>=0) and (EnumeratedAliases[Result].TypeInfo<>aTypeInfo) do
  3110. Dec(Result);
  3111. end;
  3112. Function GetEnumeratedAliases(aTypeInfo : PTypeInfo) : PElementAliasArray;
  3113. Var
  3114. I : integer;
  3115. begin
  3116. I:=IndexOfEnumeratedAliases(aTypeInfo);
  3117. if I=-1 then
  3118. Result:=Nil
  3119. else
  3120. Result:=@EnumeratedAliases[i].Aliases
  3121. end;
  3122. Function AddEnumeratedAliases(aTypeInfo : PTypeInfo) : PElementAliasArray;
  3123. Var
  3124. L : Integer;
  3125. begin
  3126. L:=Length(EnumeratedAliases);
  3127. SetLength(EnumeratedAliases,L+1);
  3128. EnumeratedAliases[L].TypeInfo:=aTypeInfo;
  3129. Result:=@EnumeratedAliases[L].Aliases;
  3130. end;
  3131. procedure RemoveEnumElementAliases(aTypeInfo: PTypeInfo);
  3132. Var
  3133. I,L : integer;
  3134. A : TEnumeratedAliases;
  3135. begin
  3136. I:=IndexOfEnumeratedAliases(aTypeInfo);
  3137. if I=-1 then
  3138. exit;
  3139. A:=EnumeratedAliases[i];
  3140. A.Aliases:=Nil;
  3141. A.TypeInfo:=Nil;
  3142. L:=Length(EnumeratedAliases)-1;
  3143. EnumeratedAliases[i]:=EnumeratedAliases[L];
  3144. EnumeratedAliases[L]:=A;
  3145. SetLength(EnumeratedAliases,L);
  3146. end;
  3147. Resourcestring
  3148. SErrNotAnEnumerated = 'Type information points to non-enumerated type';
  3149. SErrInvalidEnumeratedCount = 'Invalid number of enumerated values';
  3150. SErrDuplicateEnumerated = 'Duplicate alias for enumerated value';
  3151. procedure AddEnumElementAliases(aTypeInfo: PTypeInfo; const aNames: array of string; aStartValue: Integer = 0);
  3152. var
  3153. Aliases: PElementAliasArray;
  3154. A : TElementAliasArray;
  3155. L, I, J : Integer;
  3156. N : String;
  3157. PT : PTypeData;
  3158. begin
  3159. if (aTypeInfo^.Kind<>tkEnumeration) then
  3160. raise EArgumentException.Create(SErrNotAnEnumerated);
  3161. PT:=GetTypeData(aTypeInfo);
  3162. if (High(aNames)=-1) or ((aStartValue+High(aNames))> PT^.MaxValue) then
  3163. raise EArgumentException.Create(SErrInvalidEnumeratedCount);
  3164. Aliases:=GetEnumeratedAliases(aTypeInfo);
  3165. if (Aliases=Nil) then
  3166. Aliases:=AddEnumeratedAliases(aTypeInfo);
  3167. A:=Aliases^;
  3168. I:=0;
  3169. L:=Length(a);
  3170. SetLength(a,L+High(aNames)+1);
  3171. try
  3172. for N in aNames do
  3173. begin
  3174. for J:=0 to (L+I)-1 do
  3175. if SameText(N,A[J].Alias) then
  3176. raise EArgumentException.Create(SErrDuplicateEnumerated);
  3177. with A[L+I] do
  3178. begin
  3179. Ordinal:=aStartValue+I;
  3180. alias:=N;
  3181. end;
  3182. Inc(I);
  3183. end;
  3184. finally
  3185. // In case of exception, we need to correct the length.
  3186. if Length(A)<>I+L then
  3187. SetLength(A,I+L);
  3188. Aliases^:=A;
  3189. end;
  3190. end;
  3191. function GetEnumeratedAliasValue(aTypeInfo: PTypeInfo; const aName: string): Integer;
  3192. var
  3193. I : Integer;
  3194. Aliases: PElementAliasArray;
  3195. begin
  3196. Result:=-1;
  3197. Aliases:=GetEnumeratedAliases(aTypeInfo);
  3198. if (Aliases=Nil) then
  3199. Exit;
  3200. I:=Length(Aliases^)-1;
  3201. While (Result=-1) and (I>=0) do
  3202. begin
  3203. if SameText(Aliases^[I].Alias, aName) then
  3204. Result:=Aliases^[I].Ordinal;
  3205. Dec(I);
  3206. end;
  3207. end;
  3208. end.