typinfo.pp 115 KB

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