cvarutil.inc 18 KB

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