typinfo.pp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1998,99 by Florian Klaempfl
  5. member of the Free Pascal development team
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. { This unit provides the same functionality as the TypInfo Unit }
  13. { of Delphi }
  14. unit typinfo;
  15. interface
  16. {$MODE objfpc}
  17. uses sysutils;
  18. // temporary types:
  19. type
  20. PShortString =^ShortString;
  21. PByte =^Byte;
  22. PWord =^Word;
  23. PLongint =^Longint;
  24. PBoolean =^Boolean;
  25. PSingle =^Single;
  26. PDouble =^Double;
  27. PExtended =^Extended;
  28. PComp =^Comp;
  29. PFixed16 =^Fixed16;
  30. { Doesn't exist ?
  31. PFIxed32 = ^Fixed32;
  32. }
  33. Variant = Pointer;
  34. {$MINENUMSIZE 1 this saves a lot of memory }
  35. // if you change one of the following enumeration types
  36. // you have also to change the compiler in an appropriate way !
  37. TTypeKind = (tkUnknown,tkInteger,tkChar,tkEnumeration,
  38. tkFloat,tkSet,tkMethod,tkSString,tkLString,tkAString,
  39. tkWString,tkVariant,tkArray,tkRecord,tkInterface,
  40. tkClass,tkObject,tkWChar,tkBool);
  41. TTOrdType = (otSByte,otUByte,otSWord,otUWord,otSLong,otULong);
  42. TFloatType = (ftSingle,ftDouble,ftExtended,ftComp,ftCurr,
  43. ftFixed16,ftFixed32);
  44. TMethodKind = (mkProcedure,mkFunction,mkConstructor,mkDestructor,
  45. mkClassProcedure, mkClassFunction);
  46. TParamFlags = set of (pfVar,pfConst,pfArray,pfAddress,pfReference,pfOut);
  47. TIntfFlags = set of (ifHasGuid,ifDispInterface,ifDispatch);
  48. {$MINENUMSIZE DEFAULT}
  49. const
  50. ptField = 0;
  51. ptStatic = 1;
  52. ptVirtual = 2;
  53. ptConst = 3;
  54. tkString = tkSString;
  55. type
  56. TTypeKinds = set of TTypeKind;
  57. {$PACKRECORDS 1}
  58. TTypeInfo = record
  59. Kind : TTypeKind;
  60. Name : ShortString;
  61. // here the type data follows as TTypeData record
  62. end;
  63. PTypeInfo = ^TTypeInfo;
  64. PPTypeInfo = ^PTypeInfo;
  65. PTypeData = ^TTypeData;
  66. TTypeData = packed record
  67. case TTypeKind of
  68. tkUnKnown,tkLString,tkWString,tkAString,tkVariant:
  69. ();
  70. tkInteger,tkChar,tkEnumeration,tkWChar:
  71. (OrdType : TTOrdType;
  72. case TTypeKind of
  73. tkInteger,tkChar,tkEnumeration,tkBool,tkWChar : (
  74. MinValue,MaxValue : Longint;
  75. case TTypeKind of
  76. tkEnumeration:
  77. (
  78. BaseType : PTypeInfo;
  79. NameList : ShortString)
  80. );
  81. tkSet:
  82. (CompType : PTypeInfo)
  83. );
  84. tkFloat:
  85. (FloatType : TFloatType);
  86. tkSString:
  87. (MaxLength : Byte);
  88. tkClass:
  89. (ClassType : TClass;
  90. ParentInfo : PTypeInfo;
  91. PropCount : SmallInt;
  92. UnitName : ShortString
  93. // here the properties follow as array of TPropInfo
  94. );
  95. tkMethod:
  96. (MethodKind : TMethodKind;
  97. ParamCount : Byte;
  98. ParamList : array[0..1023] of Char
  99. {in reality ParamList is a array[1..ParamCount] of:
  100. record
  101. Flags : TParamFlags;
  102. ParamName : ShortString;
  103. TypeName : ShortString;
  104. end;
  105. followed by
  106. ResultType : ShortString}
  107. );
  108. tkInterface:
  109. ({!!!!!!!}
  110. );
  111. end;
  112. // unsed, just for completeness
  113. TPropData = packed record
  114. PropCount : Word;
  115. PropList : record end;
  116. end;
  117. PPropInfo = ^TPropInfo;
  118. TPropInfo = packed record
  119. PropType : PTypeInfo;
  120. GetProc : Pointer;
  121. SetProc : Pointer;
  122. StoredProc : Pointer;
  123. Index : Integer;
  124. Default : Longint;
  125. NameIndex : SmallInt;
  126. // contains the type of the Get/Set/Storedproc, see also ptxxx
  127. // bit 0..1 GetProc
  128. // 2..3 SetProc
  129. // 4..5 StoredProc
  130. // 6 : true, constant index property
  131. PropProcs : Byte;
  132. Name : ShortString;
  133. end;
  134. TProcInfoProc = procedure(PropInfo : PPropInfo) of object;
  135. PPropList = ^TPropList;
  136. TPropList = array[0..65535] of PPropInfo;
  137. const
  138. tkAny = [Low(TTypeKind)..High(TTypeKind)];
  139. tkMethods = [tkMethod];
  140. tkProperties = tkAny-tkMethods-[tkUnknown];
  141. { general property handling }
  142. // just skips the id and the name
  143. function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
  144. // searches in the property PropName
  145. function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string) : PPropInfo;
  146. procedure GetPropInfos(TypeInfo : PTypeInfo;PropList : PPropList);
  147. function GetPropList(TypeInfo : PTypeInfo;TypeKinds : TTypeKinds;
  148. PropList : PPropList) : Integer;
  149. // returns true, if PropInfo is a stored property
  150. function IsStoredProp(Instance : TObject;PropInfo : PPropInfo) : Boolean;
  151. { subroutines to read/write properties }
  152. function GetOrdProp(Instance : TObject;PropInfo : PPropInfo) : Longint;
  153. procedure SetOrdProp(Instance : TObject;PropInfo : PPropInfo;
  154. Value : Longint);
  155. function GetStrProp(Instance : TObject;PropInfo : PPropInfo) : Ansistring;
  156. procedure SetStrProp(Instance : TObject;PropInfo : PPropInfo;
  157. const Value : Ansistring);
  158. function GetFloatProp(Instance : TObject;PropInfo : PPropInfo) : Extended;
  159. procedure SetFloatProp(Instance : TObject;PropInfo : PPropInfo;
  160. Value : Extended);
  161. function GetVariantProp(Instance : TObject;PropInfo : PPropInfo): Variant;
  162. procedure SetVariantProp(Instance : TObject;PropInfo : PPropInfo;
  163. const Value: Variant);
  164. function GetMethodProp(Instance : TObject;PropInfo : PPropInfo) : TMethod;
  165. procedure SetMethodProp(Instance : TObject;PropInfo : PPropInfo;
  166. const Value : TMethod);
  167. { misc. stuff }
  168. function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
  169. function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
  170. implementation
  171. type
  172. PMethod = ^TMethod;
  173. {$ASMMODE ATT}
  174. function CallIntegerFunc(s : Pointer;Address : Pointer; INdex,IValue : Longint) : Integer;assembler;
  175. asm
  176. movl S,%esi
  177. movl Address,%edi
  178. // ? Indexed function
  179. movl Index,%eax
  180. xorl %eax,%eax
  181. je .LINoPush
  182. movl IValue,%eax
  183. pushl %eax
  184. .LINoPush:
  185. push %esi
  186. call %edi
  187. // now the result is in EAX
  188. end;
  189. function CallIntegerProc(s : Pointer;Address : Pointer;Value : Integer; INdex,IVAlue : Longint) : Integer;assembler;
  190. asm
  191. movl S,%esi
  192. movl Address,%edi
  193. // Push value to set
  194. movl Value,%eax
  195. pushl %eax
  196. // ? Indexed procedure
  197. movl Index,%eax
  198. xorl %eax,%eax
  199. je .LIPNoPush
  200. movl IValue,%eax
  201. pushl %eax
  202. .LIPNoPush:
  203. pushl %esi
  204. call %edi
  205. end;
  206. function CallExtendedFunc(s : Pointer;Address : Pointer; INdex,IValue : Longint) : Extended;assembler;
  207. asm
  208. movl S,%esi
  209. movl Address,%edi
  210. // ? Indexed function
  211. movl Index,%eax
  212. xorl %eax,%eax
  213. je .LINoPush
  214. movl IValue,%eax
  215. pushl %eax
  216. .LINoPush:
  217. push %esi
  218. call %edi
  219. //
  220. end;
  221. function CallExtendedProc(s : Pointer;Address : Pointer;Value : Extended; INdex,IVAlue : Longint) : Integer;assembler;
  222. asm
  223. movl S,%esi
  224. movl Address,%edi
  225. // Push value to set
  226. leal Value,%eax
  227. pushl (%eax)
  228. pushl 4(%eax)
  229. pushl 8(%eax)
  230. // ? Indexed procedure
  231. movl Index,%eax
  232. xorl %eax,%eax
  233. je .LIPNoPush
  234. movl IValue,%eax
  235. pushl %eax
  236. .LIPNoPush:
  237. push %esi
  238. call %edi
  239. end;
  240. function CallBooleanFunc(s : Pointer;Address : Pointer; Index,IValue : Longint) : Boolean;assembler;
  241. asm
  242. movl S,%esi
  243. movl Address,%edi
  244. // ? Indexed function
  245. movl Index,%eax
  246. xorl %eax,%eax
  247. je .LBNoPush
  248. movl IValue,%eax
  249. pushl %eax
  250. .LBNoPush:
  251. push %esi
  252. call %edi
  253. end;
  254. // Assembler functions can't have short stringreturn values.
  255. // So we make a procedure with var parameter.
  256. // That's not true (FK)
  257. Procedure CallSStringFunc(s : Pointer;Address : Pointer; INdex,IValue : Longint;
  258. Var Res: Shortstring);assembler;
  259. asm
  260. movl S,%esi
  261. movl Address,%edi
  262. // ? Indexed function
  263. movl Index,%eax
  264. xorl %eax,%eax
  265. jnz .LSSNoPush
  266. movl IValue,%eax
  267. pushl %eax
  268. // the result is stored in an invisible parameter
  269. pushl Res
  270. .LSSNoPush:
  271. push %esi
  272. call %edi
  273. end;
  274. Procedure CallSStringProc(s : Pointer;Address : Pointer;Const Value : ShortString; INdex,IVAlue : Longint);assembler;
  275. asm
  276. movl S,%esi
  277. movl Address,%edi
  278. // Push value to set
  279. movl Value,%eax
  280. pushl %eax
  281. // ? Indexed procedure
  282. movl Index,%eax
  283. xorl %eax,%eax
  284. jnz .LSSPNoPush
  285. movl IValue,%eax
  286. pushl %eax
  287. .LSSPNoPush:
  288. push %esi
  289. call %edi
  290. end;
  291. function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
  292. begin
  293. GetTypeData:=PTypeData(pointer(TypeInfo)+2+PByte(pointer(TypeInfo)+1)^);
  294. end;
  295. function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string) : PPropInfo;
  296. var
  297. hp : PTypeData;
  298. i : longint;
  299. begin
  300. while Assigned(TypeInfo) do
  301. begin
  302. // skip the name
  303. hp:=GetTypeData(Typeinfo);
  304. // the class info rtti the property rtti follows
  305. // immediatly
  306. Result:=PPropInfo(pointer(@hp^.UnitName)+Length(hp^.UnitName)+1+SizeOF(Word));
  307. for i:=1 to hp^.PropCount do
  308. begin
  309. // found a property of that name ?
  310. if Result^.Name=PropName then
  311. exit;
  312. // skip to next property
  313. Result:=PPropInfo(pointer(@Result^.Name)+byte(Result^.Name[0])+1);
  314. end;
  315. // parent class
  316. Typeinfo:=hp^.ParentInfo;
  317. end;
  318. Result:=Nil;
  319. end;
  320. function IsStoredProp(Instance : TObject;PropInfo : PPropInfo) : Boolean;
  321. begin
  322. case (PropInfo^.PropProcs shr 4) and 3 of
  323. ptfield:
  324. IsStoredProp:=PBoolean(Pointer(Instance)+Longint(PropInfo^.StoredProc))^;
  325. ptstatic:
  326. IsStoredProp:=CallBooleanFunc(Instance,PropInfo^.StoredProc,0,0);
  327. ptvirtual:
  328. IsStoredProp:=CallBooleanFunc(Instance,ppointer(Pointer(Instance.ClassType)+Longint(PropInfo^.StoredProc))^,0,0);
  329. ptconst:
  330. IsStoredProp:=LongBool(PropInfo^.StoredProc);
  331. end;
  332. end;
  333. procedure GetPropInfos(TypeInfo : PTypeInfo;PropList : PPropList);
  334. {
  335. Store Pointers to property information in the list pointed
  336. to by proplist. PRopList must contain enough space to hold ALL
  337. properties.
  338. }
  339. Type PWord = ^Word;
  340. Var TD : PTypeData;
  341. TP : PPropInfo;
  342. Count : Longint;
  343. begin
  344. TD:=GetTypeData(TypeInfo);
  345. // Get this objects TOTAL published properties count
  346. TP:=(@TD^.UnitName+Length(TD^.UnitName)+1);
  347. Count:=PWord(TP)^;
  348. // Now point TP to first propinfo record.
  349. Inc(Longint(TP),SizeOF(Word));
  350. While Count>0 do
  351. begin
  352. PropList^[0]:=TP;
  353. Inc(Longint(PropList),SizeOf(Pointer));
  354. // Point to TP next propinfo record.
  355. // Located at Name[Length(Name)+1] !
  356. TP:=PPropInfo(pointer(@TP^.Name)+PByte(@TP^.Name)^+1);
  357. Dec(Count);
  358. end;
  359. // recursive call for parent info.
  360. If TD^.Parentinfo<>Nil then
  361. GetPropInfos (TD^.ParentInfo,PropList);
  362. end;
  363. Procedure InsertProp (PL : PProplist;PI : PPropInfo; Count : longint);
  364. VAr I : Longint;
  365. begin
  366. I:=0;
  367. While (I<Count) and (PI^.Name>PL^[I]^.Name) do Inc(I);
  368. If I<Count then
  369. Move(PL^[I],PL[I+1],Count-I*SizeOf(Pointer));
  370. PL^[I]:=PI;
  371. end;
  372. function GetPropList(TypeInfo : PTypeInfo;TypeKinds : TTypeKinds;
  373. PropList : PPropList) : Integer;
  374. {
  375. Store Pointers to property information OF A CERTAIN KIND in the list pointed
  376. to by proplist. PRopList must contain enough space to hold ALL
  377. properties.
  378. }
  379. Var TempList : PPropList;
  380. PropInfo : PPropinfo;
  381. I,Count : longint;
  382. begin
  383. Result:=0;
  384. Count:=GetTypeData(TypeInfo)^.Propcount;
  385. If Count>0 then
  386. begin
  387. GetMem(TempList,Count*SizeOf(Pointer));
  388. Try
  389. GetPropInfos(TypeInfo,TempList);
  390. For I:=0 to Count-1 do
  391. begin
  392. PropInfo:=TempList^[i];
  393. If PropInfo^.PropType^.Kind in TypeKinds then
  394. begin
  395. InsertProp(PropList,PropInfo,Result);
  396. Inc(Result);
  397. end;
  398. end;
  399. finally
  400. FreeMem(TempList,Count*SizeOf(Pointer));
  401. end;
  402. end;
  403. end;
  404. Procedure SetIndexValues (P: PPRopInfo; Var Index,IValue : Longint);
  405. begin
  406. Index:=((P^.PropProcs shr 6) and 1);
  407. If Index<>0 then
  408. IValue:=P^.Index
  409. else
  410. IValue:=0;
  411. end;
  412. function GetOrdProp(Instance : TObject;PropInfo : PPropInfo) : Longint;
  413. var
  414. value,Index,Ivalue : longint;
  415. begin
  416. SetIndexValues(PropInfo,Index,Ivalue);
  417. case (PropInfo^.PropProcs) and 3 of
  418. ptfield:
  419. Value:=PLongint(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  420. ptstatic:
  421. Value:=CallIntegerFunc(Instance,PropInfo^.GetProc,Index,IValue);
  422. ptvirtual:
  423. Value:=CallIntegerFunc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^,Index,IValue);
  424. end;
  425. { cut off unnecessary stuff }
  426. case GetTypeData(PropInfo^.PropType)^.OrdType of
  427. otSWord,otUWord:
  428. Value:=Value and $ffff;
  429. otSByte,otUByte:
  430. Value:=Value and $ff;
  431. end;
  432. GetOrdProp:=Value;
  433. end;
  434. procedure SetOrdProp(Instance : TObject;PropInfo : PPropInfo;
  435. Value : Longint);
  436. var
  437. Index,IValue : Longint;
  438. DataSize: Integer;
  439. begin
  440. { cut off unnecessary stuff }
  441. case GetTypeData(PropInfo^.PropType)^.OrdType of
  442. otSWord,otUWord: begin
  443. Value:=Value and $ffff;
  444. DataSize := 2;
  445. end;
  446. otSByte,otUByte: begin
  447. Value:=Value and $ff;
  448. DataSize := 1;
  449. end;
  450. else DataSize := 4;
  451. end;
  452. SetIndexValues(PropInfo,Index,Ivalue);
  453. case (PropInfo^.PropProcs shr 2) and 3 of
  454. ptfield:
  455. case DataSize of
  456. 1: PByte(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Byte(Value);
  457. 2: PWord(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Word(Value);
  458. 4: PLongint(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  459. end;
  460. ptstatic:
  461. CallIntegerProc(Instance,PropInfo^.SetProc,Value,Index,IValue);
  462. ptvirtual:
  463. CallIntegerProc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.SetProc))^,Value,Index,IValue);
  464. end;
  465. end;
  466. Function GetAStrProp(Instance : TObject;PropInfo : PPropInfo):Pointer;
  467. {
  468. Dirty trick based on fact that AnsiString is just a pointer,
  469. hence can be treated like an integer type.
  470. }
  471. var
  472. value : Pointer;
  473. Index,Ivalue : Longint;
  474. begin
  475. SetIndexValues(PropInfo,Index,IValue);
  476. case (PropInfo^.PropProcs) and 3 of
  477. ptfield:
  478. Value:=Pointer(PLongint(Pointer(Instance)+Longint(PropInfo^.GetProc))^);
  479. ptstatic:
  480. Value:=Pointer(CallIntegerFunc(Instance,PropInfo^.GetProc,Index,IValue));
  481. ptvirtual:
  482. Value:=Pointer(CallIntegerFunc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^,Index,IValue));
  483. end;
  484. GetAstrProp:=Value;
  485. end;
  486. Function GetSStrProp(Instance : TObject;PropInfo : PPropInfo):ShortString;
  487. var
  488. value : ShortString;
  489. Index,IValue : Longint;
  490. begin
  491. SetIndexValues(PropInfo,Index,IValue);
  492. case (PropInfo^.PropProcs) and 3 of
  493. ptfield:
  494. Value:=PShortString(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  495. ptstatic:
  496. CallSStringFunc(Instance,PropInfo^.GetProc,Index,IValue,Value);
  497. ptvirtual:
  498. CallSSTringFunc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^,Index,Ivalue,Value);
  499. end;
  500. GetSStrProp:=Value;
  501. end;
  502. function GetStrProp(Instance : TObject;PropInfo : PPropInfo) : Ansistring;
  503. begin
  504. Case Propinfo^.PropType^.Kind of
  505. tkSString : Result:=GetSStrProp(Instance,PropInfo);
  506. tkAString : Pointer(Result):=GetAStrProp(Instance,Propinfo);
  507. else
  508. Result:='';
  509. end;
  510. end;
  511. procedure SetAStrProp(Instance : TObject;PropInfo : PPropInfo;
  512. const Value : AnsiString);
  513. {
  514. Dirty trick based on fact that AnsiString is just a pointer,
  515. hence can be treated like an integer type.
  516. }
  517. var
  518. Index,Ivalue : Longint;
  519. begin
  520. SetIndexValues(PropInfo,Index,IValue);
  521. case (PropInfo^.PropProcs shr 2) and 3 of
  522. ptfield:
  523. PLongint(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Longint(Pointer(Value)) ;
  524. ptstatic:
  525. CallIntegerProc(Instance,PropInfo^.SetProc,Longint(Pointer(Value)),Index,IValue);
  526. ptvirtual:
  527. CallIntegerProc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.SetProc))^,Longint(Pointer(Value)),Index,IValue);
  528. end;
  529. end;
  530. procedure SetSStrProp(Instance : TObject;PropInfo : PPropInfo;
  531. const Value : ShortString);
  532. Var Index,IValue: longint;
  533. begin
  534. SetIndexValues(PRopInfo,Index,IValue);
  535. case (PropInfo^.PropProcs shr 2) and 3 of
  536. ptfield:
  537. PShortString(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  538. ptstatic:
  539. CallSStringProc(Instance,PropInfo^.GetProc,Value,Index,IValue);
  540. ptvirtual:
  541. CallSStringProc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^,Value,Index,IValue);
  542. end;
  543. end;
  544. procedure SetStrProp(Instance : TObject;PropInfo : PPropInfo;
  545. const Value : AnsiString);
  546. begin
  547. Case Propinfo^.PropType^.Kind of
  548. tkSString : SetSStrProp(Instance,PropInfo,Value);
  549. tkAString : SetAStrProp(Instance,Propinfo,Value);
  550. end;
  551. end;
  552. function GetFloatProp(Instance : TObject;PropInfo : PPropInfo) : Extended;
  553. var
  554. Index,Ivalue : longint;
  555. Value : Extended;
  556. begin
  557. SetIndexValues(PropInfo,Index,Ivalue);
  558. case (PropInfo^.PropProcs) and 3 of
  559. ptfield:
  560. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  561. ftSingle:
  562. Value:=PSingle(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  563. ftDouble:
  564. Value:=PDouble(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  565. ftExtended:
  566. Value:=PExtended(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  567. ftcomp:
  568. Value:=PComp(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  569. { Uncommenting this code results in a internal error!!
  570. ftFixed16:
  571. Value:=PFixed16(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  572. ftfixed32:
  573. Value:=PFixed32(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  574. }
  575. end;
  576. ptstatic:
  577. Value:=CallExtendedFunc(Instance,PropInfo^.GetProc,Index,IValue);
  578. ptvirtual:
  579. Value:=CallExtendedFunc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^,Index,IValue);
  580. end;
  581. Result:=Value;
  582. end;
  583. procedure SetFloatProp(Instance : TObject;PropInfo : PPropInfo;
  584. Value : Extended);
  585. Var IValue,Index : longint;
  586. begin
  587. SetIndexValues(PropInfo,Index,Ivalue);
  588. case (PropInfo^.PropProcs shr 2) and 3 of
  589. ptfield:
  590. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  591. ftSingle:
  592. PSingle(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  593. ftDouble:
  594. PDouble(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  595. ftExtended:
  596. PExtended(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  597. ftcomp:
  598. PComp(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Comp(Value);
  599. { Uncommenting this code results in a internal error!!
  600. ftFixed16:
  601. PFixed16(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  602. ftfixed32:
  603. PFixed32(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  604. }
  605. end;
  606. ptstatic:
  607. CallExtendedProc(Instance,PropInfo^.SetProc,Value,Index,IValue);
  608. ptvirtual:
  609. CallExtendedProc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^,Value,Index,IValue);
  610. end;
  611. end;
  612. function GetVariantProp(Instance : TObject;PropInfo : PPropInfo): Variant;
  613. begin
  614. {!!!!!!!!!!!}
  615. Result:=nil;
  616. end;
  617. procedure SetVariantProp(Instance : TObject;PropInfo : PPropInfo;
  618. const Value: Variant);
  619. begin
  620. {!!!!!!!!!!!}
  621. end;
  622. function GetMethodProp(Instance : TObject;PropInfo : PPropInfo) : TMethod;
  623. var
  624. value: PMethod;
  625. Index,Ivalue : longint;
  626. begin
  627. SetIndexValues(PropInfo,Index,Ivalue);
  628. case (PropInfo^.PropProcs) and 3 of
  629. ptfield:
  630. Value:=PMethod(Pointer(Instance)+Longint(PropInfo^.GetProc));
  631. ptstatic:
  632. Value:=PMethod(CallIntegerFunc(Instance,PropInfo^.GetProc,Index,IValue));
  633. ptvirtual:
  634. Value:=PMethod(CallIntegerFunc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^,Index,IValue));
  635. end;
  636. GetMethodProp:=Value^;
  637. end;
  638. procedure SetMethodProp(Instance : TObject;PropInfo : PPropInfo;
  639. const Value : TMethod);
  640. var
  641. Index,IValue : Longint;
  642. begin
  643. SetIndexValues(PropInfo,Index,Ivalue);
  644. case (PropInfo^.PropProcs shr 2) and 3 of
  645. ptfield:
  646. PMethod(Pointer(Instance)+Longint(PropInfo^.SetProc))^ := Value;
  647. ptstatic:
  648. CallIntegerProc(Instance,PropInfo^.SetProc,Integer(@Value), Index, IValue);
  649. ptvirtual:
  650. CallIntegerProc(Instance,
  651. PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.SetProc))^,
  652. Integer(@Value), Index, IValue);
  653. end;
  654. end;
  655. function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
  656. Var PS : PShortString;
  657. PT : PTypeData;
  658. begin
  659. PT:=GetTypeData(TypeInfo);
  660. // ^.BaseType);
  661. // If PT^.MinValue<0 then Value:=Ord(Value<>0); {map to 0/1}
  662. PS:=@PT^.NameList;
  663. While Value>0 Do
  664. begin
  665. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  666. Dec(Value);
  667. end;
  668. Result:=PS^;
  669. end;
  670. function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
  671. Var PS : PShortString;
  672. PT : PTypeData;
  673. Count : longint;
  674. begin
  675. If Length(Name)=0 then exit(-1);
  676. PT:=GetTypeData(TypeInfo);
  677. Count:=0;
  678. Result:=-1;
  679. PS:=@PT^.NameList;
  680. While (Result=-1) and (PByte(PS)^<>0) do
  681. begin
  682. If PS^=Name then
  683. Result:=Count;
  684. PS:=PShortString(pointer(PS)+PByte(PS)^);
  685. Inc(Count);
  686. end;
  687. end;
  688. end.
  689. {
  690. $Log$
  691. Revision 1.30 1999-11-06 14:41:31 peter
  692. * truncated log
  693. Revision 1.29 1999/09/16 08:59:48 florian
  694. * GetPropInfo returns now nil if the property wasn't found
  695. Revision 1.28 1999/09/15 20:27:24 florian
  696. + patch of Sebastion Guenther applied: Get/SetMethodProp implementation
  697. Revision 1.27 1999/09/08 16:14:43 peter
  698. * pointer fixes
  699. Revision 1.26 1999/09/03 15:39:23 michael
  700. * Fixes from Sebastian Guenther
  701. Revision 1.25 1999/08/29 22:21:27 michael
  702. * Patch from Sebastian Guenther
  703. Revision 1.24 1999/08/06 13:21:40 michael
  704. * Patch from Sebastian Guenther
  705. Revision 1.23 1999/06/04 12:48:37 michael
  706. * Fix by Sebastian Guenther.
  707. Revision 1.22 1999/05/19 12:03:23 florian
  708. * the set/get procedures must be called with call %edi instead call (%edi)
  709. * handling of extended and string properties fixed
  710. Revision 1.21 1999/05/07 11:02:14 florian
  711. * two typos fixed
  712. Revision 1.20 1999/05/03 07:30:07 michael
  713. * Fixes in getenum*
  714. Revision 1.19 1999/04/08 11:31:04 peter
  715. * removed warnings
  716. Revision 1.18 1999/01/19 16:08:12 pierre
  717. ?? is callSStringProc a function ??
  718. Revision 1.17 1998/12/15 22:43:13 peter
  719. * removed temp symbols
  720. Revision 1.16 1998/12/02 12:35:07 michael
  721. More changes for type-information
  722. Revision 1.15 1998/11/26 14:57:47 michael
  723. + Added packrecords 1
  724. Revision 1.11 1998/09/24 23:45:28 peter
  725. * updated for auto objpas loading
  726. Revision 1.10 1998/09/20 08:25:34 florian
  727. + description of tpropinfo.propprocs bit 6 added
  728. Revision 1.9 1998/09/19 15:25:45 florian
  729. * procedure GetOrdProp added
  730. Revision 1.8 1998/09/19 08:33:53 florian
  731. + some procedures added
  732. Revision 1.7 1998/09/08 09:52:31 florian
  733. * small problems fixed
  734. }