variant.inc 13 KB

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