typinfo.pp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871
  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,tkInt64,tkQWord);
  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. tkInt64:
  111. (MinInt64Value, MaxInt64Value: Int64);
  112. tkQWord:
  113. (MinQWordValue, MaxQWordValue: QWord);
  114. tkInterface:
  115. ({!!!!!!!}
  116. );
  117. end;
  118. // unsed, just for completeness
  119. TPropData = packed record
  120. PropCount : Word;
  121. PropList : record end;
  122. end;
  123. PPropInfo = ^TPropInfo;
  124. TPropInfo = packed record
  125. PropType : PTypeInfo;
  126. GetProc : Pointer;
  127. SetProc : Pointer;
  128. StoredProc : Pointer;
  129. Index : Integer;
  130. Default : Longint;
  131. NameIndex : SmallInt;
  132. // contains the type of the Get/Set/Storedproc, see also ptxxx
  133. // bit 0..1 GetProc
  134. // 2..3 SetProc
  135. // 4..5 StoredProc
  136. // 6 : true, constant index property
  137. PropProcs : Byte;
  138. Name : ShortString;
  139. end;
  140. TProcInfoProc = procedure(PropInfo : PPropInfo) of object;
  141. PPropList = ^TPropList;
  142. TPropList = array[0..65535] of PPropInfo;
  143. const
  144. tkAny = [Low(TTypeKind)..High(TTypeKind)];
  145. tkMethods = [tkMethod];
  146. tkProperties = tkAny-tkMethods-[tkUnknown];
  147. { general property handling }
  148. // just skips the id and the name
  149. function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
  150. // searches in the property PropName
  151. function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string) : PPropInfo;
  152. procedure GetPropInfos(TypeInfo : PTypeInfo;PropList : PPropList);
  153. function GetPropList(TypeInfo : PTypeInfo;TypeKinds : TTypeKinds;
  154. PropList : PPropList) : Integer;
  155. // returns true, if PropInfo is a stored property
  156. function IsStoredProp(Instance : TObject;PropInfo : PPropInfo) : Boolean;
  157. { subroutines to read/write properties }
  158. function GetOrdProp(Instance : TObject;PropInfo : PPropInfo) : Longint;
  159. procedure SetOrdProp(Instance : TObject;PropInfo : PPropInfo;
  160. Value : Longint);
  161. function GetStrProp(Instance : TObject;PropInfo : PPropInfo) : Ansistring;
  162. procedure SetStrProp(Instance : TObject;PropInfo : PPropInfo;
  163. const Value : Ansistring);
  164. function GetFloatProp(Instance : TObject;PropInfo : PPropInfo) : Extended;
  165. procedure SetFloatProp(Instance : TObject;PropInfo : PPropInfo;
  166. Value : Extended);
  167. function GetVariantProp(Instance : TObject;PropInfo : PPropInfo): Variant;
  168. procedure SetVariantProp(Instance : TObject;PropInfo : PPropInfo;
  169. const Value: Variant);
  170. function GetMethodProp(Instance : TObject;PropInfo : PPropInfo) : TMethod;
  171. procedure SetMethodProp(Instance : TObject;PropInfo : PPropInfo;
  172. const Value : TMethod);
  173. function GetInt64Prop(Instance: TObject; PropInfo: PPropInfo): Int64;
  174. procedure SetInt64Prop(Instance: TObject; PropInfo: PPropInfo;
  175. const Value: Int64);
  176. { misc. stuff }
  177. function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
  178. function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
  179. const
  180. BooleanIdents: array[Boolean] of String = ('False', 'True');
  181. DotSep: String = '.';
  182. implementation
  183. type
  184. PMethod = ^TMethod;
  185. {$ASMMODE ATT}
  186. function CallIntegerFunc(s: Pointer; Address: Pointer; Index, IValue: LongInt): Int64; assembler;
  187. asm
  188. movl S,%esi
  189. movl Address,%edi
  190. // ? Indexed function
  191. movl Index,%eax
  192. testl %eax,%eax
  193. je .LINoPush
  194. movl IValue,%eax
  195. pushl %eax
  196. .LINoPush:
  197. push %esi
  198. call %edi
  199. // now the result is in EDX:EAX
  200. end;
  201. function CallIntegerProc(s : Pointer;Address : Pointer;Value : Integer; INdex,IValue : Longint) : Integer;assembler;
  202. asm
  203. movl S,%esi
  204. movl Address,%edi
  205. // Push value to set
  206. movl Value,%eax
  207. pushl %eax
  208. // ? Indexed procedure
  209. movl Index,%eax
  210. testl %eax,%eax
  211. je .LIPNoPush
  212. movl IValue,%eax
  213. pushl %eax
  214. .LIPNoPush:
  215. pushl %esi
  216. call %edi
  217. end;
  218. function CallExtendedFunc(s : Pointer;Address : Pointer; INdex,IValue : Longint) : Extended;assembler;
  219. asm
  220. movl S,%esi
  221. movl Address,%edi
  222. // ? Indexed function
  223. movl Index,%eax
  224. testl %eax,%eax
  225. je .LINoPush
  226. movl IValue,%eax
  227. pushl %eax
  228. .LINoPush:
  229. push %esi
  230. call %edi
  231. //
  232. end;
  233. function CallExtendedProc(s : Pointer;Address : Pointer;Value : Extended; INdex,IVAlue : Longint) : Integer;assembler;
  234. asm
  235. movl S,%esi
  236. movl Address,%edi
  237. // Push value to set
  238. leal Value,%eax
  239. pushl (%eax)
  240. pushl 4(%eax)
  241. pushl 8(%eax)
  242. // ? Indexed procedure
  243. movl Index,%eax
  244. testl %eax,%eax
  245. je .LIPNoPush
  246. movl IValue,%eax
  247. pushl %eax
  248. .LIPNoPush:
  249. push %esi
  250. call %edi
  251. end;
  252. function CallBooleanFunc(s : Pointer;Address : Pointer; Index,IValue : Longint) : Boolean;assembler;
  253. asm
  254. movl S,%esi
  255. movl Address,%edi
  256. // ? Indexed function
  257. movl Index,%eax
  258. testl %eax,%eax
  259. je .LBNoPush
  260. movl IValue,%eax
  261. pushl %eax
  262. .LBNoPush:
  263. push %esi
  264. call %edi
  265. end;
  266. // Assembler functions can't have short stringreturn values.
  267. // So we make a procedure with var parameter.
  268. // That's not true (FK)
  269. Procedure CallSStringFunc(s : Pointer;Address : Pointer; INdex,IValue : Longint;
  270. Var Res: Shortstring);assembler;
  271. asm
  272. movl S,%esi
  273. movl Address,%edi
  274. // ? Indexed function
  275. movl Index,%eax
  276. testl %eax,%eax
  277. jnz .LSSNoPush
  278. movl IValue,%eax
  279. pushl %eax
  280. // the result is stored in an invisible parameter
  281. pushl Res
  282. .LSSNoPush:
  283. push %esi
  284. call %edi
  285. end;
  286. Procedure CallSStringProc(s : Pointer;Address : Pointer;Const Value : ShortString; INdex,IVAlue : Longint);assembler;
  287. asm
  288. movl S,%esi
  289. movl Address,%edi
  290. // Push value to set
  291. movl Value,%eax
  292. pushl %eax
  293. // ? Indexed procedure
  294. movl Index,%eax
  295. testl %eax,%eax
  296. jnz .LSSPNoPush
  297. movl IValue,%eax
  298. pushl %eax
  299. .LSSPNoPush:
  300. push %esi
  301. call %edi
  302. end;
  303. function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
  304. begin
  305. GetTypeData:=PTypeData(pointer(TypeInfo)+2+PByte(pointer(TypeInfo)+1)^);
  306. end;
  307. function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string) : PPropInfo;
  308. var
  309. hp : PTypeData;
  310. i : longint;
  311. p : string;
  312. begin
  313. P:=UpCase(PropName);
  314. while Assigned(TypeInfo) do
  315. begin
  316. // skip the name
  317. hp:=GetTypeData(Typeinfo);
  318. // the class info rtti the property rtti follows
  319. // immediatly
  320. Result:=PPropInfo(pointer(@hp^.UnitName)+Length(hp^.UnitName)+1+SizeOF(Word));
  321. for i:=1 to hp^.PropCount do
  322. begin
  323. // found a property of that name ?
  324. if Upcase(Result^.Name)=P then
  325. exit;
  326. // skip to next property
  327. Result:=PPropInfo(pointer(@Result^.Name)+byte(Result^.Name[0])+1);
  328. end;
  329. // parent class
  330. Typeinfo:=hp^.ParentInfo;
  331. end;
  332. Result:=Nil;
  333. end;
  334. function IsStoredProp(Instance : TObject;PropInfo : PPropInfo) : Boolean;
  335. begin
  336. case (PropInfo^.PropProcs shr 4) and 3 of
  337. ptfield:
  338. IsStoredProp:=PBoolean(Pointer(Instance)+Longint(PropInfo^.StoredProc))^;
  339. ptstatic:
  340. IsStoredProp:=CallBooleanFunc(Instance,PropInfo^.StoredProc,0,0);
  341. ptvirtual:
  342. IsStoredProp:=CallBooleanFunc(Instance,ppointer(Pointer(Instance.ClassType)+Longint(PropInfo^.StoredProc))^,0,0);
  343. ptconst:
  344. IsStoredProp:=LongBool(PropInfo^.StoredProc);
  345. end;
  346. end;
  347. procedure GetPropInfos(TypeInfo : PTypeInfo;PropList : PPropList);
  348. {
  349. Store Pointers to property information in the list pointed
  350. to by proplist. PRopList must contain enough space to hold ALL
  351. properties.
  352. }
  353. Type PWord = ^Word;
  354. Var TD : PTypeData;
  355. TP : PPropInfo;
  356. Count : Longint;
  357. begin
  358. TD:=GetTypeData(TypeInfo);
  359. // Get this objects TOTAL published properties count
  360. TP:=(@TD^.UnitName+Length(TD^.UnitName)+1);
  361. Count:=PWord(TP)^;
  362. // Now point TP to first propinfo record.
  363. Inc(Longint(TP),SizeOF(Word));
  364. While Count>0 do
  365. begin
  366. PropList^[0]:=TP;
  367. Inc(Longint(PropList),SizeOf(Pointer));
  368. // Point to TP next propinfo record.
  369. // Located at Name[Length(Name)+1] !
  370. TP:=PPropInfo(pointer(@TP^.Name)+PByte(@TP^.Name)^+1);
  371. Dec(Count);
  372. end;
  373. // recursive call for parent info.
  374. If TD^.Parentinfo<>Nil then
  375. GetPropInfos (TD^.ParentInfo,PropList);
  376. end;
  377. Procedure InsertProp (PL : PProplist;PI : PPropInfo; Count : longint);
  378. VAr I : Longint;
  379. begin
  380. I:=0;
  381. While (I<Count) and (PI^.Name>PL^[I]^.Name) do Inc(I);
  382. If I<Count then
  383. Move(PL^[I], PL^[I+1], (Count - I) * SizeOf(Pointer));
  384. PL^[I]:=PI;
  385. end;
  386. function GetPropList(TypeInfo : PTypeInfo;TypeKinds : TTypeKinds;
  387. PropList : PPropList) : Integer;
  388. {
  389. Store Pointers to property information OF A CERTAIN KIND in the list pointed
  390. to by proplist. PRopList must contain enough space to hold ALL
  391. properties.
  392. }
  393. Var TempList : PPropList;
  394. PropInfo : PPropinfo;
  395. I,Count : longint;
  396. begin
  397. Result:=0;
  398. Count:=GetTypeData(TypeInfo)^.Propcount;
  399. If Count>0 then
  400. begin
  401. GetMem(TempList,Count*SizeOf(Pointer));
  402. Try
  403. GetPropInfos(TypeInfo,TempList);
  404. For I:=0 to Count-1 do
  405. begin
  406. PropInfo:=TempList^[i];
  407. If PropInfo^.PropType^.Kind in TypeKinds then
  408. begin
  409. InsertProp(PropList,PropInfo,Result);
  410. Inc(Result);
  411. end;
  412. end;
  413. finally
  414. FreeMem(TempList,Count*SizeOf(Pointer));
  415. end;
  416. end;
  417. end;
  418. Procedure SetIndexValues (P: PPRopInfo; Var Index,IValue : Longint);
  419. begin
  420. Index:=((P^.PropProcs shr 6) and 1);
  421. If Index<>0 then
  422. IValue:=P^.Index
  423. else
  424. IValue:=0;
  425. end;
  426. function GetOrdProp(Instance : TObject;PropInfo : PPropInfo) : Longint;
  427. var
  428. value,Index,Ivalue : longint;
  429. TypeInfo: PTypeInfo;
  430. begin
  431. SetIndexValues(PropInfo,Index,Ivalue);
  432. case (PropInfo^.PropProcs) and 3 of
  433. ptfield:
  434. Value:=PLongint(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  435. ptstatic:
  436. Value:=CallIntegerFunc(Instance,PropInfo^.GetProc,Index,IValue);
  437. ptvirtual:
  438. Value:=CallIntegerFunc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^,Index,IValue);
  439. end;
  440. { cut off unnecessary stuff }
  441. TypeInfo := PropInfo^.PropType;
  442. case TypeInfo^.Kind of
  443. tkChar, tkBool:
  444. Value:=Value and $ff;
  445. tkWChar:
  446. Value:=Value and $ffff;
  447. tkInteger:
  448. case GetTypeData(TypeInfo)^.OrdType of
  449. otSWord,otUWord:
  450. Value:=Value and $ffff;
  451. otSByte,otUByte:
  452. Value:=Value and $ff;
  453. end;
  454. end;
  455. GetOrdProp:=Value;
  456. end;
  457. procedure SetOrdProp(Instance : TObject;PropInfo : PPropInfo;
  458. Value : Longint);
  459. var
  460. Index,IValue : Longint;
  461. DataSize: Integer;
  462. begin
  463. { cut off unnecessary stuff }
  464. case GetTypeData(PropInfo^.PropType)^.OrdType of
  465. otSWord,otUWord: begin
  466. Value:=Value and $ffff;
  467. DataSize := 2;
  468. end;
  469. otSByte,otUByte: begin
  470. Value:=Value and $ff;
  471. DataSize := 1;
  472. end;
  473. else DataSize := 4;
  474. end;
  475. SetIndexValues(PropInfo,Index,Ivalue);
  476. case (PropInfo^.PropProcs shr 2) and 3 of
  477. ptfield:
  478. case DataSize of
  479. 1: PByte(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Byte(Value);
  480. 2: PWord(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Word(Value);
  481. 4: PLongint(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  482. end;
  483. ptstatic:
  484. CallIntegerProc(Instance,PropInfo^.SetProc,Value,Index,IValue);
  485. ptvirtual:
  486. CallIntegerProc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.SetProc))^,Value,Index,IValue);
  487. end;
  488. end;
  489. Function GetAStrProp(Instance : TObject;PropInfo : PPropInfo):Pointer;
  490. {
  491. Dirty trick based on fact that AnsiString is just a pointer,
  492. hence can be treated like an integer type.
  493. }
  494. var
  495. value : Pointer;
  496. Index,Ivalue : Longint;
  497. begin
  498. SetIndexValues(PropInfo,Index,IValue);
  499. case (PropInfo^.PropProcs) and 3 of
  500. ptfield:
  501. Value:=Pointer(PLongint(Pointer(Instance)+Longint(PropInfo^.GetProc))^);
  502. ptstatic:
  503. Value:=Pointer(LongInt(CallIntegerFunc(Instance,PropInfo^.GetProc,Index,IValue)));
  504. ptvirtual:
  505. Value:=Pointer(LongInt(CallIntegerFunc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^,Index,IValue)));
  506. end;
  507. GetAstrProp:=Value;
  508. end;
  509. Function GetSStrProp(Instance : TObject;PropInfo : PPropInfo):ShortString;
  510. var
  511. value : ShortString;
  512. Index,IValue : Longint;
  513. begin
  514. SetIndexValues(PropInfo,Index,IValue);
  515. case (PropInfo^.PropProcs) and 3 of
  516. ptfield:
  517. Value:=PShortString(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  518. ptstatic:
  519. CallSStringFunc(Instance,PropInfo^.GetProc,Index,IValue,Value);
  520. ptvirtual:
  521. CallSSTringFunc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^,Index,Ivalue,Value);
  522. end;
  523. GetSStrProp:=Value;
  524. end;
  525. function GetStrProp(Instance : TObject;PropInfo : PPropInfo) : Ansistring;
  526. begin
  527. Case Propinfo^.PropType^.Kind of
  528. tkSString : Result:=GetSStrProp(Instance,PropInfo);
  529. tkAString : Pointer(Result):=GetAStrProp(Instance,Propinfo);
  530. else
  531. Result:='';
  532. end;
  533. end;
  534. procedure SetAStrProp(Instance : TObject;PropInfo : PPropInfo;
  535. const Value : AnsiString);
  536. {
  537. Dirty trick based on fact that AnsiString is just a pointer,
  538. hence can be treated like an integer type.
  539. }
  540. var
  541. s: AnsiString;
  542. Index,Ivalue : Longint;
  543. begin
  544. { Another dirty trick which is necessary to increase the reference
  545. counter of Value... }
  546. s := Value;
  547. Pointer(s) := nil;
  548. SetIndexValues(PropInfo,Index,IValue);
  549. case (PropInfo^.PropProcs shr 2) and 3 of
  550. ptfield:
  551. PLongint(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Longint(Pointer(Value)) ;
  552. ptstatic:
  553. CallIntegerProc(Instance,PropInfo^.SetProc,Longint(Pointer(Value)),Index,IValue);
  554. ptvirtual:
  555. CallIntegerProc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.SetProc))^,Longint(Pointer(Value)),Index,IValue);
  556. end;
  557. end;
  558. procedure SetSStrProp(Instance : TObject;PropInfo : PPropInfo;
  559. const Value : ShortString);
  560. Var Index,IValue: longint;
  561. begin
  562. SetIndexValues(PRopInfo,Index,IValue);
  563. case (PropInfo^.PropProcs shr 2) and 3 of
  564. ptfield:
  565. PShortString(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  566. ptstatic:
  567. CallSStringProc(Instance,PropInfo^.GetProc,Value,Index,IValue);
  568. ptvirtual:
  569. CallSStringProc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^,Value,Index,IValue);
  570. end;
  571. end;
  572. procedure SetStrProp(Instance : TObject;PropInfo : PPropInfo;
  573. const Value : AnsiString);
  574. begin
  575. Case Propinfo^.PropType^.Kind of
  576. tkSString : SetSStrProp(Instance,PropInfo,Value);
  577. tkAString : SetAStrProp(Instance,Propinfo,Value);
  578. end;
  579. end;
  580. function GetFloatProp(Instance : TObject;PropInfo : PPropInfo) : Extended;
  581. var
  582. Index,Ivalue : longint;
  583. Value : Extended;
  584. begin
  585. SetIndexValues(PropInfo,Index,Ivalue);
  586. case (PropInfo^.PropProcs) and 3 of
  587. ptfield:
  588. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  589. ftSingle:
  590. Value:=PSingle(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  591. ftDouble:
  592. Value:=PDouble(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  593. ftExtended:
  594. Value:=PExtended(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  595. ftcomp:
  596. Value:=PComp(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  597. { Uncommenting this code results in a internal error!!
  598. ftFixed16:
  599. Value:=PFixed16(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  600. ftfixed32:
  601. Value:=PFixed32(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  602. }
  603. end;
  604. ptstatic:
  605. Value:=CallExtendedFunc(Instance,PropInfo^.GetProc,Index,IValue);
  606. ptvirtual:
  607. Value:=CallExtendedFunc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^,Index,IValue);
  608. end;
  609. Result:=Value;
  610. end;
  611. procedure SetFloatProp(Instance : TObject;PropInfo : PPropInfo;
  612. Value : Extended);
  613. Var IValue,Index : longint;
  614. begin
  615. SetIndexValues(PropInfo,Index,Ivalue);
  616. case (PropInfo^.PropProcs shr 2) and 3 of
  617. ptfield:
  618. Case GetTypeData(PropInfo^.PropType)^.FloatType of
  619. ftSingle:
  620. PSingle(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  621. ftDouble:
  622. PDouble(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  623. ftExtended:
  624. PExtended(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  625. ftcomp:
  626. PComp(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Comp(Value);
  627. { Uncommenting this code results in a internal error!!
  628. ftFixed16:
  629. PFixed16(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  630. ftfixed32:
  631. PFixed32(Pointer(Instance)+Longint(PropInfo^.SetProc))^:=Value;
  632. }
  633. end;
  634. ptstatic:
  635. CallExtendedProc(Instance,PropInfo^.SetProc,Value,Index,IValue);
  636. ptvirtual:
  637. CallExtendedProc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^,Value,Index,IValue);
  638. end;
  639. end;
  640. function GetVariantProp(Instance : TObject;PropInfo : PPropInfo): Variant;
  641. begin
  642. {!!!!!!!!!!!}
  643. Result:=nil;
  644. end;
  645. procedure SetVariantProp(Instance : TObject;PropInfo : PPropInfo;
  646. const Value: Variant);
  647. begin
  648. {!!!!!!!!!!!}
  649. end;
  650. function GetMethodProp(Instance : TObject;PropInfo : PPropInfo) : TMethod;
  651. var
  652. value: PMethod;
  653. Index,Ivalue : longint;
  654. begin
  655. SetIndexValues(PropInfo,Index,Ivalue);
  656. case (PropInfo^.PropProcs) and 3 of
  657. ptfield:
  658. Value:=PMethod(Pointer(Instance)+Longint(PropInfo^.GetProc));
  659. ptstatic:
  660. Value:=PMethod(LongInt(CallIntegerFunc(Instance,PropInfo^.GetProc,Index,IValue)));
  661. ptvirtual:
  662. Value:=PMethod(LongInt(CallIntegerFunc(Instance,PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.GetProc))^,Index,IValue)));
  663. end;
  664. GetMethodProp:=Value^;
  665. end;
  666. procedure SetMethodProp(Instance : TObject;PropInfo : PPropInfo;
  667. const Value : TMethod);
  668. var
  669. Index,IValue : Longint;
  670. begin
  671. SetIndexValues(PropInfo,Index,Ivalue);
  672. case (PropInfo^.PropProcs shr 2) and 3 of
  673. ptfield:
  674. PMethod(Pointer(Instance)+Longint(PropInfo^.SetProc))^ := Value;
  675. ptstatic:
  676. CallIntegerProc(Instance,PropInfo^.SetProc,Integer(@Value), Index, IValue);
  677. ptvirtual:
  678. CallIntegerProc(Instance,
  679. PPointer(Pointer(Instance.ClassType)+Longint(PropInfo^.SetProc))^,
  680. Integer(@Value), Index, IValue);
  681. end;
  682. end;
  683. function GetInt64Prop(Instance: TObject; PropInfo: PPropInfo): Int64;
  684. var
  685. Index, IValue: LongInt;
  686. begin
  687. SetIndexValues(PropInfo,Index,Ivalue);
  688. case PropInfo^.PropProcs and 3 of
  689. ptfield:
  690. Result := PInt64(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  691. ptstatic:
  692. Result := CallIntegerFunc(Instance, PropInfo^.GetProc, Index, IValue);
  693. ptvirtual:
  694. Result := CallIntegerFunc(Instance,
  695. PPointer(Pointer(Instance.ClassType) + LongInt(PropInfo^.GetProc))^,
  696. Index, IValue);
  697. end;
  698. end;
  699. procedure SetInt64Prop(Instance: TObject; PropInfo: PPropInfo;
  700. const Value: Int64);
  701. begin
  702. // !!!: Implement me!
  703. end;
  704. function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
  705. Var PS : PShortString;
  706. PT : PTypeData;
  707. begin
  708. PT:=GetTypeData(TypeInfo);
  709. // ^.BaseType);
  710. // If PT^.MinValue<0 then Value:=Ord(Value<>0); {map to 0/1}
  711. PS:=@PT^.NameList;
  712. While Value>0 Do
  713. begin
  714. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  715. Dec(Value);
  716. end;
  717. Result:=PS^;
  718. end;
  719. function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
  720. Var PS : PShortString;
  721. PT : PTypeData;
  722. Count : longint;
  723. begin
  724. If Length(Name)=0 then exit(-1);
  725. PT:=GetTypeData(TypeInfo);
  726. Count:=0;
  727. Result:=-1;
  728. PS:=@PT^.NameList;
  729. While (Result=-1) and (PByte(PS)^<>0) do
  730. begin
  731. If CompareText(PS^, Name) = 0 then
  732. Result:=Count;
  733. PS:=PShortString(pointer(PS)+PByte(PS)^+1);
  734. Inc(Count);
  735. end;
  736. end;
  737. end.
  738. {
  739. $Log$
  740. Revision 1.3 2000-07-17 08:37:58 sg
  741. * Fixed GetEnumValue (bug #1049, reported by Neil Graham)
  742. Revision 1.2 2000/07/13 11:33:52 michael
  743. + removed logs
  744. }