blob: 6c499260fe415267c58d1a7519a5d9d5a7477fe8 [file] [log] [blame]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001/*
2 * VARIANT
3 *
4 * Copyright 1998 Jean-Claude Cote
5 *
6 * NOTES
7 * This implements the low-level and hi-level APIs for manipulating VARIANTs.
8 * The low-level APIs are used to do data coercion between different data types.
9 * The hi-level APIs are built on top of these low-level APIs and handle
10 * initialization, copying, destroying and changing the type of VARIANTs.
11 *
12 * TODO:
Michael Veksler4405f3c1999-08-18 18:35:57 +000013 * - The Variant APIs do not support international languages, currency
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +000014 * types, number formating and calendar. They only support U.S. English format.
15 * - The Variant APIs do not the following types: IUknown, IDispatch, DECIMAL and SafeArray.
16 * The prototypes for these are commented out in the oleauto.h file. They need
17 * to be implemented and cases need to be added to the switches of the existing APIs.
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +000018 * - The parsing of date for the VarDateFromStr is not complete.
Francois Gouget519346a2000-12-02 20:18:08 +000019 * - The date manipulations do not support dates prior to 1900.
20 * - The parsing does not accept as many formats as the Windows implementation.
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +000021 */
Patrik Stridvall96336321999-10-24 22:13:47 +000022
23#include "config.h"
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +000024
Alexandre Julliardfc296da2000-02-10 19:39:48 +000025#include <string.h>
26#include <stdlib.h>
27#include <stdio.h>
28#include <math.h>
29#include <time.h>
30
31#ifdef HAVE_FLOAT_H
32# include <float.h>
33#endif
34
Jim Aston2e1cafa1999-03-14 16:35:05 +000035#include "windef.h"
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +000036#include "oleauto.h"
37#include "heap.h"
Alexandre Julliard359f497e1999-07-04 16:02:24 +000038#include "debugtools.h"
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +000039#include "winerror.h"
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +000040#include "parsedt.h"
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +000041
Alexandre Julliardfc296da2000-02-10 19:39:48 +000042DEFAULT_DEBUG_CHANNEL(ole);
Marcus Meissnerae8b10b1998-12-15 13:01:21 +000043
44#ifndef FLT_MAX
45# ifdef MAXFLOAT
46# define FLT_MAX MAXFLOAT
47# else
48# error "Can't find #define for MAXFLOAT/FLT_MAX"
49# endif
50#endif
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +000051
Todd Vierling7f573251998-12-15 15:15:16 +000052#undef CHAR_MAX
53#undef CHAR_MIN
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +000054static const char CHAR_MAX = 127;
55static const char CHAR_MIN = -128;
56static const BYTE UI1_MAX = 255;
57static const BYTE UI1_MIN = 0;
58static const unsigned short UI2_MAX = 65535;
59static const unsigned short UI2_MIN = 0;
60static const short I2_MAX = 32767;
61static const short I2_MIN = -32768;
Todd Vierling7f573251998-12-15 15:15:16 +000062static const unsigned long UI4_MAX = 4294967295U;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +000063static const unsigned long UI4_MIN = 0;
64static const long I4_MAX = 2147483647;
Todd Vierling7f573251998-12-15 15:15:16 +000065static const long I4_MIN = -(2147483648U);
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +000066static const DATE DATE_MIN = -657434;
67static const DATE DATE_MAX = 2958465;
68
69
70/* This mask is used to set a flag in wReserved1 of
71 * the VARIANTARG structure. The flag indicates if
72 * the API function is using an inner variant or not.
73 */
74#define PROCESSING_INNER_VARIANT 0x0001
75
76/* General use buffer.
77 */
78#define BUFFER_MAX 1024
79static char pBuffer[BUFFER_MAX];
80
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +000081/*
82 * Note a leap year is one that is a multiple of 4
83 * but not of a 100. Except if it is a multiple of
84 * 400 then it is a leap year.
85 */
86/* According to postgeSQL date parsing functions there is
87 * a leap year when this expression is true.
88 * (((y % 4) == 0) && (((y % 100) != 0) || ((y % 400) == 0)))
89 * So according to this there is 365.2515 days in one year.
90 * One + every four years: 1/4 -> 365.25
Lawson Whitney51044b32000-03-08 18:24:03 +000091 * One - every 100 years: 1/100 -> 365.01
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +000092 * One + every 400 years: 1/400 -> 365.0025
93 */
Lawson Whitney51044b32000-03-08 18:24:03 +000094/* static const double DAYS_IN_ONE_YEAR = 365.2515;
95 *
96 * ^^ Might this be the key to an easy way to factor large prime numbers?
97 * Let's try using arithmetic. <lawson_whitney@juno.com> 7 Mar 2000
98 */
99static const double DAYS_IN_ONE_YEAR = 365.2425;
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +0000100
101/******************************************************************************
102 * DateTimeStringToTm [INTERNAL]
103 *
104 * Converts a string representation of a date and/or time to a tm structure.
105 *
106 * Note this function uses the postgresql date parsing functions found
107 * in the parsedt.c file.
108 *
Francois Gouget519346a2000-12-02 20:18:08 +0000109 * Returns TRUE if successful.
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +0000110 *
111 * Note: This function does not parse the day of the week,
112 * daylight savings time. It will only fill the followin fields in
113 * the tm struct, tm_sec, tm_min, tm_hour, tm_year, tm_day, tm_mon.
114 *
115 ******************************************************************************/
Alexandre Julliarda3960291999-02-26 11:11:13 +0000116static BOOL DateTimeStringToTm( OLECHAR* strIn, LCID lcid, struct tm* pTm )
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +0000117{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000118 BOOL res = FALSE;
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +0000119 double fsec;
120 int tzp;
121 int dtype;
122 int nf;
123 char *field[MAXDATEFIELDS];
124 int ftype[MAXDATEFIELDS];
125 char lowstr[MAXDATELEN + 1];
126 char* strDateTime = NULL;
127
128 /* Convert the string to ASCII since this is the only format
129 * postgesql can handle.
130 */
131 strDateTime = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
132
133 if( strDateTime != NULL )
134 {
135 /* Make sure we don't go over the maximum length
136 * accepted by postgesql.
137 */
138 if( strlen( strDateTime ) <= MAXDATELEN )
139 {
140 if( ParseDateTime( strDateTime, lowstr, field, ftype, MAXDATEFIELDS, &nf) == 0 )
141 {
142 if( lcid & VAR_DATEVALUEONLY )
143 {
144 /* Get the date information.
145 * It returns 0 if date information was
146 * present and 1 if only time information was present.
147 * -1 if an error occures.
148 */
149 if( DecodeDateTime(field, ftype, nf, &dtype, pTm, &fsec, &tzp) == 0 )
150 {
151 /* Eliminate the time information since we
152 * were asked to get date information only.
153 */
154 pTm->tm_sec = 0;
155 pTm->tm_min = 0;
156 pTm->tm_hour = 0;
157 res = TRUE;
158 }
159 }
160 if( lcid & VAR_TIMEVALUEONLY )
161 {
162 /* Get time information only.
163 */
164 if( DecodeTimeOnly(field, ftype, nf, &dtype, pTm, &fsec) == 0 )
165 {
166 res = TRUE;
167 }
168 }
169 else
170 {
171 /* Get both date and time information.
172 * It returns 0 if date information was
173 * present and 1 if only time information was present.
174 * -1 if an error occures.
175 */
176 if( DecodeDateTime(field, ftype, nf, &dtype, pTm, &fsec, &tzp) != -1 )
177 {
178 res = TRUE;
179 }
180 }
181 }
182 }
183 HeapFree( GetProcessHeap(), 0, strDateTime );
184 }
185
186 return res;
187}
188
189
190
191
192
193
194/******************************************************************************
195 * TmToDATE [INTERNAL]
196 *
197 * The date is implemented using an 8 byte floating-point number.
198 * Days are represented by whole numbers increments starting with 0.00 has
199 * being December 30 1899, midnight.
200 * The hours are expressed as the fractional part of the number.
201 * December 30 1899 at midnight = 0.00
202 * January 1 1900 at midnight = 2.00
203 * January 4 1900 at 6 AM = 5.25
204 * January 4 1900 at noon = 5.50
205 * December 29 1899 at midnight = -1.00
206 * December 18 1899 at midnight = -12.00
207 * December 18 1899 at 6AM = -12.25
208 * December 18 1899 at 6PM = -12.75
209 * December 19 1899 at midnight = -11.00
210 * The tm structure is as follows:
211 * struct tm {
212 * int tm_sec; seconds after the minute - [0,59]
213 * int tm_min; minutes after the hour - [0,59]
214 * int tm_hour; hours since midnight - [0,23]
215 * int tm_mday; day of the month - [1,31]
216 * int tm_mon; months since January - [0,11]
217 * int tm_year; years
218 * int tm_wday; days since Sunday - [0,6]
219 * int tm_yday; days since January 1 - [0,365]
220 * int tm_isdst; daylight savings time flag
221 * };
222 *
223 * Note: This function does not use the tm_wday, tm_yday, tm_wday,
224 * and tm_isdst fields of the tm structure. And only converts years
225 * after 1900.
226 *
Francois Gouget519346a2000-12-02 20:18:08 +0000227 * Returns TRUE if successful.
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +0000228 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000229static BOOL TmToDATE( struct tm* pTm, DATE *pDateOut )
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +0000230{
231 if( (pTm->tm_year - 1900) >= 0 )
232 {
233 int leapYear = 0;
234
235 /* Start at 1. This is the way DATE is defined.
236 * January 1, 1900 at Midnight is 1.00.
237 * January 1, 1900 at 6AM is 1.25.
238 * and so on.
239 */
240 *pDateOut = 1;
241
242 /* Add the number of days corresponding to
243 * tm_year.
244 */
245 *pDateOut += (pTm->tm_year - 1900) * 365;
246
247 /* Add the leap days in the previous years between now and 1900.
248 * Note a leap year is one that is a multiple of 4
249 * but not of a 100. Except if it is a multiple of
250 * 400 then it is a leap year.
251 */
252 *pDateOut += ( (pTm->tm_year - 1) / 4 ) - ( 1900 / 4 );
253 *pDateOut -= ( (pTm->tm_year - 1) / 100 ) - ( 1900 / 100 );
254 *pDateOut += ( (pTm->tm_year - 1) / 400 ) - ( 1900 / 400 );
255
256 /* Set the leap year flag if the
257 * current year specified by tm_year is a
258 * leap year. This will be used to add a day
259 * to the day count.
260 */
261 if( isleap( pTm->tm_year ) )
262 leapYear = 1;
263
264 /* Add the number of days corresponding to
265 * the month.
266 */
267 switch( pTm->tm_mon )
268 {
269 case 2:
270 *pDateOut += 31;
271 break;
272 case 3:
273 *pDateOut += ( 59 + leapYear );
274 break;
275 case 4:
276 *pDateOut += ( 90 + leapYear );
277 break;
278 case 5:
279 *pDateOut += ( 120 + leapYear );
280 break;
281 case 6:
282 *pDateOut += ( 151 + leapYear );
283 break;
284 case 7:
285 *pDateOut += ( 181 + leapYear );
286 break;
287 case 8:
288 *pDateOut += ( 212 + leapYear );
289 break;
290 case 9:
291 *pDateOut += ( 243 + leapYear );
292 break;
293 case 10:
294 *pDateOut += ( 273 + leapYear );
295 break;
296 case 11:
297 *pDateOut += ( 304 + leapYear );
298 break;
299 case 12:
300 *pDateOut += ( 334 + leapYear );
301 break;
302 }
303 /* Add the number of days in this month.
304 */
305 *pDateOut += pTm->tm_mday;
306
307 /* Add the number of seconds, minutes, and hours
308 * to the DATE. Note these are the fracionnal part
309 * of the DATE so seconds / number of seconds in a day.
310 */
311 *pDateOut += pTm->tm_hour / 24.0;
312 *pDateOut += pTm->tm_min / 1440.0;
313 *pDateOut += pTm->tm_sec / 86400.0;
314 return TRUE;
315 }
316 return FALSE;
317}
318
319/******************************************************************************
320 * DateToTm [INTERNAL]
321 *
Francois Gouget519346a2000-12-02 20:18:08 +0000322 * This function converts a windows DATE to a tm structure.
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +0000323 *
324 * It does not fill all the fields of the tm structure.
325 * Here is a list of the fields that are filled:
326 * tm_sec, tm_min, tm_hour, tm_year, tm_day, tm_mon.
327 *
328 * Note this function does not support dates before the January 1, 1900
329 * or ( dateIn < 2.0 ).
330 *
Francois Gouget519346a2000-12-02 20:18:08 +0000331 * Returns TRUE if successful.
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +0000332 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000333static BOOL DateToTm( DATE dateIn, LCID lcid, struct tm* pTm )
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +0000334{
335 /* Do not process dates smaller than January 1, 1900.
336 * Which corresponds to 2.0 in the windows DATE format.
337 */
338 if( dateIn >= 2.0 )
339 {
340 double decimalPart = 0.0;
341 double wholePart = 0.0;
342
Alexandre Julliard638f1691999-01-17 16:32:32 +0000343 memset(pTm,0,sizeof(*pTm));
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +0000344
Francois Gouget282f7272001-02-28 05:31:02 +0000345 /* Because of the nature of DATE format which
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +0000346 * associates 2.0 to January 1, 1900. We will
347 * remove 1.0 from the whole part of the DATE
348 * so that in the following code 1.0
349 * will correspond to January 1, 1900.
Francois Gouget282f7272001-02-28 05:31:02 +0000350 * This simplifies the processing of the DATE value.
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +0000351 */
352 dateIn -= 1.0;
353
354 wholePart = (double) floor( dateIn );
355 decimalPart = fmod( dateIn, wholePart );
356
357 if( !(lcid & VAR_TIMEVALUEONLY) )
358 {
359 int nDay = 0;
360 int leapYear = 0;
361 double yearsSince1900 = 0;
Francois Gouget282f7272001-02-28 05:31:02 +0000362 /* Start at 1900, this is where the DATE time 0.0 starts.
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +0000363 */
364 pTm->tm_year = 1900;
365 /* find in what year the day in the "wholePart" falls into.
366 * add the value to the year field.
367 */
Owen Wang64b9d862000-02-18 19:14:29 +0000368 yearsSince1900 = floor( (wholePart / DAYS_IN_ONE_YEAR) + 0.001 );
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +0000369 pTm->tm_year += yearsSince1900;
370 /* determine if this is a leap year.
371 */
372 if( isleap( pTm->tm_year ) )
Owen Wang64b9d862000-02-18 19:14:29 +0000373 {
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +0000374 leapYear = 1;
Owen Wang64b9d862000-02-18 19:14:29 +0000375 wholePart++;
376 }
377
Francois Gouget282f7272001-02-28 05:31:02 +0000378 /* find what day of that year the "wholePart" corresponds to.
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +0000379 * Note: nDay is in [1-366] format
380 */
381 nDay = (int) ( wholePart - floor( yearsSince1900 * DAYS_IN_ONE_YEAR ) );
382 /* Set the tm_yday value.
Francois Gouget282f7272001-02-28 05:31:02 +0000383 * Note: The day must be converted from [1-366] to [0-365]
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +0000384 */
Marcus Meissnerae3921d1999-01-01 18:43:12 +0000385 /*pTm->tm_yday = nDay - 1;*/
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +0000386 /* find which mount this day corresponds to.
387 */
388 if( nDay <= 31 )
389 {
390 pTm->tm_mday = nDay;
391 pTm->tm_mon = 0;
392 }
393 else if( nDay <= ( 59 + leapYear ) )
394 {
395 pTm->tm_mday = nDay - 31;
396 pTm->tm_mon = 1;
397 }
398 else if( nDay <= ( 90 + leapYear ) )
399 {
400 pTm->tm_mday = nDay - ( 59 + leapYear );
401 pTm->tm_mon = 2;
402 }
403 else if( nDay <= ( 120 + leapYear ) )
404 {
405 pTm->tm_mday = nDay - ( 90 + leapYear );
406 pTm->tm_mon = 3;
407 }
408 else if( nDay <= ( 151 + leapYear ) )
409 {
410 pTm->tm_mday = nDay - ( 120 + leapYear );
411 pTm->tm_mon = 4;
412 }
413 else if( nDay <= ( 181 + leapYear ) )
414 {
415 pTm->tm_mday = nDay - ( 151 + leapYear );
416 pTm->tm_mon = 5;
417 }
418 else if( nDay <= ( 212 + leapYear ) )
419 {
420 pTm->tm_mday = nDay - ( 181 + leapYear );
421 pTm->tm_mon = 6;
422 }
423 else if( nDay <= ( 243 + leapYear ) )
424 {
425 pTm->tm_mday = nDay - ( 212 + leapYear );
426 pTm->tm_mon = 7;
427 }
428 else if( nDay <= ( 273 + leapYear ) )
429 {
430 pTm->tm_mday = nDay - ( 243 + leapYear );
431 pTm->tm_mon = 8;
432 }
433 else if( nDay <= ( 304 + leapYear ) )
434 {
435 pTm->tm_mday = nDay - ( 273 + leapYear );
436 pTm->tm_mon = 9;
437 }
438 else if( nDay <= ( 334 + leapYear ) )
439 {
440 pTm->tm_mday = nDay - ( 304 + leapYear );
441 pTm->tm_mon = 10;
442 }
443 else if( nDay <= ( 365 + leapYear ) )
444 {
445 pTm->tm_mday = nDay - ( 334 + leapYear );
446 pTm->tm_mon = 11;
447 }
448 }
449 if( !(lcid & VAR_DATEVALUEONLY) )
450 {
451 /* find the number of seconds in this day.
452 * fractional part times, hours, minutes, seconds.
453 */
454 pTm->tm_hour = (int) ( decimalPart * 24 );
455 pTm->tm_min = (int) ( ( ( decimalPart * 24 ) - pTm->tm_hour ) * 60 );
456 pTm->tm_sec = (int) ( ( ( decimalPart * 24 * 60 ) - ( pTm->tm_hour * 60 ) - pTm->tm_min ) * 60 );
457 }
458 return TRUE;
459 }
460 return FALSE;
461}
462
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000463
464
465/******************************************************************************
466 * SizeOfVariantData [INTERNAL]
467 *
468 * This function finds the size of the data referenced by a Variant based
469 * the type "vt" of the Variant.
470 */
471static int SizeOfVariantData( VARIANT* parg )
472{
473 int size = 0;
474 switch( parg->vt & VT_TYPEMASK )
475 {
476 case( VT_I2 ):
477 size = sizeof(short);
478 break;
479 case( VT_INT ):
480 size = sizeof(int);
481 break;
482 case( VT_I4 ):
483 size = sizeof(long);
484 break;
485 case( VT_UI1 ):
486 size = sizeof(BYTE);
487 break;
488 case( VT_UI2 ):
489 size = sizeof(unsigned short);
490 break;
491 case( VT_UINT ):
492 size = sizeof(unsigned int);
493 break;
494 case( VT_UI4 ):
495 size = sizeof(unsigned long);
496 break;
497 case( VT_R4 ):
498 size = sizeof(float);
499 break;
500 case( VT_R8 ):
501 size = sizeof(double);
502 break;
503 case( VT_DATE ):
504 size = sizeof(DATE);
505 break;
506 case( VT_BOOL ):
507 size = sizeof(VARIANT_BOOL);
508 break;
509 case( VT_BSTR ):
510 size = sizeof(void*);
511 break;
512 case( VT_CY ):
513 case( VT_DISPATCH ):
514 case( VT_UNKNOWN ):
515 case( VT_DECIMAL ):
516 default:
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000517 FIXME("Add size information for type vt=%d\n", parg->vt & VT_TYPEMASK );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000518 break;
519 }
520
521 return size;
522}
523/******************************************************************************
524 * StringDupAtoBstr [INTERNAL]
525 *
526 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000527static BSTR StringDupAtoBstr( char* strIn )
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000528{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000529 BSTR bstr = NULL;
530 OLECHAR* pNewString = NULL;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000531 pNewString = HEAP_strdupAtoW( GetProcessHeap(), 0, strIn );
Alexandre Julliarda3960291999-02-26 11:11:13 +0000532 bstr = SysAllocString( pNewString );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000533 HeapFree( GetProcessHeap(), 0, pNewString );
534 return bstr;
535}
536
537/******************************************************************************
538 * round [INTERNAL]
539 *
540 * Round the double value to the nearest integer value.
541 */
542static double round( double d )
543{
Justin Bradfordbc93bc81998-12-11 14:02:16 +0000544 double decimals = 0.0, integerValue = 0.0, roundedValue = 0.0;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000545 BOOL bEvenNumber = FALSE;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000546 int nSign = 0;
547
548 /* Save the sign of the number
549 */
Justin Bradfordbc93bc81998-12-11 14:02:16 +0000550 nSign = (d >= 0.0) ? 1 : -1;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000551 d = fabs( d );
552
553 /* Remove the decimals.
554 */
Justin Bradfordbc93bc81998-12-11 14:02:16 +0000555 integerValue = floor( d );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000556
557 /* Set the Even flag. This is used to round the number when
558 * the decimals are exactly 1/2. If the integer part is
559 * odd the number is rounded up. If the integer part
560 * is even the number is rounded down. Using this method
561 * numbers are rounded up|down half the time.
562 */
Justin Bradfordbc93bc81998-12-11 14:02:16 +0000563 bEvenNumber = (((short)fmod(integerValue, 2)) == 0) ? TRUE : FALSE;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000564
565 /* Remove the integral part of the number.
566 */
567 decimals = d - integerValue;
568
569 /* Note: Ceil returns the smallest integer that is greater that x.
570 * and floor returns the largest integer that is less than or equal to x.
571 */
572 if( decimals > 0.5 )
573 {
574 /* If the decimal part is greater than 1/2
575 */
576 roundedValue = ceil( d );
577 }
578 else if( decimals < 0.5 )
579 {
580 /* If the decimal part is smaller than 1/2
581 */
582 roundedValue = floor( d );
583 }
584 else
585 {
586 /* the decimals are exactly 1/2 so round according to
587 * the bEvenNumber flag.
588 */
589 if( bEvenNumber )
590 {
591 roundedValue = floor( d );
592 }
593 else
594 {
595 roundedValue = ceil( d );
596 }
597 }
598
599 return roundedValue * nSign;
600}
601
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000602/******************************************************************************
603 * RemoveCharacterFromString [INTERNAL]
604 *
605 * Removes any of the characters in "strOfCharToRemove" from the "str" argument.
606 */
607static void RemoveCharacterFromString( LPSTR str, LPSTR strOfCharToRemove )
608{
609 LPSTR pNewString = NULL;
610 LPSTR strToken = NULL;
611
612
613 /* Check if we have a valid argument
614 */
615 if( str != NULL )
616 {
617 pNewString = strdup( str );
618 str[0] = '\0';
619 strToken = strtok( pNewString, strOfCharToRemove );
620 while( strToken != NULL ) {
621 strcat( str, strToken );
622 strToken = strtok( NULL, strOfCharToRemove );
623 }
624 free( pNewString );
625 }
626 return;
627}
628
629/******************************************************************************
630 * GetValidRealString [INTERNAL]
631 *
632 * Checks if the string is of proper format to be converted to a real value.
633 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000634static BOOL IsValidRealString( LPSTR strRealString )
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000635{
636 /* Real values that have a decimal point are required to either have
637 * digits before or after the decimal point. We will assume that
638 * we do not have any digits at either position. If we do encounter
639 * some we will disable this flag.
640 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000641 BOOL bDigitsRequired = TRUE;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000642 /* Processed fields in the string representation of the real number.
643 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000644 BOOL bWhiteSpaceProcessed = FALSE;
645 BOOL bFirstSignProcessed = FALSE;
646 BOOL bFirstDigitsProcessed = FALSE;
647 BOOL bDecimalPointProcessed = FALSE;
648 BOOL bSecondDigitsProcessed = FALSE;
649 BOOL bExponentProcessed = FALSE;
650 BOOL bSecondSignProcessed = FALSE;
651 BOOL bThirdDigitsProcessed = FALSE;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000652 /* Assume string parameter "strRealString" is valid and try to disprove it.
653 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000654 BOOL bValidRealString = TRUE;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000655
656 /* Used to count the number of tokens in the "strRealString".
657 */
658 LPSTR strToken = NULL;
659 int nTokens = 0;
660 LPSTR pChar = NULL;
661
662 /* Check if we have a valid argument
663 */
664 if( strRealString == NULL )
665 {
666 bValidRealString = FALSE;
667 }
668
669 if( bValidRealString == TRUE )
670 {
671 /* Make sure we only have ONE token in the string.
672 */
673 strToken = strtok( strRealString, " " );
674 while( strToken != NULL ) {
675 nTokens++;
676 strToken = strtok( NULL, " " );
677 }
678
679 if( nTokens != 1 )
680 {
681 bValidRealString = FALSE;
682 }
683 }
684
685
686 /* Make sure this token contains only valid characters.
687 * The string argument to atof has the following form:
688 * [whitespace] [sign] [digits] [.digits] [ {d | D | e | E }[sign]digits]
689 * Whitespace consists of space and|or <TAB> characters, which are ignored.
690 * Sign is either plus '+' or minus '-'.
691 * Digits are one or more decimal digits.
692 * Note: If no digits appear before the decimal point, at least one must
693 * appear after the decimal point.
694 * The decimal digits may be followed by an exponent.
695 * An Exponent consists of an introductory letter ( D, d, E, or e) and
696 * an optionally signed decimal integer.
697 */
698 pChar = strRealString;
699 while( bValidRealString == TRUE && *pChar != '\0' )
700 {
701 switch( *pChar )
702 {
703 /* If whitespace...
704 */
705 case ' ':
706 case '\t':
707 if( bWhiteSpaceProcessed ||
708 bFirstSignProcessed ||
709 bFirstDigitsProcessed ||
710 bDecimalPointProcessed ||
711 bSecondDigitsProcessed ||
712 bExponentProcessed ||
713 bSecondSignProcessed ||
714 bThirdDigitsProcessed )
715 {
716 bValidRealString = FALSE;
717 }
718 break;
719 /* If sign...
720 */
721 case '+':
722 case '-':
723 if( bFirstSignProcessed == FALSE )
724 {
725 if( bFirstDigitsProcessed ||
726 bDecimalPointProcessed ||
727 bSecondDigitsProcessed ||
728 bExponentProcessed ||
729 bSecondSignProcessed ||
730 bThirdDigitsProcessed )
731 {
732 bValidRealString = FALSE;
733 }
734 bWhiteSpaceProcessed = TRUE;
735 bFirstSignProcessed = TRUE;
736 }
737 else if( bSecondSignProcessed == FALSE )
738 {
739 /* Note: The exponent must be present in
740 * order to accept the second sign...
741 */
742 if( bExponentProcessed == FALSE ||
743 bThirdDigitsProcessed ||
744 bDigitsRequired )
745 {
746 bValidRealString = FALSE;
747 }
748 bFirstSignProcessed = TRUE;
749 bWhiteSpaceProcessed = TRUE;
750 bFirstDigitsProcessed = TRUE;
751 bDecimalPointProcessed = TRUE;
752 bSecondDigitsProcessed = TRUE;
753 bSecondSignProcessed = TRUE;
754 }
755 break;
756
757 /* If decimals...
758 */
759 case '0':
760 case '1':
761 case '2':
762 case '3':
763 case '4':
764 case '5':
765 case '6':
766 case '7':
767 case '8':
768 case '9':
769 if( bFirstDigitsProcessed == FALSE )
770 {
771 if( bDecimalPointProcessed ||
772 bSecondDigitsProcessed ||
773 bExponentProcessed ||
774 bSecondSignProcessed ||
775 bThirdDigitsProcessed )
776 {
777 bValidRealString = FALSE;
778 }
779 bFirstSignProcessed = TRUE;
780 bWhiteSpaceProcessed = TRUE;
781 /* We have found some digits before the decimal point
782 * so disable the "Digits required" flag.
783 */
784 bDigitsRequired = FALSE;
785 }
786 else if( bSecondDigitsProcessed == FALSE )
787 {
788 if( bExponentProcessed ||
789 bSecondSignProcessed ||
790 bThirdDigitsProcessed )
791 {
792 bValidRealString = FALSE;
793 }
794 bFirstSignProcessed = TRUE;
795 bWhiteSpaceProcessed = TRUE;
796 bFirstDigitsProcessed = TRUE;
797 bDecimalPointProcessed = TRUE;
798 /* We have found some digits after the decimal point
799 * so disable the "Digits required" flag.
800 */
801 bDigitsRequired = FALSE;
802 }
803 else if( bThirdDigitsProcessed == FALSE )
804 {
805 /* Getting here means everything else should be processed.
806 * If we get anything else than a decimal following this
807 * digit it will be flagged by the other cases, so
808 * we do not really need to do anything in here.
809 */
810 }
811 break;
812 /* If DecimalPoint...
813 */
814 case '.':
815 if( bDecimalPointProcessed ||
816 bSecondDigitsProcessed ||
817 bExponentProcessed ||
818 bSecondSignProcessed ||
819 bThirdDigitsProcessed )
820 {
821 bValidRealString = FALSE;
822 }
823 bFirstSignProcessed = TRUE;
824 bWhiteSpaceProcessed = TRUE;
825 bFirstDigitsProcessed = TRUE;
826 bDecimalPointProcessed = TRUE;
827 break;
828 /* If Exponent...
829 */
830 case 'e':
831 case 'E':
832 case 'd':
833 case 'D':
834 if( bExponentProcessed ||
835 bSecondSignProcessed ||
836 bThirdDigitsProcessed ||
837 bDigitsRequired )
838 {
839 bValidRealString = FALSE;
840 }
841 bFirstSignProcessed = TRUE;
842 bWhiteSpaceProcessed = TRUE;
843 bFirstDigitsProcessed = TRUE;
844 bDecimalPointProcessed = TRUE;
845 bSecondDigitsProcessed = TRUE;
846 bExponentProcessed = TRUE;
847 break;
848 default:
849 bValidRealString = FALSE;
850 break;
851 }
852 /* Process next character.
853 */
854 pChar++;
855 }
856
857 /* If the required digits were not present we have an invalid
858 * string representation of a real number.
859 */
860 if( bDigitsRequired == TRUE )
861 {
862 bValidRealString = FALSE;
863 }
864
865 return bValidRealString;
866}
867
868
869/******************************************************************************
870 * Coerce [INTERNAL]
871 *
872 * This function dispatches execution to the proper conversion API
873 * to do the necessary coercion.
874 */
875static HRESULT Coerce( VARIANTARG* pd, LCID lcid, ULONG dwFlags, VARIANTARG* ps, VARTYPE vt )
876{
877 HRESULT res = S_OK;
878 unsigned short vtFrom = 0;
879 vtFrom = ps->vt & VT_TYPEMASK;
880
Owen Wang64b9d862000-02-18 19:14:29 +0000881 /* Note: Since "long" and "int" values both have 4 bytes and are
882 * both signed integers "int" will be treated as "long" in the
883 * following code.
884 * The same goes for their unsigned versions.
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000885 */
886
Owen Wang64b9d862000-02-18 19:14:29 +0000887 /* Trivial Case: If the coercion is from two types that are
888 * identical then we can blindly copy from one argument to another.*/
889 if ((vt==vtFrom))
890 {
891 return VariantCopy(pd,ps);
892 }
893
894 /* Cases requiring thought*/
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000895 switch( vt )
896 {
897
898 case( VT_EMPTY ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000899 res = VariantClear( pd );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000900 break;
901 case( VT_NULL ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000902 res = VariantClear( pd );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000903 if( res == S_OK )
904 {
905 pd->vt = VT_NULL;
906 }
907 break;
908 case( VT_I1 ):
909 switch( vtFrom )
910 {
911 case( VT_I1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000912 res = VariantCopy( pd, ps );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000913 break;
914 case( VT_I2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000915 res = VarI1FromI2( ps->u.iVal, &(pd->u.cVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000916 break;
917 case( VT_INT ):
918 case( VT_I4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000919 res = VarI1FromI4( ps->u.lVal, &(pd->u.cVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000920 break;
921 case( VT_UI1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000922 res = VarI1FromUI1( ps->u.bVal, &(pd->u.cVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000923 break;
924 case( VT_UI2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000925 res = VarI1FromUI2( ps->u.uiVal, &(pd->u.cVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000926 break;
927 case( VT_UINT ):
928 case( VT_UI4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000929 res = VarI1FromUI4( ps->u.ulVal, &(pd->u.cVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000930 break;
931 case( VT_R4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000932 res = VarI1FromR4( ps->u.fltVal, &(pd->u.cVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000933 break;
934 case( VT_R8 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000935 res = VarI1FromR8( ps->u.dblVal, &(pd->u.cVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000936 break;
937 case( VT_DATE ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000938 res = VarI1FromDate( ps->u.date, &(pd->u.cVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000939 break;
940 case( VT_BOOL ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000941 res = VarI1FromBool( ps->u.boolVal, &(pd->u.cVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000942 break;
943 case( VT_BSTR ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000944 res = VarI1FromStr( ps->u.bstrVal, lcid, dwFlags, &(pd->u.cVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000945 break;
946 case( VT_CY ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000947 res = VarI1FromCy( ps->u.cyVal, &(pd->u.cVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000948 case( VT_DISPATCH ):
949 /*res = VarI1FromDisp32( ps->u.pdispVal, lcid, &(pd->u.cVal) );*/
950 case( VT_UNKNOWN ):
951 /*res = VarI1From32( ps->u.lVal, &(pd->u.cVal) );*/
952 case( VT_DECIMAL ):
953 /*res = VarI1FromDec32( ps->u.decVal, &(pd->u.cVal) );*/
954 default:
955 res = DISP_E_TYPEMISMATCH;
Alexandre Julliard359f497e1999-07-04 16:02:24 +0000956 FIXME("Coercion from %d to %d\n", vtFrom, vt );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000957 break;
958 }
959 break;
960
961 case( VT_I2 ):
962 switch( vtFrom )
963 {
964 case( VT_I1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000965 res = VarI2FromI1( ps->u.cVal, &(pd->u.iVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000966 break;
967 case( VT_I2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000968 res = VariantCopy( pd, ps );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000969 break;
970 case( VT_INT ):
971 case( VT_I4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000972 res = VarI2FromI4( ps->u.lVal, &(pd->u.iVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000973 break;
974 case( VT_UI1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000975 res = VarI2FromUI1( ps->u.bVal, &(pd->u.iVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000976 break;
977 case( VT_UI2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000978 res = VarI2FromUI2( ps->u.uiVal, &(pd->u.iVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000979 break;
980 case( VT_UINT ):
981 case( VT_UI4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000982 res = VarI2FromUI4( ps->u.ulVal, &(pd->u.iVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000983 break;
984 case( VT_R4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000985 res = VarI2FromR4( ps->u.fltVal, &(pd->u.iVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000986 break;
987 case( VT_R8 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000988 res = VarI2FromR8( ps->u.dblVal, &(pd->u.iVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000989 break;
990 case( VT_DATE ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000991 res = VarI2FromDate( ps->u.date, &(pd->u.iVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000992 break;
993 case( VT_BOOL ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000994 res = VarI2FromBool( ps->u.boolVal, &(pd->u.iVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000995 break;
996 case( VT_BSTR ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000997 res = VarI2FromStr( ps->u.bstrVal, lcid, dwFlags, &(pd->u.iVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000998 break;
999 case( VT_CY ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001000 res = VarI2FromCy( ps->u.cyVal, &(pd->u.iVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001001 case( VT_DISPATCH ):
1002 /*res = VarI2FromDisp32( ps->u.pdispVal, lcid, &(pd->u.iVal) );*/
1003 case( VT_UNKNOWN ):
1004 /*res = VarI2From32( ps->u.lVal, &(pd->u.iVal) );*/
1005 case( VT_DECIMAL ):
1006 /*res = VarI2FromDec32( ps->u.deiVal, &(pd->u.iVal) );*/
1007 default:
1008 res = DISP_E_TYPEMISMATCH;
Alexandre Julliard359f497e1999-07-04 16:02:24 +00001009 FIXME("Coercion from %d to %d\n", vtFrom, vt );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001010 break;
1011 }
1012 break;
1013
1014 case( VT_INT ):
1015 case( VT_I4 ):
1016 switch( vtFrom )
1017 {
1018 case( VT_I1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001019 res = VarI4FromI1( ps->u.cVal, &(pd->u.lVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001020 break;
1021 case( VT_I2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001022 res = VarI4FromI2( ps->u.iVal, &(pd->u.lVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001023 break;
1024 case( VT_INT ):
1025 case( VT_I4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001026 res = VariantCopy( pd, ps );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001027 break;
1028 case( VT_UI1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001029 res = VarI4FromUI1( ps->u.bVal, &(pd->u.lVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001030 break;
1031 case( VT_UI2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001032 res = VarI4FromUI2( ps->u.uiVal, &(pd->u.lVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001033 break;
1034 case( VT_UINT ):
1035 case( VT_UI4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001036 res = VarI4FromUI4( ps->u.ulVal, &(pd->u.lVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001037 break;
1038 case( VT_R4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001039 res = VarI4FromR4( ps->u.fltVal, &(pd->u.lVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001040 break;
1041 case( VT_R8 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001042 res = VarI4FromR8( ps->u.dblVal, &(pd->u.lVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001043 break;
1044 case( VT_DATE ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001045 res = VarI4FromDate( ps->u.date, &(pd->u.lVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001046 break;
1047 case( VT_BOOL ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001048 res = VarI4FromBool( ps->u.boolVal, &(pd->u.lVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001049 break;
1050 case( VT_BSTR ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001051 res = VarI4FromStr( ps->u.bstrVal, lcid, dwFlags, &(pd->u.lVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001052 break;
1053 case( VT_CY ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001054 res = VarI4FromCy( ps->u.cyVal, &(pd->u.lVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001055 case( VT_DISPATCH ):
1056 /*res = VarI4FromDisp32( ps->u.pdispVal, lcid, &(pd->u.lVal) );*/
1057 case( VT_UNKNOWN ):
1058 /*res = VarI4From32( ps->u.lVal, &(pd->u.lVal) );*/
1059 case( VT_DECIMAL ):
1060 /*res = VarI4FromDec32( ps->u.deiVal, &(pd->u.lVal) );*/
1061 default:
1062 res = DISP_E_TYPEMISMATCH;
Alexandre Julliard359f497e1999-07-04 16:02:24 +00001063 FIXME("Coercion from %d to %d\n", vtFrom, vt );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001064 break;
1065 }
1066 break;
1067
1068 case( VT_UI1 ):
1069 switch( vtFrom )
1070 {
1071 case( VT_I1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001072 res = VarUI1FromI1( ps->u.cVal, &(pd->u.bVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001073 break;
1074 case( VT_I2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001075 res = VarUI1FromI2( ps->u.iVal, &(pd->u.bVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001076 break;
1077 case( VT_INT ):
1078 case( VT_I4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001079 res = VarUI1FromI4( ps->u.lVal, &(pd->u.bVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001080 break;
1081 case( VT_UI1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001082 res = VariantCopy( pd, ps );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001083 break;
1084 case( VT_UI2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001085 res = VarUI1FromUI2( ps->u.uiVal, &(pd->u.bVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001086 break;
1087 case( VT_UINT ):
1088 case( VT_UI4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001089 res = VarUI1FromUI4( ps->u.ulVal, &(pd->u.bVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001090 break;
1091 case( VT_R4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001092 res = VarUI1FromR4( ps->u.fltVal, &(pd->u.bVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001093 break;
1094 case( VT_R8 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001095 res = VarUI1FromR8( ps->u.dblVal, &(pd->u.bVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001096 break;
1097 case( VT_DATE ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001098 res = VarUI1FromDate( ps->u.date, &(pd->u.bVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001099 break;
1100 case( VT_BOOL ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001101 res = VarUI1FromBool( ps->u.boolVal, &(pd->u.bVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001102 break;
1103 case( VT_BSTR ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001104 res = VarUI1FromStr( ps->u.bstrVal, lcid, dwFlags, &(pd->u.bVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001105 break;
1106 case( VT_CY ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001107 res = VarUI1FromCy( ps->u.cyVal, &(pd->u.bVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001108 case( VT_DISPATCH ):
1109 /*res = VarUI1FromDisp32( ps->u.pdispVal, lcid, &(pd->u.bVal) );*/
1110 case( VT_UNKNOWN ):
1111 /*res = VarUI1From32( ps->u.lVal, &(pd->u.bVal) );*/
1112 case( VT_DECIMAL ):
1113 /*res = VarUI1FromDec32( ps->u.deiVal, &(pd->u.bVal) );*/
1114 default:
1115 res = DISP_E_TYPEMISMATCH;
Alexandre Julliard359f497e1999-07-04 16:02:24 +00001116 FIXME("Coercion from %d to %d\n", vtFrom, vt );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001117 break;
1118 }
1119 break;
1120
1121 case( VT_UI2 ):
1122 switch( vtFrom )
1123 {
1124 case( VT_I1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001125 res = VarUI2FromI1( ps->u.cVal, &(pd->u.uiVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001126 break;
1127 case( VT_I2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001128 res = VarUI2FromI2( ps->u.iVal, &(pd->u.uiVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001129 break;
1130 case( VT_INT ):
1131 case( VT_I4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001132 res = VarUI2FromI4( ps->u.lVal, &(pd->u.uiVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001133 break;
1134 case( VT_UI1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001135 res = VarUI2FromUI1( ps->u.bVal, &(pd->u.uiVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001136 break;
1137 case( VT_UI2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001138 res = VariantCopy( pd, ps );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001139 break;
1140 case( VT_UINT ):
1141 case( VT_UI4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001142 res = VarUI2FromUI4( ps->u.ulVal, &(pd->u.uiVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001143 break;
1144 case( VT_R4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001145 res = VarUI2FromR4( ps->u.fltVal, &(pd->u.uiVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001146 break;
1147 case( VT_R8 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001148 res = VarUI2FromR8( ps->u.dblVal, &(pd->u.uiVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001149 break;
1150 case( VT_DATE ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001151 res = VarUI2FromDate( ps->u.date, &(pd->u.uiVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001152 break;
1153 case( VT_BOOL ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001154 res = VarUI2FromBool( ps->u.boolVal, &(pd->u.uiVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001155 break;
1156 case( VT_BSTR ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001157 res = VarUI2FromStr( ps->u.bstrVal, lcid, dwFlags, &(pd->u.uiVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001158 break;
1159 case( VT_CY ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001160 res = VarUI2FromCy( ps->u.cyVal, &(pd->u.uiVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001161 case( VT_DISPATCH ):
1162 /*res = VarUI2FromDisp32( ps->u.pdispVal, lcid, &(pd->u.uiVal) );*/
1163 case( VT_UNKNOWN ):
1164 /*res = VarUI2From32( ps->u.lVal, &(pd->u.uiVal) );*/
1165 case( VT_DECIMAL ):
1166 /*res = VarUI2FromDec32( ps->u.deiVal, &(pd->u.uiVal) );*/
1167 default:
1168 res = DISP_E_TYPEMISMATCH;
Alexandre Julliard359f497e1999-07-04 16:02:24 +00001169 FIXME("Coercion from %d to %d\n", vtFrom, vt );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001170 break;
1171 }
1172 break;
1173
1174 case( VT_UINT ):
1175 case( VT_UI4 ):
1176 switch( vtFrom )
1177 {
1178 case( VT_I1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001179 res = VarUI4FromI1( ps->u.cVal, &(pd->u.ulVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001180 break;
1181 case( VT_I2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001182 res = VarUI4FromI2( ps->u.iVal, &(pd->u.ulVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001183 break;
1184 case( VT_INT ):
1185 case( VT_I4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001186 res = VarUI4FromI4( ps->u.lVal, &(pd->u.ulVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001187 break;
1188 case( VT_UI1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001189 res = VarUI4FromUI1( ps->u.bVal, &(pd->u.ulVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001190 break;
1191 case( VT_UI2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001192 res = VarUI4FromUI2( ps->u.uiVal, &(pd->u.ulVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001193 break;
1194 case( VT_UI4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001195 res = VariantCopy( pd, ps );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001196 break;
1197 case( VT_R4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001198 res = VarUI4FromR4( ps->u.fltVal, &(pd->u.ulVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001199 break;
1200 case( VT_R8 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001201 res = VarUI4FromR8( ps->u.dblVal, &(pd->u.ulVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001202 break;
1203 case( VT_DATE ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001204 res = VarUI4FromDate( ps->u.date, &(pd->u.ulVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001205 break;
1206 case( VT_BOOL ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001207 res = VarUI4FromBool( ps->u.boolVal, &(pd->u.ulVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001208 break;
1209 case( VT_BSTR ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001210 res = VarUI4FromStr( ps->u.bstrVal, lcid, dwFlags, &(pd->u.ulVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001211 break;
1212 case( VT_CY ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001213 res = VarUI4FromCy( ps->u.cyVal, &(pd->u.ulVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001214 case( VT_DISPATCH ):
1215 /*res = VarUI4FromDisp32( ps->u.pdispVal, lcid, &(pd->u.ulVal) );*/
1216 case( VT_UNKNOWN ):
1217 /*res = VarUI4From32( ps->u.lVal, &(pd->u.ulVal) );*/
1218 case( VT_DECIMAL ):
1219 /*res = VarUI4FromDec32( ps->u.deiVal, &(pd->u.ulVal) );*/
1220 default:
1221 res = DISP_E_TYPEMISMATCH;
Alexandre Julliard359f497e1999-07-04 16:02:24 +00001222 FIXME("Coercion from %d to %d\n", vtFrom, vt );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001223 break;
1224 }
1225 break;
1226
1227 case( VT_R4 ):
1228 switch( vtFrom )
1229 {
1230 case( VT_I1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001231 res = VarR4FromI1( ps->u.cVal, &(pd->u.fltVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001232 break;
1233 case( VT_I2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001234 res = VarR4FromI2( ps->u.iVal, &(pd->u.fltVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001235 break;
1236 case( VT_INT ):
1237 case( VT_I4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001238 res = VarR4FromI4( ps->u.lVal, &(pd->u.fltVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001239 break;
1240 case( VT_UI1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001241 res = VarR4FromUI1( ps->u.bVal, &(pd->u.fltVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001242 break;
1243 case( VT_UI2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001244 res = VarR4FromUI2( ps->u.uiVal, &(pd->u.fltVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001245 break;
1246 case( VT_UINT ):
1247 case( VT_UI4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001248 res = VarR4FromUI4( ps->u.ulVal, &(pd->u.fltVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001249 break;
1250 case( VT_R4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001251 res = VariantCopy( pd, ps );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001252 break;
1253 case( VT_R8 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001254 res = VarR4FromR8( ps->u.dblVal, &(pd->u.fltVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001255 break;
1256 case( VT_DATE ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001257 res = VarR4FromDate( ps->u.date, &(pd->u.fltVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001258 break;
1259 case( VT_BOOL ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001260 res = VarR4FromBool( ps->u.boolVal, &(pd->u.fltVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001261 break;
1262 case( VT_BSTR ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001263 res = VarR4FromStr( ps->u.bstrVal, lcid, dwFlags, &(pd->u.fltVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001264 break;
1265 case( VT_CY ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001266 res = VarR4FromCy( ps->u.cyVal, &(pd->u.fltVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001267 case( VT_DISPATCH ):
1268 /*res = VarR4FromDisp32( ps->u.pdispVal, lcid, &(pd->u.fltVal) );*/
1269 case( VT_UNKNOWN ):
1270 /*res = VarR4From32( ps->u.lVal, &(pd->u.fltVal) );*/
1271 case( VT_DECIMAL ):
1272 /*res = VarR4FromDec32( ps->u.deiVal, &(pd->u.fltVal) );*/
1273 default:
1274 res = DISP_E_TYPEMISMATCH;
Alexandre Julliard359f497e1999-07-04 16:02:24 +00001275 FIXME("Coercion from %d to %d\n", vtFrom, vt );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001276 break;
1277 }
1278 break;
1279
1280 case( VT_R8 ):
1281 switch( vtFrom )
1282 {
1283 case( VT_I1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001284 res = VarR8FromI1( ps->u.cVal, &(pd->u.dblVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001285 break;
1286 case( VT_I2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001287 res = VarR8FromI2( ps->u.iVal, &(pd->u.dblVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001288 break;
1289 case( VT_INT ):
1290 case( VT_I4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001291 res = VarR8FromI4( ps->u.lVal, &(pd->u.dblVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001292 break;
1293 case( VT_UI1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001294 res = VarR8FromUI1( ps->u.bVal, &(pd->u.dblVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001295 break;
1296 case( VT_UI2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001297 res = VarR8FromUI2( ps->u.uiVal, &(pd->u.dblVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001298 break;
1299 case( VT_UINT ):
1300 case( VT_UI4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001301 res = VarR8FromUI4( ps->u.ulVal, &(pd->u.dblVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001302 break;
1303 case( VT_R4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001304 res = VarR8FromR4( ps->u.fltVal, &(pd->u.dblVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001305 break;
1306 case( VT_R8 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001307 res = VariantCopy( pd, ps );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001308 break;
1309 case( VT_DATE ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001310 res = VarR8FromDate( ps->u.date, &(pd->u.dblVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001311 break;
1312 case( VT_BOOL ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001313 res = VarR8FromBool( ps->u.boolVal, &(pd->u.dblVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001314 break;
1315 case( VT_BSTR ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001316 res = VarR8FromStr( ps->u.bstrVal, lcid, dwFlags, &(pd->u.dblVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001317 break;
1318 case( VT_CY ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001319 res = VarR8FromCy( ps->u.cyVal, &(pd->u.dblVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001320 case( VT_DISPATCH ):
1321 /*res = VarR8FromDisp32( ps->u.pdispVal, lcid, &(pd->u.dblVal) );*/
1322 case( VT_UNKNOWN ):
1323 /*res = VarR8From32( ps->u.lVal, &(pd->u.dblVal) );*/
1324 case( VT_DECIMAL ):
1325 /*res = VarR8FromDec32( ps->u.deiVal, &(pd->u.dblVal) );*/
1326 default:
1327 res = DISP_E_TYPEMISMATCH;
Alexandre Julliard359f497e1999-07-04 16:02:24 +00001328 FIXME("Coercion from %d to %d\n", vtFrom, vt );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001329 break;
1330 }
1331 break;
1332
1333 case( VT_DATE ):
1334 switch( vtFrom )
1335 {
1336 case( VT_I1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001337 res = VarDateFromI1( ps->u.cVal, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001338 break;
1339 case( VT_I2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001340 res = VarDateFromI2( ps->u.iVal, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001341 break;
1342 case( VT_INT ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001343 res = VarDateFromInt( ps->u.intVal, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001344 break;
1345 case( VT_I4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001346 res = VarDateFromI4( ps->u.lVal, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001347 break;
1348 case( VT_UI1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001349 res = VarDateFromUI1( ps->u.bVal, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001350 break;
1351 case( VT_UI2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001352 res = VarDateFromUI2( ps->u.uiVal, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001353 break;
1354 case( VT_UINT ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001355 res = VarDateFromUint( ps->u.uintVal, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001356 break;
1357 case( VT_UI4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001358 res = VarDateFromUI4( ps->u.ulVal, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001359 break;
1360 case( VT_R4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001361 res = VarDateFromR4( ps->u.fltVal, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001362 break;
1363 case( VT_R8 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001364 res = VarDateFromR8( ps->u.dblVal, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001365 break;
1366 case( VT_DATE ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001367 res = VariantCopy( pd, ps );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001368 break;
1369 case( VT_BOOL ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001370 res = VarDateFromBool( ps->u.boolVal, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001371 break;
1372 case( VT_BSTR ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001373 res = VarDateFromStr( ps->u.bstrVal, lcid, dwFlags, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001374 break;
1375 case( VT_CY ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001376 res = VarDateFromCy( ps->u.cyVal, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001377 case( VT_DISPATCH ):
1378 /*res = VarDateFromDisp32( ps->u.pdispVal, lcid, &(pd->u.date) );*/
1379 case( VT_UNKNOWN ):
1380 /*res = VarDateFrom32( ps->u.lVal, &(pd->u.date) );*/
1381 case( VT_DECIMAL ):
1382 /*res = VarDateFromDec32( ps->u.deiVal, &(pd->u.date) );*/
1383 default:
1384 res = DISP_E_TYPEMISMATCH;
Alexandre Julliard359f497e1999-07-04 16:02:24 +00001385 FIXME("Coercion from %d to %d\n", vtFrom, vt );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001386 break;
1387 }
1388 break;
1389
1390 case( VT_BOOL ):
1391 switch( vtFrom )
1392 {
1393 case( VT_I1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001394 res = VarBoolFromI1( ps->u.cVal, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001395 break;
1396 case( VT_I2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001397 res = VarBoolFromI2( ps->u.iVal, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001398 break;
1399 case( VT_INT ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001400 res = VarBoolFromInt( ps->u.intVal, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001401 break;
1402 case( VT_I4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001403 res = VarBoolFromI4( ps->u.lVal, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001404 break;
1405 case( VT_UI1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001406 res = VarBoolFromUI1( ps->u.bVal, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001407 break;
1408 case( VT_UI2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001409 res = VarBoolFromUI2( ps->u.uiVal, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001410 break;
1411 case( VT_UINT ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001412 res = VarBoolFromUint( ps->u.uintVal, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001413 break;
1414 case( VT_UI4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001415 res = VarBoolFromUI4( ps->u.ulVal, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001416 break;
1417 case( VT_R4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001418 res = VarBoolFromR4( ps->u.fltVal, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001419 break;
1420 case( VT_R8 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001421 res = VarBoolFromR8( ps->u.dblVal, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001422 break;
1423 case( VT_DATE ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001424 res = VarBoolFromDate( ps->u.date, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001425 break;
1426 case( VT_BOOL ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001427 res = VariantCopy( pd, ps );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001428 break;
1429 case( VT_BSTR ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001430 res = VarBoolFromStr( ps->u.bstrVal, lcid, dwFlags, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001431 break;
1432 case( VT_CY ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001433 res = VarBoolFromCy( ps->u.cyVal, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001434 case( VT_DISPATCH ):
1435 /*res = VarBoolFromDisp32( ps->u.pdispVal, lcid, &(pd->u.boolVal) );*/
1436 case( VT_UNKNOWN ):
1437 /*res = VarBoolFrom32( ps->u.lVal, &(pd->u.boolVal) );*/
1438 case( VT_DECIMAL ):
1439 /*res = VarBoolFromDec32( ps->u.deiVal, &(pd->u.boolVal) );*/
1440 default:
1441 res = DISP_E_TYPEMISMATCH;
Alexandre Julliard359f497e1999-07-04 16:02:24 +00001442 FIXME("Coercion from %d to %d\n", vtFrom, vt );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001443 break;
1444 }
1445 break;
1446
1447 case( VT_BSTR ):
1448 switch( vtFrom )
1449 {
Francois Jacques26c0b762000-11-25 01:20:37 +00001450 case( VT_EMPTY ):
1451 if ((pd->u.bstrVal = SysAllocStringLen(NULL, 0)))
1452 res = S_OK;
1453 else
1454 res = E_OUTOFMEMORY;
1455 break;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001456 case( VT_I1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001457 res = VarBstrFromI1( ps->u.cVal, lcid, dwFlags, &(pd->u.bstrVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001458 break;
1459 case( VT_I2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001460 res = VarBstrFromI2( ps->u.iVal, lcid, dwFlags, &(pd->u.bstrVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001461 break;
1462 case( VT_INT ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001463 res = VarBstrFromInt( ps->u.intVal, lcid, dwFlags, &(pd->u.bstrVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001464 break;
1465 case( VT_I4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001466 res = VarBstrFromI4( ps->u.lVal, lcid, dwFlags, &(pd->u.bstrVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001467 break;
1468 case( VT_UI1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001469 res = VarBstrFromUI1( ps->u.bVal, lcid, dwFlags, &(pd->u.bstrVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001470 break;
1471 case( VT_UI2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001472 res = VarBstrFromUI2( ps->u.uiVal, lcid, dwFlags, &(pd->u.bstrVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001473 break;
1474 case( VT_UINT ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001475 res = VarBstrFromUint( ps->u.uintVal, lcid, dwFlags, &(pd->u.bstrVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001476 break;
1477 case( VT_UI4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001478 res = VarBstrFromUI4( ps->u.ulVal, lcid, dwFlags, &(pd->u.bstrVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001479 break;
1480 case( VT_R4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001481 res = VarBstrFromR4( ps->u.fltVal, lcid, dwFlags, &(pd->u.bstrVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001482 break;
1483 case( VT_R8 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001484 res = VarBstrFromR8( ps->u.dblVal, lcid, dwFlags, &(pd->u.bstrVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001485 break;
1486 case( VT_DATE ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001487 res = VarBstrFromDate( ps->u.date, lcid, dwFlags, &(pd->u.bstrVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001488 break;
1489 case( VT_BOOL ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001490 res = VarBstrFromBool( ps->u.boolVal, lcid, dwFlags, &(pd->u.bstrVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001491 break;
1492 case( VT_BSTR ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001493 res = VariantCopy( pd, ps );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001494 break;
1495 case( VT_CY ):
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001496 /*res = VarBstrFromCy32( ps->u.cyVal, lcid, dwFlags, &(pd->u.bstrVal) );*/
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001497 case( VT_DISPATCH ):
1498 /*res = VarBstrFromDisp32( ps->u.pdispVal, lcid, lcid, dwFlags, &(pd->u.bstrVal) );*/
1499 case( VT_UNKNOWN ):
1500 /*res = VarBstrFrom32( ps->u.lVal, lcid, dwFlags, &(pd->u.bstrVal) );*/
1501 case( VT_DECIMAL ):
1502 /*res = VarBstrFromDec32( ps->u.deiVal, lcid, dwFlags, &(pd->u.bstrVal) );*/
1503 default:
1504 res = DISP_E_TYPEMISMATCH;
Alexandre Julliard359f497e1999-07-04 16:02:24 +00001505 FIXME("Coercion from %d to %d\n", vtFrom, vt );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001506 break;
1507 }
1508 break;
1509
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001510 case( VT_CY ):
1511 switch( vtFrom )
1512 {
1513 case( VT_I1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001514 res = VarCyFromI1( ps->u.cVal, &(pd->u.cyVal) );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001515 break;
1516 case( VT_I2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001517 res = VarCyFromI2( ps->u.iVal, &(pd->u.cyVal) );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001518 break;
1519 case( VT_INT ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001520 res = VarCyFromInt( ps->u.intVal, &(pd->u.cyVal) );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001521 break;
1522 case( VT_I4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001523 res = VarCyFromI4( ps->u.lVal, &(pd->u.cyVal) );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001524 break;
1525 case( VT_UI1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001526 res = VarCyFromUI1( ps->u.bVal, &(pd->u.cyVal) );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001527 break;
1528 case( VT_UI2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001529 res = VarCyFromUI2( ps->u.uiVal, &(pd->u.cyVal) );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001530 break;
1531 case( VT_UINT ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001532 res = VarCyFromUint( ps->u.uintVal, &(pd->u.cyVal) );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001533 break;
1534 case( VT_UI4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001535 res = VarCyFromUI4( ps->u.ulVal, &(pd->u.cyVal) );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001536 break;
1537 case( VT_R4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001538 res = VarCyFromR4( ps->u.fltVal, &(pd->u.cyVal) );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001539 break;
1540 case( VT_R8 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001541 res = VarCyFromR8( ps->u.dblVal, &(pd->u.cyVal) );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001542 break;
1543 case( VT_DATE ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001544 res = VarCyFromDate( ps->u.date, &(pd->u.cyVal) );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001545 break;
1546 case( VT_BOOL ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001547 res = VarCyFromBool( ps->u.date, &(pd->u.cyVal) );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001548 break;
1549 case( VT_CY ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001550 res = VariantCopy( pd, ps );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001551 break;
1552 case( VT_BSTR ):
1553 /*res = VarCyFromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.cyVal) );*/
1554 case( VT_DISPATCH ):
1555 /*res = VarCyFromDisp32( ps->u.pdispVal, lcid, &(pd->u.boolVal) );*/
1556 case( VT_UNKNOWN ):
1557 /*res = VarCyFrom32( ps->u.lVal, &(pd->u.boolVal) );*/
1558 case( VT_DECIMAL ):
1559 /*res = VarCyFromDec32( ps->u.deiVal, &(pd->u.boolVal) );*/
1560 default:
1561 res = DISP_E_TYPEMISMATCH;
Alexandre Julliard359f497e1999-07-04 16:02:24 +00001562 FIXME("Coercion from %d to %d\n", vtFrom, vt );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001563 break;
1564 }
1565 break;
1566
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001567 default:
1568 res = DISP_E_TYPEMISMATCH;
Alexandre Julliard359f497e1999-07-04 16:02:24 +00001569 FIXME("Coercion from %d to %d\n", vtFrom, vt );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001570 break;
1571 }
1572
1573 return res;
1574}
1575
1576/******************************************************************************
1577 * ValidateVtRange [INTERNAL]
1578 *
1579 * Used internally by the hi-level Variant API to determine
1580 * if the vartypes are valid.
1581 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00001582static HRESULT WINAPI ValidateVtRange( VARTYPE vt )
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001583{
1584 /* if by value we must make sure it is in the
1585 * range of the valid types.
1586 */
1587 if( ( vt & VT_TYPEMASK ) > VT_MAXVALIDTYPE )
1588 {
1589 return DISP_E_BADVARTYPE;
1590 }
1591 return S_OK;
1592}
1593
1594
1595/******************************************************************************
1596 * ValidateVartype [INTERNAL]
1597 *
1598 * Used internally by the hi-level Variant API to determine
1599 * if the vartypes are valid.
1600 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00001601static HRESULT WINAPI ValidateVariantType( VARTYPE vt )
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001602{
1603 HRESULT res = S_OK;
1604
1605 /* check if we have a valid argument.
1606 */
1607 if( vt & VT_BYREF )
1608 {
1609 /* if by reference check that the type is in
1610 * the valid range and that it is not of empty or null type
1611 */
1612 if( ( vt & VT_TYPEMASK ) == VT_EMPTY ||
1613 ( vt & VT_TYPEMASK ) == VT_NULL ||
1614 ( vt & VT_TYPEMASK ) > VT_MAXVALIDTYPE )
1615 {
1616 res = E_INVALIDARG;
1617 }
1618
1619 }
1620 else
1621 {
1622 res = ValidateVtRange( vt );
1623 }
1624
1625 return res;
1626}
1627
1628/******************************************************************************
1629 * ValidateVt [INTERNAL]
1630 *
1631 * Used internally by the hi-level Variant API to determine
1632 * if the vartypes are valid.
1633 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00001634static HRESULT WINAPI ValidateVt( VARTYPE vt )
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001635{
1636 HRESULT res = S_OK;
1637
1638 /* check if we have a valid argument.
1639 */
1640 if( vt & VT_BYREF )
1641 {
1642 /* if by reference check that the type is in
1643 * the valid range and that it is not of empty or null type
1644 */
1645 if( ( vt & VT_TYPEMASK ) == VT_EMPTY ||
1646 ( vt & VT_TYPEMASK ) == VT_NULL ||
1647 ( vt & VT_TYPEMASK ) > VT_MAXVALIDTYPE )
1648 {
1649 res = DISP_E_BADVARTYPE;
1650 }
1651
1652 }
1653 else
1654 {
1655 res = ValidateVtRange( vt );
1656 }
1657
1658 return res;
1659}
1660
1661
1662
1663
1664
1665/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001666 * VariantInit [OLEAUT32.8]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001667 *
1668 * Initializes the Variant. Unlike VariantClear it does not interpret the current
1669 * contents of the Variant.
1670 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001671void WINAPI VariantInit(VARIANTARG* pvarg)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001672{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00001673 TRACE("(%p),stub\n",pvarg);
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001674
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001675 memset(pvarg, 0, sizeof (VARIANTARG));
1676 pvarg->vt = VT_EMPTY;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001677
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001678 return;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001679}
1680
1681/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001682 * VariantClear [OLEAUT32.9]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001683 *
1684 * This function clears the VARIANT by setting the vt field to VT_EMPTY. It also
1685 * sets the wReservedX field to 0. The current contents of the VARIANT are
1686 * freed. If the vt is VT_BSTR the string is freed. If VT_DISPATCH the object is
1687 * released. If VT_ARRAY the array is freed.
1688 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001689HRESULT WINAPI VariantClear(VARIANTARG* pvarg)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001690{
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001691 HRESULT res = S_OK;
Alexandre Julliard359f497e1999-07-04 16:02:24 +00001692 TRACE("(%p)\n",pvarg);
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001693
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001694 res = ValidateVariantType( pvarg->vt );
1695 if( res == S_OK )
1696 {
1697 if( !( pvarg->vt & VT_BYREF ) )
1698 {
1699 /*
1700 * The VT_ARRAY flag is a special case of a safe array.
1701 */
1702 if ( (pvarg->vt & VT_ARRAY) != 0)
1703 {
1704 SafeArrayDestroy(pvarg->u.parray);
1705 }
1706 else
1707 {
1708 switch( pvarg->vt & VT_TYPEMASK )
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001709 {
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001710 case( VT_BSTR ):
1711 SysFreeString( pvarg->u.bstrVal );
1712 break;
1713 case( VT_DISPATCH ):
Owen Wang64b9d862000-02-18 19:14:29 +00001714 if(pvarg->u.pdispVal!=NULL)
1715 ICOM_CALL(Release,pvarg->u.pdispVal);
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001716 break;
1717 case( VT_VARIANT ):
Owen Wang64b9d862000-02-18 19:14:29 +00001718 VariantClear(pvarg->u.pvarVal);
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001719 break;
1720 case( VT_UNKNOWN ):
Owen Wang64b9d862000-02-18 19:14:29 +00001721 if(pvarg->u.punkVal!=NULL)
1722 ICOM_CALL(Release,pvarg->u.punkVal);
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001723 break;
1724 case( VT_SAFEARRAY ):
1725 SafeArrayDestroy(pvarg->u.parray);
1726 break;
1727 default:
1728 break;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001729 }
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001730 }
1731 }
1732
1733 /*
1734 * Empty all the fields and mark the type as empty.
1735 */
1736 memset(pvarg, 0, sizeof (VARIANTARG));
1737 pvarg->vt = VT_EMPTY;
1738 }
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001739
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001740 return res;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001741}
1742
1743/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001744 * VariantCopy [OLEAUT32.10]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001745 *
1746 * Frees up the designation variant and makes a copy of the source.
1747 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001748HRESULT WINAPI VariantCopy(VARIANTARG* pvargDest, VARIANTARG* pvargSrc)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001749{
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001750 HRESULT res = S_OK;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001751
Alexandre Julliard359f497e1999-07-04 16:02:24 +00001752 TRACE("(%p, %p)\n", pvargDest, pvargSrc);
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001753
1754 res = ValidateVariantType( pvargSrc->vt );
1755
1756 /* If the pointer are to the same variant we don't need
1757 * to do anything.
1758 */
1759 if( pvargDest != pvargSrc && res == S_OK )
1760 {
1761 res = VariantClear( pvargDest );
1762
1763 if( res == S_OK )
1764 {
1765 if( pvargSrc->vt & VT_BYREF )
1766 {
1767 /* In the case of byreference we only need
1768 * to copy the pointer.
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001769 */
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001770 pvargDest->u = pvargSrc->u;
1771 pvargDest->vt = pvargSrc->vt;
1772 }
1773 else
1774 {
1775 /*
1776 * The VT_ARRAY flag is another way to designate a safe array.
1777 */
1778 if (pvargSrc->vt & VT_ARRAY)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001779 {
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001780 SafeArrayCopy(pvargSrc->u.parray, &pvargDest->u.parray);
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001781 }
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001782 else
1783 {
1784 /* In the case of by value we need to
1785 * copy the actuall value. In the case of
1786 * VT_BSTR a copy of the string is made,
1787 * if VT_DISPATCH or VT_IUNKNOWN AddReff is
1788 * called to increment the object's reference count.
1789 */
1790 switch( pvargSrc->vt & VT_TYPEMASK )
1791 {
1792 case( VT_BSTR ):
1793 pvargDest->u.bstrVal = SysAllocString( pvargSrc->u.bstrVal );
1794 break;
1795 case( VT_DISPATCH ):
Owen Wang64b9d862000-02-18 19:14:29 +00001796 pvargDest->u.pdispVal = pvargSrc->u.pdispVal;
1797 if (pvargDest->u.pdispVal!=NULL)
1798 ICOM_CALL(AddRef,pvargDest->u.pdispVal);
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001799 break;
1800 case( VT_VARIANT ):
Owen Wang64b9d862000-02-18 19:14:29 +00001801 VariantCopy(pvargDest->u.pvarVal,pvargSrc->u.pvarVal);
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001802 break;
1803 case( VT_UNKNOWN ):
Owen Wang64b9d862000-02-18 19:14:29 +00001804 pvargDest->u.punkVal = pvargSrc->u.punkVal;
1805 if (pvargDest->u.pdispVal!=NULL)
1806 ICOM_CALL(AddRef,pvargDest->u.punkVal);
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001807 break;
1808 case( VT_SAFEARRAY ):
1809 SafeArrayCopy(pvargSrc->u.parray, &pvargDest->u.parray);
1810 break;
1811 default:
1812 pvargDest->u = pvargSrc->u;
1813 break;
1814 }
1815 }
1816
1817 pvargDest->vt = pvargSrc->vt;
1818 }
1819 }
1820 }
1821
1822 return res;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001823}
1824
1825
1826/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001827 * VariantCopyInd [OLEAUT32.11]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001828 *
1829 * Frees up the destination variant and makes a copy of the source. If
1830 * the source is of type VT_BYREF it performs the necessary indirections.
1831 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001832HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, VARIANTARG* pvargSrc)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001833{
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001834 HRESULT res = S_OK;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001835
Alexandre Julliard359f497e1999-07-04 16:02:24 +00001836 TRACE("(%p, %p)\n", pvargDest, pvargSrc);
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001837
1838 res = ValidateVariantType( pvargSrc->vt );
1839
1840 if( res != S_OK )
1841 return res;
1842
1843 if( pvargSrc->vt & VT_BYREF )
1844 {
1845 VARIANTARG varg;
1846 VariantInit( &varg );
1847
1848 /* handle the in place copy.
1849 */
1850 if( pvargDest == pvargSrc )
1851 {
1852 /* we will use a copy of the source instead.
1853 */
1854 res = VariantCopy( &varg, pvargSrc );
1855 pvargSrc = &varg;
1856 }
1857
1858 if( res == S_OK )
1859 {
1860 res = VariantClear( pvargDest );
1861
1862 if( res == S_OK )
1863 {
1864 /*
1865 * The VT_ARRAY flag is another way to designate a safearray variant.
1866 */
1867 if ( pvargSrc->vt & VT_ARRAY)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001868 {
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001869 SafeArrayCopy(*pvargSrc->u.pparray, &pvargDest->u.parray);
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001870 }
1871 else
1872 {
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001873 /* In the case of by reference we need
1874 * to copy the date pointed to by the variant.
1875 */
1876
1877 /* Get the variant type.
1878 */
1879 switch( pvargSrc->vt & VT_TYPEMASK )
1880 {
1881 case( VT_BSTR ):
1882 pvargDest->u.bstrVal = SysAllocString( *(pvargSrc->u.pbstrVal) );
1883 break;
1884 case( VT_DISPATCH ):
1885 break;
1886 case( VT_VARIANT ):
1887 {
1888 /* Prevent from cycling. According to tests on
1889 * VariantCopyInd in Windows and the documentation
1890 * this API dereferences the inner Variants to only one depth.
1891 * If the inner Variant itself contains an
1892 * other inner variant the E_INVALIDARG error is
1893 * returned.
1894 */
1895 if( pvargSrc->wReserved1 & PROCESSING_INNER_VARIANT )
1896 {
1897 /* If we get here we are attempting to deference
1898 * an inner variant that that is itself contained
1899 * in an inner variant so report E_INVALIDARG error.
1900 */
1901 res = E_INVALIDARG;
1902 }
1903 else
1904 {
1905 /* Set the processing inner variant flag.
1906 * We will set this flag in the inner variant
1907 * that will be passed to the VariantCopyInd function.
1908 */
1909 (pvargSrc->u.pvarVal)->wReserved1 |= PROCESSING_INNER_VARIANT;
1910
1911 /* Dereference the inner variant.
1912 */
1913 res = VariantCopyInd( pvargDest, pvargSrc->u.pvarVal );
Lawson Whitneya18fc8a2000-03-09 18:31:52 +00001914 /* We must also copy its type, I think.
1915 */
1916 pvargSrc->vt = pvargSrc->u.pvarVal->vt;
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001917 }
1918 }
1919 break;
1920 case( VT_UNKNOWN ):
1921 break;
1922 case( VT_SAFEARRAY ):
1923 SafeArrayCopy(*pvargSrc->u.pparray, &pvargDest->u.parray);
1924 break;
1925 default:
1926 /* This is a by reference Variant which means that the union
1927 * part of the Variant contains a pointer to some data of
1928 * type "pvargSrc->vt & VT_TYPEMASK".
1929 * We will deference this data in a generic fashion using
1930 * the void pointer "Variant.u.byref".
1931 * We will copy this data into the union of the destination
1932 * Variant.
1933 */
1934 memcpy( &pvargDest->u, pvargSrc->u.byref, SizeOfVariantData( pvargSrc ) );
1935 break;
1936 }
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001937 }
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001938
1939 pvargDest->vt = pvargSrc->vt & VT_TYPEMASK;
1940 }
1941 }
1942
1943 /* this should not fail.
1944 */
1945 VariantClear( &varg );
1946 }
1947 else
1948 {
1949 res = VariantCopy( pvargDest, pvargSrc );
1950 }
1951
1952 return res;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001953}
1954
1955/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001956 * VariantChangeType [OLEAUT32.12]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001957 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001958HRESULT WINAPI VariantChangeType(VARIANTARG* pvargDest, VARIANTARG* pvargSrc,
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001959 USHORT wFlags, VARTYPE vt)
1960{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001961 return VariantChangeTypeEx( pvargDest, pvargSrc, 0, wFlags, vt );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001962}
1963
1964/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00001965 * VariantChangeTypeEx [OLEAUT32.147]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001966 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001967HRESULT WINAPI VariantChangeTypeEx(VARIANTARG* pvargDest, VARIANTARG* pvargSrc,
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001968 LCID lcid, USHORT wFlags, VARTYPE vt)
1969{
1970 HRESULT res = S_OK;
1971 VARIANTARG varg;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001972 VariantInit( &varg );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001973
Alexandre Julliard359f497e1999-07-04 16:02:24 +00001974 TRACE("(%p, %p, %ld, %u, %u),stub\n", pvargDest, pvargSrc, lcid, wFlags, vt);
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001975
1976 /* validate our source argument.
1977 */
1978 res = ValidateVariantType( pvargSrc->vt );
1979
1980 /* validate the vartype.
1981 */
1982 if( res == S_OK )
1983 {
1984 res = ValidateVt( vt );
1985 }
1986
1987 /* if we are doing an in-place conversion make a copy of the source.
1988 */
1989 if( res == S_OK && pvargDest == pvargSrc )
1990 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001991 res = VariantCopy( &varg, pvargSrc );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001992 pvargSrc = &varg;
1993 }
1994
1995 if( res == S_OK )
1996 {
1997 /* free up the destination variant.
1998 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001999 res = VariantClear( pvargDest );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002000 }
2001
2002 if( res == S_OK )
2003 {
2004 if( pvargSrc->vt & VT_BYREF )
2005 {
2006 /* Convert the source variant to a "byvalue" variant.
2007 */
2008 VARIANTARG Variant;
Alexandre Julliarda3960291999-02-26 11:11:13 +00002009 VariantInit( &Variant );
2010 res = VariantCopyInd( &Variant, pvargSrc );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002011 if( res == S_OK )
2012 {
2013 res = Coerce( pvargDest, lcid, wFlags, &Variant, vt );
2014 /* this should not fail.
2015 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002016 VariantClear( &Variant );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002017 }
2018
2019 }
2020 else
2021 {
2022 /* Use the current "byvalue" source variant.
2023 */
2024 res = Coerce( pvargDest, lcid, wFlags, pvargSrc, vt );
2025 }
2026 }
2027 /* this should not fail.
2028 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002029 VariantClear( &varg );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002030
Stephane Lussier74517741999-03-19 16:44:32 +00002031 /* set the type of the destination
2032 */
2033 if ( res == S_OK )
2034 pvargDest->vt = vt;
2035
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002036 return res;
2037}
2038
2039
2040
2041
2042/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002043 * VarUI1FromI2 [OLEAUT32.130]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002044 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002045HRESULT WINAPI VarUI1FromI2(short sIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002046{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002047 TRACE("( %d, %p ), stub\n", sIn, pbOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002048
2049 /* Check range of value.
2050 */
2051 if( sIn < UI1_MIN || sIn > UI1_MAX )
2052 {
2053 return DISP_E_OVERFLOW;
2054 }
2055
2056 *pbOut = (BYTE) sIn;
2057
2058 return S_OK;
2059}
2060
2061/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002062 * VarUI1FromI4 [OLEAUT32.131]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002063 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002064HRESULT WINAPI VarUI1FromI4(LONG lIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002065{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002066 TRACE("( %ld, %p ), stub\n", lIn, pbOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002067
2068 /* Check range of value.
2069 */
2070 if( lIn < UI1_MIN || lIn > UI1_MAX )
2071 {
2072 return DISP_E_OVERFLOW;
2073 }
2074
2075 *pbOut = (BYTE) lIn;
2076
2077 return S_OK;
2078}
2079
2080
2081/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002082 * VarUI1FromR4 [OLEAUT32.132]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002083 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002084HRESULT WINAPI VarUI1FromR4(FLOAT fltIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002085{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002086 TRACE("( %f, %p ), stub\n", fltIn, pbOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002087
2088 /* Check range of value.
2089 */
2090 fltIn = round( fltIn );
2091 if( fltIn < UI1_MIN || fltIn > UI1_MAX )
2092 {
2093 return DISP_E_OVERFLOW;
2094 }
2095
2096 *pbOut = (BYTE) fltIn;
2097
2098 return S_OK;
2099}
2100
2101/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002102 * VarUI1FromR8 [OLEAUT32.133]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002103 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002104HRESULT WINAPI VarUI1FromR8(double dblIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002105{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002106 TRACE("( %f, %p ), stub\n", dblIn, pbOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002107
2108 /* Check range of value.
2109 */
2110 dblIn = round( dblIn );
2111 if( dblIn < UI1_MIN || dblIn > UI1_MAX )
2112 {
2113 return DISP_E_OVERFLOW;
2114 }
2115
2116 *pbOut = (BYTE) dblIn;
2117
2118 return S_OK;
2119}
2120
2121/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002122 * VarUI1FromDate [OLEAUT32.135]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002123 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002124HRESULT WINAPI VarUI1FromDate(DATE dateIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002125{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002126 TRACE("( %f, %p ), stub\n", dateIn, pbOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002127
2128 /* Check range of value.
2129 */
2130 dateIn = round( dateIn );
2131 if( dateIn < UI1_MIN || dateIn > UI1_MAX )
2132 {
2133 return DISP_E_OVERFLOW;
2134 }
2135
2136 *pbOut = (BYTE) dateIn;
2137
2138 return S_OK;
2139}
2140
2141/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002142 * VarUI1FromBool [OLEAUT32.138]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002143 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002144HRESULT WINAPI VarUI1FromBool(VARIANT_BOOL boolIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002145{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002146 TRACE("( %d, %p ), stub\n", boolIn, pbOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002147
2148 *pbOut = (BYTE) boolIn;
2149
2150 return S_OK;
2151}
2152
2153/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002154 * VarUI1FromI1 [OLEAUT32.237]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002155 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002156HRESULT WINAPI VarUI1FromI1(CHAR cIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002157{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002158 TRACE("( %c, %p ), stub\n", cIn, pbOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002159
2160 *pbOut = cIn;
2161
2162 return S_OK;
2163}
2164
2165/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002166 * VarUI1FromUI2 [OLEAUT32.238]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002167 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002168HRESULT WINAPI VarUI1FromUI2(USHORT uiIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002169{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002170 TRACE("( %d, %p ), stub\n", uiIn, pbOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002171
2172 /* Check range of value.
2173 */
2174 if( uiIn > UI1_MAX )
2175 {
2176 return DISP_E_OVERFLOW;
2177 }
2178
2179 *pbOut = (BYTE) uiIn;
2180
2181 return S_OK;
2182}
2183
2184/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002185 * VarUI1FromUI4 [OLEAUT32.239]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002186 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002187HRESULT WINAPI VarUI1FromUI4(ULONG ulIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002188{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002189 TRACE("( %ld, %p ), stub\n", ulIn, pbOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002190
2191 /* Check range of value.
2192 */
2193 if( ulIn > UI1_MAX )
2194 {
2195 return DISP_E_OVERFLOW;
2196 }
2197
2198 *pbOut = (BYTE) ulIn;
2199
2200 return S_OK;
2201}
2202
2203
2204/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002205 * VarUI1FromStr [OLEAUT32.54]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002206 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002207HRESULT WINAPI VarUI1FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002208{
2209 double dValue = 0.0;
2210 LPSTR pNewString = NULL;
2211
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002212 TRACE("( %p, 0x%08lx, 0x%08lx, %p ), stub\n", strIn, lcid, dwFlags, pbOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002213
2214 /* Check if we have a valid argument
2215 */
2216 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
2217 RemoveCharacterFromString( pNewString, "," );
2218 if( IsValidRealString( pNewString ) == FALSE )
2219 {
2220 return DISP_E_TYPEMISMATCH;
2221 }
2222
2223 /* Convert the valid string to a floating point number.
2224 */
2225 dValue = atof( pNewString );
2226
2227 /* We don't need the string anymore so free it.
2228 */
2229 HeapFree( GetProcessHeap(), 0 , pNewString );
2230
2231 /* Check range of value.
2232 */
2233 dValue = round( dValue );
2234 if( dValue < UI1_MIN || dValue > UI1_MAX )
2235 {
2236 return DISP_E_OVERFLOW;
2237 }
2238
2239 *pbOut = (BYTE) dValue;
2240
2241 return S_OK;
2242}
2243
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002244/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002245 * VarUI1FromCy [OLEAUT32.134]
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002246 * Convert currency to unsigned char
2247 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002248HRESULT WINAPI VarUI1FromCy(CY cyIn, BYTE* pbOut) {
Patrik Stridvall311e4561999-09-19 14:20:33 +00002249 double t = round((((double)cyIn.s.Hi * 4294967296.0) + (double)cyIn.s.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002250
2251 if (t > UI1_MAX || t < UI1_MIN) return DISP_E_OVERFLOW;
2252
2253 *pbOut = (BYTE)t;
2254 return S_OK;
2255}
2256
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002257/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002258 * VarI2FromUI1 [OLEAUT32.48]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002259 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002260HRESULT WINAPI VarI2FromUI1(BYTE bIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002261{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002262 TRACE("( 0x%08x, %p ), stub\n", bIn, psOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002263
2264 *psOut = (short) bIn;
2265
2266 return S_OK;
2267}
2268
2269/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002270 * VarI2FromI4 [OLEAUT32.49]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002271 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002272HRESULT WINAPI VarI2FromI4(LONG lIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002273{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002274 TRACE("( %lx, %p ), stub\n", lIn, psOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002275
2276 /* Check range of value.
2277 */
2278 if( lIn < I2_MIN || lIn > I2_MAX )
2279 {
2280 return DISP_E_OVERFLOW;
2281 }
2282
2283 *psOut = (short) lIn;
2284
2285 return S_OK;
2286}
2287
2288/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002289 * VarI2FromR4 [OLEAUT32.50]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002290 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002291HRESULT WINAPI VarI2FromR4(FLOAT fltIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002292{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002293 TRACE("( %f, %p ), stub\n", fltIn, psOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002294
2295 /* Check range of value.
2296 */
2297 fltIn = round( fltIn );
2298 if( fltIn < I2_MIN || fltIn > I2_MAX )
2299 {
2300 return DISP_E_OVERFLOW;
2301 }
2302
2303 *psOut = (short) fltIn;
2304
2305 return S_OK;
2306}
2307
2308/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002309 * VarI2FromR8 [OLEAUT32.51]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002310 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002311HRESULT WINAPI VarI2FromR8(double dblIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002312{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002313 TRACE("( %f, %p ), stub\n", dblIn, psOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002314
2315 /* Check range of value.
2316 */
2317 dblIn = round( dblIn );
2318 if( dblIn < I2_MIN || dblIn > I2_MAX )
2319 {
2320 return DISP_E_OVERFLOW;
2321 }
2322
2323 *psOut = (short) dblIn;
2324
2325 return S_OK;
2326}
2327
2328/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002329 * VarI2FromDate [OLEAUT32.53]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002330 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002331HRESULT WINAPI VarI2FromDate(DATE dateIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002332{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002333 TRACE("( %f, %p ), stub\n", dateIn, psOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002334
2335 /* Check range of value.
2336 */
2337 dateIn = round( dateIn );
2338 if( dateIn < I2_MIN || dateIn > I2_MAX )
2339 {
2340 return DISP_E_OVERFLOW;
2341 }
2342
2343 *psOut = (short) dateIn;
2344
2345 return S_OK;
2346}
2347
2348/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002349 * VarI2FromBool [OLEAUT32.56]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002350 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002351HRESULT WINAPI VarI2FromBool(VARIANT_BOOL boolIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002352{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002353 TRACE("( %d, %p ), stub\n", boolIn, psOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002354
2355 *psOut = (short) boolIn;
2356
2357 return S_OK;
2358}
2359
2360/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002361 * VarI2FromI1 [OLEAUT32.48]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002362 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002363HRESULT WINAPI VarI2FromI1(CHAR cIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002364{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002365 TRACE("( %c, %p ), stub\n", cIn, psOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002366
2367 *psOut = (short) cIn;
2368
2369 return S_OK;
2370}
2371
2372/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002373 * VarI2FromUI2 [OLEAUT32.206]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002374 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002375HRESULT WINAPI VarI2FromUI2(USHORT uiIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002376{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002377 TRACE("( %d, %p ), stub\n", uiIn, psOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002378
2379 /* Check range of value.
2380 */
2381 if( uiIn > I2_MAX )
2382 {
2383 return DISP_E_OVERFLOW;
2384 }
2385
2386 *psOut = (short) uiIn;
2387
2388 return S_OK;
2389}
2390
2391/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002392 * VarI2FromUI4 [OLEAUT32.49]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002393 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002394HRESULT WINAPI VarI2FromUI4(ULONG ulIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002395{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002396 TRACE("( %lx, %p ), stub\n", ulIn, psOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002397
2398 /* Check range of value.
2399 */
2400 if( ulIn < I2_MIN || ulIn > I2_MAX )
2401 {
2402 return DISP_E_OVERFLOW;
2403 }
2404
2405 *psOut = (short) ulIn;
2406
2407 return S_OK;
2408}
2409
2410/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002411 * VarI2FromStr [OLEAUT32.54]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002412 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002413HRESULT WINAPI VarI2FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002414{
2415 double dValue = 0.0;
2416 LPSTR pNewString = NULL;
2417
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002418 TRACE("( %p, 0x%08lx, 0x%08lx, %p ), stub\n", strIn, lcid, dwFlags, psOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002419
2420 /* Check if we have a valid argument
2421 */
2422 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
2423 RemoveCharacterFromString( pNewString, "," );
2424 if( IsValidRealString( pNewString ) == FALSE )
2425 {
2426 return DISP_E_TYPEMISMATCH;
2427 }
2428
2429 /* Convert the valid string to a floating point number.
2430 */
2431 dValue = atof( pNewString );
2432
2433 /* We don't need the string anymore so free it.
2434 */
2435 HeapFree( GetProcessHeap(), 0, pNewString );
2436
2437 /* Check range of value.
2438 */
2439 dValue = round( dValue );
2440 if( dValue < I2_MIN || dValue > I2_MAX )
2441 {
2442 return DISP_E_OVERFLOW;
2443 }
2444
2445 *psOut = (short) dValue;
2446
2447 return S_OK;
2448}
2449
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002450/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002451 * VarI2FromCy [OLEAUT32.52]
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002452 * Convert currency to signed short
2453 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002454HRESULT WINAPI VarI2FromCy(CY cyIn, short* psOut) {
Patrik Stridvall311e4561999-09-19 14:20:33 +00002455 double t = round((((double)cyIn.s.Hi * 4294967296.0) + (double)cyIn.s.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002456
2457 if (t > I2_MAX || t < I2_MIN) return DISP_E_OVERFLOW;
2458
2459 *psOut = (SHORT)t;
2460 return S_OK;
2461}
2462
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002463/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002464 * VarI4FromUI1 [OLEAUT32.58]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002465 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002466HRESULT WINAPI VarI4FromUI1(BYTE bIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002467{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002468 TRACE("( %X, %p ), stub\n", bIn, plOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002469
2470 *plOut = (LONG) bIn;
2471
2472 return S_OK;
2473}
2474
2475
2476/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002477 * VarI4FromR4 [OLEAUT32.60]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002478 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002479HRESULT WINAPI VarI4FromR4(FLOAT fltIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002480{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002481 TRACE("( %f, %p ), stub\n", fltIn, plOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002482
2483 /* Check range of value.
2484 */
2485 fltIn = round( fltIn );
2486 if( fltIn < I4_MIN || fltIn > I4_MAX )
2487 {
2488 return DISP_E_OVERFLOW;
2489 }
2490
2491 *plOut = (LONG) fltIn;
2492
2493 return S_OK;
2494}
2495
2496/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002497 * VarI4FromR8 [OLEAUT32.61]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002498 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002499HRESULT WINAPI VarI4FromR8(double dblIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002500{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002501 TRACE("( %f, %p ), stub\n", dblIn, plOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002502
2503 /* Check range of value.
2504 */
2505 dblIn = round( dblIn );
2506 if( dblIn < I4_MIN || dblIn > I4_MAX )
2507 {
2508 return DISP_E_OVERFLOW;
2509 }
2510
2511 *plOut = (LONG) dblIn;
2512
2513 return S_OK;
2514}
2515
2516/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002517 * VarI4FromDate [OLEAUT32.63]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002518 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002519HRESULT WINAPI VarI4FromDate(DATE dateIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002520{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002521 TRACE("( %f, %p ), stub\n", dateIn, plOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002522
2523 /* Check range of value.
2524 */
2525 dateIn = round( dateIn );
2526 if( dateIn < I4_MIN || dateIn > I4_MAX )
2527 {
2528 return DISP_E_OVERFLOW;
2529 }
2530
2531 *plOut = (LONG) dateIn;
2532
2533 return S_OK;
2534}
2535
2536/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002537 * VarI4FromBool [OLEAUT32.66]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002538 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002539HRESULT WINAPI VarI4FromBool(VARIANT_BOOL boolIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002540{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002541 TRACE("( %d, %p ), stub\n", boolIn, plOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002542
2543 *plOut = (LONG) boolIn;
2544
2545 return S_OK;
2546}
2547
2548/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002549 * VarI4FromI1 [OLEAUT32.209]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002550 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002551HRESULT WINAPI VarI4FromI1(CHAR cIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002552{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002553 TRACE("( %c, %p ), stub\n", cIn, plOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002554
2555 *plOut = (LONG) cIn;
2556
2557 return S_OK;
2558}
2559
2560/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002561 * VarI4FromUI2 [OLEAUT32.210]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002562 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002563HRESULT WINAPI VarI4FromUI2(USHORT uiIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002564{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002565 TRACE("( %d, %p ), stub\n", uiIn, plOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002566
2567 *plOut = (LONG) uiIn;
2568
2569 return S_OK;
2570}
2571
2572/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002573 * VarI4FromUI4 [OLEAUT32.211]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002574 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002575HRESULT WINAPI VarI4FromUI4(ULONG ulIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002576{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002577 TRACE("( %lx, %p ), stub\n", ulIn, plOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002578
2579 /* Check range of value.
2580 */
2581 if( ulIn < I4_MIN || ulIn > I4_MAX )
2582 {
2583 return DISP_E_OVERFLOW;
2584 }
2585
2586 *plOut = (LONG) ulIn;
2587
2588 return S_OK;
2589}
2590
2591/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002592 * VarI4FromI2 [OLEAUT32.59]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002593 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002594HRESULT WINAPI VarI4FromI2(short sIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002595{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002596 TRACE("( %d, %p ), stub\n", sIn, plOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002597
2598 *plOut = (LONG) sIn;
2599
2600 return S_OK;
2601}
2602
2603/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002604 * VarI4FromStr [OLEAUT32.64]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002605 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002606HRESULT WINAPI VarI4FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002607{
2608 double dValue = 0.0;
2609 LPSTR pNewString = NULL;
2610
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002611 TRACE("( %p, 0x%08lx, 0x%08lx, %p ), stub\n", strIn, lcid, dwFlags, plOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002612
2613 /* Check if we have a valid argument
2614 */
2615 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
2616 RemoveCharacterFromString( pNewString, "," );
2617 if( IsValidRealString( pNewString ) == FALSE )
2618 {
2619 return DISP_E_TYPEMISMATCH;
2620 }
2621
2622 /* Convert the valid string to a floating point number.
2623 */
2624 dValue = atof( pNewString );
2625
2626 /* We don't need the string anymore so free it.
2627 */
2628 HeapFree( GetProcessHeap(), 0, pNewString );
2629
2630 /* Check range of value.
2631 */
2632 dValue = round( dValue );
2633 if( dValue < I4_MIN || dValue > I4_MAX )
2634 {
2635 return DISP_E_OVERFLOW;
2636 }
2637
2638 *plOut = (LONG) dValue;
2639
2640 return S_OK;
2641}
2642
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002643/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002644 * VarI4FromCy [OLEAUT32.62]
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002645 * Convert currency to signed long
2646 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002647HRESULT WINAPI VarI4FromCy(CY cyIn, LONG* plOut) {
Patrik Stridvall311e4561999-09-19 14:20:33 +00002648 double t = round((((double)cyIn.s.Hi * 4294967296.0) + (double)cyIn.s.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002649
2650 if (t > I4_MAX || t < I4_MIN) return DISP_E_OVERFLOW;
2651
2652 *plOut = (LONG)t;
2653 return S_OK;
2654}
2655
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002656/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002657 * VarR4FromUI1 [OLEAUT32.68]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002658 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002659HRESULT WINAPI VarR4FromUI1(BYTE bIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002660{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002661 TRACE("( %X, %p ), stub\n", bIn, pfltOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002662
2663 *pfltOut = (FLOAT) bIn;
2664
2665 return S_OK;
2666}
2667
2668/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002669 * VarR4FromI2 [OLEAUT32.69]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002670 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002671HRESULT WINAPI VarR4FromI2(short sIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002672{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002673 TRACE("( %d, %p ), stub\n", sIn, pfltOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002674
2675 *pfltOut = (FLOAT) sIn;
2676
2677 return S_OK;
2678}
2679
2680/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002681 * VarR4FromI4 [OLEAUT32.70]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002682 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002683HRESULT WINAPI VarR4FromI4(LONG lIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002684{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002685 TRACE("( %lx, %p ), stub\n", lIn, pfltOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002686
2687 *pfltOut = (FLOAT) lIn;
2688
2689 return S_OK;
2690}
2691
2692/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002693 * VarR4FromR8 [OLEAUT32.71]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002694 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002695HRESULT WINAPI VarR4FromR8(double dblIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002696{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002697 TRACE("( %f, %p ), stub\n", dblIn, pfltOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002698
2699 /* Check range of value.
2700 */
2701 if( dblIn < -(FLT_MAX) || dblIn > FLT_MAX )
2702 {
2703 return DISP_E_OVERFLOW;
2704 }
2705
2706 *pfltOut = (FLOAT) dblIn;
2707
2708 return S_OK;
2709}
2710
2711/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002712 * VarR4FromDate [OLEAUT32.73]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002713 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002714HRESULT WINAPI VarR4FromDate(DATE dateIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002715{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002716 TRACE("( %f, %p ), stub\n", dateIn, pfltOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002717
2718 /* Check range of value.
2719 */
2720 if( dateIn < -(FLT_MAX) || dateIn > FLT_MAX )
2721 {
2722 return DISP_E_OVERFLOW;
2723 }
2724
2725 *pfltOut = (FLOAT) dateIn;
2726
2727 return S_OK;
2728}
2729
2730/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002731 * VarR4FromBool [OLEAUT32.76]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002732 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002733HRESULT WINAPI VarR4FromBool(VARIANT_BOOL boolIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002734{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002735 TRACE("( %d, %p ), stub\n", boolIn, pfltOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002736
2737 *pfltOut = (FLOAT) boolIn;
2738
2739 return S_OK;
2740}
2741
2742/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002743 * VarR4FromI1 [OLEAUT32.213]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002744 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002745HRESULT WINAPI VarR4FromI1(CHAR cIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002746{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002747 TRACE("( %c, %p ), stub\n", cIn, pfltOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002748
2749 *pfltOut = (FLOAT) cIn;
2750
2751 return S_OK;
2752}
2753
2754/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002755 * VarR4FromUI2 [OLEAUT32.214]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002756 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002757HRESULT WINAPI VarR4FromUI2(USHORT uiIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002758{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002759 TRACE("( %d, %p ), stub\n", uiIn, pfltOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002760
2761 *pfltOut = (FLOAT) uiIn;
2762
2763 return S_OK;
2764}
2765
2766/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002767 * VarR4FromUI4 [OLEAUT32.215]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002768 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002769HRESULT WINAPI VarR4FromUI4(ULONG ulIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002770{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002771 TRACE("( %ld, %p ), stub\n", ulIn, pfltOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002772
2773 *pfltOut = (FLOAT) ulIn;
2774
2775 return S_OK;
2776}
2777
2778/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002779 * VarR4FromStr [OLEAUT32.74]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002780 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002781HRESULT WINAPI VarR4FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002782{
2783 double dValue = 0.0;
2784 LPSTR pNewString = NULL;
2785
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002786 TRACE("( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, pfltOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002787
2788 /* Check if we have a valid argument
2789 */
2790 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
2791 RemoveCharacterFromString( pNewString, "," );
2792 if( IsValidRealString( pNewString ) == FALSE )
2793 {
2794 return DISP_E_TYPEMISMATCH;
2795 }
2796
2797 /* Convert the valid string to a floating point number.
2798 */
2799 dValue = atof( pNewString );
2800
2801 /* We don't need the string anymore so free it.
2802 */
2803 HeapFree( GetProcessHeap(), 0, pNewString );
2804
2805 /* Check range of value.
2806 */
2807 if( dValue < -(FLT_MAX) || dValue > FLT_MAX )
2808 {
2809 return DISP_E_OVERFLOW;
2810 }
2811
2812 *pfltOut = (FLOAT) dValue;
2813
2814 return S_OK;
2815}
2816
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002817/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002818 * VarR4FromCy [OLEAUT32.72]
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002819 * Convert currency to float
2820 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002821HRESULT WINAPI VarR4FromCy(CY cyIn, FLOAT* pfltOut) {
Patrik Stridvall311e4561999-09-19 14:20:33 +00002822 *pfltOut = (FLOAT)((((double)cyIn.s.Hi * 4294967296.0) + (double)cyIn.s.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002823
2824 return S_OK;
2825}
2826
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002827/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002828 * VarR8FromUI1 [OLEAUT32.68]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002829 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002830HRESULT WINAPI VarR8FromUI1(BYTE bIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002831{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002832 TRACE("( %d, %p ), stub\n", bIn, pdblOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002833
2834 *pdblOut = (double) bIn;
2835
2836 return S_OK;
2837}
2838
2839/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002840 * VarR8FromI2 [OLEAUT32.69]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002841 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002842HRESULT WINAPI VarR8FromI2(short sIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002843{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002844 TRACE("( %d, %p ), stub\n", sIn, pdblOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002845
2846 *pdblOut = (double) sIn;
2847
2848 return S_OK;
2849}
2850
2851/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002852 * VarR8FromI4 [OLEAUT32.70]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002853 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002854HRESULT WINAPI VarR8FromI4(LONG lIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002855{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002856 TRACE("( %ld, %p ), stub\n", lIn, pdblOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002857
2858 *pdblOut = (double) lIn;
2859
2860 return S_OK;
2861}
2862
2863/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002864 * VarR8FromR4 [OLEAUT32.81]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002865 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002866HRESULT WINAPI VarR8FromR4(FLOAT fltIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002867{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002868 TRACE("( %f, %p ), stub\n", fltIn, pdblOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002869
2870 *pdblOut = (double) fltIn;
2871
2872 return S_OK;
2873}
2874
2875/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002876 * VarR8FromDate [OLEAUT32.83]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002877 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002878HRESULT WINAPI VarR8FromDate(DATE dateIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002879{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002880 TRACE("( %f, %p ), stub\n", dateIn, pdblOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002881
2882 *pdblOut = (double) dateIn;
2883
2884 return S_OK;
2885}
2886
2887/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002888 * VarR8FromBool [OLEAUT32.86]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002889 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002890HRESULT WINAPI VarR8FromBool(VARIANT_BOOL boolIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002891{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002892 TRACE("( %d, %p ), stub\n", boolIn, pdblOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002893
2894 *pdblOut = (double) boolIn;
2895
2896 return S_OK;
2897}
2898
2899/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002900 * VarR8FromI1 [OLEAUT32.217]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002901 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002902HRESULT WINAPI VarR8FromI1(CHAR cIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002903{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002904 TRACE("( %c, %p ), stub\n", cIn, pdblOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002905
2906 *pdblOut = (double) cIn;
2907
2908 return S_OK;
2909}
2910
2911/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002912 * VarR8FromUI2 [OLEAUT32.218]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002913 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002914HRESULT WINAPI VarR8FromUI2(USHORT uiIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002915{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002916 TRACE("( %d, %p ), stub\n", uiIn, pdblOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002917
2918 *pdblOut = (double) uiIn;
2919
2920 return S_OK;
2921}
2922
2923/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002924 * VarR8FromUI4 [OLEAUT32.219]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002925 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002926HRESULT WINAPI VarR8FromUI4(ULONG ulIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002927{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002928 TRACE("( %ld, %p ), stub\n", ulIn, pdblOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002929
2930 *pdblOut = (double) ulIn;
2931
2932 return S_OK;
2933}
2934
2935/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002936 * VarR8FromStr [OLEAUT32.84]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002937 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002938HRESULT WINAPI VarR8FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002939{
2940 double dValue = 0.0;
2941 LPSTR pNewString = NULL;
2942
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002943 TRACE("( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, pdblOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002944
2945 /* Check if we have a valid argument
2946 */
2947 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
2948 RemoveCharacterFromString( pNewString, "," );
2949 if( IsValidRealString( pNewString ) == FALSE )
2950 {
2951 return DISP_E_TYPEMISMATCH;
2952 }
2953
2954 /* Convert the valid string to a floating point number.
2955 */
2956 dValue = atof( pNewString );
2957
2958 /* We don't need the string anymore so free it.
2959 */
2960 HeapFree( GetProcessHeap(), 0, pNewString );
2961
2962 *pdblOut = dValue;
2963
2964 return S_OK;
2965}
2966
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002967/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002968 * VarR8FromCy [OLEAUT32.82]
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002969 * Convert currency to double
2970 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002971HRESULT WINAPI VarR8FromCy(CY cyIn, double* pdblOut) {
Patrik Stridvall311e4561999-09-19 14:20:33 +00002972 *pdblOut = (double)((((double)cyIn.s.Hi * 4294967296.0) + (double)cyIn.s.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002973
2974 return S_OK;
2975}
2976
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002977/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002978 * VarDateFromUI1 [OLEAUT32.]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002979 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002980HRESULT WINAPI VarDateFromUI1(BYTE bIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002981{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002982 TRACE("( %d, %p ), stub\n", bIn, pdateOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002983
2984 *pdateOut = (DATE) bIn;
2985
2986 return S_OK;
2987}
2988
2989/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00002990 * VarDateFromI2 [OLEAUT32.222]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002991 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002992HRESULT WINAPI VarDateFromI2(short sIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002993{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00002994 TRACE("( %d, %p ), stub\n", sIn, pdateOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002995
2996 *pdateOut = (DATE) sIn;
2997
2998 return S_OK;
2999}
3000
3001/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003002 * VarDateFromI4 [OLEAUT32.90]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003003 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003004HRESULT WINAPI VarDateFromI4(LONG lIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003005{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003006 TRACE("( %ld, %p ), stub\n", lIn, pdateOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003007
3008 if( lIn < DATE_MIN || lIn > DATE_MAX )
3009 {
3010 return DISP_E_OVERFLOW;
3011 }
3012
3013 *pdateOut = (DATE) lIn;
3014
3015 return S_OK;
3016}
3017
3018/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003019 * VarDateFromR4 [OLEAUT32.91]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003020 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003021HRESULT WINAPI VarDateFromR4(FLOAT fltIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003022{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003023 TRACE("( %f, %p ), stub\n", fltIn, pdateOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003024
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +00003025 if( ceil(fltIn) < DATE_MIN || floor(fltIn) > DATE_MAX )
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003026 {
3027 return DISP_E_OVERFLOW;
3028 }
3029
3030 *pdateOut = (DATE) fltIn;
3031
3032 return S_OK;
3033}
3034
3035/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003036 * VarDateFromR8 [OLEAUT32.92]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003037 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003038HRESULT WINAPI VarDateFromR8(double dblIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003039{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003040 TRACE("( %f, %p ), stub\n", dblIn, pdateOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003041
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +00003042 if( ceil(dblIn) < DATE_MIN || floor(dblIn) > DATE_MAX )
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003043 {
3044 return DISP_E_OVERFLOW;
3045 }
3046
3047 *pdateOut = (DATE) dblIn;
3048
3049 return S_OK;
3050}
3051
3052/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003053 * VarDateFromStr [OLEAUT32.94]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003054 * The string representing the date is composed of two parts, a date and time.
3055 *
3056 * The format of the time is has follows:
3057 * hh[:mm][:ss][AM|PM]
3058 * Whitespace can be inserted anywhere between these tokens. A whitespace consists
3059 * of space and/or tab characters, which are ignored.
3060 *
3061 * The formats for the date part are has follows:
3062 * mm/[dd/][yy]yy
3063 * [dd/]mm/[yy]yy
3064 * [yy]yy/mm/dd
3065 * January dd[,] [yy]yy
3066 * dd January [yy]yy
3067 * [yy]yy January dd
3068 * Whitespace can be inserted anywhere between these tokens.
3069 *
3070 * The formats for the date and time string are has follows.
3071 * date[whitespace][time]
3072 * [time][whitespace]date
3073 *
3074 * These are the only characters allowed in a string representing a date and time:
3075 * [A-Z] [a-z] [0-9] ':' '-' '/' ',' ' ' '\t'
3076 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003077HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003078{
Alexandre Julliard908464d2000-11-01 03:11:12 +00003079 HRESULT ret = S_OK;
3080 struct tm TM;
3081
3082 memset( &TM, 0, sizeof(TM) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003083
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003084 TRACE("( %p, %lx, %lx, %p ), stub\n", strIn, lcid, dwFlags, pdateOut );
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +00003085
3086 if( DateTimeStringToTm( strIn, lcid, &TM ) )
3087 {
3088 if( TmToDATE( &TM, pdateOut ) == FALSE )
3089 {
3090 ret = E_INVALIDARG;
3091 }
3092 }
3093 else
3094 {
3095 ret = DISP_E_TYPEMISMATCH;
3096 }
3097
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003098
3099 return ret;
3100}
3101
3102/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003103 * VarDateFromI1 [OLEAUT32.221]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003104 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003105HRESULT WINAPI VarDateFromI1(CHAR cIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003106{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003107 TRACE("( %c, %p ), stub\n", cIn, pdateOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003108
3109 *pdateOut = (DATE) cIn;
3110
3111 return S_OK;
3112}
3113
3114/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003115 * VarDateFromUI2 [OLEAUT32.222]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003116 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003117HRESULT WINAPI VarDateFromUI2(USHORT uiIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003118{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003119 TRACE("( %d, %p ), stub\n", uiIn, pdateOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003120
3121 if( uiIn > DATE_MAX )
3122 {
3123 return DISP_E_OVERFLOW;
3124 }
3125
3126 *pdateOut = (DATE) uiIn;
3127
3128 return S_OK;
3129}
3130
3131/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003132 * VarDateFromUI4 [OLEAUT32.223]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003133 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003134HRESULT WINAPI VarDateFromUI4(ULONG ulIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003135{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003136 TRACE("( %ld, %p ), stub\n", ulIn, pdateOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003137
3138 if( ulIn < DATE_MIN || ulIn > DATE_MAX )
3139 {
3140 return DISP_E_OVERFLOW;
3141 }
3142
3143 *pdateOut = (DATE) ulIn;
3144
3145 return S_OK;
3146}
3147
3148/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003149 * VarDateFromBool [OLEAUT32.96]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003150 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003151HRESULT WINAPI VarDateFromBool(VARIANT_BOOL boolIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003152{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003153 TRACE("( %d, %p ), stub\n", boolIn, pdateOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003154
3155 *pdateOut = (DATE) boolIn;
3156
3157 return S_OK;
3158}
3159
Justin Bradfordbc93bc81998-12-11 14:02:16 +00003160/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003161 * VarDateFromCy [OLEAUT32.93]
Justin Bradfordbc93bc81998-12-11 14:02:16 +00003162 * Convert currency to date
3163 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003164HRESULT WINAPI VarDateFromCy(CY cyIn, DATE* pdateOut) {
Patrik Stridvall311e4561999-09-19 14:20:33 +00003165 *pdateOut = (DATE)((((double)cyIn.s.Hi * 4294967296.0) + (double)cyIn.s.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00003166
3167 if (*pdateOut > DATE_MAX || *pdateOut < DATE_MIN) return DISP_E_TYPEMISMATCH;
3168 return S_OK;
3169}
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003170
3171/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003172 * VarBstrFromUI1 [OLEAUT32.108]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003173 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003174HRESULT WINAPI VarBstrFromUI1(BYTE bVal, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003175{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003176 TRACE("( %d, %ld, %ld, %p ), stub\n", bVal, lcid, dwFlags, pbstrOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003177 sprintf( pBuffer, "%d", bVal );
3178
3179 *pbstrOut = StringDupAtoBstr( pBuffer );
3180
3181 return S_OK;
3182}
3183
3184/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003185 * VarBstrFromI2 [OLEAUT32.109]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003186 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003187HRESULT WINAPI VarBstrFromI2(short iVal, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003188{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003189 TRACE("( %d, %ld, %ld, %p ), stub\n", iVal, lcid, dwFlags, pbstrOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003190 sprintf( pBuffer, "%d", iVal );
3191 *pbstrOut = StringDupAtoBstr( pBuffer );
3192
3193 return S_OK;
3194}
3195
3196/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003197 * VarBstrFromI4 [OLEAUT32.110]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003198 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003199HRESULT WINAPI VarBstrFromI4(LONG lIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003200{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003201 TRACE("( %ld, %ld, %ld, %p ), stub\n", lIn, lcid, dwFlags, pbstrOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003202
3203 sprintf( pBuffer, "%ld", lIn );
3204 *pbstrOut = StringDupAtoBstr( pBuffer );
3205
3206 return S_OK;
3207}
3208
3209/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003210 * VarBstrFromR4 [OLEAUT32.111]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003211 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003212HRESULT WINAPI VarBstrFromR4(FLOAT fltIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003213{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003214 TRACE("( %f, %ld, %ld, %p ), stub\n", fltIn, lcid, dwFlags, pbstrOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003215
3216 sprintf( pBuffer, "%.7g", fltIn );
3217 *pbstrOut = StringDupAtoBstr( pBuffer );
3218
3219 return S_OK;
3220}
3221
3222/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003223 * VarBstrFromR8 [OLEAUT32.112]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003224 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003225HRESULT WINAPI VarBstrFromR8(double dblIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003226{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003227 TRACE("( %f, %ld, %ld, %p ), stub\n", dblIn, lcid, dwFlags, pbstrOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003228
3229 sprintf( pBuffer, "%.15g", dblIn );
3230 *pbstrOut = StringDupAtoBstr( pBuffer );
3231
3232 return S_OK;
3233}
3234
3235/******************************************************************************
Alexandre Julliardf80b2ab1999-03-28 13:15:40 +00003236 * VarBstrFromCy [OLEAUT32.113]
3237 */
3238HRESULT WINAPI VarBstrFromCy(CY cyIn, LCID lcid, ULONG dwFlags, BSTR *pbstrOut) {
3239 /* FIXME */
3240 return E_NOTIMPL;
3241}
3242
3243
3244/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003245 * VarBstrFromDate [OLEAUT32.114]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003246 *
3247 * The date is implemented using an 8 byte floating-point number.
Francois Gougetcd8d1812001-05-18 21:01:38 +00003248 * Days are represented by whole numbers increments starting with 0.00 as
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003249 * being December 30 1899, midnight.
3250 * The hours are expressed as the fractional part of the number.
3251 * December 30 1899 at midnight = 0.00
3252 * January 1 1900 at midnight = 2.00
3253 * January 4 1900 at 6 AM = 5.25
3254 * January 4 1900 at noon = 5.50
3255 * December 29 1899 at midnight = -1.00
3256 * December 18 1899 at midnight = -12.00
3257 * December 18 1899 at 6AM = -12.25
3258 * December 18 1899 at 6PM = -12.75
3259 * December 19 1899 at midnight = -11.00
3260 * The tm structure is as follows:
3261 * struct tm {
3262 * int tm_sec; seconds after the minute - [0,59]
3263 * int tm_min; minutes after the hour - [0,59]
3264 * int tm_hour; hours since midnight - [0,23]
3265 * int tm_mday; day of the month - [1,31]
3266 * int tm_mon; months since January - [0,11]
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +00003267 * int tm_year; years
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003268 * int tm_wday; days since Sunday - [0,6]
3269 * int tm_yday; days since January 1 - [0,365]
3270 * int tm_isdst; daylight savings time flag
3271 * };
3272 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003273HRESULT WINAPI VarBstrFromDate(DATE dateIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003274{
Alexandre Julliard908464d2000-11-01 03:11:12 +00003275 struct tm TM;
3276 memset( &TM, 0, sizeof(TM) );
3277
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003278 TRACE("( %f, %ld, %ld, %p ), stub\n", dateIn, lcid, dwFlags, pbstrOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003279
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +00003280 if( DateToTm( dateIn, lcid, &TM ) == FALSE )
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003281 {
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +00003282 return E_INVALIDARG;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003283 }
3284
Owen Wang64b9d862000-02-18 19:14:29 +00003285 if( dwFlags & VAR_DATEVALUEONLY )
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003286 strftime( pBuffer, BUFFER_MAX, "%x", &TM );
Owen Wang64b9d862000-02-18 19:14:29 +00003287 else if( dwFlags & VAR_TIMEVALUEONLY )
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003288 strftime( pBuffer, BUFFER_MAX, "%X", &TM );
3289 else
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +00003290 strftime( pBuffer, BUFFER_MAX, "%x %X", &TM );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003291
3292 *pbstrOut = StringDupAtoBstr( pBuffer );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003293
3294 return S_OK;
3295}
3296
3297/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003298 * VarBstrFromBool [OLEAUT32.116]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003299 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003300HRESULT WINAPI VarBstrFromBool(VARIANT_BOOL boolIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003301{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003302 TRACE("( %d, %ld, %ld, %p ), stub\n", boolIn, lcid, dwFlags, pbstrOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003303
3304 if( boolIn == VARIANT_FALSE )
3305 {
3306 sprintf( pBuffer, "False" );
3307 }
3308 else
3309 {
3310 sprintf( pBuffer, "True" );
3311 }
3312
3313 *pbstrOut = StringDupAtoBstr( pBuffer );
3314
3315 return S_OK;
3316}
3317
3318/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003319 * VarBstrFromI1 [OLEAUT32.229]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003320 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003321HRESULT WINAPI VarBstrFromI1(CHAR cIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003322{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003323 TRACE("( %c, %ld, %ld, %p ), stub\n", cIn, lcid, dwFlags, pbstrOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003324 sprintf( pBuffer, "%d", cIn );
3325 *pbstrOut = StringDupAtoBstr( pBuffer );
3326
3327 return S_OK;
3328}
3329
3330/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003331 * VarBstrFromUI2 [OLEAUT32.230]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003332 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003333HRESULT WINAPI VarBstrFromUI2(USHORT uiIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003334{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003335 TRACE("( %d, %ld, %ld, %p ), stub\n", uiIn, lcid, dwFlags, pbstrOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003336 sprintf( pBuffer, "%d", uiIn );
3337 *pbstrOut = StringDupAtoBstr( pBuffer );
3338
3339 return S_OK;
3340}
3341
3342/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003343 * VarBstrFromUI4 [OLEAUT32.231]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003344 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003345HRESULT WINAPI VarBstrFromUI4(ULONG ulIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003346{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003347 TRACE("( %ld, %ld, %ld, %p ), stub\n", ulIn, lcid, dwFlags, pbstrOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003348 sprintf( pBuffer, "%ld", ulIn );
3349 *pbstrOut = StringDupAtoBstr( pBuffer );
3350
3351 return S_OK;
3352}
3353
3354/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003355 * VarBoolFromUI1 [OLEAUT32.118]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003356 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003357HRESULT WINAPI VarBoolFromUI1(BYTE bIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003358{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003359 TRACE("( %d, %p ), stub\n", bIn, pboolOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003360
3361 if( bIn == 0 )
3362 {
3363 *pboolOut = VARIANT_FALSE;
3364 }
3365 else
3366 {
3367 *pboolOut = VARIANT_TRUE;
3368 }
3369
3370 return S_OK;
3371}
3372
3373/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003374 * VarBoolFromI2 [OLEAUT32.119]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003375 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003376HRESULT WINAPI VarBoolFromI2(short sIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003377{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003378 TRACE("( %d, %p ), stub\n", sIn, pboolOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003379
3380 if( sIn == 0 )
3381 {
3382 *pboolOut = VARIANT_FALSE;
3383 }
3384 else
3385 {
3386 *pboolOut = VARIANT_TRUE;
3387 }
3388
3389 return S_OK;
3390}
3391
3392/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003393 * VarBoolFromI4 [OLEAUT32.120]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003394 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003395HRESULT WINAPI VarBoolFromI4(LONG lIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003396{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003397 TRACE("( %ld, %p ), stub\n", lIn, pboolOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003398
3399 if( lIn == 0 )
3400 {
3401 *pboolOut = VARIANT_FALSE;
3402 }
3403 else
3404 {
3405 *pboolOut = VARIANT_TRUE;
3406 }
3407
3408 return S_OK;
3409}
3410
3411/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003412 * VarBoolFromR4 [OLEAUT32.121]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003413 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003414HRESULT WINAPI VarBoolFromR4(FLOAT fltIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003415{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003416 TRACE("( %f, %p ), stub\n", fltIn, pboolOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003417
3418 if( fltIn == 0.0 )
3419 {
3420 *pboolOut = VARIANT_FALSE;
3421 }
3422 else
3423 {
3424 *pboolOut = VARIANT_TRUE;
3425 }
3426
3427 return S_OK;
3428}
3429
3430/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003431 * VarBoolFromR8 [OLEAUT32.122]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003432 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003433HRESULT WINAPI VarBoolFromR8(double dblIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003434{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003435 TRACE("( %f, %p ), stub\n", dblIn, pboolOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003436
3437 if( dblIn == 0.0 )
3438 {
3439 *pboolOut = VARIANT_FALSE;
3440 }
3441 else
3442 {
3443 *pboolOut = VARIANT_TRUE;
3444 }
3445
3446 return S_OK;
3447}
3448
3449/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003450 * VarBoolFromDate [OLEAUT32.123]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003451 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003452HRESULT WINAPI VarBoolFromDate(DATE dateIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003453{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003454 TRACE("( %f, %p ), stub\n", dateIn, pboolOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003455
3456 if( dateIn == 0.0 )
3457 {
3458 *pboolOut = VARIANT_FALSE;
3459 }
3460 else
3461 {
3462 *pboolOut = VARIANT_TRUE;
3463 }
3464
3465 return S_OK;
3466}
3467
3468/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003469 * VarBoolFromStr [OLEAUT32.125]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003470 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003471HRESULT WINAPI VarBoolFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003472{
3473 HRESULT ret = S_OK;
3474 char* pNewString = NULL;
3475
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003476 TRACE("( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, pboolOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003477
3478 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
3479
3480 if( pNewString == NULL || strlen( pNewString ) == 0 )
3481 {
3482 ret = DISP_E_TYPEMISMATCH;
3483 }
3484
3485 if( ret == S_OK )
3486 {
3487 if( strncasecmp( pNewString, "True", strlen( pNewString ) ) == 0 )
3488 {
3489 *pboolOut = VARIANT_TRUE;
3490 }
3491 else if( strncasecmp( pNewString, "False", strlen( pNewString ) ) == 0 )
3492 {
3493 *pboolOut = VARIANT_FALSE;
3494 }
3495 else
3496 {
3497 /* Try converting the string to a floating point number.
3498 */
3499 double dValue = 0.0;
Alexandre Julliarda3960291999-02-26 11:11:13 +00003500 HRESULT res = VarR8FromStr( strIn, lcid, dwFlags, &dValue );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003501 if( res != S_OK )
3502 {
3503 ret = DISP_E_TYPEMISMATCH;
3504 }
3505 else if( dValue == 0.0 )
3506 {
3507 *pboolOut = VARIANT_FALSE;
3508 }
3509 else
3510 {
3511 *pboolOut = VARIANT_TRUE;
3512 }
3513 }
3514 }
3515
3516 HeapFree( GetProcessHeap(), 0, pNewString );
3517
3518 return ret;
3519}
3520
3521/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003522 * VarBoolFromI1 [OLEAUT32.233]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003523 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003524HRESULT WINAPI VarBoolFromI1(CHAR cIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003525{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003526 TRACE("( %c, %p ), stub\n", cIn, pboolOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003527
3528 if( cIn == 0 )
3529 {
3530 *pboolOut = VARIANT_FALSE;
3531 }
3532 else
3533 {
3534 *pboolOut = VARIANT_TRUE;
3535 }
3536
3537 return S_OK;
3538}
3539
3540/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003541 * VarBoolFromUI2 [OLEAUT32.234]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003542 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003543HRESULT WINAPI VarBoolFromUI2(USHORT uiIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003544{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003545 TRACE("( %d, %p ), stub\n", uiIn, pboolOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003546
3547 if( uiIn == 0 )
3548 {
3549 *pboolOut = VARIANT_FALSE;
3550 }
3551 else
3552 {
3553 *pboolOut = VARIANT_TRUE;
3554 }
3555
3556 return S_OK;
3557}
3558
3559/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003560 * VarBoolFromUI4 [OLEAUT32.235]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003561 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003562HRESULT WINAPI VarBoolFromUI4(ULONG ulIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003563{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003564 TRACE("( %ld, %p ), stub\n", ulIn, pboolOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003565
3566 if( ulIn == 0 )
3567 {
3568 *pboolOut = VARIANT_FALSE;
3569 }
3570 else
3571 {
3572 *pboolOut = VARIANT_TRUE;
3573 }
3574
3575 return S_OK;
3576}
3577
Justin Bradfordbc93bc81998-12-11 14:02:16 +00003578/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003579 * VarBoolFromCy [OLEAUT32.124]
Justin Bradfordbc93bc81998-12-11 14:02:16 +00003580 * Convert currency to boolean
3581 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003582HRESULT WINAPI VarBoolFromCy(CY cyIn, VARIANT_BOOL* pboolOut) {
Patrik Stridvall311e4561999-09-19 14:20:33 +00003583 if (cyIn.s.Hi || cyIn.s.Lo) *pboolOut = -1;
Justin Bradfordbc93bc81998-12-11 14:02:16 +00003584 else *pboolOut = 0;
3585
3586 return S_OK;
3587}
3588
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003589/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003590 * VarI1FromUI1 [OLEAUT32.244]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003591 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003592HRESULT WINAPI VarI1FromUI1(BYTE bIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003593{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003594 TRACE("( %d, %p ), stub\n", bIn, pcOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003595
3596 /* Check range of value.
3597 */
3598 if( bIn > CHAR_MAX )
3599 {
3600 return DISP_E_OVERFLOW;
3601 }
3602
3603 *pcOut = (CHAR) bIn;
3604
3605 return S_OK;
3606}
3607
3608/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003609 * VarI1FromI2 [OLEAUT32.245]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003610 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003611HRESULT WINAPI VarI1FromI2(short uiIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003612{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003613 TRACE("( %d, %p ), stub\n", uiIn, pcOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003614
3615 if( uiIn > CHAR_MAX )
3616 {
3617 return DISP_E_OVERFLOW;
3618 }
3619
3620 *pcOut = (CHAR) uiIn;
3621
3622 return S_OK;
3623}
3624
3625/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003626 * VarI1FromI4 [OLEAUT32.246]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003627 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003628HRESULT WINAPI VarI1FromI4(LONG lIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003629{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003630 TRACE("( %ld, %p ), stub\n", lIn, pcOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003631
3632 if( lIn < CHAR_MIN || lIn > CHAR_MAX )
3633 {
3634 return DISP_E_OVERFLOW;
3635 }
3636
3637 *pcOut = (CHAR) lIn;
3638
3639 return S_OK;
3640}
3641
3642/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003643 * VarI1FromR4 [OLEAUT32.247]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003644 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003645HRESULT WINAPI VarI1FromR4(FLOAT fltIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003646{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003647 TRACE("( %f, %p ), stub\n", fltIn, pcOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003648
3649 fltIn = round( fltIn );
3650 if( fltIn < CHAR_MIN || fltIn > CHAR_MAX )
3651 {
3652 return DISP_E_OVERFLOW;
3653 }
3654
3655 *pcOut = (CHAR) fltIn;
3656
3657 return S_OK;
3658}
3659
3660/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003661 * VarI1FromR8 [OLEAUT32.248]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003662 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003663HRESULT WINAPI VarI1FromR8(double dblIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003664{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003665 TRACE("( %f, %p ), stub\n", dblIn, pcOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003666
3667 dblIn = round( dblIn );
3668 if( dblIn < CHAR_MIN || dblIn > CHAR_MAX )
3669 {
3670 return DISP_E_OVERFLOW;
3671 }
3672
3673 *pcOut = (CHAR) dblIn;
3674
3675 return S_OK;
3676}
3677
3678/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003679 * VarI1FromDate [OLEAUT32.249]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003680 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003681HRESULT WINAPI VarI1FromDate(DATE dateIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003682{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003683 TRACE("( %f, %p ), stub\n", dateIn, pcOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003684
3685 dateIn = round( dateIn );
3686 if( dateIn < CHAR_MIN || dateIn > CHAR_MAX )
3687 {
3688 return DISP_E_OVERFLOW;
3689 }
3690
3691 *pcOut = (CHAR) dateIn;
3692
3693 return S_OK;
3694}
3695
3696/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003697 * VarI1FromStr [OLEAUT32.251]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003698 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003699HRESULT WINAPI VarI1FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003700{
3701 double dValue = 0.0;
3702 LPSTR pNewString = NULL;
3703
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003704 TRACE("( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, pcOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003705
3706 /* Check if we have a valid argument
3707 */
3708 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
3709 RemoveCharacterFromString( pNewString, "," );
3710 if( IsValidRealString( pNewString ) == FALSE )
3711 {
3712 return DISP_E_TYPEMISMATCH;
3713 }
3714
3715 /* Convert the valid string to a floating point number.
3716 */
3717 dValue = atof( pNewString );
3718
3719 /* We don't need the string anymore so free it.
3720 */
3721 HeapFree( GetProcessHeap(), 0, pNewString );
3722
3723 /* Check range of value.
3724 */
3725 dValue = round( dValue );
3726 if( dValue < CHAR_MIN || dValue > CHAR_MAX )
3727 {
3728 return DISP_E_OVERFLOW;
3729 }
3730
3731 *pcOut = (CHAR) dValue;
3732
3733 return S_OK;
3734}
3735
3736/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003737 * VarI1FromBool [OLEAUT32.253]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003738 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003739HRESULT WINAPI VarI1FromBool(VARIANT_BOOL boolIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003740{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003741 TRACE("( %d, %p ), stub\n", boolIn, pcOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003742
3743 *pcOut = (CHAR) boolIn;
3744
3745 return S_OK;
3746}
3747
3748/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003749 * VarI1FromUI2 [OLEAUT32.254]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003750 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003751HRESULT WINAPI VarI1FromUI2(USHORT uiIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003752{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003753 TRACE("( %d, %p ), stub\n", uiIn, pcOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003754
3755 if( uiIn > CHAR_MAX )
3756 {
3757 return DISP_E_OVERFLOW;
3758 }
3759
3760 *pcOut = (CHAR) uiIn;
3761
3762 return S_OK;
3763}
3764
3765/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003766 * VarI1FromUI4 [OLEAUT32.255]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003767 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003768HRESULT WINAPI VarI1FromUI4(ULONG ulIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003769{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003770 TRACE("( %ld, %p ), stub\n", ulIn, pcOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003771
3772 if( ulIn > CHAR_MAX )
3773 {
3774 return DISP_E_OVERFLOW;
3775 }
3776
3777 *pcOut = (CHAR) ulIn;
3778
3779 return S_OK;
3780}
3781
Justin Bradfordbc93bc81998-12-11 14:02:16 +00003782/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003783 * VarI1FromCy [OLEAUT32.250]
Justin Bradfordbc93bc81998-12-11 14:02:16 +00003784 * Convert currency to signed char
3785 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003786HRESULT WINAPI VarI1FromCy(CY cyIn, CHAR* pcOut) {
Patrik Stridvall311e4561999-09-19 14:20:33 +00003787 double t = round((((double)cyIn.s.Hi * 4294967296.0) + (double)cyIn.s.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00003788
3789 if (t > CHAR_MAX || t < CHAR_MIN) return DISP_E_OVERFLOW;
3790
3791 *pcOut = (CHAR)t;
3792 return S_OK;
3793}
3794
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003795/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003796 * VarUI2FromUI1 [OLEAUT32.257]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003797 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003798HRESULT WINAPI VarUI2FromUI1(BYTE bIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003799{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003800 TRACE("( %d, %p ), stub\n", bIn, puiOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003801
3802 *puiOut = (USHORT) bIn;
3803
3804 return S_OK;
3805}
3806
3807/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003808 * VarUI2FromI2 [OLEAUT32.258]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003809 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003810HRESULT WINAPI VarUI2FromI2(short uiIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003811{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003812 TRACE("( %d, %p ), stub\n", uiIn, puiOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003813
3814 if( uiIn < UI2_MIN )
3815 {
3816 return DISP_E_OVERFLOW;
3817 }
3818
3819 *puiOut = (USHORT) uiIn;
3820
3821 return S_OK;
3822}
3823
3824/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003825 * VarUI2FromI4 [OLEAUT32.259]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003826 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003827HRESULT WINAPI VarUI2FromI4(LONG lIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003828{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003829 TRACE("( %ld, %p ), stub\n", lIn, puiOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003830
3831 if( lIn < UI2_MIN || lIn > UI2_MAX )
3832 {
3833 return DISP_E_OVERFLOW;
3834 }
3835
3836 *puiOut = (USHORT) lIn;
3837
3838 return S_OK;
3839}
3840
3841/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003842 * VarUI2FromR4 [OLEAUT32.260]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003843 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003844HRESULT WINAPI VarUI2FromR4(FLOAT fltIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003845{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003846 TRACE("( %f, %p ), stub\n", fltIn, puiOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003847
3848 fltIn = round( fltIn );
3849 if( fltIn < UI2_MIN || fltIn > UI2_MAX )
3850 {
3851 return DISP_E_OVERFLOW;
3852 }
3853
3854 *puiOut = (USHORT) fltIn;
3855
3856 return S_OK;
3857}
3858
3859/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003860 * VarUI2FromR8 [OLEAUT32.261]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003861 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003862HRESULT WINAPI VarUI2FromR8(double dblIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003863{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003864 TRACE("( %f, %p ), stub\n", dblIn, puiOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003865
3866 dblIn = round( dblIn );
3867 if( dblIn < UI2_MIN || dblIn > UI2_MAX )
3868 {
3869 return DISP_E_OVERFLOW;
3870 }
3871
3872 *puiOut = (USHORT) dblIn;
3873
3874 return S_OK;
3875}
3876
3877/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003878 * VarUI2FromDate [OLEAUT32.262]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003879 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003880HRESULT WINAPI VarUI2FromDate(DATE dateIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003881{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003882 TRACE("( %f, %p ), stub\n", dateIn, puiOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003883
3884 dateIn = round( dateIn );
3885 if( dateIn < UI2_MIN || dateIn > UI2_MAX )
3886 {
3887 return DISP_E_OVERFLOW;
3888 }
3889
3890 *puiOut = (USHORT) dateIn;
3891
3892 return S_OK;
3893}
3894
3895/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003896 * VarUI2FromStr [OLEAUT32.264]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003897 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003898HRESULT WINAPI VarUI2FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003899{
3900 double dValue = 0.0;
3901 LPSTR pNewString = NULL;
3902
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003903 TRACE("( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, puiOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003904
3905 /* Check if we have a valid argument
3906 */
3907 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
3908 RemoveCharacterFromString( pNewString, "," );
3909 if( IsValidRealString( pNewString ) == FALSE )
3910 {
3911 return DISP_E_TYPEMISMATCH;
3912 }
3913
3914 /* Convert the valid string to a floating point number.
3915 */
3916 dValue = atof( pNewString );
3917
3918 /* We don't need the string anymore so free it.
3919 */
3920 HeapFree( GetProcessHeap(), 0, pNewString );
3921
3922 /* Check range of value.
3923 */
3924 dValue = round( dValue );
3925 if( dValue < UI2_MIN || dValue > UI2_MAX )
3926 {
3927 return DISP_E_OVERFLOW;
3928 }
3929
3930 *puiOut = (USHORT) dValue;
3931
3932 return S_OK;
3933}
3934
3935/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003936 * VarUI2FromBool [OLEAUT32.266]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003937 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003938HRESULT WINAPI VarUI2FromBool(VARIANT_BOOL boolIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003939{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003940 TRACE("( %d, %p ), stub\n", boolIn, puiOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003941
3942 *puiOut = (USHORT) boolIn;
3943
3944 return S_OK;
3945}
3946
3947/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003948 * VarUI2FromI1 [OLEAUT32.267]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003949 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003950HRESULT WINAPI VarUI2FromI1(CHAR cIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003951{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003952 TRACE("( %c, %p ), stub\n", cIn, puiOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003953
3954 *puiOut = (USHORT) cIn;
3955
3956 return S_OK;
3957}
3958
3959/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003960 * VarUI2FromUI4 [OLEAUT32.268]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003961 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003962HRESULT WINAPI VarUI2FromUI4(ULONG ulIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003963{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003964 TRACE("( %ld, %p ), stub\n", ulIn, puiOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003965
3966 if( ulIn < UI2_MIN || ulIn > UI2_MAX )
3967 {
3968 return DISP_E_OVERFLOW;
3969 }
3970
3971 *puiOut = (USHORT) ulIn;
3972
3973 return S_OK;
3974}
3975
3976/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00003977 * VarUI4FromStr [OLEAUT32.277]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003978 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003979HRESULT WINAPI VarUI4FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003980{
3981 double dValue = 0.0;
3982 LPSTR pNewString = NULL;
3983
Alexandre Julliard359f497e1999-07-04 16:02:24 +00003984 TRACE("( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, pulOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003985
3986 /* Check if we have a valid argument
3987 */
3988 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
3989 RemoveCharacterFromString( pNewString, "," );
3990 if( IsValidRealString( pNewString ) == FALSE )
3991 {
3992 return DISP_E_TYPEMISMATCH;
3993 }
3994
3995 /* Convert the valid string to a floating point number.
3996 */
3997 dValue = atof( pNewString );
3998
3999 /* We don't need the string anymore so free it.
4000 */
4001 HeapFree( GetProcessHeap(), 0, pNewString );
4002
4003 /* Check range of value.
4004 */
4005 dValue = round( dValue );
4006 if( dValue < UI4_MIN || dValue > UI4_MAX )
4007 {
4008 return DISP_E_OVERFLOW;
4009 }
4010
4011 *pulOut = (ULONG) dValue;
4012
4013 return S_OK;
4014}
4015
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004016/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00004017 * VarUI2FromCy [OLEAUT32.263]
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004018 * Convert currency to unsigned short
4019 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004020HRESULT WINAPI VarUI2FromCy(CY cyIn, USHORT* pusOut) {
Patrik Stridvall311e4561999-09-19 14:20:33 +00004021 double t = round((((double)cyIn.s.Hi * 4294967296.0) + (double)cyIn.s.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004022
4023 if (t > UI2_MAX || t < UI2_MIN) return DISP_E_OVERFLOW;
4024
4025 *pusOut = (USHORT)t;
4026
4027 return S_OK;
4028}
4029
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004030/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00004031 * VarUI4FromUI1 [OLEAUT32.270]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004032 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004033HRESULT WINAPI VarUI4FromUI1(BYTE bIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004034{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00004035 TRACE("( %d, %p ), stub\n", bIn, pulOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004036
4037 *pulOut = (USHORT) bIn;
4038
4039 return S_OK;
4040}
4041
4042/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00004043 * VarUI4FromI2 [OLEAUT32.271]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004044 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004045HRESULT WINAPI VarUI4FromI2(short uiIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004046{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00004047 TRACE("( %d, %p ), stub\n", uiIn, pulOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004048
4049 if( uiIn < UI4_MIN )
4050 {
4051 return DISP_E_OVERFLOW;
4052 }
4053
4054 *pulOut = (ULONG) uiIn;
4055
4056 return S_OK;
4057}
4058
4059/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00004060 * VarUI4FromI4 [OLEAUT32.272]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004061 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004062HRESULT WINAPI VarUI4FromI4(LONG lIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004063{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00004064 TRACE("( %ld, %p ), stub\n", lIn, pulOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004065
4066 if( lIn < UI4_MIN )
4067 {
4068 return DISP_E_OVERFLOW;
4069 }
4070
4071 *pulOut = (ULONG) lIn;
4072
4073 return S_OK;
4074}
4075
4076/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00004077 * VarUI4FromR4 [OLEAUT32.273]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004078 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004079HRESULT WINAPI VarUI4FromR4(FLOAT fltIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004080{
4081 fltIn = round( fltIn );
4082 if( fltIn < UI4_MIN || fltIn > UI4_MAX )
4083 {
4084 return DISP_E_OVERFLOW;
4085 }
4086
4087 *pulOut = (ULONG) fltIn;
4088
4089 return S_OK;
4090}
4091
4092/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00004093 * VarUI4FromR8 [OLEAUT32.274]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004094 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004095HRESULT WINAPI VarUI4FromR8(double dblIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004096{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00004097 TRACE("( %f, %p ), stub\n", dblIn, pulOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004098
4099 dblIn = round( dblIn );
4100 if( dblIn < UI4_MIN || dblIn > UI4_MAX )
4101 {
4102 return DISP_E_OVERFLOW;
4103 }
4104
4105 *pulOut = (ULONG) dblIn;
4106
4107 return S_OK;
4108}
4109
4110/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00004111 * VarUI4FromDate [OLEAUT32.275]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004112 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004113HRESULT WINAPI VarUI4FromDate(DATE dateIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004114{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00004115 TRACE("( %f, %p ), stub\n", dateIn, pulOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004116
4117 dateIn = round( dateIn );
4118 if( dateIn < UI4_MIN || dateIn > UI4_MAX )
4119 {
4120 return DISP_E_OVERFLOW;
4121 }
4122
4123 *pulOut = (ULONG) dateIn;
4124
4125 return S_OK;
4126}
4127
4128/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00004129 * VarUI4FromBool [OLEAUT32.279]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004130 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004131HRESULT WINAPI VarUI4FromBool(VARIANT_BOOL boolIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004132{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00004133 TRACE("( %d, %p ), stub\n", boolIn, pulOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004134
4135 *pulOut = (ULONG) boolIn;
4136
4137 return S_OK;
4138}
4139
4140/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00004141 * VarUI4FromI1 [OLEAUT32.280]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004142 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004143HRESULT WINAPI VarUI4FromI1(CHAR cIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004144{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00004145 TRACE("( %c, %p ), stub\n", cIn, pulOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004146
4147 *pulOut = (ULONG) cIn;
4148
4149 return S_OK;
4150}
4151
4152/******************************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00004153 * VarUI4FromUI2 [OLEAUT32.281]
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004154 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004155HRESULT WINAPI VarUI4FromUI2(USHORT uiIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004156{
Alexandre Julliard359f497e1999-07-04 16:02:24 +00004157 TRACE("( %d, %p ), stub\n", uiIn, pulOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004158
4159 *pulOut = (ULONG) uiIn;
4160
4161 return S_OK;
4162}
4163
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004164/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00004165 * VarUI4FromCy [OLEAUT32.276]
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004166 * Convert currency to unsigned long
4167 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004168HRESULT WINAPI VarUI4FromCy(CY cyIn, ULONG* pulOut) {
Patrik Stridvall311e4561999-09-19 14:20:33 +00004169 double t = round((((double)cyIn.s.Hi * 4294967296.0) + (double)cyIn.s.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004170
4171 if (t > UI4_MAX || t < UI4_MIN) return DISP_E_OVERFLOW;
4172
4173 *pulOut = (ULONG)t;
4174
4175 return S_OK;
4176}
4177
4178/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00004179 * VarCyFromUI1 [OLEAUT32.98]
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004180 * Convert unsigned char to currency
4181 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004182HRESULT WINAPI VarCyFromUI1(BYTE bIn, CY* pcyOut) {
Patrik Stridvall311e4561999-09-19 14:20:33 +00004183 pcyOut->s.Hi = 0;
4184 pcyOut->s.Lo = ((ULONG)bIn) * 10000;
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004185
4186 return S_OK;
4187}
4188
4189/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00004190 * VarCyFromI2 [OLEAUT32.99]
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004191 * Convert signed short to currency
4192 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004193HRESULT WINAPI VarCyFromI2(short sIn, CY* pcyOut) {
Patrik Stridvall311e4561999-09-19 14:20:33 +00004194 if (sIn < 0) pcyOut->s.Hi = -1;
4195 else pcyOut->s.Hi = 0;
4196 pcyOut->s.Lo = ((ULONG)sIn) * 10000;
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004197
4198 return S_OK;
4199}
4200
4201/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00004202 * VarCyFromI4 [OLEAUT32.100]
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004203 * Convert signed long to currency
4204 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004205HRESULT WINAPI VarCyFromI4(LONG lIn, CY* pcyOut) {
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004206 double t = (double)lIn * (double)10000;
Patrik Stridvall311e4561999-09-19 14:20:33 +00004207 pcyOut->s.Hi = (LONG)(t / (double)4294967296.0);
4208 pcyOut->s.Lo = (ULONG)fmod(t, (double)4294967296.0);
4209 if (lIn < 0) pcyOut->s.Hi--;
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004210
4211 return S_OK;
4212}
4213
4214/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00004215 * VarCyFromR4 [OLEAUT32.101]
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004216 * Convert float to currency
4217 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004218HRESULT WINAPI VarCyFromR4(FLOAT fltIn, CY* pcyOut) {
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004219 double t = round((double)fltIn * (double)10000);
Patrik Stridvall311e4561999-09-19 14:20:33 +00004220 pcyOut->s.Hi = (LONG)(t / (double)4294967296.0);
4221 pcyOut->s.Lo = (ULONG)fmod(t, (double)4294967296.0);
4222 if (fltIn < 0) pcyOut->s.Hi--;
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004223
4224 return S_OK;
4225}
4226
4227/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00004228 * VarCyFromR8 [OLEAUT32.102]
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004229 * Convert double to currency
4230 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004231HRESULT WINAPI VarCyFromR8(double dblIn, CY* pcyOut) {
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004232 double t = round(dblIn * (double)10000);
Patrik Stridvall311e4561999-09-19 14:20:33 +00004233 pcyOut->s.Hi = (LONG)(t / (double)4294967296.0);
4234 pcyOut->s.Lo = (ULONG)fmod(t, (double)4294967296.0);
4235 if (dblIn < 0) pcyOut->s.Hi--;
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004236
4237 return S_OK;
4238}
4239
4240/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00004241 * VarCyFromDate [OLEAUT32.103]
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004242 * Convert date to currency
4243 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004244HRESULT WINAPI VarCyFromDate(DATE dateIn, CY* pcyOut) {
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004245 double t = round((double)dateIn * (double)10000);
Patrik Stridvall311e4561999-09-19 14:20:33 +00004246 pcyOut->s.Hi = (LONG)(t / (double)4294967296.0);
4247 pcyOut->s.Lo = (ULONG)fmod(t, (double)4294967296.0);
4248 if (dateIn < 0) pcyOut->s.Hi--;
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004249
4250 return S_OK;
4251}
4252
4253/**********************************************************************
Patrik Stridvallfcfacb92000-03-24 20:46:04 +00004254 * VarCyFromStr [OLEAUT32.104]
Alexandre Julliardf80b2ab1999-03-28 13:15:40 +00004255 */
4256HRESULT WINAPI VarCyFromStr(OLECHAR *strIn, LCID lcid, ULONG dwFlags, CY *pcyOut) {
4257 /* FIXME */
4258 return E_NOTIMPL;
4259}
4260
4261
4262/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00004263 * VarCyFromBool [OLEAUT32.106]
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004264 * Convert boolean to currency
4265 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004266HRESULT WINAPI VarCyFromBool(VARIANT_BOOL boolIn, CY* pcyOut) {
Patrik Stridvall311e4561999-09-19 14:20:33 +00004267 if (boolIn < 0) pcyOut->s.Hi = -1;
4268 else pcyOut->s.Hi = 0;
4269 pcyOut->s.Lo = (ULONG)boolIn * (ULONG)10000;
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004270
4271 return S_OK;
4272}
4273
4274/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00004275 * VarCyFromI1 [OLEAUT32.225]
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004276 * Convert signed char to currency
4277 */
Josh DuBoisa57eb652001-01-22 19:23:54 +00004278HRESULT WINAPI VarCyFromI1(signed char cIn, CY* pcyOut) {
Patrik Stridvall311e4561999-09-19 14:20:33 +00004279 if (cIn < 0) pcyOut->s.Hi = -1;
4280 else pcyOut->s.Hi = 0;
4281 pcyOut->s.Lo = (ULONG)cIn * (ULONG)10000;
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004282
4283 return S_OK;
4284}
4285
4286/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00004287 * VarCyFromUI2 [OLEAUT32.226]
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004288 * Convert unsigned short to currency
4289 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004290HRESULT WINAPI VarCyFromUI2(USHORT usIn, CY* pcyOut) {
Patrik Stridvall311e4561999-09-19 14:20:33 +00004291 pcyOut->s.Hi = 0;
4292 pcyOut->s.Lo = (ULONG)usIn * (ULONG)10000;
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004293
4294 return S_OK;
4295}
4296
4297/**********************************************************************
Patrik Stridvall2d6457c2000-03-28 20:22:59 +00004298 * VarCyFromUI4 [OLEAUT32.227]
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004299 * Convert unsigned long to currency
4300 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004301HRESULT WINAPI VarCyFromUI4(ULONG ulIn, CY* pcyOut) {
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004302 double t = (double)ulIn * (double)10000;
Patrik Stridvall311e4561999-09-19 14:20:33 +00004303 pcyOut->s.Hi = (LONG)(t / (double)4294967296.0);
4304 pcyOut->s.Lo = (ULONG)fmod(t, (double)4294967296.0);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004305
4306 return S_OK;
4307}
Stephane Lussier986de4b1999-03-12 17:02:32 +00004308
4309
4310/**********************************************************************
4311 * DosDateTimeToVariantTime [OLEAUT32.14]
4312 * Convert dos representation of time to the date and time representation
4313 * stored in a variant.
4314 */
4315INT WINAPI DosDateTimeToVariantTime(USHORT wDosDate, USHORT wDosTime,
4316 DATE *pvtime)
4317{
4318 struct tm t;
4319
Alexandre Julliard359f497e1999-07-04 16:02:24 +00004320 TRACE("( 0x%x, 0x%x, 0x%p ), stub\n", wDosDate, wDosTime, pvtime );
Stephane Lussier986de4b1999-03-12 17:02:32 +00004321
4322 t.tm_sec = (wDosTime & 0x001f) * 2;
4323 t.tm_min = (wDosTime & 0x07e0) >> 5;
4324 t.tm_hour = (wDosTime & 0xf800) >> 11;
4325
4326 t.tm_mday = (wDosDate & 0x001f);
4327 t.tm_mon = (wDosDate & 0x01e0) >> 5;
4328 t.tm_year = ((wDosDate & 0xfe00) >> 9) + 1980;
4329
4330 return TmToDATE( &t, pvtime );
4331}
4332