cvarutil.inc 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635
  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. {$ifdef HASCURRENCY}
  341. VarCurrency: Result:=Trunc(VCurrency);
  342. {$else}
  343. VarCurrency: Result:=VCurrency;
  344. {$endif}
  345. VarDate : Result:=Trunc(VDate);
  346. VarOleStr : NoWideStrings;
  347. VarBoolean : Result:=Longint(VBoolean);
  348. VarByte : Result:=VByte;
  349. VarWord : Result:=VWord;
  350. VarLongWord : Result:=VLongWord;
  351. VarInt64 : Result:=VInt64;
  352. VarQword : Result:=VQWord;
  353. else
  354. VariantTypeMismatch;
  355. end;
  356. except
  357. On EConvertError do
  358. VariantTypeMismatch;
  359. else
  360. Raise;
  361. end;
  362. end;
  363. Function VariantToQWord(Const VargSrc : TVarData) : QWord;
  364. begin
  365. Try
  366. With VargSrc do
  367. Case (VType and VarTypeMask) of
  368. VarSmallInt: Result:=VSmallint;
  369. VarShortInt: Result:=VShortInt;
  370. VarInteger : Result:=VInteger;
  371. VarSingle : Result:=Trunc(VSingle);
  372. VarDouble : Result:=Trunc(VDouble);
  373. {$ifdef HASCURRENCY}
  374. VarCurrency: Result:=Trunc(VCurrency);
  375. {$else}
  376. VarCurrency: Result:=VCurrency;
  377. {$endif}
  378. VarDate : Result:=Trunc(VDate);
  379. VarOleStr : NoWideStrings;
  380. VarBoolean : Result:=Longint(VBoolean);
  381. VarByte : Result:=VByte;
  382. VarWord : Result:=VWord;
  383. VarLongWord : Result:=VLongWord;
  384. VarInt64 : Result:=VInt64;
  385. VarQword : Result:=VQWord;
  386. else
  387. VariantTypeMismatch;
  388. end;
  389. except
  390. On EConvertError do
  391. VariantTypeMismatch;
  392. else
  393. Raise;
  394. end;
  395. end;
  396. Function VariantToWideString(Const VargSrc : TVarData) : WideString;
  397. Const
  398. BS : Array[Boolean] of WideString = ('False','True');
  399. begin
  400. Try
  401. With VargSrc do
  402. Case (VType and VarTypeMask) of
  403. VarSmallInt : Result:=IntTostr(VSmallint);
  404. VarShortInt : Result:=IntToStr(VShortInt);
  405. VarInteger : Result:=IntToStr(VInteger);
  406. VarSingle : Result:=FloatToStr(VSingle);
  407. VarDouble : Result:=FloatToStr(VDouble);
  408. VarCurrency : Result:=FloatToStr(VCurrency);
  409. VarDate : Result:=DateTimeToStr(VDate);
  410. VarOleStr : Result:=WideString(Pointer(VOleStr));
  411. VarBoolean : Result:=BS[VBoolean];
  412. VarByte : Result:=IntToStr(VByte);
  413. VarWord : Result:=IntToStr(VWord);
  414. VarLongWord : Result:=IntToStr(VLongWord);
  415. VarInt64 : Result:=IntToStr(VInt64);
  416. VarQword : Result:=IntToStr(VQWord);
  417. else
  418. VariantTypeMismatch;
  419. end;
  420. except
  421. On EConvertError do
  422. VariantTypeMismatch;
  423. else
  424. Raise;
  425. end;
  426. end;
  427. Function VariantToAnsiString(Const VargSrc : TVarData) : AnsiString;
  428. Const
  429. BS : Array[Boolean] of AnsiString = ('False','True');
  430. begin
  431. Try
  432. With VargSrc do
  433. Case (VType and VarTypeMask) of
  434. VarSmallInt : Result:=IntTostr(VSmallint);
  435. VarShortInt : Result:=IntToStr(VShortInt);
  436. VarInteger : Result:=IntToStr(VInteger);
  437. VarSingle : Result:=FloatToStr(VSingle);
  438. VarDouble : Result:=FloatToStr(VDouble);
  439. VarCurrency : Result:=FloatToStr(VCurrency);
  440. VarDate : Result:=DateTimeToStr(VDate);
  441. VarOleStr : Result:=WideCharToString(VOleStr);
  442. VarBoolean : Result:=BS[VBoolean];
  443. VarByte : Result:=IntToStr(VByte);
  444. VarWord : Result:=IntToStr(VWord);
  445. VarLongWord : Result:=IntToStr(VLongWord);
  446. VarInt64 : Result:=IntToStr(VInt64);
  447. VarQword : Result:=IntToStr(VQWord);
  448. VarString : Result:=ansistring(VString);
  449. else
  450. VariantTypeMismatch;
  451. end;
  452. except
  453. On EConvertError do
  454. VariantTypeMismatch;
  455. else
  456. Raise;
  457. end;
  458. end;
  459. Function VariantToShortString(Const VargSrc : TVarData) : ShortString;
  460. Var
  461. S : AnsiString;
  462. begin
  463. S:=VariantToAnsiString(VArgSrc);
  464. Result:=S;
  465. end;
  466. { ---------------------------------------------------------------------
  467. Some debug routines
  468. ---------------------------------------------------------------------}
  469. Procedure DumpVariant(Const VArgSrc : TVarData);
  470. begin
  471. DumpVariant(Output,VArgSrc);
  472. end;
  473. (*
  474. tvardata = packed record
  475. vtype : tvartype;
  476. case integer of
  477. 0:(res1 : word;
  478. case integer of
  479. 0:
  480. (res2,res3 : word;
  481. case word of
  482. varsmallint : (vsmallint : smallint);
  483. varinteger : (vinteger : longint);
  484. varsingle : (vsingle : single);
  485. vardouble : (vdouble : double);
  486. varcurrency : (vcurrency : currency);
  487. vardate : (vdate : tdatetime);
  488. varolestr : (volestr : pwidechar);
  489. vardispatch : (vdispatch : pointer);
  490. varerror : (verror : dword);
  491. varboolean : (vboolean : wordbool);
  492. varunknown : (vunknown : pointer);
  493. // vardecimal : ( : );
  494. varshortint : (vshortint : shortint);
  495. varbyte : (vbyte : byte);
  496. varword : (vword : word);
  497. varlongword : (vlongword : dword);
  498. varint64 : (vint64 : int64);
  499. varqword : (vqword : qword);
  500. varword64 : (vword64 : qword);
  501. varstring : (vstring : pointer);
  502. varany : (vany : pointer);
  503. vararray : (varray : pvararray);
  504. varbyref : (vpointer : pointer);
  505. );
  506. 1:
  507. (vlongs : array[0..2] of longint);
  508. );
  509. 1:(vwords : array[0..6] of word);
  510. 2:(vbytes : array[0..13] of byte);
  511. end;
  512. *)
  513. Const
  514. VarTypeStrings : Array [varEmpty..varqword] of string = (
  515. 'empty', 'null', 'smallint', 'integer', 'single', 'double',
  516. 'currency', 'date', 'olestr', 'dispatch', 'error', 'boolean',
  517. 'variant', 'unknown', 'unknown','decimal', 'shortint', 'byte', 'word',
  518. 'longword', 'int64', 'qword');
  519. Procedure DumpVariant(Var F : Text; Const VArgSrc : TVarData);
  520. Var
  521. W : WideString;
  522. begin
  523. If VArgSrc.vType in [varEmpty..varqword] then
  524. Writeln(F,'Variant has type : ',VarTypeStrings[VArgSrc.vType])
  525. else if (VArgSrc.vType=VarArray) Then
  526. begin
  527. Write(F,'Variant is array.');
  528. exit;
  529. end
  530. else if (VargSrc.vType=VarByRef) then
  531. begin
  532. Writeln(F,'Variant is by reference.');
  533. exit;
  534. end
  535. else
  536. begin
  537. Writeln(F,'Variant has unknown type: ', VargSrc.vType);
  538. Exit;
  539. end;
  540. If VArgSrc.vType<>varEmpty then
  541. With VArgSrc do
  542. begin
  543. Write(F,'Value is: ') ;
  544. Case vtype of
  545. varnull : Write(F,'Null');
  546. varsmallint : Write(F,vsmallint);
  547. varinteger : Write(F,vinteger);
  548. varsingle : Write(F,vsingle);
  549. vardouble : Write(F,vdouble);
  550. varcurrency : Write(F,vcurrency) ;
  551. vardate : Write(F,vdate) ;
  552. varolestr : begin
  553. W:=vOleStr;
  554. Write(F,W) ;
  555. end;
  556. vardispatch : Write(F,'Not suppordted') ;
  557. varerror : Write(F,'Error') ;
  558. varboolean : Write(F,vboolean) ;
  559. varvariant : Write(F,'Unsupported') ;
  560. varunknown : Write(F,'Unsupported') ;
  561. vardecimal : Write(F,'Unsupported') ;
  562. varshortint : Write(F,vshortint) ;
  563. varbyte : Write(F,vbyte) ;
  564. varword : Write(F,vword) ;
  565. varlongword : Write(F,vlongword) ;
  566. varint64 : Write(F,vint64) ;
  567. varqword : Write(F,vqword) ;
  568. end;
  569. Writeln(f);
  570. end;
  571. end;