cvarutil.inc 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453
  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. Procedure VariantTypeMismatch; overload;
  23. begin
  24. Raise EVariantError.CreateCode(VAR_TYPEMISMATCH);
  25. end;
  26. Procedure VariantTypeMismatch(const SourceType, DestType: TVarType);
  27. begin
  28. { ignore the types for now ... }
  29. Raise EVariantError.CreateCode(VAR_TYPEMISMATCH);
  30. end;
  31. Function ExceptionToVariantError (E : Exception): HResult;
  32. begin
  33. If E is EoutOfMemory then
  34. Result:=VAR_OUTOFMEMORY
  35. else
  36. Result:=VAR_EXCEPTION;
  37. end;
  38. { ---------------------------------------------------------------------
  39. OS-independent functions not present in Windows
  40. ---------------------------------------------------------------------}
  41. {--- SmallInt ---}
  42. Function WStrToSmallInt(p: Pointer) : SmallInt;
  43. var
  44. Error : Word;
  45. begin
  46. Val(WideString(p), Result, Error);
  47. if Error <> 0 then
  48. VariantTypeMismatch(varOleStr, varSmallInt);
  49. end;
  50. Function LStrToSmallInt(p: Pointer) : SmallInt;
  51. var
  52. Error : Word;
  53. begin
  54. Val(AnsiString(p), Result, Error);
  55. if Error <> 0 then
  56. VariantTypeMismatch(varString, varSmallInt);
  57. end;
  58. Function VariantToSmallInt(const VargSrc : TVarData) : SmallInt;
  59. begin
  60. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  61. DumpVariant('VariantToSmallInt', VargSrc);
  62. end; {$ENDIF}
  63. with VargSrc do
  64. case vType and not varTypeMask of
  65. 0: case vType of
  66. varEmpty : Result := 0;
  67. varSmallInt : Result := vSmallInt;
  68. varShortInt : Result := vShortInt;
  69. varInteger : Result := smallint(vInteger);
  70. {$ifndef FPUNONE}
  71. varSingle : Result := smallint(Round(vSingle));
  72. varDouble : Result := smallint(Round(vDouble));
  73. varDate : Result := smallint(Round(vDate));
  74. {$endif}
  75. varCurrency : Result := smallint(Round(vCurrency));
  76. varBoolean : Result := smallint(SmallInt(vBoolean));
  77. varVariant : Result := VariantToSmallInt(PVarData(vPointer)^);
  78. varByte : Result := vByte;
  79. varWord : Result := smallint(vWord);
  80. varLongWord : Result := smallint(vLongWord);
  81. varInt64 : Result := smallint(vInt64);
  82. varQword : Result := smallint(vQWord);
  83. varOleStr : Result := WStrToSmallInt(vOleStr);
  84. varString : Result := LStrToSmallInt(vString);
  85. else
  86. VariantTypeMismatch(vType, varSmallInt);
  87. end;
  88. varByRef: if Assigned(vPointer) then case vType of
  89. varSmallInt : Result := PSmallInt(vPointer)^;
  90. varShortInt : Result := PShortInt(vPointer)^;
  91. varInteger : Result := smallint(PInteger(vPointer)^);
  92. {$ifndef FPUNONE}
  93. varSingle : Result := smallint(Round(PSingle(vPointer)^));
  94. varDouble : Result := smallint(Round(PDouble(vPointer)^));
  95. varDate : Result := smallint(Round(PDate(vPointer)^));
  96. {$endif}
  97. varCurrency : Result := smallint(Round(PCurrency(vPointer)^));
  98. varBoolean : Result := SmallInt(PWordBool(vPointer)^);
  99. varVariant : Result := VariantToSmallInt(PVarData(vPointer)^);
  100. varByte : Result := PByte(vPointer)^;
  101. varWord : Result := smallint(PWord(vPointer)^);
  102. varLongWord : Result := smallint(PLongWord(vPointer)^);
  103. varInt64 : Result := smallint(PInt64(vPointer)^);
  104. varQword : Result := smallint(PQWord(vPointer)^);
  105. varOleStr : Result := WStrToSmallInt(PPointer(vPointer)^);
  106. varString : Result := LStrToSmallInt(PPointer(vPointer)^);
  107. else { other vtype }
  108. VariantTypeMismatch(vType, varSmallInt);
  109. end else { pointer is nil }
  110. VariantTypeMismatch(vType, varSmallInt);
  111. else { array or something like that }
  112. VariantTypeMismatch(vType, varSmallInt);
  113. end;
  114. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  115. WriteLn('VariantToSmallInt -> ', Result);
  116. end; {$ENDIF}
  117. end;
  118. {--- ShortInt ---}
  119. Function WStrToShortInt(p: Pointer) : ShortInt;
  120. var
  121. Error : Word;
  122. begin
  123. Val(WideString(p), Result, Error);
  124. if Error <> 0 then
  125. VariantTypeMismatch(varOleStr, varShortInt);
  126. end;
  127. Function LStrToShortInt(p: Pointer) : ShortInt;
  128. var
  129. Error : Word;
  130. begin
  131. Val(AnsiString(p), Result, Error);
  132. if Error <> 0 then
  133. VariantTypeMismatch(varString, varShortInt);
  134. end;
  135. Function VariantToShortInt(const VargSrc : TVarData) : ShortInt;
  136. begin
  137. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  138. DumpVariant('VariantToShortInt', VargSrc);
  139. end; {$ENDIF}
  140. with VargSrc do
  141. case vType and not varTypeMask of
  142. 0: case vType of
  143. varEmpty : Result := 0;
  144. varSmallInt : Result := shortint(vSmallInt);
  145. varShortInt : Result := vShortInt;
  146. varInteger : Result := shortint(vInteger);
  147. {$ifndef FPUNONE}
  148. varSingle : Result := shortint(Round(vSingle));
  149. varDouble : Result := shortint(Round(vDouble));
  150. varDate : Result := shortint(Round(vDate));
  151. {$endif}
  152. varCurrency : Result := shortint(Round(vCurrency));
  153. varBoolean : Result := shortint(vBoolean);
  154. varVariant : Result := VariantToShortInt(PVarData(vPointer)^);
  155. varByte : Result := shortint(vByte);
  156. varWord : Result := shortint(vWord);
  157. varLongWord : Result := shortint(vLongWord);
  158. varInt64 : Result := shortint(vInt64);
  159. varQword : Result := shortint(vQWord);
  160. varOleStr : Result := WStrToShortInt(vOleStr);
  161. varString : Result := LStrToShortInt(vString);
  162. else
  163. VariantTypeMismatch(vType, varShortInt);
  164. end;
  165. varByRef: if Assigned(vPointer) then case vType of
  166. varSmallInt : Result := shortint(PSmallInt(vPointer)^);
  167. varShortInt : Result := PShortInt(vPointer)^;
  168. varInteger : Result := shortint(PInteger(vPointer)^);
  169. {$ifndef FPUNONE}
  170. varSingle : Result := shortint(Round(PSingle(vPointer)^));
  171. varDouble : Result := shortint(Round(PDouble(vPointer)^));
  172. varDate : Result := shortint(Round(PDate(vPointer)^));
  173. {$endif}
  174. varCurrency : Result := shortint(Round(PCurrency(vPointer)^));
  175. varBoolean : Result := SmallInt(PWordBool(vPointer)^);
  176. varVariant : Result := VariantToShortInt(PVarData(vPointer)^);
  177. varByte : Result := shortint(PByte(vPointer)^);
  178. varWord : Result := shortint(PWord(vPointer)^);
  179. varLongWord : Result := shortint(PLongWord(vPointer)^);
  180. varInt64 : Result := shortint(PInt64(vPointer)^);
  181. varQword : Result := shortint(PQWord(vPointer)^);
  182. varOleStr : Result := WStrToShortInt(PPointer(vPointer)^);
  183. varString : Result := LStrToShortInt(PPointer(vPointer)^);
  184. else { other vtype }
  185. VariantTypeMismatch(vType, varShortInt);
  186. end else { pointer is nil }
  187. VariantTypeMismatch(vType, varShortInt);
  188. else { array or something like that }
  189. VariantTypeMismatch(vType, varShortInt);
  190. end;
  191. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  192. WriteLn('VariantToShortInt -> ', Result);
  193. end; {$ENDIF}
  194. end;
  195. {--- LongInt ---}
  196. Function WStrToLongInt(p: Pointer) : LongInt;
  197. var
  198. Error : Word;
  199. begin
  200. Val(WideString(p), Result, Error);
  201. if Error <> 0 then
  202. VariantTypeMismatch(varOleStr, varInteger);
  203. end;
  204. Function LStrToLongInt(p: Pointer) : LongInt;
  205. var
  206. Error : Word;
  207. begin
  208. Val(AnsiString(p), Result, Error);
  209. if Error <> 0 then
  210. VariantTypeMismatch(varString, varInteger);
  211. end;
  212. Function VariantToLongInt(const VargSrc : TVarData) : LongInt;
  213. begin
  214. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  215. DumpVariant('VariantToLongInt', VargSrc);
  216. end; {$ENDIF}
  217. with VargSrc do
  218. case vType and not varTypeMask of
  219. 0: case vType of
  220. varEmpty : Result := 0;
  221. varSmallInt : Result := vSmallInt;
  222. varShortInt : Result := vShortInt;
  223. varInteger : Result := vInteger;
  224. {$ifndef FPUNONE}
  225. varSingle : Result := longint(Round(vSingle));
  226. varDouble : Result := longint(Round(vDouble));
  227. varDate : Result := longint(Round(vDate));
  228. {$endif}
  229. varCurrency : Result := longint(Round(vCurrency));
  230. varBoolean : Result := SmallInt(vBoolean);
  231. varVariant : Result := VariantToLongInt(PVarData(vPointer)^);
  232. varByte : Result := vByte;
  233. varWord : Result := vWord;
  234. varLongWord : Result := longint(vLongWord);
  235. varInt64 : Result := longint(vInt64);
  236. varQword : Result := longint(vQWord);
  237. varOleStr : Result := WStrToLongInt(vOleStr);
  238. varString : Result := LStrToLongInt(vString);
  239. else
  240. VariantTypeMismatch(vType, varInteger);
  241. end;
  242. varByRef: if Assigned(vPointer) then case vType of
  243. varSmallInt : Result := PSmallInt(vPointer)^;
  244. varShortInt : Result := PShortInt(vPointer)^;
  245. varInteger : Result := PInteger(vPointer)^;
  246. {$ifndef FPUNONE}
  247. varSingle : Result := longint(Round(PSingle(vPointer)^));
  248. varDouble : Result := longint(Round(PDouble(vPointer)^));
  249. varDate : Result := longint(Round(PDate(vPointer)^));
  250. {$endif}
  251. varCurrency : Result := longint(Round(PCurrency(vPointer)^));
  252. varBoolean : Result := SmallInt(PWordBool(vPointer)^);
  253. varVariant : Result := VariantToLongInt(PVarData(vPointer)^);
  254. varByte : Result := PByte(vPointer)^;
  255. varWord : Result := PWord(vPointer)^;
  256. varLongWord : Result := longint(PLongWord(vPointer)^);
  257. varInt64 : Result := longint(PInt64(vPointer)^);
  258. varQword : Result := longint(PQWord(vPointer)^);
  259. varOleStr : Result := WStrToLongInt(PPointer(vPointer)^);
  260. varString : Result := LStrToLongInt(PPointer(vPointer)^);
  261. else { other vtype }
  262. VariantTypeMismatch(vType, varInteger);
  263. end else { pointer is nil }
  264. VariantTypeMismatch(vType, varInteger);
  265. else { array or something like that }
  266. VariantTypeMismatch(vType, varInteger);
  267. end;
  268. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  269. WriteLn('VariantToLongInt -> ', Result);
  270. end; {$ENDIF}
  271. end;
  272. {--- Cardinal ---}
  273. Function WStrToCardinal(p: Pointer) : Cardinal;
  274. var
  275. Error : Word;
  276. begin
  277. Val(WideString(p), Result, Error);
  278. if Error <> 0 then
  279. VariantTypeMismatch(varOleStr, varLongWord);
  280. end;
  281. Function LStrToCardinal(p: Pointer) : Cardinal;
  282. var
  283. Error : Word;
  284. begin
  285. Val(AnsiString(p), Result, Error);
  286. if Error <> 0 then
  287. VariantTypeMismatch(varString, varLongWord);
  288. end;
  289. Function VariantToCardinal(const VargSrc : TVarData) : Cardinal;
  290. begin
  291. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  292. DumpVariant('VariantToCardinal', VargSrc);
  293. end; {$ENDIF}
  294. with VargSrc do
  295. case vType and not varTypeMask of
  296. 0: case vType of
  297. varEmpty : Result := 0;
  298. varSmallInt : Result := vSmallInt;
  299. varShortInt : Result := vShortInt;
  300. varInteger : Result := cardinal(vInteger);
  301. {$ifndef FPUNONE}
  302. varSingle : Result := cardinal(Round(vSingle));
  303. varDouble : Result := cardinal(Round(vDouble));
  304. varDate : Result := cardinal(Round(vDate));
  305. {$endif}
  306. varCurrency : Result := cardinal(Round(vCurrency));
  307. varBoolean : Result := cardinal(SmallInt(vBoolean));
  308. varVariant : Result := VariantToCardinal(PVarData(vPointer)^);
  309. varByte : Result := vByte;
  310. varWord : Result := vWord;
  311. varLongWord : Result := vLongWord;
  312. varInt64 : Result := cardinal(vInt64);
  313. varQword : Result := cardinal(vQWord);
  314. varOleStr : Result := WStrToCardinal(vOleStr);
  315. varString : Result := LStrToCardinal(vString);
  316. else
  317. VariantTypeMismatch(vType, varLongWord);
  318. end;
  319. varByRef: if Assigned(vPointer) then case vType of
  320. varSmallInt : Result := cardinal(PSmallInt(vPointer)^);
  321. varShortInt : Result := cardinal(PShortInt(vPointer)^);
  322. varInteger : Result := cardinal(PInteger(vPointer)^);
  323. {$ifndef FPUNONE}
  324. varSingle : Result := cardinal(Round(PSingle(vPointer)^));
  325. varDouble : Result := cardinal(Round(PDouble(vPointer)^));
  326. varDate : Result := cardinal(Round(PDate(vPointer)^));
  327. {$endif}
  328. varCurrency : Result := cardinal(Round(PCurrency(vPointer)^));
  329. varBoolean : Result := cardinal(SmallInt(PWordBool(vPointer)^));
  330. varVariant : Result := VariantToCardinal(PVarData(vPointer)^);
  331. varByte : Result := PByte(vPointer)^;
  332. varWord : Result := PWord(vPointer)^;
  333. varLongWord : Result := PLongWord(vPointer)^;
  334. varInt64 : Result := cardinal(PInt64(vPointer)^);
  335. varQword : Result := cardinal(PQWord(vPointer)^);
  336. varOleStr : Result := WStrToCardinal(PPointer(vPointer)^);
  337. varString : Result := LStrToCardinal(PPointer(vPointer)^);
  338. else { other vtype }
  339. VariantTypeMismatch(vType, varLongWord);
  340. end else { pointer is nil }
  341. VariantTypeMismatch(vType, varLongWord);
  342. else { array or something like that }
  343. VariantTypeMismatch(vType, varLongWord);
  344. end;
  345. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  346. WriteLn('VariantToCardinal -> ', Result);
  347. end; {$ENDIF}
  348. end;
  349. procedure PrepareFloatStr(var s: ShortString);
  350. var
  351. i, j : Byte;
  352. begin
  353. j := 1;
  354. for i := 1 to Length(s) do
  355. if s[i] <> ThousandSeparator then begin
  356. if s[i] = DecimalSeparator then
  357. s[j] := '.'
  358. else
  359. s[j] := s[i];
  360. Inc(j);
  361. end;
  362. SetLength(s, Pred(j));
  363. end;
  364. {--- Single ---}
  365. {$ifndef FPUNONE}
  366. Function WStrToSingle(p: Pointer) : Single;
  367. var
  368. s : ShortString;
  369. Error : Word;
  370. begin
  371. if Length(WideString(p)) > 255 then
  372. VariantTypeMismatch(varOleStr, varSingle);
  373. s := WideString(p);
  374. PrepareFloatStr(s);
  375. Val(s, Result, Error);
  376. if Error <> 0 then
  377. VariantTypeMismatch(varOleStr, varSingle);
  378. end;
  379. Function LStrToSingle(p: Pointer) : Single;
  380. var
  381. s : ShortString;
  382. Error : Word;
  383. begin
  384. if Length(AnsiString(p)) > 255 then
  385. VariantTypeMismatch(varString, varSingle);
  386. s := AnsiString(p);
  387. PrepareFloatStr(s);
  388. Val(s, Result, Error);
  389. if Error <> 0 then
  390. VariantTypeMismatch(varString, varSingle);
  391. end;
  392. Function VariantToSingle(const VargSrc : TVarData) : Single;
  393. begin
  394. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  395. DumpVariant('VariantToSingle', VargSrc);
  396. end; {$ENDIF}
  397. with VargSrc do
  398. case vType and not varTypeMask of
  399. 0: case vType of
  400. varEmpty : Result := 0;
  401. varSmallInt : Result := vSmallInt;
  402. varShortInt : Result := vShortInt;
  403. varInteger : Result := vInteger;
  404. varSingle : Result := vSingle;
  405. varDouble : Result := vDouble;
  406. varCurrency : Result := vCurrency;
  407. varDate : Result := vDate;
  408. varBoolean : Result := SmallInt(vBoolean);
  409. varVariant : Result := VariantToSingle(PVarData(vPointer)^);
  410. varByte : Result := vByte;
  411. varWord : Result := vWord;
  412. varLongWord : Result := vLongWord;
  413. varInt64 : Result := vInt64;
  414. varQword : Result := vQWord;
  415. varOleStr : Result := WStrToSingle(vOleStr);
  416. varString : Result := LStrToSingle(vString);
  417. else
  418. VariantTypeMismatch(vType, varSingle);
  419. end;
  420. varByRef: if Assigned(vPointer) then case vType of
  421. varSmallInt : Result := PSmallInt(vPointer)^;
  422. varShortInt : Result := PShortInt(vPointer)^;
  423. varInteger : Result := PInteger(vPointer)^;
  424. varSingle : Result := PSingle(vPointer)^;
  425. varDouble : Result := PDouble(vPointer)^;
  426. varCurrency : Result := PCurrency(vPointer)^;
  427. varDate : Result := PDate(vPointer)^;
  428. varBoolean : Result := SmallInt(PWordBool(vPointer)^);
  429. varVariant : Result := VariantToSingle(PVarData(vPointer)^);
  430. varByte : Result := PByte(vPointer)^;
  431. varWord : Result := PWord(vPointer)^;
  432. varLongWord : Result := PLongWord(vPointer)^;
  433. varInt64 : Result := PInt64(vPointer)^;
  434. varQword : Result := PQWord(vPointer)^;
  435. varOleStr : Result := WStrToSingle(PPointer(vPointer)^);
  436. varString : Result := LStrToSingle(PPointer(vPointer)^);
  437. else { other vtype }
  438. VariantTypeMismatch(vType, varSingle);
  439. end else { pointer is nil }
  440. VariantTypeMismatch(vType, varSingle);
  441. else { array or something like that }
  442. VariantTypeMismatch(vType, varSingle);
  443. end;
  444. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  445. WriteLn('VariantToSingle -> ', Result);
  446. end; {$ENDIF}
  447. end;
  448. {--- Double ---}
  449. Function WStrToDouble(p: Pointer) : Double;
  450. var
  451. s : ShortString;
  452. Error : Word;
  453. begin
  454. if Length(WideString(p)) > 255 then
  455. VariantTypeMismatch(varOleStr, varDouble);
  456. s := WideString(p);
  457. PrepareFloatStr(s);
  458. Val(s, Result, Error);
  459. if Error <> 0 then
  460. VariantTypeMismatch(varOleStr, varDouble);
  461. end;
  462. Function LStrToDouble(p: Pointer) : Double;
  463. var
  464. s : ShortString;
  465. Error : Word;
  466. begin
  467. if Length(AnsiString(p)) > 255 then
  468. VariantTypeMismatch(varString, varDouble);
  469. s := AnsiString(p);
  470. PrepareFloatStr(s);
  471. Val(s, Result, Error);
  472. if Error <> 0 then
  473. VariantTypeMismatch(varString, varDouble);
  474. end;
  475. Function VariantToDouble(const VargSrc : TVarData) : Double;
  476. begin
  477. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  478. DumpVariant('VariantToDouble', VargSrc);
  479. end; {$ENDIF}
  480. with VargSrc do
  481. case vType and not varTypeMask of
  482. 0: case vType of
  483. varEmpty : Result := 0;
  484. varSmallInt : Result := vSmallInt;
  485. varShortInt : Result := vShortInt;
  486. varInteger : Result := vInteger;
  487. varSingle : Result := vSingle;
  488. varDouble : Result := vDouble;
  489. varCurrency : Result := vCurrency;
  490. varDate : Result := vDate;
  491. varBoolean : Result := SmallInt(vBoolean);
  492. varVariant : Result := VariantToDouble(PVarData(vPointer)^);
  493. varByte : Result := vByte;
  494. varWord : Result := vWord;
  495. varLongWord : Result := vLongWord;
  496. varInt64 : Result := vInt64;
  497. varQword : Result := vQWord;
  498. varOleStr : Result := WStrToDouble(vOleStr);
  499. varString : Result := LStrToDouble(vString);
  500. else
  501. VariantTypeMismatch(vType, varDouble);
  502. end;
  503. varByRef: if Assigned(vPointer) then case vType of
  504. varSmallInt : Result := PSmallInt(vPointer)^;
  505. varShortInt : Result := PShortInt(vPointer)^;
  506. varInteger : Result := PInteger(vPointer)^;
  507. varSingle : Result := PSingle(vPointer)^;
  508. varDouble : Result := PDouble(vPointer)^;
  509. varCurrency : Result := PCurrency(vPointer)^;
  510. varDate : Result := PDate(vPointer)^;
  511. varBoolean : Result := SmallInt(PWordBool(vPointer)^);
  512. varVariant : Result := VariantToDouble(PVarData(vPointer)^);
  513. varByte : Result := PByte(vPointer)^;
  514. varWord : Result := PWord(vPointer)^;
  515. varLongWord : Result := PLongWord(vPointer)^;
  516. varInt64 : Result := PInt64(vPointer)^;
  517. varQword : Result := PQWord(vPointer)^;
  518. varOleStr : Result := WStrToDouble(PPointer(vPointer)^);
  519. varString : Result := LStrToDouble(PPointer(vPointer)^);
  520. else { other vtype }
  521. VariantTypeMismatch(vType, varDouble);
  522. end else { pointer is nil }
  523. VariantTypeMismatch(vType, varDouble);
  524. else { array or something like that }
  525. VariantTypeMismatch(vType, varDouble);
  526. end;
  527. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  528. WriteLn('VariantToDouble -> ', Result);
  529. end; {$ENDIF}
  530. end;
  531. {$endif FPUNONE}
  532. {--- Currency ---}
  533. Function WStrToCurrency(p: Pointer) : Currency;
  534. var
  535. s : ShortString;
  536. Error : Word;
  537. {$IFNDEF FPC_HAS_STR_CURRENCY}
  538. Temp : Extended;
  539. {$ENDIF FPC_HAS_STR_CURRENCY}
  540. begin
  541. if Length(WideString(p)) > 255 then
  542. VariantTypeMismatch(varOleStr, varCurrency);
  543. s := WideString(p);
  544. PrepareFloatStr(s);
  545. {$IFDEF FPC_HAS_STR_CURRENCY}
  546. Val(s, Result, Error);
  547. {$ELSE FPC_HAS_STR_CURRENCY} { needed for platforms where Currency = Int64 }
  548. Val(s, Temp, Error);
  549. Result := Temp;
  550. {$ENDIF FPC_HAS_STR_CURRENCY}
  551. if Error <> 0 then
  552. VariantTypeMismatch(varOleStr, varCurrency);
  553. end;
  554. Function LStrToCurrency(p: Pointer) : Currency;
  555. var
  556. s : ShortString;
  557. Error : Word;
  558. {$IFNDEF FPC_HAS_STR_CURRENCY}
  559. Temp : Extended;
  560. {$ENDIF FPC_HAS_STR_CURRENCY}
  561. begin
  562. if Length(AnsiString(p)) > 255 then
  563. VariantTypeMismatch(varString, varCurrency);
  564. s := AnsiString(p);
  565. PrepareFloatStr(s);
  566. {$IFDEF FPC_HAS_STR_CURRENCY}
  567. Val(s, Result, Error);
  568. {$ELSE FPC_HAS_STR_CURRENCY} { needed for platforms where Currency = Int64 }
  569. Val(s, Temp, Error);
  570. Result := Temp;
  571. {$ENDIF FPC_HAS_STR_CURRENCY}
  572. if Error <> 0 then
  573. VariantTypeMismatch(varString, varCurrency);
  574. end;
  575. Function VariantToCurrency(const VargSrc : TVarData) : Currency;
  576. begin
  577. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  578. DumpVariant('VariantToCurrency', VargSrc);
  579. end; {$ENDIF}
  580. with VargSrc do
  581. case vType and not varTypeMask of
  582. 0: case vType of
  583. varEmpty : Result := 0;
  584. varSmallInt : Result := vSmallInt;
  585. varShortInt : Result := vShortInt;
  586. varInteger : Result := vInteger;
  587. {$ifndef FPUNONE}
  588. varSingle : begin
  589. if (vSingle > MaxCurrency) or (vSingle < MinCurrency) then
  590. VariantTypeMismatch(vType, varCurrency);
  591. Result := vSingle;
  592. end;
  593. varDouble : begin
  594. if (vDouble > MaxCurrency) or (vDouble < MinCurrency) then
  595. VariantTypeMismatch(vType, varCurrency);
  596. Result := vDouble;
  597. end;
  598. varDate : begin
  599. if (varDate > MaxCurrency) or (varDate < MinCurrency) then
  600. VariantTypeMismatch(vType, varCurrency);
  601. Result := vDate;
  602. end;
  603. {$endif}
  604. varCurrency : Result := vCurrency;
  605. varBoolean : Result := SmallInt(vBoolean);
  606. varVariant : Result := VariantToCurrency(PVarData(vPointer)^);
  607. varByte : Result := vByte;
  608. varWord : Result := vWord;
  609. varLongWord : Result := vLongWord;
  610. varInt64 : Result := vInt64;
  611. varQword : Result := currency(vQWord);
  612. varOleStr : Result := WStrToCurrency(vOleStr);
  613. varString : Result := LStrToCurrency(vString);
  614. else
  615. VariantTypeMismatch(vType, varCurrency);
  616. end;
  617. varByRef: if Assigned(vPointer) then case vType of
  618. varSmallInt : Result := PSmallInt(vPointer)^;
  619. varShortInt : Result := PShortInt(vPointer)^;
  620. varInteger : Result := PInteger(vPointer)^;
  621. {$ifndef FPUNONE}
  622. varSingle : begin
  623. if (PSingle(vPointer)^ > MaxCurrency) or (PSingle(vPointer)^ < MinCurrency) then
  624. VariantTypeMismatch(vType, varCurrency);
  625. Result := PSingle(vPointer)^;
  626. end;
  627. varDouble : begin
  628. if (PDouble(vPointer)^ > MaxCurrency) or (PDouble(vPointer)^ < MinCurrency) then
  629. VariantTypeMismatch(vType, varCurrency);
  630. Result := PDouble(vPointer)^;
  631. end;
  632. varDate : begin
  633. if (PDate(vPointer)^ > MaxCurrency) or (PDate(vPointer)^ < MinCurrency) then
  634. VariantTypeMismatch(vType, varCurrency);
  635. Result := PDate(vPointer)^;
  636. end;
  637. {$endif}
  638. varCurrency : Result := PCurrency(vPointer)^;
  639. varBoolean : Result := SmallInt(PWordBool(vPointer)^);
  640. varVariant : Result := VariantToCurrency(PVarData(vPointer)^);
  641. varByte : Result := PByte(vPointer)^;
  642. varWord : Result := PWord(vPointer)^;
  643. varLongWord : Result := PLongWord(vPointer)^;
  644. varInt64 : Result := PInt64(vPointer)^;
  645. varQword : Result := currency(PQWord(vPointer)^);
  646. varOleStr : Result := WStrToCurrency(PPointer(vPointer)^);
  647. varString : Result := LStrToCurrency(PPointer(vPointer)^);
  648. else { other vtype }
  649. VariantTypeMismatch(vType, varCurrency);
  650. end else { pointer is nil }
  651. VariantTypeMismatch(vType, varCurrency);
  652. else { array or something like that }
  653. VariantTypeMismatch(vType, varCurrency);
  654. end;
  655. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  656. WriteLn('VariantToCurrency -> ', Result);
  657. end; {$ENDIF}
  658. end;
  659. {--- Date ---}
  660. {$ifndef FPUNONE}
  661. Function WStrToDate(p: Pointer) : TDateTime;
  662. var
  663. s: string;
  664. begin
  665. s := WideString(p);
  666. if not (TryStrToDateTime(s, Result) or
  667. TryStrToDate(s, Result) or
  668. TryStrToTime(s, Result)) then
  669. VariantTypeMismatch(varOleStr, varDate);
  670. end;
  671. Function LStrToDate(p: Pointer) : TDateTime;
  672. begin
  673. if not (TryStrToDateTime(AnsiString(p), Result) or
  674. TryStrToDate(AnsiString(p), Result) or
  675. TryStrToTime(AnsiString(p), Result)) then
  676. VariantTypeMismatch(varString, varDate);
  677. end;
  678. Function VariantToDate(const VargSrc : TVarData) : TDateTime;
  679. begin
  680. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  681. DumpVariant('VariantToDate', VargSrc);
  682. end; {$ENDIF}
  683. with VargSrc do
  684. case vType and not varTypeMask of
  685. 0: case vType of
  686. varEmpty : Result := 0;
  687. varSmallInt : Result := vSmallInt;
  688. varShortInt : Result := vShortInt;
  689. varInteger : Result := vInteger;
  690. varSingle : Result := vSingle;
  691. varDouble : Result := vDouble;
  692. varCurrency : Result := vCurrency;
  693. varDate : Result := vDate;
  694. varBoolean : Result := SmallInt(vBoolean);
  695. varVariant : Result := VariantToDate(PVarData(vPointer)^);
  696. varByte : Result := vByte;
  697. varWord : Result := vWord;
  698. varLongWord : Result := vLongWord;
  699. varInt64 : Result := vInt64;
  700. varQword : Result := vQWord;
  701. varOleStr : Result := WStrToDate(vOleStr);
  702. varString : Result := LStrToDate(vString);
  703. else
  704. VariantTypeMismatch(vType, varDate);
  705. end;
  706. varByRef: if Assigned(vPointer) then case vType of
  707. varSmallInt : Result := PSmallInt(vPointer)^;
  708. varShortInt : Result := PShortInt(vPointer)^;
  709. varInteger : Result := PInteger(vPointer)^;
  710. varSingle : Result := PSingle(vPointer)^;
  711. varDouble : Result := PDouble(vPointer)^;
  712. varCurrency : Result := PCurrency(vPointer)^;
  713. varDate : Result := PDate(vPointer)^;
  714. varBoolean : Result := SmallInt(PWordBool(vPointer)^);
  715. varVariant : Result := VariantToDate(PVarData(vPointer)^);
  716. varByte : Result := PByte(vPointer)^;
  717. varWord : Result := PWord(vPointer)^;
  718. varLongWord : Result := PLongWord(vPointer)^;
  719. varInt64 : Result := PInt64(vPointer)^;
  720. varQword : Result := PQWord(vPointer)^;
  721. varOleStr : Result := WStrToDate(PPointer(vPointer)^);
  722. varString : Result := LStrToDate(PPointer(vPointer)^);
  723. else { other vtype }
  724. VariantTypeMismatch(vType, varDate);
  725. end else { pointer is nil }
  726. VariantTypeMismatch(vType, varDate);
  727. else { array or something like that }
  728. VariantTypeMismatch(vType, varDate);
  729. end;
  730. if (Result < MinDateTime) or (Result > MaxDateTime) then
  731. VariantTypeMismatch(VargSrc.vType, varDate);
  732. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  733. WriteLn('VariantToDate -> ', Result);
  734. end; {$ENDIF}
  735. end;
  736. {$endif}
  737. {--- Boolean ---}
  738. Function WStrToBoolean(p: Pointer) : Boolean;
  739. begin
  740. if not TryStrToBool(WideString(p), Result) then
  741. VariantTypeMismatch(varOleStr, varBoolean);
  742. end;
  743. Function LStrToBoolean(p: Pointer) : Boolean;
  744. begin
  745. if not TryStrToBool(AnsiString(p), Result) then
  746. VariantTypeMismatch(varString, varBoolean);
  747. end;
  748. Function VariantToBoolean(const VargSrc : TVarData) : Boolean;
  749. begin
  750. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  751. DumpVariant('VariantToBoolean', VargSrc);
  752. end; {$ENDIF}
  753. with VargSrc do
  754. case vType and not varTypeMask of
  755. 0: case vType of
  756. varEmpty : Result := False;
  757. varSmallInt : Result := vSmallInt <> 0;
  758. varShortInt : Result := vShortInt <> 0;
  759. varInteger : Result := vInteger <> 0;
  760. {$ifndef FPUNONE}
  761. varSingle : Result := vSingle <> 0;
  762. varDouble : Result := vDouble <> 0;
  763. varCurrency : Result := vCurrency <> 0;
  764. varDate : Result := vDate <> 0;
  765. {$endif}
  766. varBoolean : Result := vBoolean;
  767. varVariant : Result := VariantToBoolean(PVarData(vPointer)^);
  768. varByte : Result := vByte <> 0;
  769. varWord : Result := vWord <> 0;
  770. varLongWord : Result := vLongWord <> 0;
  771. varInt64 : Result := vInt64 <> 0;
  772. varQword : Result := vQWord <> 0;
  773. varOleStr : Result := WStrToBoolean(vOleStr);
  774. varString : Result := LStrToBoolean(vString);
  775. else
  776. VariantTypeMismatch(vType, varBoolean);
  777. end;
  778. varByRef: if Assigned(vPointer) then case vType of
  779. varSmallInt : Result := PSmallInt(vPointer)^ <> 0;
  780. varShortInt : Result := PShortInt(vPointer)^ <> 0;
  781. varInteger : Result := PInteger(vPointer)^ <> 0;
  782. {$ifndef FPUNONE}
  783. varSingle : Result := PSingle(vPointer)^ <> 0;
  784. varDouble : Result := PDouble(vPointer)^ <> 0;
  785. varCurrency : Result := PCurrency(vPointer)^ <> 0;
  786. varDate : Result := PDate(vPointer)^ <> 0;
  787. {$endif}
  788. varBoolean : Result := SmallInt(PWordBool(vPointer)^) <> 0;
  789. varVariant : Result := VariantToBoolean(PVarData(vPointer)^);
  790. varByte : Result := PByte(vPointer)^ <> 0;
  791. varWord : Result := PWord(vPointer)^ <> 0;
  792. varLongWord : Result := PLongWord(vPointer)^ <> 0;
  793. varInt64 : Result := PInt64(vPointer)^ <> 0;
  794. varQword : Result := PQWord(vPointer)^ <> 0;
  795. varOleStr : Result := WStrToBoolean(PPointer(vPointer)^);
  796. varString : Result := LStrToBoolean(PPointer(vPointer)^);
  797. else { other vtype }
  798. VariantTypeMismatch(vType, varBoolean);
  799. end else { pointer is nil }
  800. Result := False;
  801. else { array or something like that }
  802. VariantTypeMismatch(vType, varBoolean);
  803. end;
  804. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  805. WriteLn('VariantToBoolean -> ', Result);
  806. end; {$ENDIF}
  807. end;
  808. {--- Byte ---}
  809. Function WStrToByte(p: Pointer) : Byte;
  810. var
  811. Error : Word;
  812. begin
  813. Val(WideString(p), Result, Error);
  814. if Error <> 0 then
  815. VariantTypeMismatch(varOleStr, varByte);
  816. end;
  817. Function LStrToByte(p: Pointer) : Byte;
  818. var
  819. Error : Word;
  820. begin
  821. Val(AnsiString(p), Result, Error);
  822. if Error <> 0 then
  823. VariantTypeMismatch(varString, varByte);
  824. end;
  825. Function VariantToByte(const VargSrc : TVarData) : Byte;
  826. begin
  827. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  828. DumpVariant('VariantToByte', VargSrc);
  829. end; {$ENDIF}
  830. with VargSrc do
  831. case vType and not varTypeMask of
  832. 0: case vType of
  833. varEmpty : Result := 0;
  834. varSmallInt : Result := byte(vSmallInt);
  835. varShortInt : Result := byte(vShortInt);
  836. varInteger : Result := byte(vInteger);
  837. {$ifndef FPUNONE}
  838. varSingle : Result := byte(Round(vSingle));
  839. varDouble : Result := byte(Round(vDouble));
  840. varCurrency : Result := byte(Round(vCurrency));
  841. varDate : Result := byte(Round(vDate));
  842. {$endif}
  843. varBoolean : Result := byte(SmallInt(vBoolean));
  844. varVariant : Result := VariantToByte(PVarData(vPointer)^);
  845. varByte : Result := vByte;
  846. varWord : Result := byte(vWord);
  847. varLongWord : Result := byte(vLongWord);
  848. varInt64 : Result := byte(vInt64);
  849. varQword : Result := byte(vQWord);
  850. varOleStr : Result := WStrToByte(vOleStr);
  851. varString : Result := LStrToByte(vString);
  852. else
  853. VariantTypeMismatch(vType, varByte);
  854. end;
  855. varByRef: if Assigned(vPointer) then case vType of
  856. varSmallInt : Result := byte(PSmallInt(vPointer)^);
  857. varShortInt : Result := byte(PShortInt(vPointer)^);
  858. varInteger : Result := byte(PInteger(vPointer)^);
  859. {$ifndef FPUNONE}
  860. varSingle : Result := byte(Round(PSingle(vPointer)^));
  861. varDouble : Result := byte(Round(PDouble(vPointer)^));
  862. varCurrency : Result := byte(Round(PCurrency(vPointer)^));
  863. varDate : Result := byte(Round(PDate(vPointer)^));
  864. {$endif}
  865. varBoolean : Result := byte(SmallInt(PWordBool(vPointer)^));
  866. varVariant : Result := byte(VariantToByte(PVarData(vPointer)^));
  867. varByte : Result := PByte(vPointer)^;
  868. varWord : Result := byte(PWord(vPointer)^);
  869. varLongWord : Result := byte(PLongWord(vPointer)^);
  870. varInt64 : Result := byte(PInt64(vPointer)^);
  871. varQword : Result := byte(PQWord(vPointer)^);
  872. varOleStr : Result := WStrToByte(PPointer(vPointer)^);
  873. varString : Result := LStrToByte(PPointer(vPointer)^);
  874. else { other vtype }
  875. VariantTypeMismatch(vType, varByte);
  876. end else { pointer is nil }
  877. VariantTypeMismatch(vType, varByte);
  878. else { array or something like that }
  879. VariantTypeMismatch(vType, varByte);
  880. end;
  881. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  882. WriteLn('VariantToByte -> ', Result);
  883. end; {$ENDIF}
  884. end;
  885. {--- Int64 ---}
  886. Function WStrToInt64(p: Pointer) : Int64;
  887. var
  888. Error : Word;
  889. begin
  890. Val(WideString(p), Result, Error);
  891. if Error <> 0 then
  892. VariantTypeMismatch(varOleStr, varInt64);
  893. end;
  894. Function LStrToInt64(p: Pointer) : Int64;
  895. var
  896. Error : Word;
  897. begin
  898. Val(AnsiString(p), Result, Error);
  899. if Error <> 0 then
  900. VariantTypeMismatch(varString, varInt64);
  901. end;
  902. Function VariantToInt64(const VargSrc : TVarData) : Int64;
  903. begin
  904. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  905. DumpVariant('VariantToInt64', VargSrc);
  906. end; {$ENDIF}
  907. with VargSrc do
  908. case vType and not varTypeMask of
  909. 0: case vType of
  910. varEmpty : Result := 0;
  911. varSmallInt : Result := vSmallInt;
  912. varShortInt : Result := vShortInt;
  913. varInteger : Result := vInteger;
  914. {$ifndef FPUNONE}
  915. varSingle : Result := Round(vSingle);
  916. varDouble : Result := Round(vDouble);
  917. varCurrency : Result := Round(vCurrency);
  918. varDate : Result := Round(vDate);
  919. {$endif}
  920. varBoolean : Result := SmallInt(vBoolean);
  921. varVariant : Result := VariantToInt64(PVarData(vPointer)^);
  922. varByte : Result := vByte;
  923. varWord : Result := vWord;
  924. varLongWord : Result := vLongWord;
  925. varInt64 : Result := vInt64;
  926. varQword : Result := int64(vQWord);
  927. varOleStr : Result := WStrToInt64(vOleStr);
  928. varString : Result := LStrToInt64(vString);
  929. else
  930. VariantTypeMismatch(vType, varInt64);
  931. end;
  932. varByRef: if Assigned(vPointer) then case vType of
  933. varSmallInt : Result := PSmallInt(vPointer)^;
  934. varShortInt : Result := PShortInt(vPointer)^;
  935. varInteger : Result := PInteger(vPointer)^;
  936. {$ifndef FPUNONE}
  937. varSingle : Result := Round(PSingle(vPointer)^);
  938. varDouble : Result := Round(PDouble(vPointer)^);
  939. varCurrency : Result := Round(PCurrency(vPointer)^);
  940. varDate : Result := Round(PDate(vPointer)^);
  941. {$endif}
  942. varBoolean : Result := SmallInt(PWordBool(vPointer)^);
  943. varVariant : Result := VariantToInt64(PVarData(vPointer)^);
  944. varByte : Result := PByte(vPointer)^;
  945. varWord : Result := PWord(vPointer)^;
  946. varLongWord : Result := PLongWord(vPointer)^;
  947. varInt64 : Result := PInt64(vPointer)^;
  948. varQword : Result := PQWord(vPointer)^;
  949. varOleStr : Result := WStrToInt64(PPointer(vPointer)^);
  950. varString : Result := LStrToInt64(PPointer(vPointer)^);
  951. else { other vtype }
  952. VariantTypeMismatch(vType, varInt64);
  953. end else { pointer is nil }
  954. VariantTypeMismatch(vType, varInt64);
  955. else { array or something like that }
  956. VariantTypeMismatch(vType, varInt64);
  957. end;
  958. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  959. WriteLn('VariantToInt64 -> ', Result);
  960. end; {$ENDIF}
  961. end;
  962. {--- QWord ---}
  963. Function WStrToQWord(p: Pointer) : QWord;
  964. var
  965. Error : Word;
  966. begin
  967. Val(WideString(p), Result, Error);
  968. if Error <> 0 then
  969. VariantTypeMismatch(varOleStr, varQWord);
  970. end;
  971. Function LStrToQWord(p: Pointer) : QWord;
  972. var
  973. Error : Word;
  974. begin
  975. Val(AnsiString(p), Result, Error);
  976. if Error <> 0 then
  977. VariantTypeMismatch(varString, varQWord);
  978. end;
  979. Function VariantToQWord(const VargSrc : TVarData) : QWord;
  980. begin
  981. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  982. DumpVariant('VariantToQWord', VargSrc);
  983. end; {$ENDIF}
  984. with VargSrc do
  985. case vType and not varTypeMask of
  986. 0: case vType of
  987. varEmpty : Result := 0;
  988. varSmallInt : Result := qword(vSmallInt);
  989. varShortInt : Result := qword(vShortInt);
  990. varInteger : Result := qword(vInteger);
  991. {$ifndef FPUNONE}
  992. varSingle : Result := qword(Round(vSingle));
  993. varDouble : Result := qword(Round(vDouble));
  994. varCurrency : Result := qword(Round(vCurrency));
  995. varDate : Result := qword(Round(vDate));
  996. {$endif}
  997. varBoolean : Result := qword(SmallInt(vBoolean));
  998. varVariant : Result := VariantToQWord(PVarData(vPointer)^);
  999. varByte : Result := vByte;
  1000. varWord : Result := vWord;
  1001. varLongWord : Result := vLongWord;
  1002. varInt64 : Result := qword(vInt64);
  1003. varQword : Result := vQWord;
  1004. varOleStr : Result := WStrToQWord(vOleStr);
  1005. varString : Result := LStrToQWord(vString);
  1006. else
  1007. VariantTypeMismatch(vType, varQWord);
  1008. end;
  1009. varByRef: if Assigned(vPointer) then case vType of
  1010. varSmallInt : Result := qword(PSmallInt(vPointer)^);
  1011. varShortInt : Result := qword(PShortInt(vPointer)^);
  1012. varInteger : Result := qword(PInteger(vPointer)^);
  1013. {$ifndef FPUNONE}
  1014. varSingle : Result := qword(Round(PSingle(vPointer)^));
  1015. varDouble : Result := qword(Round(PDouble(vPointer)^));
  1016. varCurrency : Result := qword(Round(PCurrency(vPointer)^));
  1017. varDate : Result := qword(Round(PDate(vPointer)^));
  1018. {$endif}
  1019. varBoolean : Result := qword(SmallInt(PWordBool(vPointer)^));
  1020. varVariant : Result := VariantToQWord(PVarData(vPointer)^);
  1021. varByte : Result := PByte(vPointer)^;
  1022. varWord : Result := PWord(vPointer)^;
  1023. varLongWord : Result := PLongWord(vPointer)^;
  1024. varInt64 : Result := qword(PInt64(vPointer)^);
  1025. varQword : Result := PQWord(vPointer)^;
  1026. varOleStr : Result := WStrToQWord(PPointer(vPointer)^);
  1027. varString : Result := LStrToQWord(PPointer(vPointer)^);
  1028. else { other vtype }
  1029. VariantTypeMismatch(vType, varQWord);
  1030. end else { pointer is nil }
  1031. VariantTypeMismatch(vType, varQWord);
  1032. else { array or something like that }
  1033. VariantTypeMismatch(vType, varQWord);
  1034. end;
  1035. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  1036. WriteLn('VariantToQWord -> ', Result);
  1037. end; {$ENDIF}
  1038. end;
  1039. {--- WideString ---}
  1040. Function VariantToWideString(const VargSrc : TVarData) : WideString;
  1041. begin
  1042. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  1043. DumpVariant('VariantToWideString', VargSrc);
  1044. end; {$ENDIF}
  1045. with VargSrc do
  1046. case vType and not varTypeMask of
  1047. 0: case vType of
  1048. varEmpty : Result := '';
  1049. varSmallInt : Result := IntToStr(vSmallInt);
  1050. varShortInt : Result := IntToStr(vShortInt);
  1051. varInteger : Result := IntToStr(vInteger);
  1052. {$ifndef FPUNONE}
  1053. varSingle : Result := FloatToStr(vSingle);
  1054. varDouble : Result := FloatToStr(vDouble);
  1055. varCurrency : Result := FloatToStr(vCurrency);
  1056. varDate : Result := FloatToStr(vDate);
  1057. {$endif}
  1058. varBoolean : Result := BoolToStr(vBoolean, True);
  1059. varVariant : Result := VariantToWideString(PVarData(vPointer)^);
  1060. varByte : Result := IntToStr(vByte);
  1061. varWord : Result := IntToStr(vWord);
  1062. varLongWord : Result := IntToStr(vLongWord);
  1063. varInt64 : Result := IntToStr(vInt64);
  1064. varQword : Result := IntToStr(vQWord);
  1065. varOleStr : Result := WideString(Pointer(vOleStr));
  1066. varString : Result := AnsiString(vString);
  1067. else
  1068. VariantTypeMismatch(vType, varOleStr);
  1069. end;
  1070. varByRef: if Assigned(vPointer) then case vType of
  1071. varSmallInt : Result := IntToStr(PSmallInt(vPointer)^);
  1072. varShortInt : Result := IntToStr(PShortInt(vPointer)^);
  1073. varInteger : Result := IntToStr(PInteger(vPointer)^);
  1074. {$ifndef FPUNONE}
  1075. varSingle : Result := FloatToStr(PSingle(vPointer)^);
  1076. varDouble : Result := FloatToStr(PDouble(vPointer)^);
  1077. varCurrency : Result := FloatToStr(PCurrency(vPointer)^);
  1078. varDate : Result := FloatToStr(PDate(vPointer)^);
  1079. {$endif}
  1080. varBoolean : Result := BoolToStr(PWordBool(vPointer)^, True);
  1081. varVariant : Result := VariantToWideString(PVarData(vPointer)^);
  1082. varByte : Result := IntToStr(PByte(vPointer)^);
  1083. varWord : Result := IntToStr(PWord(vPointer)^);
  1084. varLongWord : Result := IntToStr(PLongWord(vPointer)^);
  1085. varInt64 : Result := IntToStr(PInt64(vPointer)^);
  1086. varQword : Result := IntToStr(PQWord(vPointer)^);
  1087. varOleStr : Result := WideString(PPointer(vPointer)^);
  1088. varString : Result := AnsiString(PPointer(vPointer)^);
  1089. else { other vtype }
  1090. VariantTypeMismatch(vType, varOleStr);
  1091. end else { pointer is nil }
  1092. VariantTypeMismatch(vType, varOleStr);
  1093. else { array or something like that }
  1094. VariantTypeMismatch(vType, varOleStr);
  1095. end;
  1096. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  1097. WriteLn('VariantToWideString -> ', Result);
  1098. end; {$ENDIF}
  1099. end;
  1100. {--- AnsiString ---}
  1101. Function VariantToAnsiString(const VargSrc : TVarData) : AnsiString;
  1102. begin
  1103. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  1104. DumpVariant('VariantToAnsiString', VargSrc);
  1105. end; {$ENDIF}
  1106. with VargSrc do
  1107. case vType and not varTypeMask of
  1108. 0: case vType of
  1109. varEmpty : Result := '';
  1110. varSmallInt : Result := IntToStr(vSmallInt);
  1111. varShortInt : Result := IntToStr(vShortInt);
  1112. varInteger : Result := IntToStr(vInteger);
  1113. {$ifndef FPUNONE}
  1114. varSingle : Result := FloatToStr(vSingle);
  1115. varDouble : Result := FloatToStr(vDouble);
  1116. varCurrency : Result := FloatToStr(vCurrency);
  1117. varDate : Result := DateToStr(vDate);
  1118. {$endif}
  1119. varBoolean : Result := BoolToStr(vBoolean, True);
  1120. varVariant : Result := VariantToAnsiString(PVarData(vPointer)^);
  1121. varByte : Result := IntToStr(vByte);
  1122. varWord : Result := IntToStr(vWord);
  1123. varLongWord : Result := IntToStr(vLongWord);
  1124. varInt64 : Result := IntToStr(vInt64);
  1125. varQword : Result := IntToStr(vQWord);
  1126. varOleStr : Result := WideString(Pointer(vOleStr));
  1127. varString : Result := AnsiString(vString);
  1128. else
  1129. VariantTypeMismatch(vType, varString);
  1130. end;
  1131. varByRef: if Assigned(vPointer) then case vType of
  1132. varSmallInt : Result := IntToStr(PSmallInt(vPointer)^);
  1133. varShortInt : Result := IntToStr(PShortInt(vPointer)^);
  1134. varInteger : Result := IntToStr(PInteger(vPointer)^);
  1135. {$ifndef FPUNONE}
  1136. varSingle : Result := FloatToStr(PSingle(vPointer)^);
  1137. varDouble : Result := FloatToStr(PDouble(vPointer)^);
  1138. varCurrency : Result := FloatToStr(PCurrency(vPointer)^);
  1139. varDate : Result := DateToStr(PDate(vPointer)^);
  1140. {$endif}
  1141. varBoolean : Result := BoolToStr(PWordBool(vPointer)^, True);
  1142. varVariant : Result := VariantToAnsiString(PVarData(vPointer)^);
  1143. varByte : Result := IntToStr(PByte(vPointer)^);
  1144. varWord : Result := IntToStr(PWord(vPointer)^);
  1145. varLongWord : Result := IntToStr(PLongWord(vPointer)^);
  1146. varInt64 : Result := IntToStr(PInt64(vPointer)^);
  1147. varQword : Result := IntToStr(PQWord(vPointer)^);
  1148. varOleStr : Result := WideString(PPointer(vPointer)^);
  1149. varString : Result := AnsiString(PPointer(vPointer)^);
  1150. else { other vtype }
  1151. VariantTypeMismatch(vType, varString);
  1152. end else { pointer is nil }
  1153. VariantTypeMismatch(vType, varString);
  1154. else { array or something like that }
  1155. VariantTypeMismatch(vType, varString);
  1156. end;
  1157. {$IFDEF DEBUG_VARUTILS} if __DEBUG_VARUTILS then begin
  1158. WriteLn('VariantToAnsiString -> ', Result);
  1159. end; {$ENDIF}
  1160. end;
  1161. Function VariantToShortString(const VargSrc : TVarData) : ShortString;
  1162. begin
  1163. Result:=VariantToAnsiString(VargSrc);
  1164. end;
  1165. { ---------------------------------------------------------------------
  1166. Some debug routines
  1167. ---------------------------------------------------------------------}
  1168. Procedure DumpVariant(const VSrc : Variant);
  1169. begin
  1170. DumpVariant(Output, '', TVarData(VSrc));
  1171. end;
  1172. Procedure DumpVariant(const aName: string; const VSrc : Variant);
  1173. begin
  1174. DumpVariant(Output, aName, TVarData(VSrc));
  1175. end;
  1176. Procedure DumpVariant(Var F : Text; const VSrc : Variant);
  1177. begin
  1178. DumpVariant(F, '', TVarData(VSrc));
  1179. end;
  1180. procedure DumpVariant(var F : Text; const aName: string; const VSrc : Variant);
  1181. begin
  1182. DumpVariant(F, aName, TVarData(VSrc));
  1183. end;
  1184. Procedure DumpVariant(const VargSrc : TVarData);
  1185. begin
  1186. DumpVariant(Output, '', VargSrc);
  1187. end;
  1188. Procedure DumpVariant(const aName: string; const VargSrc : TVarData);
  1189. begin
  1190. DumpVariant(Output, aName, VargSrc);
  1191. end;
  1192. Procedure DumpVariant(Var F : Text; const VargSrc : TVarData);
  1193. begin
  1194. DumpVariant(F, '', VargSrc);
  1195. end;
  1196. const
  1197. VarTypeStrings : array [varEmpty..varQword] of string = (
  1198. 'empty', { varempty = 0 }
  1199. 'null', { varnull = 1 }
  1200. 'smallint', { varsmallint = 2 }
  1201. 'integer', { varinteger = 3 }
  1202. 'single', { varsingle = 4 }
  1203. 'double', { vardouble = 5 }
  1204. 'currency', { varcurrency = 6 }
  1205. 'date', { vardate = 7 }
  1206. 'olestr', { varolestr = 8 }
  1207. 'dispatch', { vardispatch = 9 }
  1208. 'error', { varerror = 10 }
  1209. 'boolean', { varboolean = 11 }
  1210. 'variant', { varvariant = 12 }
  1211. 'unknown', { varunknown = 13 }
  1212. 'decimal', { vardecimal = 14 }
  1213. 'undefined',
  1214. 'shortint', { varshortint = 16 }
  1215. 'byte', { varbyte = 17 }
  1216. 'word', { varword = 18 }
  1217. 'longword', { varlongword = 19 }
  1218. 'int64', { varint64 = 20 }
  1219. 'qword'); { varqword = 21 }
  1220. Procedure DumpVariant(Var F : Text; const aName: string; const VargSrc : TVarData);
  1221. Var
  1222. i: Integer;
  1223. begin
  1224. Writeln(F,'---> ', aName, ' at $', IntToHex(Cardinal(@VargSrc), 8), ' <----------------');
  1225. with VargSrc do begin
  1226. if vType and varByRef = varByRef then
  1227. Writeln(F,'Variant is by reference.');
  1228. if vType and varArray = varArray then
  1229. Writeln(F,'Variant is an array.');
  1230. if vType and not (varTypeMask or varArray or varByRef) <> 0 then
  1231. Writeln(F,'Variant has unknown flags set in type: $', IntToHex(vType, 4));
  1232. If (vType and varTypeMask) in [varEmpty..varQword] then
  1233. Writeln(F,'Variant has type : ', VarTypeStrings[vType and varTypeMask])
  1234. else If (vType and varTypeMask) = varString then
  1235. Writeln(F,'Variant has type : string')
  1236. else
  1237. Writeln(F,'Variant has unknown type : $', IntToHex(vType and varTypeMask, 4));
  1238. Write('Bytes :');
  1239. for i := 0 to 13 do
  1240. Write(IntToHex(VBytes[i], 2),' ');
  1241. WriteLn;
  1242. if vType and varArray = varArray then begin
  1243. Writeln(F,'---< ', aName, ' at $', IntToHex(Cardinal(@VargSrc), 8), ' >----------------');
  1244. Writeln(F);
  1245. Exit;
  1246. end;
  1247. If vType <> varEmpty then begin
  1248. Write(F,'Value is: [');
  1249. if (vType and varByRef = varByRef) or (vType and varTypeMask = varVariant) then
  1250. if not Assigned(vPointer) then begin
  1251. WriteLn(F, 'nil]');
  1252. Writeln(F,'---< ', aName, ' at $', IntToHex(Cardinal(@VargSrc), 8), ' >----------------');
  1253. Writeln(F);
  1254. Exit;
  1255. end;
  1256. case vType of
  1257. varNull : Write(F, 'Null');
  1258. varSmallInt : Write(F, vSmallInt);
  1259. varInteger : Write(F, vInteger);
  1260. {$ifndef FPUNONE}
  1261. varSingle : Write(F, vSingle);
  1262. varDouble : Write(F, vDouble);
  1263. varCurrency : Write(F, vCurrency);
  1264. varDate : Write(F, vDate);
  1265. {$endif}
  1266. varOleStr : Write(F, WideString(Pointer(vOleStr)));
  1267. varError : Write(F, IntToHex(Cardinal(vError), 8));
  1268. varBoolean : Write(F, vBoolean);
  1269. varVariant, varVariant or varByRef : begin
  1270. WriteLn(' dereferencing -> ]');
  1271. DumpVariant(F, aName+'^', PVarData(vPointer)^);
  1272. Exit;
  1273. end;
  1274. varShortInt : Write(F, vShortInt);
  1275. varByte : Write(F, vByte);
  1276. varWord : Write(F, vWord);
  1277. varLongWord : Write(F, vLongWord);
  1278. varInt64 : Write(F, vInt64);
  1279. varQword : Write(F, vQWord);
  1280. varString : Write(F, AnsiString(vString));
  1281. varNull or varByRef : Write(F, 'Null');
  1282. varSmallInt or varByRef : Write(F, PSmallInt(vPointer)^);
  1283. varInteger or varByRef : Write(F, PInteger(vPointer)^);
  1284. {$ifndef FPUNONE}
  1285. varSingle or varByRef : Write(F, PSingle(vPointer)^);
  1286. varDouble or varByRef : Write(F, PDouble(vPointer)^);
  1287. varCurrency or varByRef : Write(F, PCurrency(vPointer)^);
  1288. varDate or varByRef : Write(F, PDate(vPointer)^);
  1289. {$endif}
  1290. varOleStr or varByRef : Write(F, WideString(PPointer(vPointer)^));
  1291. varError or varByRef : Write(F, IntToHex(Cardinal(PLongWord(vPointer)^), 8));
  1292. varBoolean or varByRef : Write(F, PWordBool(vPointer)^);
  1293. varShortInt or varByRef : Write(F, PShortInt(vPointer)^);
  1294. varByte or varByRef : Write(F, PByte(vPointer)^);
  1295. varWord or varByRef : Write(F, PWord(vPointer)^);
  1296. varLongWord or varByRef : Write(F, PLongWord(vPointer)^);
  1297. varInt64 or varByRef : Write(F, PInt64(vPointer)^);
  1298. varQword or varByRef : Write(F, PQWord(vPointer)^);
  1299. varString or varByRef : Write(F, AnsiString(PPointer(vPointer)^));
  1300. else
  1301. Write(F, 'Unsupported');
  1302. end;
  1303. WriteLn(F, ']');
  1304. end;
  1305. end;
  1306. Writeln(F,'---< ', aName, ' at $', IntToHex(Cardinal(@VargSrc), 8), ' >----------------');
  1307. Writeln(F);
  1308. end;