variant.inc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638
  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']; compilerproc;
  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. if len=-1 then
  48. variantmanager.write0variant(f,v)
  49. else
  50. variantmanager.writevariant(f,v,len);
  51. fmInput: InOutRes:=105
  52. else InOutRes:=103;
  53. end;
  54. End;
  55. function fpc_variant_to_dynarray(const v : variant;typeinfo : pointer) : pointer;compilerproc;
  56. begin
  57. end;
  58. function fpc_dynarray_to_variant(const v : variant;typeinfo : pointer) : pointer;compilerproc;
  59. begin
  60. end;
  61. { ---------------------------------------------------------------------
  62. Overloaded operators.
  63. ---------------------------------------------------------------------}
  64. { Integer }
  65. operator :=(const source : byte) dest : variant;
  66. begin
  67. Variant_Init(Dest);
  68. Variantmanager.varfromInt(Dest,Source,1);
  69. end;
  70. operator :=(const source : shortint) dest : variant;
  71. begin
  72. Variant_Init(Dest);
  73. Variantmanager.varfromInt(Dest,Source,-1);
  74. end;
  75. operator :=(const source : word) dest : variant;
  76. begin
  77. Variant_Init(Dest);
  78. Variantmanager.varfromInt(Dest,Source,2);
  79. end;
  80. operator :=(const source : smallint) dest : variant;
  81. begin
  82. Variant_Init(Dest);
  83. Variantmanager.varfromInt(Dest,Source,-2);
  84. end;
  85. operator :=(const source : dword) dest : variant;
  86. begin
  87. Variant_Init(Dest);
  88. Variantmanager.varfromInt(Dest,Source,4);
  89. end;
  90. operator :=(const source : longint) dest : variant;
  91. begin
  92. // Variant_Init(Dest);
  93. Variantmanager.varfromInt(Dest,Source,-4);
  94. end;
  95. operator :=(const source : qword) dest : variant;
  96. begin
  97. Variant_Init(Dest);
  98. Variantmanager.varfromWord64(Dest,Source);
  99. end;
  100. operator :=(const source : int64) dest : variant;
  101. begin
  102. Variant_Init(Dest);
  103. Variantmanager.varfromInt64(Dest,Source);
  104. end;
  105. { Boolean }
  106. operator :=(const source : boolean) dest : variant;
  107. begin
  108. Variant_Init(Dest);
  109. Variantmanager.varfromBool(Dest,Source);
  110. end;
  111. operator :=(const source : wordbool) dest : variant;
  112. begin
  113. Variant_Init(Dest);
  114. Variantmanager.varfromBool(Dest,Boolean(Source));
  115. end;
  116. operator :=(const source : longbool) dest : variant;
  117. begin
  118. Variant_Init(Dest);
  119. Variantmanager.varfromBool(Dest,Boolean(Source));
  120. end;
  121. { Chars }
  122. operator :=(const source : char) dest : variant;
  123. begin
  124. Variant_Init(Dest);
  125. VariantManager.VarFromPStr(Dest,Source);
  126. end;
  127. operator :=(const source : widechar) dest : variant;
  128. begin
  129. Variant_Init(Dest);
  130. VariantManager.VarFromWStr(Dest,Source);
  131. end;
  132. { Strings }
  133. operator :=(const source : shortstring) dest : variant;
  134. begin
  135. Variant_Init(Dest);
  136. VariantManager.VarFromPStr(Dest,Source);
  137. end;
  138. operator :=(const source : ansistring) dest : variant;
  139. begin
  140. Variant_Init(Dest);
  141. VariantManager.VarFromLStr(Dest,Source);
  142. end;
  143. operator :=(const source : widestring) dest : variant;
  144. begin
  145. Variant_Init(Dest);
  146. VariantManager.VarFromWStr(Dest,Source);
  147. end;
  148. { Floats }
  149. {$ifdef SUPPORT_SINGLE}
  150. operator :=(const source : single) dest : variant;
  151. begin
  152. Variant_Init(Dest);
  153. VariantManager.VarFromReal(Dest,Source);
  154. end;
  155. {$endif SUPPORT_SINGLE}
  156. {$ifdef SUPPORT_DOUBLE}
  157. operator :=(const source : double) dest : variant;
  158. begin
  159. Variant_Init(Dest);
  160. VariantManager.VarFromReal(Dest,Source);
  161. end;
  162. {$endif SUPPORT_DOUBLE}
  163. {$ifdef SUPPORT_EXTENDED}
  164. operator :=(const source : extended) dest : variant;
  165. begin
  166. Variant_Init(Dest);
  167. VariantManager.VarFromReal(Dest,Source);
  168. end;
  169. {$endif SUPPORT_EXTENDED}
  170. {$ifdef SUPPORT_COMP}
  171. Operator :=(const source : comp) dest : variant;
  172. begin
  173. Variant_Init(Dest);
  174. VariantManager.VarFromReal(Dest,Source);
  175. end;
  176. {$endif SUPPORT_COMP}
  177. { Misc. }
  178. { Fixme!!!
  179. operator :=(const source : currency) dest : variant;
  180. begin
  181. end;
  182. operator :=(const source : tdatetime) dest : variant;
  183. begin
  184. end;
  185. }
  186. {**********************************************************************
  187. from Variant assignments
  188. **********************************************************************}
  189. { Integer }
  190. operator :=(const source : variant) dest : byte;
  191. begin
  192. dest:=variantmanager.vartoint(source);
  193. end;
  194. operator :=(const source : variant) dest : shortint;
  195. begin
  196. dest:=variantmanager.vartoint(source);
  197. end;
  198. operator :=(const source : variant) dest : word;
  199. begin
  200. dest:=variantmanager.vartoint(source);
  201. end;
  202. operator :=(const source : variant) dest : smallint;
  203. begin
  204. dest:=variantmanager.vartoint(source);
  205. end;
  206. operator :=(const source : variant) dest : dword;
  207. begin
  208. dest:=variantmanager.vartoint(source);
  209. end;
  210. operator :=(const source : variant) dest : longint;
  211. begin
  212. dest:=variantmanager.vartoint(source);
  213. end;
  214. operator :=(const source : variant) dest : qword;
  215. begin
  216. dest:=variantmanager.vartoword64(source);
  217. end;
  218. operator :=(const source : variant) dest : int64;
  219. begin
  220. dest:=variantmanager.vartoint64(source);
  221. end;
  222. { Boolean }
  223. operator :=(const source : variant) dest : boolean;
  224. begin
  225. dest:=variantmanager.vartobool(source);
  226. end;
  227. operator :=(const source : variant) dest : wordbool;
  228. begin
  229. dest:=variantmanager.vartobool(source);
  230. end;
  231. operator :=(const source : variant) dest : longbool;
  232. begin
  233. dest:=variantmanager.vartobool(source);
  234. end;
  235. { Chars }
  236. operator :=(const source : variant) dest : char;
  237. Var
  238. S : String;
  239. begin
  240. VariantManager.VarToPStr(S,Source);
  241. If Length(S)>0 then
  242. Dest:=S[1];
  243. end;
  244. operator :=(const source : variant) dest : widechar;
  245. Var
  246. WS : WideString;
  247. begin
  248. VariantManager.VarToWStr(WS,Source);
  249. If Length(WS)>0 then
  250. Dest:=WS[1];
  251. end;
  252. { Strings }
  253. operator :=(const source : variant) dest : shortstring;
  254. begin
  255. VariantManager.VarToPStr(Dest,Source);
  256. end;
  257. operator :=(const source : variant) dest : ansistring;
  258. begin
  259. VariantManager.vartolstr(dest,source);
  260. end;
  261. operator :=(const source : variant) dest : widestring;
  262. begin
  263. variantmanager.vartowstr(dest,source);
  264. end;
  265. { Floats }
  266. {$ifdef SUPPORT_SINGLE}
  267. operator :=(const source : variant) dest : single;
  268. begin
  269. dest:=variantmanager.vartoreal(source);
  270. end;
  271. {$endif SUPPORT_SINGLE}
  272. {$ifdef SUPPORT_DOUBLE}
  273. operator :=(const source : variant) dest : double;
  274. begin
  275. dest:=variantmanager.vartoreal(source);
  276. end;
  277. {$endif SUPPORT_DOUBLE}
  278. {$ifdef SUPPORT_EXTENDED}
  279. operator :=(const source : variant) dest : extended;
  280. begin
  281. dest:=variantmanager.vartoreal(source);
  282. end;
  283. {$endif SUPPORT_EXTENDED}
  284. {$ifdef SUPPORT_COMP}
  285. operator :=(const source : variant) dest : comp;
  286. begin
  287. dest:=comp(variantmanager.vartoreal(source));
  288. end;
  289. {$endif SUPPORT_COMP}
  290. { Misc. }
  291. operator :=(const source : variant) dest : currency;
  292. begin
  293. dest:=variantmanager.vartocurr(source);
  294. end;
  295. (* FIXME !!!
  296. operator :=(const source : variant) dest : tdatetime;
  297. begin
  298. dest:=variantmanager.currtovar(source);
  299. end;
  300. *)
  301. {**********************************************************************
  302. Operators
  303. **********************************************************************}
  304. operator or(const op1,op2 : variant) dest : variant;
  305. begin
  306. dest:=op1;
  307. variantmanager.varop(dest,op2,opor);
  308. end;
  309. operator and(const op1,op2 : variant) dest : variant;
  310. begin
  311. dest:=op1;
  312. variantmanager.varop(dest,op2,opand);
  313. end;
  314. operator xor(const op1,op2 : variant) dest : variant;
  315. begin
  316. dest:=op1;
  317. variantmanager.varop(dest,op2,opxor);
  318. end;
  319. operator not(const op : variant) dest : variant;
  320. begin
  321. dest:=op;
  322. variantmanager.varnot(dest);
  323. end;
  324. operator shl(const op1,op2 : variant) dest : variant;
  325. begin
  326. dest:=op1;
  327. variantmanager.varop(dest,op2,opshiftleft);
  328. end;
  329. operator shr(const op1,op2 : variant) dest : variant;
  330. begin
  331. dest:=op1;
  332. variantmanager.varop(dest,op2,opshiftright);
  333. end;
  334. operator +(const op1,op2 : variant) dest : variant;
  335. begin
  336. dest:=op1;
  337. variantmanager.varop(dest,op2,opadd);
  338. end;
  339. operator -(const op1,op2 : variant) dest : variant;
  340. begin
  341. dest:=op1;
  342. variantmanager.varop(dest,op2,opsubtract);
  343. end;
  344. operator *(const op1,op2 : variant) dest : variant;
  345. begin
  346. dest:=op1;
  347. variantmanager.varop(dest,op2,opmultiply);
  348. end;
  349. operator /(const op1,op2 : variant) dest : variant;
  350. begin
  351. dest:=op1;
  352. variantmanager.varop(dest,op2,opdivide);
  353. end;
  354. operator div(const op1,op2 : variant) dest : variant;
  355. begin
  356. dest:=op1;
  357. variantmanager.varop(dest,op2,opintdivide);
  358. end;
  359. operator mod(const op1,op2 : variant) dest : variant;
  360. begin
  361. dest:=op1;
  362. variantmanager.varop(dest,op2,opmodulus);
  363. end;
  364. operator -(const op : variant) dest : variant;
  365. begin
  366. dest:=op;
  367. variantmanager.varneg(dest);
  368. end;
  369. operator =(const op1,op2 : variant) dest : boolean;
  370. begin
  371. dest:=variantmanager.cmpop(op1,op2,opcmpeq);
  372. end;
  373. operator <(const op1,op2 : variant) dest : boolean;
  374. begin
  375. dest:=variantmanager.cmpop(op1,op2,opcmplt);
  376. end;
  377. operator >(const op1,op2 : variant) dest : boolean;
  378. begin
  379. dest:=variantmanager.cmpop(op1,op2,opcmpgt);
  380. end;
  381. operator >=(const op1,op2 : variant) dest : boolean;
  382. begin
  383. dest:=variantmanager.cmpop(op1,op2,opcmpge);
  384. end;
  385. operator <=(const op1,op2 : variant) dest : boolean;
  386. begin
  387. dest:=variantmanager.cmpop(op1,op2,opcmplt);
  388. end;
  389. {**********************************************************************
  390. Variant manager functions
  391. **********************************************************************}
  392. procedure GetVariantManager(var VarMgr: TVariantManager);
  393. begin
  394. VarMgr:=VariantManager;
  395. end;
  396. procedure SetVariantManager(const VarMgr: TVariantManager);
  397. begin
  398. VariantManager:=VarMgr;
  399. end;
  400. function IsVariantManagerSet: Boolean;
  401. var
  402. i : longint;
  403. begin
  404. I:=0;
  405. Result:=True;
  406. While Result and (I<(sizeof(tvariantmanager) div sizeof(pointer))-1) do
  407. begin
  408. Result:=Pointer(ppointer(@variantmanager+i*sizeof(pointer))^)<>Pointer(@invalidvariantop);
  409. Inc(I);
  410. end;
  411. end;
  412. procedure initvariantmanager;
  413. var
  414. i : longint;
  415. begin
  416. VarDispProc:=@vardisperror;
  417. DispCallByIDProc:=@vardisperror;
  418. tvardata(Unassigned).VType:=varEmpty;
  419. tvardata(Null).VType:=varNull;
  420. for i:=0 to (sizeof(tvariantmanager) div sizeof(pointer))-1 do
  421. ppointer(@variantmanager+i*sizeof(pointer))^:=@invalidvariantop;
  422. pointer(variantmanager.varclear):=@varclear
  423. end;
  424. {
  425. $Log$
  426. Revision 1.16 2003-12-10 01:36:39 florian
  427. * real functions ifdef'ed depending on the supported types
  428. Revision 1.15 2003/11/05 15:26:37 florian
  429. + currency type can be assigned to variants now
  430. Revision 1.14 2003/10/04 23:40:42 florian
  431. * write helper comproc for variants fixed
  432. Revision 1.13 2003/09/03 14:09:37 florian
  433. * arm fixes to the common rtl code
  434. * some generic math code fixed
  435. * ...
  436. Revision 1.12 2002/10/10 19:24:28 florian
  437. + write(ln) support for variants added
  438. Revision 1.11 2002/10/09 20:13:26 florian
  439. * hopefully last fix to get things working :/
  440. Revision 1.10 2002/10/09 19:56:01 florian
  441. * variant assignments don't work yet, commented out
  442. Revision 1.9 2002/10/09 19:08:22 florian
  443. + Variant constants Unassigned and Null added
  444. Revision 1.8 2002/10/07 15:10:45 florian
  445. + variant wrappers for cmp operators added
  446. Revision 1.7 2002/10/07 10:27:45 florian
  447. + more variant wrappers added
  448. Revision 1.6 2002/10/06 22:13:55 florian
  449. * wrappers for xor, or and and operator with variants added
  450. Revision 1.5 2002/09/07 15:07:46 peter
  451. * old logs removed and tabs fixed
  452. }