typinfo.pp 27 KB

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