typinfo.pp 27 KB

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