cvarutil.inc 49 KB

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