typinfo.pp 98 KB

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