typinfo.pp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1998 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. uses
  17. sysutils;
  18. type
  19. {$MINENUMSIZE 1 this saves a lot of memory }
  20. // if you change one of the following enumeration types
  21. // you have also to change the compiler in an appropriate way !
  22. TTypeKind = (tkUnknown,tkInteger,tkChar,tkEnumeration,
  23. tkFloat,tkSet,tkMethod,tkSString,tkLString,tkAString,
  24. tkWString,tkVariant,tkArray,tkRecord,tkInterface,
  25. tkClass,tkObject,tkWChar);
  26. TTOrdType = (otSByte,otUByte,otSWord,otUWord,otSLong,otULong);
  27. TFloatType = (ftSingle,ftDouble,ftExtended,ftComp,ftCurr,
  28. ftFixed16,ftFixed32);
  29. {$MINENUMSIZE DEFAULT}
  30. const
  31. ptField = 0;
  32. ptStatic = 1;
  33. ptVirtual = 2;
  34. ptConst = 3;
  35. const
  36. tkString = tkSString;
  37. type
  38. TMethodKind = Byte;
  39. TTypeKinds = set of TTypeKind;
  40. TTypeInfo = record
  41. Kind : TTypeKind;
  42. Name : ShortString;
  43. end;
  44. PTypeInfo = ^TTypeInfo;
  45. PPTypeInfo = ^PTypeInfo;
  46. PTypeData = ^TTypeData;
  47. TTypeData = packed record
  48. case TTypeKind of
  49. tkUnKnown,tkLString,tkWString,tkAString,tkVariant:
  50. ();
  51. tkInteger,tkChar,tkEnumeration,tkWChar:
  52. ( //!!!!! To be added );
  53. tkFloat:
  54. (FloatType : TFloatType);
  55. tkSString:
  56. (MaxLength : Byte);
  57. tkClass:
  58. (ClassType : TClass;
  59. ParentInfo : PTypeInfo;
  60. PropCount : SmallInt;
  61. UnitName : ShortString;
  62. end;
  63. PPropInfo = ^TPropInfo;
  64. TPropInfo = packed record
  65. PropType : PTypeInfo;
  66. GetProc : Pointer;
  67. SetProc : Pointer;
  68. StoredProc : Pointer;
  69. Index : Integer;
  70. Default : Longint;
  71. NameIndex : SmallInt;
  72. // contains the type of the Get/Set/Storedproc, see also ptxxx
  73. // bit 0..1 GetProc
  74. // 2..3 SetProc
  75. // 4..5 StoredProc
  76. ProcProcs : Byte;
  77. Name : ShortString;
  78. end;
  79. TProcInfoProc = procedure(PropInfo : PPropInfo) of object;
  80. PPropList = ^TPropList;
  81. TPropList = array[0..65535] of PPropInfo;
  82. const
  83. tkAny = [Low(TTypeKind)..High(TTypeKind)];
  84. tkMethods = [tkMethod];
  85. tkProperties = tkAny-tkMethods-[tkUnknown];
  86. // just skips the id and the name
  87. function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
  88. // searches in the property PropName
  89. function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string) : PPropInfo;
  90. // returns true, if PropInfo is a stored property
  91. function IsStoredProp(Instance: TObject; PropInfo: PPropInfo): Boolean;
  92. {
  93. procedure GetPropInfos(TypeInfo : PTypeInfo;PropList : PPropList);
  94. function GetPropList(TypeInfo : PTypeInfo;TypeKinds : TTypeKinds;
  95. PropList : PPropList) : Integer;
  96. }
  97. implementation
  98. function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
  99. begin
  100. GetTypeData:=PTypeData(TypeInfo)+2+PByte(TypeInfo+1)^;
  101. end;
  102. function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string) : PPropInfo;
  103. var
  104. hp : PTypeData;
  105. begin
  106. Result:=Nil;
  107. while Assigned(hp) do
  108. begin
  109. // skip the name
  110. hp:=GetTypeData;
  111. // the class info rtti the property rtti follows
  112. // immediatly
  113. Result:=PPropInfo(@hp^.UnitName)+byte(hp^.UnitName[0])+1;
  114. for i:=1 to hp^.PropCount do
  115. begin
  116. // found a property of that name ?
  117. if Result^.Name=PropName then
  118. exit;
  119. // skip to next property
  120. Result:=PPropInfo(@Result^.Name)+byte(Result^.Name[0])+1;
  121. end;
  122. // parent class
  123. hp:=hp^.ParentInfo;
  124. end;
  125. end;
  126. function IsStoredProp(Instance: TObject; PropInfo: PPropInfo): Boolean;
  127. type
  128. tbfunction = function : boolean of object;
  129. var
  130. caller : packed record
  131. Instance : Pointer;
  132. Address : Pointer;
  133. end;
  134. begin
  135. caller.Instance:=Instance;
  136. case (PropInfo^.PropProcs shr 4) and 3 of
  137. 0:
  138. IsStoredProp:=
  139. PBoolean(Pointer(Instance)+Longint(PropInfo^.StoredProc))^;
  140. 1:
  141. begin
  142. caller.Address:=PropInfo^.StoredProc;
  143. IsStoredProc:=tbfunction(caller);
  144. end;
  145. 2:
  146. begin
  147. caller.Address:=PPointer(PPointer(Instance.ClassType)+Longint(PropInfo^.StoredProc))^;
  148. IsStoredProc:=tbfunction(caller);
  149. end;
  150. 4:
  151. begin
  152. IsStoredProp:=
  153. LongBool(PropInfo^.StoredProc);
  154. end;
  155. end;
  156. end;
  157. end.
  158. {
  159. $Log$
  160. Revision 1.4 1998-09-07 19:34:47 florian
  161. * constant value is now supported as stored condition
  162. Revision 1.3 1998/09/07 08:32:59 florian
  163. + procedure IsStoredProc added
  164. Revision 1.2 1998/09/06 21:27:05 florian
  165. + some methods and declarations added
  166. Revision 1.1 1998/08/25 22:30:00 florian
  167. + initial revision:
  168. o constants
  169. o basic type data record
  170. }