cvarutil.inc 50 KB

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