typinfo.pp 115 KB

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