variant.inc 12 KB

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