typinfo.pp 112 KB

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