typinfo.pp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  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. begin
  302. while Assigned(TypeInfo) do
  303. begin
  304. // skip the name
  305. hp:=GetTypeData(Typeinfo);
  306. // the class info rtti the property rtti follows
  307. // immediatly
  308. Result:=PPropInfo(pointer(@hp^.UnitName)+Length(hp^.UnitName)+1+SizeOF(Word));
  309. for i:=1 to hp^.PropCount do
  310. begin
  311. // found a property of that name ?
  312. if Result^.Name=PropName then
  313. exit;
  314. // skip to next property
  315. Result:=PPropInfo(pointer(@Result^.Name)+byte(Result^.Name[0])+1);
  316. end;
  317. // parent class
  318. Typeinfo:=hp^.ParentInfo;
  319. end;
  320. Result:=Nil;
  321. end;
  322. function IsStoredProp(Instance : TObject;PropInfo : PPropInfo) : Boolean;
  323. begin
  324. case (PropInfo^.PropProcs shr 4) and 3 of
  325. ptfield:
  326. IsStoredProp:=PBoolean(Pointer(Instance)+Longint(PropInfo^.StoredProc))^;
  327. ptstatic:
  328. IsStoredProp:=CallBooleanFunc(Instance,PropInfo^.StoredProc,0,0);
  329. ptvirtual:
  330. IsStoredProp:=CallBooleanFunc(Instance,ppointer(Pointer(Instance.ClassType)+Longint(PropInfo^.StoredProc))^,0,0);
  331. ptconst:
  332. IsStoredProp:=LongBool(PropInfo^.StoredProc);
  333. end;
  334. end;
  335. procedure GetPropInfos(TypeInfo : PTypeInfo;PropList : PPropList);
  336. {
  337. Store Pointers to property information in the list pointed
  338. to by proplist. PRopList must contain enough space to hold ALL
  339. properties.
  340. }
  341. Type PWord = ^Word;
  342. Var TD : PTypeData;
  343. TP : PPropInfo;
  344. Count : Longint;
  345. begin
  346. TD:=GetTypeData(TypeInfo);
  347. // Get this objects TOTAL published properties count
  348. TP:=(@TD^.UnitName+Length(TD^.UnitName)+1);
  349. Count:=PWord(TP)^;
  350. // Now point TP to first propinfo record.
  351. Inc(Longint(TP),SizeOF(Word));
  352. While Count>0 do
  353. begin
  354. PropList^[0]:=TP;
  355. Inc(Longint(PropList),SizeOf(Pointer));
  356. // Point to TP next propinfo record.
  357. // Located at Name[Length(Name)+1] !
  358. TP:=PPropInfo(pointer(@TP^.Name)+PByte(@TP^.Name)^+1);
  359. Dec(Count);
  360. end;
  361. // recursive call for parent info.
  362. If TD^.Parentinfo<>Nil then
  363. GetPropInfos (TD^.ParentInfo,PropList);
  364. end;
  365. Procedure InsertProp (PL : PProplist;PI : PPropInfo; Count : longint);
  366. VAr I : Longint;
  367. begin
  368. I:=0;
  369. While (I<Count) and (PI^.Name>PL^[I]^.Name) do Inc(I);
  370. If I<Count then
  371. Move(PL^[I], PL^[I+1], (Count - I) * SizeOf(Pointer));
  372. PL^[I]:=PI;
  373. end;
  374. function GetPropList(TypeInfo : PTypeInfo;TypeKinds : TTypeKinds;
  375. PropList : PPropList) : Integer;
  376. {
  377. Store Pointers to property information OF A CERTAIN KIND in the list pointed
  378. to by proplist. PRopList must contain enough space to hold ALL
  379. properties.
  380. }
  381. Var TempList : PPropList;
  382. PropInfo : PPropinfo;
  383. I,Count : longint;
  384. begin
  385. Result:=0;
  386. Count:=GetTypeData(TypeInfo)^.Propcount;
  387. If Count>0 then
  388. begin
  389. GetMem(TempList,Count*SizeOf(Pointer));
  390. Try
  391. GetPropInfos(TypeInfo,TempList);
  392. For I:=0 to Count-1 do
  393. begin
  394. PropInfo:=TempList^[i];
  395. If PropInfo^.PropType^.Kind in TypeKinds then
  396. begin
  397. InsertProp(PropList,PropInfo,Result);
  398. Inc(Result);
  399. end;
  400. end;
  401. finally
  402. FreeMem(TempList,Count*SizeOf(Pointer));
  403. end;
  404. end;
  405. end;
  406. Procedure SetIndexValues (P: PPRopInfo; Var Index,IValue : Longint);
  407. begin
  408. Index:=((P^.PropProcs shr 6) and 1);
  409. If Index<>0 then
  410. IValue:=P^.Index
  411. else
  412. IValue:=0;
  413. end;
  414. function GetOrdProp(Instance : TObject;PropInfo : PPropInfo) : Longint;
  415. var
  416. value,Index,Ivalue : longint;
  417. TypeInfo: PTypeInfo;
  418. begin
  419. SetIndexValues(PropInfo,Index,Ivalue);
  420. case (PropInfo^.PropProcs) and 3 of
  421. ptfield:
  422. Value:=PLongint(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  423. ptstatic:
  424. Value:=CallIntegerFunc(Instance,PropInfo^.GetProc,Index,IValue);
  425. ptvirtual:
  426. Value:=CallIntegerFunc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^,Index,IValue);
  427. end;
  428. { cut off unnecessary stuff }
  429. TypeInfo := PropInfo^.PropType;
  430. case TypeInfo^.Kind of
  431. tkChar, tkBool:
  432. Value:=Value and $ff;
  433. tkWChar:
  434. Value:=Value and $ffff;
  435. tkInteger:
  436. case GetTypeData(TypeInfo)^.OrdType of
  437. otSWord,otUWord:
  438. Value:=Value and $ffff;
  439. otSByte,otUByte:
  440. Value:=Value and $ff;
  441. end;
  442. end;
  443. GetOrdProp:=Value;
  444. end;
  445. procedure SetOrdProp(Instance : TObject;PropInfo : PPropInfo;
  446. Value : Longint);
  447. var
  448. Index,IValue : Longint;
  449. DataSize: Integer;
  450. begin
  451. { cut off unnecessary stuff }
  452. case GetTypeData(PropInfo^.PropType)^.OrdType of
  453. otSWord,otUWord: begin
  454. Value:=Value and $ffff;
  455. DataSize := 2;
  456. end;
  457. otSByte,otUByte: begin
  458. Value:=Value and $ff;
  459. DataSize := 1;
  460. end;
  461. else DataSize := 4;
  462. end;
  463. SetIndexValues(PropInfo,Index,Ivalue);
  464. case (PropInfo^.PropProcs shr 2) and 3 of
  465. ptfield:
  466. case DataSize of
  467. 1: PByte(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Byte(Value);
  468. 2: PWord(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Word(Value);
  469. 4: PLongint(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  470. end;
  471. ptstatic:
  472. CallIntegerProc(Instance,PropInfo^.SetProc,Value,Index,IValue);
  473. ptvirtual:
  474. CallIntegerProc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.SetProc))^,Value,Index,IValue);
  475. end;
  476. end;
  477. Function GetAStrProp(Instance : TObject;PropInfo : PPropInfo):Pointer;
  478. {
  479. Dirty trick based on fact that AnsiString is just a pointer,
  480. hence can be treated like an integer type.
  481. }
  482. var
  483. value : Pointer;
  484. Index,Ivalue : Longint;
  485. begin
  486. SetIndexValues(PropInfo,Index,IValue);
  487. case (PropInfo^.PropProcs) and 3 of
  488. ptfield:
  489. Value:=Pointer(PLongint(Pointer(Instance)+Longint(PropInfo^.GetProc))^);
  490. ptstatic:
  491. Value:=Pointer(CallIntegerFunc(Instance,PropInfo^.GetProc,Index,IValue));
  492. ptvirtual:
  493. Value:=Pointer(CallIntegerFunc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^,Index,IValue));
  494. end;
  495. GetAstrProp:=Value;
  496. end;
  497. Function GetSStrProp(Instance : TObject;PropInfo : PPropInfo):ShortString;
  498. var
  499. value : ShortString;
  500. Index,IValue : Longint;
  501. begin
  502. SetIndexValues(PropInfo,Index,IValue);
  503. case (PropInfo^.PropProcs) and 3 of
  504. ptfield:
  505. Value:=PShortString(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  506. ptstatic:
  507. CallSStringFunc(Instance,PropInfo^.GetProc,Index,IValue,Value);
  508. ptvirtual:
  509. CallSSTringFunc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^,Index,Ivalue,Value);
  510. end;
  511. GetSStrProp:=Value;
  512. end;
  513. function GetStrProp(Instance : TObject;PropInfo : PPropInfo) : Ansistring;
  514. begin
  515. Case Propinfo^.PropType^.Kind of
  516. tkSString : Result:=GetSStrProp(Instance,PropInfo);
  517. tkAString : Pointer(Result):=GetAStrProp(Instance,Propinfo);
  518. else
  519. Result:='';
  520. end;
  521. end;
  522. procedure SetAStrProp(Instance : TObject;PropInfo : PPropInfo;
  523. const Value : AnsiString);
  524. {
  525. Dirty trick based on fact that AnsiString is just a pointer,
  526. hence can be treated like an integer type.
  527. }
  528. var
  529. Index,Ivalue : Longint;
  530. begin
  531. SetIndexValues(PropInfo,Index,IValue);
  532. case (PropInfo^.PropProcs shr 2) and 3 of
  533. ptfield:
  534. PLongint(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Longint(Pointer(Value)) ;
  535. ptstatic:
  536. CallIntegerProc(Instance,PropInfo^.SetProc,Longint(Pointer(Value)),Index,IValue);
  537. ptvirtual:
  538. CallIntegerProc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.SetProc))^,Longint(Pointer(Value)),Index,IValue);
  539. end;
  540. end;
  541. procedure SetSStrProp(Instance : TObject;PropInfo : PPropInfo;
  542. const Value : ShortString);
  543. Var Index,IValue: longint;
  544. begin
  545. SetIndexValues(PRopInfo,Index,IValue);
  546. case (PropInfo^.PropProcs shr 2) and 3 of
  547. ptfield:
  548. PShortString(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  549. ptstatic:
  550. CallSStringProc(Instance,PropInfo^.GetProc,Value,Index,IValue);
  551. ptvirtual:
  552. CallSStringProc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^,Value,Index,IValue);
  553. end;
  554. end;
  555. procedure SetStrProp(Instance : TObject;PropInfo : PPropInfo;
  556. const Value : AnsiString);
  557. begin
  558. Case Propinfo^.PropType^.Kind of
  559. tkSString : SetSStrProp(Instance,PropInfo,Value);
  560. tkAString : SetAStrProp(Instance,Propinfo,Value);
  561. end;
  562. end;
  563. function GetFloatProp(Instance : TObject;PropInfo : PPropInfo) : Extended;
  564. var
  565. Index,Ivalue : longint;
  566. Value : Extended;
  567. begin
  568. SetIndexValues(PropInfo,Index,Ivalue);
  569. case (PropInfo^.PropProcs) and 3 of
  570. ptfield:
  571. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  572. ftSingle:
  573. Value:=PSingle(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  574. ftDouble:
  575. Value:=PDouble(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  576. ftExtended:
  577. Value:=PExtended(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  578. ftcomp:
  579. Value:=PComp(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  580. { Uncommenting this code results in a internal error!!
  581. ftFixed16:
  582. Value:=PFixed16(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  583. ftfixed32:
  584. Value:=PFixed32(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  585. }
  586. end;
  587. ptstatic:
  588. Value:=CallExtendedFunc(Instance,PropInfo^.GetProc,Index,IValue);
  589. ptvirtual:
  590. Value:=CallExtendedFunc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^,Index,IValue);
  591. end;
  592. Result:=Value;
  593. end;
  594. procedure SetFloatProp(Instance : TObject;PropInfo : PPropInfo;
  595. Value : Extended);
  596. Var IValue,Index : longint;
  597. begin
  598. SetIndexValues(PropInfo,Index,Ivalue);
  599. case (PropInfo^.PropProcs shr 2) and 3 of
  600. ptfield:
  601. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  602. ftSingle:
  603. PSingle(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  604. ftDouble:
  605. PDouble(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  606. ftExtended:
  607. PExtended(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  608. ftcomp:
  609. PComp(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Comp(Value);
  610. { Uncommenting this code results in a internal error!!
  611. ftFixed16:
  612. PFixed16(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  613. ftfixed32:
  614. PFixed32(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  615. }
  616. end;
  617. ptstatic:
  618. CallExtendedProc(Instance,PropInfo^.SetProc,Value,Index,IValue);
  619. ptvirtual:
  620. CallExtendedProc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^,Value,Index,IValue);
  621. end;
  622. end;
  623. function GetVariantProp(Instance : TObject;PropInfo : PPropInfo): Variant;
  624. begin
  625. {!!!!!!!!!!!}
  626. Result:=nil;
  627. end;
  628. procedure SetVariantProp(Instance : TObject;PropInfo : PPropInfo;
  629. const Value: Variant);
  630. begin
  631. {!!!!!!!!!!!}
  632. end;
  633. function GetMethodProp(Instance : TObject;PropInfo : PPropInfo) : TMethod;
  634. var
  635. value: PMethod;
  636. Index,Ivalue : longint;
  637. begin
  638. SetIndexValues(PropInfo,Index,Ivalue);
  639. case (PropInfo^.PropProcs) and 3 of
  640. ptfield:
  641. Value:=PMethod(Pointer(Instance)+Longint(PropInfo^.GetProc));
  642. ptstatic:
  643. Value:=PMethod(CallIntegerFunc(Instance,PropInfo^.GetProc,Index,IValue));
  644. ptvirtual:
  645. Value:=PMethod(CallIntegerFunc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^,Index,IValue));
  646. end;
  647. GetMethodProp:=Value^;
  648. end;
  649. procedure SetMethodProp(Instance : TObject;PropInfo : PPropInfo;
  650. const Value : TMethod);
  651. var
  652. Index,IValue : Longint;
  653. begin
  654. SetIndexValues(PropInfo,Index,Ivalue);
  655. case (PropInfo^.PropProcs shr 2) and 3 of
  656. ptfield:
  657. PMethod(Pointer(Instance)+Longint(PropInfo^.SetProc))^ := Value;
  658. ptstatic:
  659. CallIntegerProc(Instance,PropInfo^.SetProc,Integer(@Value), Index, IValue);
  660. ptvirtual:
  661. CallIntegerProc(Instance,
  662. PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.SetProc))^,
  663. Integer(@Value), Index, IValue);
  664. end;
  665. end;
  666. function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
  667. Var PS : PShortString;
  668. PT : PTypeData;
  669. begin
  670. PT:=GetTypeData(TypeInfo);
  671. // ^.BaseType);
  672. // If PT^.MinValue<0 then Value:=Ord(Value<>0); {map to 0/1}
  673. PS:=@PT^.NameList;
  674. While Value>0 Do
  675. begin
  676. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  677. Dec(Value);
  678. end;
  679. Result:=PS^;
  680. end;
  681. function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
  682. Var PS : PShortString;
  683. PT : PTypeData;
  684. Count : longint;
  685. begin
  686. If Length(Name)=0 then exit(-1);
  687. PT:=GetTypeData(TypeInfo);
  688. Count:=0;
  689. Result:=-1;
  690. PS:=@PT^.NameList;
  691. While (Result=-1) and (PByte(PS)^<>0) do
  692. begin
  693. If PS^=Name then
  694. Result:=Count;
  695. PS:=PShortString(pointer(PS)+PByte(PS)^);
  696. Inc(Count);
  697. end;
  698. end;
  699. end.
  700. {
  701. $Log$
  702. Revision 1.38 2000-02-15 14:39:56 florian
  703. * disabled FIXED data type per default
  704. Revision 1.37 2000/02/09 16:59:33 peter
  705. * truncated log
  706. Revision 1.36 2000/01/07 16:41:44 daniel
  707. * copyright 2000
  708. Revision 1.35 2000/01/07 16:32:29 daniel
  709. * copyright 2000 added
  710. Revision 1.34 2000/01/06 01:08:33 sg
  711. * _This_ is the real revision 1.32... :-)
  712. Revision 1.33 2000/01/06 00:23:24 pierre
  713. * missing declarations for otChar andotWChar added
  714. Revision 1.32 2000/01/05 18:59:56 sg
  715. * Fixed missing () in InsertProp which caused memory corruptions
  716. * GetOrdProp handles Char and WChar now. (there are still some
  717. property types missing!)
  718. Revision 1.31 1999/12/28 12:19:36 jonas
  719. * replaced "movl mem,%eax; xorl %eax,%eax" with "movl mem,%eax;
  720. testl %eax,%eax"
  721. Revision 1.30 1999/11/06 14:41:31 peter
  722. * truncated log
  723. Revision 1.29 1999/09/16 08:59:48 florian
  724. * GetPropInfo returns now nil if the property wasn't found
  725. Revision 1.28 1999/09/15 20:27:24 florian
  726. + patch of Sebastion Guenther applied: Get/SetMethodProp implementation
  727. Revision 1.27 1999/09/08 16:14:43 peter
  728. * pointer fixes
  729. Revision 1.26 1999/09/03 15:39:23 michael
  730. * Fixes from Sebastian Guenther
  731. Revision 1.25 1999/08/29 22:21:27 michael
  732. * Patch from Sebastian Guenther
  733. Revision 1.24 1999/08/06 13:21:40 michael
  734. * Patch from Sebastian Guenther
  735. }