cvarutil.inc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 2000,2001 by the Free Pascal development team
  5. Interface and OS-dependent part of variant support
  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. {$ifdef HASVARIANT}
  13. Resourcestring
  14. SNoWidestrings = 'No widestrings supported';
  15. SNoInterfaces = 'No interfaces supported';
  16. Procedure NoWidestrings;
  17. begin
  18. Raise Exception.Create(SNoWideStrings);
  19. end;
  20. Procedure NoInterfaces;
  21. begin
  22. Raise Exception.Create(SNoInterfaces);
  23. end;
  24. Constructor EVariantError.CreateCode (Code : longint);
  25. begin
  26. ErrCode:=Code;
  27. end;
  28. Procedure VariantTypeMismatch;
  29. begin
  30. Raise EVariantError.CreateCode(VAR_TYPEMISMATCH);
  31. end;
  32. Function ExceptionToVariantError (E : Exception): HResult;
  33. begin
  34. If E is EoutOfMemory then
  35. Result:=VAR_OUTOFMEMORY
  36. else
  37. Result:=VAR_EXCEPTION;
  38. end;
  39. { ---------------------------------------------------------------------
  40. OS-independent functions not present in Windows
  41. ---------------------------------------------------------------------}
  42. Function VariantToSmallInt(Const VargSrc : TVarData) : SmallInt;
  43. begin
  44. With VargSrc do
  45. Case (VType and VarTypeMask) of
  46. VarSmallInt: Result:=VSmallInt;
  47. VarShortInt: Result:=VShortInt;
  48. VarInteger : Result:=VInteger;
  49. VarSingle : Result:=Round(VSingle);
  50. VarDouble : Result:=Round(VDouble);
  51. VarCurrency: Result:=Round(VCurrency);
  52. VarDate : Result:=Round(VDate);
  53. VarOleStr : Result:=StrToInt(WideCharToString(vOleStr));
  54. VarBoolean : Result:=SmallInt(VBoolean);
  55. VarByte : Result:=VByte;
  56. VarWord : Result:=VWord;
  57. VarLongWord : Result:=VLongWord;
  58. VarInt64 : Result:=VInt64;
  59. VarQword : Result:=VQWord;
  60. else
  61. VariantTypeMismatch;
  62. end;
  63. end;
  64. Function VariantToShortInt(Const VargSrc : TVarData) : ShortInt;
  65. begin
  66. With VargSrc do
  67. Case (VType and VarTypeMask) of
  68. VarSmallInt: Result:=VSmallInt;
  69. VarShortInt: Result:=VShortInt;
  70. VarInteger : Result:=VInteger;
  71. VarSingle : Result:=Round(VSingle);
  72. VarDouble : Result:=Round(VDouble);
  73. VarCurrency: Result:=Round(VCurrency);
  74. VarDate : Result:=Round(VDate);
  75. VarOleStr : Result:=StrToInt(WideCharToString(vOleStr));
  76. VarBoolean : Result:=SmallInt(VBoolean);
  77. VarByte : Result:=VByte;
  78. VarWord : Result:=VWord;
  79. VarLongWord : Result:=VLongWord;
  80. VarInt64 : Result:=VInt64;
  81. VarQword : Result:=VQWord;
  82. else
  83. VariantTypeMismatch;
  84. end;
  85. end;
  86. Function VariantToLongint(Const VargSrc : TVarData) : Longint;
  87. begin
  88. With VargSrc do
  89. Case (VType and VarTypeMask) of
  90. VarSmallInt: Result:=VSmallInt;
  91. VarShortInt: Result:=VShortInt;
  92. VarInteger : Result:=VInteger;
  93. VarSingle : Result:=Round(VSingle);
  94. VarDouble : Result:=Round(VDouble);
  95. VarCurrency: Result:=Round(VCurrency);
  96. VarDate : Result:=Round(VDate);
  97. VarOleStr : Result:=StrToInt(WideCharToString(vOleStr));
  98. VarBoolean : Result:=Longint(VBoolean);
  99. VarByte : Result:=VByte;
  100. VarWord : Result:=VWord;
  101. VarLongWord : Result:=VLongWord;
  102. VarInt64 : Result:=VInt64;
  103. VarQword : Result:=VQWord;
  104. else
  105. VariantTypeMismatch;
  106. end;
  107. end;
  108. Function VariantToCardinal(Const VargSrc : TVarData) : Cardinal;
  109. begin
  110. With VargSrc do
  111. Case (VType and VarTypeMask) of
  112. VarSmallInt: Result:=VSmallInt;
  113. VarShortInt: Result:=VShortInt;
  114. VarInteger : Result:=VInteger;
  115. VarSingle : Result:=Round(VSingle);
  116. VarDouble : Result:=Round(VDouble);
  117. VarCurrency: Result:=Round(VCurrency);
  118. VarDate : Result:=Round(VDate);
  119. VarOleStr : Result:=StrToInt(WideCharToString(vOleStr));
  120. VarBoolean : Result:=Longint(VBoolean);
  121. VarByte : Result:=VByte;
  122. VarWord : Result:=VWord;
  123. VarLongWord : Result:=VLongWord;
  124. VarInt64 : Result:=VInt64;
  125. VarQword : Result:=VQWord;
  126. else
  127. VariantTypeMismatch;
  128. end;
  129. end;
  130. Function VariantToSingle(Const VargSrc : TVarData) : Single;
  131. begin
  132. With VargSrc do
  133. Case (VType and VarTypeMask) of
  134. VarSmallInt: Result:=VSmallInt;
  135. VarShortInt: Result:=VShortInt;
  136. VarInteger : Result:=VInteger;
  137. VarSingle : Result:=VSingle;
  138. VarDouble : Result:=VDouble;
  139. VarCurrency: Result:=VCurrency;
  140. VarDate : Result:=VDate;
  141. VarOleStr : NoWideStrings;
  142. VarBoolean : Result:=Longint(VBoolean);
  143. VarByte : Result:=VByte;
  144. VarWord : Result:=VWord;
  145. VarLongWord : Result:=VLongWord;
  146. VarInt64 : Result:=VInt64;
  147. VarQword : Result:=VQWord;
  148. else
  149. VariantTypeMismatch;
  150. end;
  151. end;
  152. Function VariantToDouble(Const VargSrc : TVarData) : Double;
  153. begin
  154. With VargSrc do
  155. Case (VType and VarTypeMask) of
  156. VarSmallInt: Result:=VSmallInt;
  157. VarShortInt: Result:=VShortInt;
  158. VarInteger : Result:=VInteger;
  159. VarSingle : Result:=VSingle;
  160. VarDouble : Result:=VDouble;
  161. VarCurrency: Result:=VCurrency;
  162. VarDate : Result:=VDate;
  163. VarOleStr : NoWideStrings;
  164. VarBoolean : Result:=Longint(VBoolean);
  165. VarByte : Result:=VByte;
  166. VarWord : Result:=VWord;
  167. VarLongWord : Result:=VLongWord;
  168. VarInt64 : Result:=VInt64;
  169. VarQword : Result:=VQWord;
  170. else
  171. VariantTypeMismatch;
  172. end;
  173. end;
  174. Function VariantToCurrency(Const VargSrc : TVarData) : Currency;
  175. begin
  176. Try
  177. With VargSrc do
  178. Case (VType and VarTypeMask) of
  179. VarSmallInt: Result:=VSmallInt;
  180. VarShortInt: Result:=VShortInt;
  181. VarInteger : Result:=VInteger;
  182. VarSingle : Result:=FloatToCurr(VSingle);
  183. VarDouble : Result:=FloatToCurr(VDouble);
  184. VarCurrency: Result:=VCurrency;
  185. VarDate : Result:=FloatToCurr(VDate);
  186. VarOleStr : NoWideStrings;
  187. VarBoolean : Result:=Longint(VBoolean);
  188. VarByte : Result:=VByte;
  189. VarWord : Result:=VWord;
  190. VarLongWord : Result:=VLongWord;
  191. VarInt64 : Result:=VInt64;
  192. VarQword : Result:=VQWord;
  193. else
  194. VariantTypeMismatch;
  195. end;
  196. except
  197. On EConvertError do
  198. VariantTypeMismatch;
  199. else
  200. Raise;
  201. end;
  202. end;
  203. Function VariantToDate(Const VargSrc : TVarData) : TDateTime;
  204. begin
  205. Try
  206. With VargSrc do
  207. Case (VType and VarTypeMask) of
  208. VarSmallInt: Result:=FloatToDateTime(VSmallInt);
  209. VarShortInt: Result:=FloatToDateTime(VShortInt);
  210. VarInteger : Result:=FloatToDateTime(VInteger);
  211. VarSingle : Result:=FloatToDateTime(VSingle);
  212. VarDouble : Result:=FloatToDateTime(VDouble);
  213. VarCurrency: Result:=FloatToDateTime(VCurrency);
  214. VarDate : Result:=VDate;
  215. VarOleStr : NoWideStrings;
  216. VarBoolean : Result:=FloatToDateTime(Longint(VBoolean));
  217. VarByte : Result:=FloatToDateTime(VByte);
  218. VarWord : Result:=FloatToDateTime(VWord);
  219. VarLongWord : Result:=FloatToDateTime(VLongWord);
  220. VarInt64 : Result:=FloatToDateTime(VInt64);
  221. VarQWord : Result:=FloatToDateTime(VQword);
  222. else
  223. VariantTypeMismatch;
  224. end;
  225. except
  226. On EConvertError do
  227. VariantTypeMismatch;
  228. else
  229. Raise;
  230. end;
  231. end;
  232. Function VariantToBoolean(Const VargSrc : TVarData) : Boolean;
  233. begin
  234. With VargSrc do
  235. Case (VType and VarTypeMask) of
  236. VarSmallInt: Result:=VSmallInt<>0;
  237. VarShortInt: Result:=VShortInt<>0;
  238. VarInteger : Result:=VInteger<>0;
  239. VarSingle : Result:=VSingle<>0;
  240. VarDouble : Result:=VDouble<>0;
  241. VarCurrency: Result:=VCurrency<>0;
  242. VarDate : Result:=VDate<>0;
  243. VarOleStr : NoWideStrings;
  244. VarBoolean : Result:=VBoolean;
  245. VarByte : Result:=VByte<>0;
  246. VarWord : Result:=VWord<>0;
  247. VarLongWord : Result:=VLongWord<>0;
  248. VarInt64 : Result:=Vint64<>0;
  249. VarQword : Result:=VQWord<>0;
  250. else
  251. VariantTypeMismatch;
  252. end;
  253. end;
  254. Function VariantToByte(Const VargSrc : TVarData) : Byte;
  255. begin
  256. Try
  257. With VargSrc do
  258. Case (VType and VarTypeMask) of
  259. VarSmallInt: Result:=VSmallInt;
  260. VarShortInt: Result:=VShortInt;
  261. VarInteger : Result:=VInteger;
  262. VarSingle : Result:=Round(VSingle);
  263. VarDouble : Result:=Round(VDouble);
  264. VarCurrency: Result:=Round(VCurrency);
  265. VarDate : Result:=Round(VDate);
  266. VarOleStr : NoWideStrings;
  267. VarBoolean : Result:=Longint(VBoolean);
  268. VarByte : Result:=VByte;
  269. VarWord : Result:=VWord;
  270. VarLongWord : Result:=VLongWord;
  271. VarInt64 : Result:=Vint64;
  272. VarQword : Result:=VQWord;
  273. else
  274. VariantTypeMismatch;
  275. end;
  276. except
  277. On EConvertError do
  278. VariantTypeMismatch;
  279. else
  280. Raise;
  281. end;
  282. end;
  283. Function VariantToInt64(Const VargSrc : TVarData) : Int64;
  284. begin
  285. Try
  286. With VargSrc do
  287. Case (VType and VarTypeMask) of
  288. VarSmallInt: Result:=VSmallInt;
  289. VarShortInt: Result:=VShortInt;
  290. VarInteger : Result:=VInteger;
  291. VarSingle : Result:=Trunc(VSingle);
  292. VarDouble : Result:=Trunc(VDouble);
  293. {$ifdef HASCURRENCY}
  294. VarCurrency: Result:=Trunc(VCurrency);
  295. {$else}
  296. VarCurrency: Result:=VCurrency;
  297. {$endif}
  298. VarDate : Result:=Trunc(VDate);
  299. VarOleStr : NoWideStrings;
  300. VarBoolean : Result:=Longint(VBoolean);
  301. VarByte : Result:=VByte;
  302. VarWord : Result:=VWord;
  303. VarLongWord : Result:=VLongWord;
  304. VarInt64 : Result:=VInt64;
  305. VarQword : Result:=VQWord;
  306. else
  307. VariantTypeMismatch;
  308. end;
  309. except
  310. On EConvertError do
  311. VariantTypeMismatch;
  312. else
  313. Raise;
  314. end;
  315. end;
  316. Function VariantToQWord(Const VargSrc : TVarData) : QWord;
  317. begin
  318. Try
  319. With VargSrc do
  320. Case (VType and VarTypeMask) of
  321. VarSmallInt: Result:=VSmallint;
  322. VarShortInt: Result:=VShortInt;
  323. VarInteger : Result:=VInteger;
  324. VarSingle : Result:=Trunc(VSingle);
  325. VarDouble : Result:=Trunc(VDouble);
  326. {$ifdef HASCURRENCY}
  327. VarCurrency: Result:=Trunc(VCurrency);
  328. {$else}
  329. VarCurrency: Result:=VCurrency;
  330. {$endif}
  331. VarDate : Result:=Trunc(VDate);
  332. VarOleStr : NoWideStrings;
  333. VarBoolean : Result:=Longint(VBoolean);
  334. VarByte : Result:=VByte;
  335. VarWord : Result:=VWord;
  336. VarLongWord : Result:=VLongWord;
  337. VarInt64 : Result:=VInt64;
  338. VarQword : Result:=VQWord;
  339. else
  340. VariantTypeMismatch;
  341. end;
  342. except
  343. On EConvertError do
  344. VariantTypeMismatch;
  345. else
  346. Raise;
  347. end;
  348. end;
  349. Function VariantToWideString(Const VargSrc : TVarData) : WideString;
  350. Const
  351. BS : Array[Boolean] of WideString = ('False','True');
  352. begin
  353. Try
  354. With VargSrc do
  355. Case (VType and VarTypeMask) of
  356. VarSmallInt : Result:=IntTostr(VSmallint);
  357. VarShortInt : Result:=IntToStr(VShortInt);
  358. VarInteger : Result:=IntToStr(VInteger);
  359. VarSingle : Result:=FloatToStr(VSingle);
  360. VarDouble : Result:=FloatToStr(VDouble);
  361. VarCurrency : Result:=FloatToStr(VCurrency);
  362. VarDate : Result:=DateTimeToStr(VDate);
  363. VarOleStr : Result:=WideString(Pointer(VOleStr));
  364. VarBoolean : Result:=BS[VBoolean];
  365. VarByte : Result:=IntToStr(VByte);
  366. VarWord : Result:=IntToStr(VWord);
  367. VarLongWord : Result:=IntToStr(VLongWord);
  368. VarInt64 : Result:=IntToStr(VInt64);
  369. VarQword : Result:=IntToStr(VQWord);
  370. else
  371. VariantTypeMismatch;
  372. end;
  373. except
  374. On EConvertError do
  375. VariantTypeMismatch;
  376. else
  377. Raise;
  378. end;
  379. end;
  380. Function VariantToAnsiString(Const VargSrc : TVarData) : AnsiString;
  381. Const
  382. BS : Array[Boolean] of AnsiString = ('False','True');
  383. begin
  384. Try
  385. With VargSrc do
  386. Case (VType and VarTypeMask) of
  387. VarSmallInt : Result:=IntTostr(VSmallint);
  388. VarShortInt : Result:=IntToStr(VShortInt);
  389. VarInteger : Result:=IntToStr(VInteger);
  390. VarSingle : Result:=FloatToStr(VSingle);
  391. VarDouble : Result:=FloatToStr(VDouble);
  392. VarCurrency : Result:=FloatToStr(VCurrency);
  393. VarDate : Result:=DateTimeToStr(VDate);
  394. VarOleStr : Result:=WideCharToString(VOleStr);
  395. VarBoolean : Result:=BS[VBoolean];
  396. VarByte : Result:=IntToStr(VByte);
  397. VarWord : Result:=IntToStr(VWord);
  398. VarLongWord : Result:=IntToStr(VLongWord);
  399. VarInt64 : Result:=IntToStr(VInt64);
  400. VarQword : Result:=IntToStr(VQWord);
  401. else
  402. VariantTypeMismatch;
  403. end;
  404. except
  405. On EConvertError do
  406. VariantTypeMismatch;
  407. else
  408. Raise;
  409. end;
  410. end;
  411. Function VariantToShortString(Const VargSrc : TVarData) : ShortString;
  412. Var
  413. S : AnsiString;
  414. begin
  415. S:=VariantToAnsiString(VArgSrc);
  416. Result:=S;
  417. end;
  418. { ---------------------------------------------------------------------
  419. Some debug routines
  420. ---------------------------------------------------------------------}
  421. Procedure DumpVariant(Const VArgSrc : TVarData);
  422. begin
  423. DumpVariant(Output,VArgSrc);
  424. end;
  425. (*
  426. tvardata = packed record
  427. vtype : tvartype;
  428. case integer of
  429. 0:(res1 : word;
  430. case integer of
  431. 0:
  432. (res2,res3 : word;
  433. case word of
  434. varsmallint : (vsmallint : smallint);
  435. varinteger : (vinteger : longint);
  436. varsingle : (vsingle : single);
  437. vardouble : (vdouble : double);
  438. varcurrency : (vcurrency : currency);
  439. vardate : (vdate : tdatetime);
  440. varolestr : (volestr : pwidechar);
  441. vardispatch : (vdispatch : pointer);
  442. varerror : (verror : dword);
  443. varboolean : (vboolean : wordbool);
  444. varunknown : (vunknown : pointer);
  445. // vardecimal : ( : );
  446. varshortint : (vshortint : shortint);
  447. varbyte : (vbyte : byte);
  448. varword : (vword : word);
  449. varlongword : (vlongword : dword);
  450. varint64 : (vint64 : int64);
  451. varqword : (vqword : qword);
  452. varword64 : (vword64 : qword);
  453. varstring : (vstring : pointer);
  454. varany : (vany : pointer);
  455. vararray : (varray : pvararray);
  456. varbyref : (vpointer : pointer);
  457. );
  458. 1:
  459. (vlongs : array[0..2] of longint);
  460. );
  461. 1:(vwords : array[0..6] of word);
  462. 2:(vbytes : array[0..13] of byte);
  463. end;
  464. *)
  465. Const
  466. VarTypeStrings : Array [varEmpty..varqword] of string = (
  467. 'empty', 'null', 'smallint', 'integer', 'single', 'double',
  468. 'currency', 'date', 'olestr', 'dispatch', 'error', 'boolean',
  469. 'variant', 'unknown', 'unknown','decimal', 'shortint', 'byte', 'word',
  470. 'longword', 'int64', 'qword');
  471. Procedure DumpVariant(Var F : Text; Const VArgSrc : TVarData);
  472. Var
  473. W : WideString;
  474. begin
  475. If VArgSrc.vType in [varEmpty..varqword] then
  476. Writeln(F,'Variant has type : ',VarTypeStrings[VArgSrc.vType])
  477. else if (VArgSrc.vType=VarArray) Then
  478. begin
  479. Write(F,'Variant is array.');
  480. exit;
  481. end
  482. else if (VargSrc.vType=VarByRef) then
  483. begin
  484. Writeln(F,'Variant is by reference.');
  485. exit;
  486. end
  487. else
  488. begin
  489. Writeln(F,'Variant has unknown type: ', VargSrc.vType);
  490. Exit;
  491. end;
  492. If VArgSrc.vType<>varEmpty then
  493. With VArgSrc do
  494. begin
  495. Write(F,'Value is: ') ;
  496. Case vtype of
  497. varnull : Write(F,'Null');
  498. varsmallint : Write(F,vsmallint);
  499. varinteger : Write(F,vinteger);
  500. varsingle : Write(F,vsingle);
  501. vardouble : Write(F,vdouble);
  502. varcurrency : Write(F,vcurrency) ;
  503. vardate : Write(F,vdate) ;
  504. varolestr : begin
  505. W:=vOleStr;
  506. Write(F,W) ;
  507. end;
  508. vardispatch : Write(F,'Not suppordted') ;
  509. varerror : Write(F,'Error') ;
  510. varboolean : Write(F,vboolean) ;
  511. varvariant : Write(F,'Unsupported') ;
  512. varunknown : Write(F,'Unsupported') ;
  513. vardecimal : Write(F,'Unsupported') ;
  514. varshortint : Write(F,vshortint) ;
  515. varbyte : Write(F,vbyte) ;
  516. varword : Write(F,vword) ;
  517. varlongword : Write(F,vlongword) ;
  518. varint64 : Write(F,vint64) ;
  519. varqword : Write(F,vqword) ;
  520. end;
  521. Writeln(f);
  522. end;
  523. end;
  524. {$endif HASVARIANT}
  525. {
  526. $Log$
  527. Revision 1.10 2003-11-04 23:15:58 michael
  528. Support for ansistring and better debug outpu
  529. Revision 1.9 2003/11/04 22:53:55 michael
  530. + Removed debug statements
  531. Revision 1.8 2003/11/04 22:27:43 michael
  532. + Some fixes for string support
  533. Revision 1.7 2002/09/07 16:01:22 peter
  534. * old logs removed and tabs fixed
  535. Revision 1.6 2002/07/01 16:25:10 peter
  536. * currency updates
  537. }