cvarutil.inc 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  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. begin
  183. With VargSrc do
  184. Case (VType and VarTypeMask) of
  185. VarSmallInt: Result:=VSmallInt;
  186. VarShortInt: Result:=VShortInt;
  187. VarInteger : Result:=VInteger;
  188. VarSingle : Result:=VSingle;
  189. VarDouble : Result:=VDouble;
  190. VarCurrency: Result:=VCurrency;
  191. VarDate : Result:=VDate;
  192. VarOleStr :
  193. begin
  194. if not(TryStrToFloat(WideCharToString(vOleStr),Result)) then
  195. VariantTypeMismatch;
  196. end;
  197. VarBoolean : Result:=Longint(VBoolean);
  198. VarByte : Result:=VByte;
  199. VarWord : Result:=VWord;
  200. VarLongWord : Result:=VLongWord;
  201. VarInt64 : Result:=VInt64;
  202. VarQword : Result:=VQWord;
  203. else
  204. VariantTypeMismatch;
  205. end;
  206. end;
  207. Function VariantToCurrency(Const VargSrc : TVarData) : Currency;
  208. begin
  209. Try
  210. With VargSrc do
  211. Case (VType and VarTypeMask) of
  212. VarSmallInt: Result:=VSmallInt;
  213. VarShortInt: Result:=VShortInt;
  214. VarInteger : Result:=VInteger;
  215. VarSingle : Result:=FloatToCurr(VSingle);
  216. VarDouble : Result:=FloatToCurr(VDouble);
  217. VarCurrency: Result:=VCurrency;
  218. VarDate : Result:=FloatToCurr(VDate);
  219. VarOleStr :
  220. if not(TryStrToCurr(WideCharToString(vOleStr),Result)) then
  221. VariantTypeMismatch;
  222. VarString :
  223. if not(TryStrToCurr(ansistring(vString),Result)) then
  224. VariantTypeMismatch;
  225. VarBoolean : Result:=Longint(VBoolean);
  226. VarByte : Result:=VByte;
  227. VarWord : Result:=VWord;
  228. VarLongWord : Result:=VLongWord;
  229. VarInt64 : Result:=VInt64;
  230. VarQword : Result:=VQWord;
  231. else
  232. VariantTypeMismatch;
  233. end;
  234. except
  235. On EConvertError do
  236. VariantTypeMismatch;
  237. else
  238. Raise;
  239. end;
  240. end;
  241. Function VariantToDate(Const VargSrc : TVarData) : TDateTime;
  242. begin
  243. Try
  244. With VargSrc do
  245. Case (VType and VarTypeMask) of
  246. VarSmallInt: Result:=FloatToDateTime(VSmallInt);
  247. VarShortInt: Result:=FloatToDateTime(VShortInt);
  248. VarInteger : Result:=FloatToDateTime(VInteger);
  249. VarSingle : Result:=FloatToDateTime(VSingle);
  250. VarDouble : Result:=FloatToDateTime(VDouble);
  251. VarCurrency: Result:=FloatToDateTime(VCurrency);
  252. VarDate : Result:=VDate;
  253. VarOleStr : NoWideStrings;
  254. VarBoolean : Result:=FloatToDateTime(Longint(VBoolean));
  255. VarByte : Result:=FloatToDateTime(VByte);
  256. VarWord : Result:=FloatToDateTime(VWord);
  257. VarLongWord : Result:=FloatToDateTime(VLongWord);
  258. VarInt64 : Result:=FloatToDateTime(VInt64);
  259. VarQWord : Result:=FloatToDateTime(VQword);
  260. else
  261. VariantTypeMismatch;
  262. end;
  263. except
  264. On EConvertError do
  265. VariantTypeMismatch;
  266. else
  267. Raise;
  268. end;
  269. end;
  270. Function VariantToBoolean(Const VargSrc : TVarData) : Boolean;
  271. begin
  272. With VargSrc do
  273. Case (VType and VarTypeMask) of
  274. VarSmallInt: Result:=VSmallInt<>0;
  275. VarShortInt: Result:=VShortInt<>0;
  276. VarInteger : Result:=VInteger<>0;
  277. VarSingle : Result:=VSingle<>0;
  278. VarDouble : Result:=VDouble<>0;
  279. VarCurrency: Result:=VCurrency<>0;
  280. VarDate : Result:=VDate<>0;
  281. VarOleStr : NoWideStrings;
  282. VarBoolean : Result:=VBoolean;
  283. VarByte : Result:=VByte<>0;
  284. VarWord : Result:=VWord<>0;
  285. VarLongWord : Result:=VLongWord<>0;
  286. VarInt64 : Result:=Vint64<>0;
  287. VarQword : Result:=VQWord<>0;
  288. else
  289. VariantTypeMismatch;
  290. end;
  291. end;
  292. Function VariantToByte(Const VargSrc : TVarData) : Byte;
  293. begin
  294. Try
  295. With VargSrc do
  296. Case (VType and VarTypeMask) of
  297. VarSmallInt: Result:=VSmallInt;
  298. VarShortInt: Result:=VShortInt;
  299. VarInteger : Result:=VInteger;
  300. VarSingle : Result:=Round(VSingle);
  301. VarDouble : Result:=Round(VDouble);
  302. VarCurrency: Result:=Round(VCurrency);
  303. VarDate : Result:=Round(VDate);
  304. VarOleStr : NoWideStrings;
  305. VarBoolean : Result:=Longint(VBoolean);
  306. VarByte : Result:=VByte;
  307. VarWord : Result:=VWord;
  308. VarLongWord : Result:=VLongWord;
  309. VarInt64 : Result:=Vint64;
  310. VarQword : Result:=VQWord;
  311. else
  312. VariantTypeMismatch;
  313. end;
  314. except
  315. On EConvertError do
  316. VariantTypeMismatch;
  317. else
  318. Raise;
  319. end;
  320. end;
  321. Function VariantToInt64(Const VargSrc : TVarData) : Int64;
  322. begin
  323. Try
  324. With VargSrc do
  325. Case (VType and VarTypeMask) of
  326. VarSmallInt: Result:=VSmallInt;
  327. VarShortInt: Result:=VShortInt;
  328. VarInteger : Result:=VInteger;
  329. VarSingle : Result:=Trunc(VSingle);
  330. VarDouble : Result:=Trunc(VDouble);
  331. VarCurrency: Result:=Trunc(VCurrency);
  332. VarDate : Result:=Trunc(VDate);
  333. VarOleStr : NoWideStrings;
  334. VarBoolean : Result:=Longint(VBoolean);
  335. VarByte : Result:=VByte;
  336. VarWord : Result:=VWord;
  337. VarLongWord : Result:=VLongWord;
  338. VarInt64 : Result:=VInt64;
  339. VarQword : Result:=VQWord;
  340. else
  341. VariantTypeMismatch;
  342. end;
  343. except
  344. On EConvertError do
  345. VariantTypeMismatch;
  346. else
  347. Raise;
  348. end;
  349. end;
  350. Function VariantToQWord(Const VargSrc : TVarData) : QWord;
  351. begin
  352. Try
  353. With VargSrc do
  354. Case (VType and VarTypeMask) of
  355. VarSmallInt: Result:=VSmallint;
  356. VarShortInt: Result:=VShortInt;
  357. VarInteger : Result:=VInteger;
  358. VarSingle : Result:=Trunc(VSingle);
  359. VarDouble : Result:=Trunc(VDouble);
  360. VarCurrency: Result:=Trunc(VCurrency);
  361. VarDate : Result:=Trunc(VDate);
  362. VarOleStr : NoWideStrings;
  363. VarBoolean : Result:=Longint(VBoolean);
  364. VarByte : Result:=VByte;
  365. VarWord : Result:=VWord;
  366. VarLongWord : Result:=VLongWord;
  367. VarInt64 : Result:=VInt64;
  368. VarQword : Result:=VQWord;
  369. else
  370. VariantTypeMismatch;
  371. end;
  372. except
  373. On EConvertError do
  374. VariantTypeMismatch;
  375. else
  376. Raise;
  377. end;
  378. end;
  379. Function VariantToWideString(Const VargSrc : TVarData) : WideString;
  380. Const
  381. BS : Array[Boolean] of WideString = ('False','True');
  382. begin
  383. Try
  384. With VargSrc do
  385. Case (VType and VarTypeMask) of
  386. VarSmallInt : Result:=IntTostr(VSmallint);
  387. VarShortInt : Result:=IntToStr(VShortInt);
  388. VarInteger : Result:=IntToStr(VInteger);
  389. VarSingle : Result:=FloatToStr(VSingle);
  390. VarDouble : Result:=FloatToStr(VDouble);
  391. VarCurrency : Result:=FloatToStr(VCurrency);
  392. VarDate : Result:=DateTimeToStr(VDate);
  393. VarOleStr : Result:=WideString(Pointer(VOleStr));
  394. VarBoolean : Result:=BS[VBoolean];
  395. VarByte : Result:=IntToStr(VByte);
  396. VarWord : Result:=IntToStr(VWord);
  397. VarLongWord : Result:=IntToStr(VLongWord);
  398. VarInt64 : Result:=IntToStr(VInt64);
  399. VarQword : Result:=IntToStr(VQWord);
  400. else
  401. VariantTypeMismatch;
  402. end;
  403. except
  404. On EConvertError do
  405. VariantTypeMismatch;
  406. else
  407. Raise;
  408. end;
  409. end;
  410. Function VariantToAnsiString(Const VargSrc : TVarData) : AnsiString;
  411. Const
  412. BS : Array[Boolean] of AnsiString = ('False','True');
  413. begin
  414. Try
  415. With VargSrc do
  416. Case (VType and VarTypeMask) of
  417. VarSmallInt : Result:=IntTostr(VSmallint);
  418. VarShortInt : Result:=IntToStr(VShortInt);
  419. VarInteger : Result:=IntToStr(VInteger);
  420. VarSingle : Result:=FloatToStr(VSingle);
  421. VarDouble : Result:=FloatToStr(VDouble);
  422. VarCurrency : Result:=FloatToStr(VCurrency);
  423. VarDate : Result:=DateTimeToStr(VDate);
  424. VarOleStr : Result:=WideCharToString(VOleStr);
  425. VarBoolean : Result:=BS[VBoolean];
  426. VarByte : Result:=IntToStr(VByte);
  427. VarWord : Result:=IntToStr(VWord);
  428. VarLongWord : Result:=IntToStr(VLongWord);
  429. VarInt64 : Result:=IntToStr(VInt64);
  430. VarQword : Result:=IntToStr(VQWord);
  431. VarString : Result:=ansistring(VString);
  432. else
  433. VariantTypeMismatch;
  434. end;
  435. except
  436. On EConvertError do
  437. VariantTypeMismatch;
  438. else
  439. Raise;
  440. end;
  441. end;
  442. Function VariantToShortString(Const VargSrc : TVarData) : ShortString;
  443. Var
  444. S : AnsiString;
  445. begin
  446. S:=VariantToAnsiString(VArgSrc);
  447. Result:=S;
  448. end;
  449. { ---------------------------------------------------------------------
  450. Some debug routines
  451. ---------------------------------------------------------------------}
  452. Procedure DumpVariant(Const VArgSrc : TVarData);
  453. begin
  454. DumpVariant(Output,VArgSrc);
  455. end;
  456. (*
  457. tvardata = packed record
  458. vtype : tvartype;
  459. case integer of
  460. 0:(res1 : word;
  461. case integer of
  462. 0:
  463. (res2,res3 : word;
  464. case word of
  465. varsmallint : (vsmallint : smallint);
  466. varinteger : (vinteger : longint);
  467. varsingle : (vsingle : single);
  468. vardouble : (vdouble : double);
  469. varcurrency : (vcurrency : currency);
  470. vardate : (vdate : tdatetime);
  471. varolestr : (volestr : pwidechar);
  472. vardispatch : (vdispatch : pointer);
  473. varerror : (verror : dword);
  474. varboolean : (vboolean : wordbool);
  475. varunknown : (vunknown : pointer);
  476. // vardecimal : ( : );
  477. varshortint : (vshortint : shortint);
  478. varbyte : (vbyte : byte);
  479. varword : (vword : word);
  480. varlongword : (vlongword : dword);
  481. varint64 : (vint64 : int64);
  482. varqword : (vqword : qword);
  483. varword64 : (vword64 : qword);
  484. varstring : (vstring : pointer);
  485. varany : (vany : pointer);
  486. vararray : (varray : pvararray);
  487. varbyref : (vpointer : pointer);
  488. );
  489. 1:
  490. (vlongs : array[0..2] of longint);
  491. );
  492. 1:(vwords : array[0..6] of word);
  493. 2:(vbytes : array[0..13] of byte);
  494. end;
  495. *)
  496. Const
  497. VarTypeStrings : Array [varEmpty..varqword] of string = (
  498. 'empty', 'null', 'smallint', 'integer', 'single', 'double',
  499. 'currency', 'date', 'olestr', 'dispatch', 'error', 'boolean',
  500. 'variant', 'unknown', 'unknown','decimal', 'shortint', 'byte', 'word',
  501. 'longword', 'int64', 'qword');
  502. Procedure DumpVariant(Var F : Text; Const VArgSrc : TVarData);
  503. Var
  504. W : WideString;
  505. begin
  506. If VArgSrc.vType in [varEmpty..varqword] then
  507. Writeln(F,'Variant has type : ',VarTypeStrings[VArgSrc.vType])
  508. else if (VArgSrc.vType=VarArray) Then
  509. begin
  510. Write(F,'Variant is array.');
  511. exit;
  512. end
  513. else if (VargSrc.vType=VarByRef) then
  514. begin
  515. Writeln(F,'Variant is by reference.');
  516. exit;
  517. end
  518. else
  519. begin
  520. Writeln(F,'Variant has unknown type: ', VargSrc.vType);
  521. Exit;
  522. end;
  523. If VArgSrc.vType<>varEmpty then
  524. With VArgSrc do
  525. begin
  526. Write(F,'Value is: ') ;
  527. Case vtype of
  528. varnull : Write(F,'Null');
  529. varsmallint : Write(F,vsmallint);
  530. varinteger : Write(F,vinteger);
  531. varsingle : Write(F,vsingle);
  532. vardouble : Write(F,vdouble);
  533. varcurrency : Write(F,vcurrency) ;
  534. vardate : Write(F,vdate) ;
  535. varolestr : begin
  536. W:=vOleStr;
  537. Write(F,W) ;
  538. end;
  539. vardispatch : Write(F,'Not suppordted') ;
  540. varerror : Write(F,'Error') ;
  541. varboolean : Write(F,vboolean) ;
  542. varvariant : Write(F,'Unsupported') ;
  543. varunknown : Write(F,'Unsupported') ;
  544. vardecimal : Write(F,'Unsupported') ;
  545. varshortint : Write(F,vshortint) ;
  546. varbyte : Write(F,vbyte) ;
  547. varword : Write(F,vword) ;
  548. varlongword : Write(F,vlongword) ;
  549. varint64 : Write(F,vint64) ;
  550. varqword : Write(F,vqword) ;
  551. end;
  552. Writeln(f);
  553. end;
  554. end;