cvarutil.inc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  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. VarString : Result:=ansistring(VString);
  402. else
  403. VariantTypeMismatch;
  404. end;
  405. except
  406. On EConvertError do
  407. VariantTypeMismatch;
  408. else
  409. Raise;
  410. end;
  411. end;
  412. Function VariantToShortString(Const VargSrc : TVarData) : ShortString;
  413. Var
  414. S : AnsiString;
  415. begin
  416. S:=VariantToAnsiString(VArgSrc);
  417. Result:=S;
  418. end;
  419. { ---------------------------------------------------------------------
  420. Some debug routines
  421. ---------------------------------------------------------------------}
  422. Procedure DumpVariant(Const VArgSrc : TVarData);
  423. begin
  424. DumpVariant(Output,VArgSrc);
  425. end;
  426. (*
  427. tvardata = packed record
  428. vtype : tvartype;
  429. case integer of
  430. 0:(res1 : word;
  431. case integer of
  432. 0:
  433. (res2,res3 : word;
  434. case word of
  435. varsmallint : (vsmallint : smallint);
  436. varinteger : (vinteger : longint);
  437. varsingle : (vsingle : single);
  438. vardouble : (vdouble : double);
  439. varcurrency : (vcurrency : currency);
  440. vardate : (vdate : tdatetime);
  441. varolestr : (volestr : pwidechar);
  442. vardispatch : (vdispatch : pointer);
  443. varerror : (verror : dword);
  444. varboolean : (vboolean : wordbool);
  445. varunknown : (vunknown : pointer);
  446. // vardecimal : ( : );
  447. varshortint : (vshortint : shortint);
  448. varbyte : (vbyte : byte);
  449. varword : (vword : word);
  450. varlongword : (vlongword : dword);
  451. varint64 : (vint64 : int64);
  452. varqword : (vqword : qword);
  453. varword64 : (vword64 : qword);
  454. varstring : (vstring : pointer);
  455. varany : (vany : pointer);
  456. vararray : (varray : pvararray);
  457. varbyref : (vpointer : pointer);
  458. );
  459. 1:
  460. (vlongs : array[0..2] of longint);
  461. );
  462. 1:(vwords : array[0..6] of word);
  463. 2:(vbytes : array[0..13] of byte);
  464. end;
  465. *)
  466. Const
  467. VarTypeStrings : Array [varEmpty..varqword] of string = (
  468. 'empty', 'null', 'smallint', 'integer', 'single', 'double',
  469. 'currency', 'date', 'olestr', 'dispatch', 'error', 'boolean',
  470. 'variant', 'unknown', 'unknown','decimal', 'shortint', 'byte', 'word',
  471. 'longword', 'int64', 'qword');
  472. Procedure DumpVariant(Var F : Text; Const VArgSrc : TVarData);
  473. Var
  474. W : WideString;
  475. begin
  476. If VArgSrc.vType in [varEmpty..varqword] then
  477. Writeln(F,'Variant has type : ',VarTypeStrings[VArgSrc.vType])
  478. else if (VArgSrc.vType=VarArray) Then
  479. begin
  480. Write(F,'Variant is array.');
  481. exit;
  482. end
  483. else if (VargSrc.vType=VarByRef) then
  484. begin
  485. Writeln(F,'Variant is by reference.');
  486. exit;
  487. end
  488. else
  489. begin
  490. Writeln(F,'Variant has unknown type: ', VargSrc.vType);
  491. Exit;
  492. end;
  493. If VArgSrc.vType<>varEmpty then
  494. With VArgSrc do
  495. begin
  496. Write(F,'Value is: ') ;
  497. Case vtype of
  498. varnull : Write(F,'Null');
  499. varsmallint : Write(F,vsmallint);
  500. varinteger : Write(F,vinteger);
  501. varsingle : Write(F,vsingle);
  502. vardouble : Write(F,vdouble);
  503. varcurrency : Write(F,vcurrency) ;
  504. vardate : Write(F,vdate) ;
  505. varolestr : begin
  506. W:=vOleStr;
  507. Write(F,W) ;
  508. end;
  509. vardispatch : Write(F,'Not suppordted') ;
  510. varerror : Write(F,'Error') ;
  511. varboolean : Write(F,vboolean) ;
  512. varvariant : Write(F,'Unsupported') ;
  513. varunknown : Write(F,'Unsupported') ;
  514. vardecimal : Write(F,'Unsupported') ;
  515. varshortint : Write(F,vshortint) ;
  516. varbyte : Write(F,vbyte) ;
  517. varword : Write(F,vword) ;
  518. varlongword : Write(F,vlongword) ;
  519. varint64 : Write(F,vint64) ;
  520. varqword : Write(F,vqword) ;
  521. end;
  522. Writeln(f);
  523. end;
  524. end;
  525. {$endif HASVARIANT}
  526. {
  527. $Log$
  528. Revision 1.12 2005-03-10 21:05:36 florian
  529. + writing of variants implemented
  530. Revision 1.11 2005/02/14 17:13:31 peter
  531. * truncate log
  532. }