cvarutil.inc 51 KB

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