2
0

typinfo.pp 113 KB

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