typinfo.pp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  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. {$MODE objfpc}
  17. {$ifndef AUTOOBJPAS}
  18. uses
  19. objpas;
  20. {$endif}
  21. // temporary types:
  22. type
  23. ShortString=String;
  24. PByte =^Byte;
  25. PBoolean =^Boolean;
  26. {$MINENUMSIZE 1 this saves a lot of memory }
  27. // if you change one of the following enumeration types
  28. // you have also to change the compiler in an appropriate way !
  29. TTypeKind = (tkUnknown,tkInteger,tkChar,tkEnumeration,
  30. tkFloat,tkSet,tkMethod,tkSString,tkLString,tkAString,
  31. tkWString,tkVariant,tkArray,tkRecord,tkInterface,
  32. tkClass,tkObject,tkWChar,tkBool);
  33. TTOrdType = (otSByte,otUByte,otSWord,otUWord,otSLong,otULong);
  34. TFloatType = (ftSingle,ftDouble,ftExtended,ftComp,ftCurr,
  35. ftFixed16,ftFixed32);
  36. TMethodKind = (mkProcedure,mkFunction,mkSafeProcedure,mkSafeFunction);
  37. TParamFlags = set of (pfVar,pfConst,pfArray,pfAddress,pfReference,pfOut);
  38. TIntfFlags = set of (ifHasGuid,ifDispInterface,ifDispatch);
  39. {$MINENUMSIZE DEFAULT}
  40. const
  41. ptField = 0;
  42. ptStatic = 1;
  43. ptVirtual = 2;
  44. ptConst = 3;
  45. tkString = tkSString;
  46. type
  47. TTypeKinds = set of TTypeKind;
  48. TTypeInfo = record
  49. Kind : TTypeKind;
  50. Name : ShortString;
  51. // here the type data follows as TTypeData record
  52. end;
  53. PTypeInfo = ^TTypeInfo;
  54. PPTypeInfo = ^PTypeInfo;
  55. PTypeData = ^TTypeData;
  56. TTypeData = packed record
  57. case TTypeKind of
  58. tkUnKnown,tkLString,tkWString,tkAString,tkVariant:
  59. ();
  60. tkInteger,tkChar,tkEnumeration,tkWChar:
  61. (OrdType : TTOrdType;
  62. case TTypeKind of
  63. tkInteger,tkChar,tkEnumeration,tkBool,tkWChar : (
  64. MinValue,MaxValue : Longint;
  65. case TTypeKind of
  66. tkEnumeration:
  67. (
  68. BaseType : PTypeInfo;
  69. NameList : ShortString)
  70. );
  71. tkSet:
  72. (CompType : PTypeInfo)
  73. );
  74. tkFloat:
  75. (FloatType : TFloatType);
  76. tkSString:
  77. (MaxLength : Byte);
  78. tkClass:
  79. (ClassType : TClass;
  80. ParentInfo : PTypeInfo;
  81. PropCount : SmallInt;
  82. UnitName : ShortString
  83. // here the properties follow as array of TPropInfo
  84. );
  85. tkMethod:
  86. ({!!!!!!!}
  87. );
  88. tkInterface:
  89. ({!!!!!!!}
  90. );
  91. end;
  92. // unsed, just for completeness
  93. TPropData = packed record
  94. PropCount : Word;
  95. PropList : record end;
  96. end;
  97. PPropInfo = ^TPropInfo;
  98. TPropInfo = packed record
  99. PropType : PTypeInfo;
  100. GetProc : Pointer;
  101. SetProc : Pointer;
  102. StoredProc : Pointer;
  103. Index : Integer;
  104. Default : Longint;
  105. NameIndex : SmallInt;
  106. // contains the type of the Get/Set/Storedproc, see also ptxxx
  107. // bit 0..1 GetProc
  108. // 2..3 SetProc
  109. // 4..5 StoredProc
  110. // 6 : true, constant index property
  111. PropProcs : Byte;
  112. Name : ShortString;
  113. end;
  114. TProcInfoProc = procedure(PropInfo : PPropInfo) of object;
  115. PPropList = ^TPropList;
  116. TPropList = array[0..65535] of PPropInfo;
  117. const
  118. tkAny = [Low(TTypeKind)..High(TTypeKind)];
  119. tkMethods = [tkMethod];
  120. tkProperties = tkAny-tkMethods-[tkUnknown];
  121. { general property handling }
  122. // just skips the id and the name
  123. function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
  124. // searches in the property PropName
  125. function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string) : PPropInfo;
  126. procedure GetPropInfos(TypeInfo : PTypeInfo;PropList : PPropList);
  127. function GetPropList(TypeInfo : PTypeInfo;TypeKinds : TTypeKinds;
  128. PropList : PPropList) : Integer;
  129. // returns true, if PropInfo is a stored property
  130. function IsStoredProp(Instance : TObject;PropInfo : PPropInfo) : Boolean;
  131. { subroutines to read/write properties }
  132. function GetOrdProp(Instance : TObject;PropInfo : PPropInfo) : Longint;
  133. procedure SetOrdProp(Instance : TObject;PropInfo : PPropInfo;
  134. Value : Longint);
  135. function GetStrProp(Instance : TObject;PropInfo : PPropInfo) : string;
  136. procedure SetStrProp(Instance : TObject;PropInfo : PPropInfo;
  137. const Value : string);
  138. function GetFloatProp(Instance : TObject;PropInfo : PPropInfo) : Extended;
  139. procedure SetFloatProp(Instance : TObject;PropInfo : PPropInfo;
  140. Value : Extended);
  141. function GetVariantProp(Instance : TObject;PropInfo : PPropInfo): Variant;
  142. procedure SetVariantProp(Instance : TObject;PropInfo : PPropInfo;
  143. const Value: Variant);
  144. function GetMethodProp(Instance : TObject;PropInfo : PPropInfo) : TMethod;
  145. procedure SetMethodProp(Instance : TObject;PropInfo : PPropInfo;
  146. const Value : TMethod);
  147. { misc. stuff }
  148. function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
  149. function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
  150. implementation
  151. {$ASMMODE INTEL}
  152. function CallMethod_Integer(s : Pointer;Address : Pointer) : Integer;assembler;
  153. asm
  154. mov ESI,s
  155. mov EDI,Address
  156. call [EDI]
  157. // now the result should be in EAX, untested yet (FK)
  158. end;
  159. function CallMethod_Boolean(s : Pointer;Address : Pointer) : Boolean;assembler;
  160. asm
  161. mov ESI,s
  162. mov EDI,Address
  163. call [EDI]
  164. // now the result should be in EAX, untested yet (FK)
  165. end;
  166. function GetTypeData(TypeInfo : PTypeInfo) : PTypeData;
  167. begin
  168. GetTypeData:=PTypeData(TypeInfo)+2+PByte(TypeInfo+1)^;
  169. end;
  170. function GetPropInfo(TypeInfo : PTypeInfo;const PropName : string) : PPropInfo;
  171. var
  172. hp : PTypeData;
  173. i : longint;
  174. begin
  175. Result:=Nil;
  176. while Assigned(TypeInfo) do
  177. begin
  178. // skip the name
  179. hp:=GetTypeData(Typeinfo);
  180. // the class info rtti the property rtti follows
  181. // immediatly
  182. Result:=PPropInfo(@hp^.UnitName)+byte(hp^.UnitName[0])+1;
  183. for i:=1 to hp^.PropCount do
  184. begin
  185. // found a property of that name ?
  186. if Result^.Name=PropName then
  187. exit;
  188. // skip to next property
  189. Result:=PPropInfo(@Result^.Name)+byte(Result^.Name[0])+1;
  190. end;
  191. // parent class
  192. Typeinfo:=hp^.ParentInfo;
  193. end;
  194. end;
  195. function IsStoredProp(Instance : TObject;PropInfo : PPropInfo) : Boolean;
  196. begin
  197. case (PropInfo^.PropProcs shr 4) and 3 of
  198. 0:
  199. IsStoredProp:=PBoolean(Pointer(Instance)+Longint(PropInfo^.StoredProc))^;
  200. 1:
  201. IsStoredProp:=CallMethod(Instance,PropInfo^.StoredProc);
  202. 2:
  203. IsStoredProp:=CallMethod(Instance,(PPointer(Instance.ClassType)+Longint(PropInfo^.StoredProc)^);
  204. 3:
  205. IsStoredProp:=LongBool(PropInfo^.StoredProc);
  206. end;
  207. end;
  208. procedure GetPropInfos(TypeInfo : PTypeInfo;PropList : PPropList);
  209. begin
  210. {!!!!!!!!!!!}
  211. end;
  212. function GetPropList(TypeInfo : PTypeInfo;TypeKinds : TTypeKinds;
  213. PropList : PPropList) : Integer;
  214. begin
  215. {!!!!!!!!!!!}
  216. end;
  217. function GetOrdProp(Instance : TObject;PropInfo : PPropInfo) : Longint;
  218. var
  219. value : longint;
  220. begin
  221. case (PropInfo^.PropProcs) and 3 of
  222. 0:
  223. Value:=PLongint(Pointer(Instance)+Longint(PropInfo^.GetProc))^;
  224. 1:
  225. Value:=CallMethod(Instance,PropInfo^.GetProc);
  226. 2:
  227. Value:=CallMethod(Instance,(PPointer(Instance.ClassType)+Longint(PropInfo^.GetProc)^);
  228. end;
  229. { cut off unnecessary stuff }
  230. case GetTypeData(PropInfo^.PropType)^.OrdType of
  231. otSWord,otUWord:
  232. Value:=Value and $ffff;
  233. otSByte,otUByte:
  234. Value:=Value and $ff;
  235. end;
  236. GetOrdProp:=Value;
  237. end;
  238. procedure SetOrdProp(Instance : TObject;PropInfo : PPropInfo;
  239. Value : Longint);
  240. begin
  241. {!!!!!!!!!!!}
  242. end;
  243. function GetStrProp(Instance : TObject;PropInfo : PPropInfo) : string;
  244. begin
  245. {!!!!!!!!!!!}
  246. end;
  247. procedure SetStrProp(Instance : TObject;PropInfo : PPropInfo;
  248. const Value : string);
  249. begin
  250. {!!!!!!!!!!!}
  251. end;
  252. function GetFloatProp(Instance : TObject;PropInfo : PPropInfo) : Extended;
  253. begin
  254. {!!!!!!!!!!!}
  255. end;
  256. procedure SetFloatProp(Instance : TObject;PropInfo : PPropInfo;
  257. Value : Extended);
  258. begin
  259. {!!!!!!!!!!!}
  260. end;
  261. function GetVariantProp(Instance : TObject;PropInfo : PPropInfo): Variant;
  262. begin
  263. {!!!!!!!!!!!}
  264. end;
  265. procedure SetVariantProp(Instance : TObject;PropInfo : PPropInfo;
  266. const Value: Variant);
  267. begin
  268. {!!!!!!!!!!!}
  269. end;
  270. function GetMethodProp(Instance : TObject;PropInfo : PPropInfo) : TMethod;
  271. begin
  272. {!!!!!!!!!!!}
  273. end;
  274. procedure SetMethodProp(Instance : TObject;PropInfo : PPropInfo;
  275. const Value : TMethod);
  276. begin
  277. {!!!!!!!!!!!}
  278. end;
  279. function GetEnumName(TypeInfo : PTypeInfo;Value : Integer) : string;
  280. begin
  281. {!!!!!!!!!!!}
  282. end;
  283. function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;
  284. begin
  285. {!!!!!!!!!!!}
  286. end;
  287. end.
  288. {
  289. $Log$
  290. Revision 1.11 1998-09-24 23:45:28 peter
  291. * updated for auto objpas loading
  292. Revision 1.10 1998/09/20 08:25:34 florian
  293. + description of tpropinfo.propprocs bit 6 added
  294. Revision 1.9 1998/09/19 15:25:45 florian
  295. * procedure GetOrdProp added
  296. Revision 1.8 1998/09/19 08:33:53 florian
  297. + some procedures added
  298. Revision 1.7 1998/09/08 09:52:31 florian
  299. * small problems fixed
  300. Revision 1.6 1998/09/08 00:08:36 michael
  301. Made it compilable
  302. Revision 1.5 1998/09/07 23:11:43 florian
  303. + more fields to TTypeInfo added
  304. Revision 1.4 1998/09/07 19:34:47 florian
  305. * constant value is now supported as stored condition
  306. Revision 1.3 1998/09/07 08:32:59 florian
  307. + procedure IsStoredProc added
  308. Revision 1.2 1998/09/06 21:27:05 florian
  309. + some methods and declarations added
  310. Revision 1.1 1998/08/25 22:30:00 florian
  311. + initial revision:
  312. o constants
  313. o basic type data record
  314. }