typinfo.pp 27 KB

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