typinfo.pp 115 KB

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