variant.inc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 2001 by the Free Pascal development team
  5. This include file contains the implementation for variants
  6. support in FPC as far as it is part of the system unit
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. var
  14. variantmanager : tvariantmanager;
  15. procedure invalidvariantop;
  16. begin
  17. HandleErrorFrame(221,get_frame);
  18. end;
  19. procedure vardisperror;
  20. begin
  21. HandleErrorFrame(222,get_frame);
  22. end;
  23. { ---------------------------------------------------------------------
  24. Compiler helper routines.
  25. ---------------------------------------------------------------------}
  26. procedure varclear(var v : tvardata);
  27. begin
  28. if not(v.vtype in [varempty,varerror,varnull]) then
  29. invalidvariantop;
  30. end;
  31. procedure variant_init(var v : variant);[Public,Alias:'FPC_VARIANT_INIT'];
  32. begin
  33. { calling the variant manager here is a problem because the static/global variants
  34. are initialized while the variant manager isn't assigned }
  35. fillchar(v,sizeof(variant),0);
  36. end;
  37. procedure variant_clear(var v : variant);[Public,Alias:'FPC_VARIANT_CLEAR'];
  38. begin
  39. variantmanager.varclear(v);
  40. end;
  41. Procedure fpc_Write_Text_Variant(Len : Longint;var f : Text;const v : variant); iocheck; [Public,Alias:'FPC_WRITE_TEXT_VARIANT']; {$ifdef hascompilerproc} compilerproc; {$endif}
  42. Begin
  43. If (InOutRes<>0) then
  44. exit;
  45. case TextRec(f).mode of
  46. fmOutput { fmAppend gets changed to fmOutPut in do_open (JM) }:
  47. variantmanager.writevariant(f,v,len);
  48. fmInput: InOutRes:=105
  49. else InOutRes:=103;
  50. end;
  51. End;
  52. { ---------------------------------------------------------------------
  53. Overloaded operators.
  54. ---------------------------------------------------------------------}
  55. { Integer }
  56. operator :=(const source : byte) dest : variant;
  57. begin
  58. Variant_Init(Dest);
  59. Variantmanager.varfromInt(Dest,Source,1);
  60. end;
  61. operator :=(const source : shortint) dest : variant;
  62. begin
  63. Variant_Init(Dest);
  64. Variantmanager.varfromInt(Dest,Source,-1);
  65. end;
  66. operator :=(const source : word) dest : variant;
  67. begin
  68. Variant_Init(Dest);
  69. Variantmanager.varfromInt(Dest,Source,2);
  70. end;
  71. operator :=(const source : smallint) dest : variant;
  72. begin
  73. Variant_Init(Dest);
  74. Variantmanager.varfromInt(Dest,Source,-2);
  75. end;
  76. operator :=(const source : dword) dest : variant;
  77. begin
  78. Variant_Init(Dest);
  79. Variantmanager.varfromInt(Dest,Source,4);
  80. end;
  81. operator :=(const source : longint) dest : variant;
  82. begin
  83. // Variant_Init(Dest);
  84. Variantmanager.varfromInt(Dest,Source,-4);
  85. end;
  86. operator :=(const source : qword) dest : variant;
  87. begin
  88. Variant_Init(Dest);
  89. Variantmanager.varfromWord64(Dest,Source);
  90. end;
  91. operator :=(const source : int64) dest : variant;
  92. begin
  93. Variant_Init(Dest);
  94. Variantmanager.varfromInt64(Dest,Source);
  95. end;
  96. { Boolean }
  97. operator :=(const source : boolean) dest : variant;
  98. begin
  99. Variant_Init(Dest);
  100. Variantmanager.varfromBool(Dest,Source);
  101. end;
  102. operator :=(const source : wordbool) dest : variant;
  103. begin
  104. Variant_Init(Dest);
  105. Variantmanager.varfromBool(Dest,Boolean(Source));
  106. end;
  107. operator :=(const source : longbool) dest : variant;
  108. begin
  109. Variant_Init(Dest);
  110. Variantmanager.varfromBool(Dest,Boolean(Source));
  111. end;
  112. { Chars }
  113. operator :=(const source : char) dest : variant;
  114. begin
  115. Variant_Init(Dest);
  116. VariantManager.VarFromPStr(Dest,Source);
  117. end;
  118. operator :=(const source : widechar) dest : variant;
  119. begin
  120. Variant_Init(Dest);
  121. VariantManager.VarFromWStr(Dest,Source);
  122. end;
  123. { Strings }
  124. operator :=(const source : shortstring) dest : variant;
  125. begin
  126. Variant_Init(Dest);
  127. VariantManager.VarFromPStr(Dest,Source);
  128. end;
  129. operator :=(const source : ansistring) dest : variant;
  130. begin
  131. Variant_Init(Dest);
  132. VariantManager.VarFromLStr(Dest,Source);
  133. end;
  134. operator :=(const source : widestring) dest : variant;
  135. begin
  136. Variant_Init(Dest);
  137. VariantManager.VarFromWStr(Dest,Source);
  138. end;
  139. { Floats }
  140. operator :=(const source : single) dest : variant;
  141. begin
  142. Variant_Init(Dest);
  143. VariantManager.VarFromReal(Dest,Source);
  144. end;
  145. operator :=(const source : double) dest : variant;
  146. begin
  147. Variant_Init(Dest);
  148. VariantManager.VarFromReal(Dest,Source);
  149. end;
  150. operator :=(const source : extended) dest : variant;
  151. begin
  152. Variant_Init(Dest);
  153. VariantManager.VarFromReal(Dest,Source);
  154. end;
  155. Operator :=(const source : comp) dest : variant;
  156. begin
  157. Variant_Init(Dest);
  158. VariantManager.VarFromReal(Dest,Source);
  159. end;
  160. { Misc. }
  161. { Fixme!!!
  162. operator :=(const source : currency) dest : variant;
  163. begin
  164. end;
  165. operator :=(const source : tdatetime) dest : variant;
  166. begin
  167. end;
  168. }
  169. {**********************************************************************
  170. from Variant assignments
  171. **********************************************************************}
  172. { Integer }
  173. operator :=(const source : variant) dest : byte;
  174. begin
  175. dest:=variantmanager.vartoint(source);
  176. end;
  177. operator :=(const source : variant) dest : shortint;
  178. begin
  179. dest:=variantmanager.vartoint(source);
  180. end;
  181. operator :=(const source : variant) dest : word;
  182. begin
  183. dest:=variantmanager.vartoint(source);
  184. end;
  185. operator :=(const source : variant) dest : smallint;
  186. begin
  187. dest:=variantmanager.vartoint(source);
  188. end;
  189. operator :=(const source : variant) dest : dword;
  190. begin
  191. dest:=variantmanager.vartoint(source);
  192. end;
  193. operator :=(const source : variant) dest : longint;
  194. begin
  195. dest:=variantmanager.vartoint(source);
  196. end;
  197. operator :=(const source : variant) dest : qword;
  198. begin
  199. dest:=variantmanager.vartoword64(source);
  200. end;
  201. operator :=(const source : variant) dest : int64;
  202. begin
  203. dest:=variantmanager.vartoint64(source);
  204. end;
  205. { Boolean }
  206. operator :=(const source : variant) dest : boolean;
  207. begin
  208. dest:=variantmanager.vartobool(source);
  209. end;
  210. operator :=(const source : variant) dest : wordbool;
  211. begin
  212. dest:=variantmanager.vartobool(source);
  213. end;
  214. operator :=(const source : variant) dest : longbool;
  215. begin
  216. dest:=variantmanager.vartobool(source);
  217. end;
  218. { Chars }
  219. operator :=(const source : variant) dest : char;
  220. Var
  221. S : String;
  222. begin
  223. VariantManager.VarToPStr(S,Source);
  224. If Length(S)>0 then
  225. Dest:=S[1];
  226. end;
  227. operator :=(const source : variant) dest : widechar;
  228. Var
  229. WS : WideString;
  230. begin
  231. VariantManager.VarToWStr(WS,Source);
  232. If Length(WS)>0 then
  233. Dest:=WS[1];
  234. end;
  235. { Strings }
  236. operator :=(const source : variant) dest : shortstring;
  237. begin
  238. VariantManager.VarToPStr(Dest,Source);
  239. end;
  240. operator :=(const source : variant) dest : ansistring;
  241. begin
  242. VariantManager.vartolstr(dest,source);
  243. end;
  244. operator :=(const source : variant) dest : widestring;
  245. begin
  246. variantmanager.vartowstr(dest,source);
  247. end;
  248. { Floats }
  249. operator :=(const source : variant) dest : single;
  250. begin
  251. dest:=variantmanager.vartoreal(source);
  252. end;
  253. operator :=(const source : variant) dest : double;
  254. begin
  255. dest:=variantmanager.vartoreal(source);
  256. end;
  257. operator :=(const source : variant) dest : extended;
  258. begin
  259. dest:=variantmanager.vartoreal(source);
  260. end;
  261. operator :=(const source : variant) dest : comp;
  262. begin
  263. dest:=comp(variantmanager.vartoreal(source));
  264. end;
  265. { Misc. }
  266. { FIXME !!!!!!!
  267. operator :=(const source : variant) dest : currency;
  268. begin
  269. dest:=variantmanager.vartocurr(source);
  270. end;
  271. operator :=(const source : variant) dest : tdatetime;
  272. begin
  273. end;
  274. }
  275. {**********************************************************************
  276. Operators
  277. **********************************************************************}
  278. operator or(const op1,op2 : variant) dest : variant;
  279. begin
  280. dest:=op1;
  281. variantmanager.varop(dest,op2,opor);
  282. end;
  283. operator and(const op1,op2 : variant) dest : variant;
  284. begin
  285. dest:=op1;
  286. variantmanager.varop(dest,op2,opand);
  287. end;
  288. operator xor(const op1,op2 : variant) dest : variant;
  289. begin
  290. dest:=op1;
  291. variantmanager.varop(dest,op2,opxor);
  292. end;
  293. operator not(const op : variant) dest : variant;
  294. begin
  295. dest:=op;
  296. variantmanager.varnot(dest);
  297. end;
  298. operator shl(const op1,op2 : variant) dest : variant;
  299. begin
  300. dest:=op1;
  301. variantmanager.varop(dest,op2,opshiftleft);
  302. end;
  303. operator shr(const op1,op2 : variant) dest : variant;
  304. begin
  305. dest:=op1;
  306. variantmanager.varop(dest,op2,opshiftright);
  307. end;
  308. operator +(const op1,op2 : variant) dest : variant;
  309. begin
  310. dest:=op1;
  311. variantmanager.varop(dest,op2,opadd);
  312. end;
  313. operator -(const op1,op2 : variant) dest : variant;
  314. begin
  315. dest:=op1;
  316. variantmanager.varop(dest,op2,opsubtract);
  317. end;
  318. operator *(const op1,op2 : variant) dest : variant;
  319. begin
  320. dest:=op1;
  321. variantmanager.varop(dest,op2,opmultiply);
  322. end;
  323. operator /(const op1,op2 : variant) dest : variant;
  324. begin
  325. dest:=op1;
  326. variantmanager.varop(dest,op2,opdivide);
  327. end;
  328. operator div(const op1,op2 : variant) dest : variant;
  329. begin
  330. dest:=op1;
  331. variantmanager.varop(dest,op2,opintdivide);
  332. end;
  333. operator mod(const op1,op2 : variant) dest : variant;
  334. begin
  335. dest:=op1;
  336. variantmanager.varop(dest,op2,opmodulus);
  337. end;
  338. operator -(const op : variant) dest : variant;
  339. begin
  340. dest:=op;
  341. variantmanager.varneg(dest);
  342. end;
  343. operator =(const op1,op2 : variant) dest : boolean;
  344. begin
  345. dest:=variantmanager.cmpop(op1,op2,opcmpeq);
  346. end;
  347. operator <(const op1,op2 : variant) dest : boolean;
  348. begin
  349. dest:=variantmanager.cmpop(op1,op2,opcmplt);
  350. end;
  351. operator >(const op1,op2 : variant) dest : boolean;
  352. begin
  353. dest:=variantmanager.cmpop(op1,op2,opcmpgt);
  354. end;
  355. operator >=(const op1,op2 : variant) dest : boolean;
  356. begin
  357. dest:=variantmanager.cmpop(op1,op2,opcmpge);
  358. end;
  359. operator <=(const op1,op2 : variant) dest : boolean;
  360. begin
  361. dest:=variantmanager.cmpop(op1,op2,opcmplt);
  362. end;
  363. {**********************************************************************
  364. Variant manager functions
  365. **********************************************************************}
  366. procedure GetVariantManager(var VarMgr: TVariantManager);
  367. begin
  368. VarMgr:=VariantManager;
  369. end;
  370. procedure SetVariantManager(const VarMgr: TVariantManager);
  371. begin
  372. VariantManager:=VarMgr;
  373. end;
  374. function IsVariantManagerSet: Boolean;
  375. var
  376. i : longint;
  377. begin
  378. I:=0;
  379. Result:=True;
  380. While Result and (I<(sizeof(tvariantmanager) div sizeof(pointer))-1) do
  381. begin
  382. Result:=Pointer(ppointer(@variantmanager+i*sizeof(pointer))^)<>Pointer(@invalidvariantop);
  383. Inc(I);
  384. end;
  385. end;
  386. procedure initvariantmanager;
  387. var
  388. i : longint;
  389. begin
  390. VarDispProc:=@vardisperror;
  391. DispCallByIDProc:=@vardisperror;
  392. tvardata(Unassigned).VType:=varEmpty;
  393. tvardata(Null).VType:=varNull;
  394. for i:=0 to (sizeof(tvariantmanager) div sizeof(pointer))-1 do
  395. ppointer(@variantmanager+i*sizeof(pointer))^:=@invalidvariantop;
  396. pointer(variantmanager.varclear):=@varclear
  397. end;
  398. {
  399. $Log$
  400. Revision 1.12 2002-10-10 19:24:28 florian
  401. + write(ln) support for variants added
  402. Revision 1.11 2002/10/09 20:13:26 florian
  403. * hopefully last fix to get things working :/
  404. Revision 1.10 2002/10/09 19:56:01 florian
  405. * variant assignments don't work yet, commented out
  406. Revision 1.9 2002/10/09 19:08:22 florian
  407. + Variant constants Unassigned and Null added
  408. Revision 1.8 2002/10/07 15:10:45 florian
  409. + variant wrappers for cmp operators added
  410. Revision 1.7 2002/10/07 10:27:45 florian
  411. + more variant wrappers added
  412. Revision 1.6 2002/10/06 22:13:55 florian
  413. * wrappers for xor, or and and operator with variants added
  414. Revision 1.5 2002/09/07 15:07:46 peter
  415. * old logs removed and tabs fixed
  416. }