cvarutil.inc 18 KB

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