typinfo.pp 103 KB

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