typinfo.pp 112 KB

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