blob: 8dd46b826a5003675976cb1ed68803c4ac829c3b [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:
13 * - The Variant APIs are do not support international languages, currency
14 * 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.
19 * - The date manipulations do not support date prior to 1900.
20 * - The parsing does not accept has many formats has the Windows implementation.
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +000021 */
22
Justin Bradfordbc93bc81998-12-11 14:02:16 +000023#include "wintypes.h"
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +000024#include "oleauto.h"
25#include "heap.h"
26#include "debug.h"
27#include "winerror.h"
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +000028#include "parsedt.h"
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +000029
30#include <string.h>
31#include <stdlib.h>
32#include <math.h>
33#include <time.h>
34
Marcus Meissnerae8b10b1998-12-15 13:01:21 +000035#ifdef HAVE_FLOAT_H
36# include <float.h>
37#endif
38
39#ifndef FLT_MAX
40# ifdef MAXFLOAT
41# define FLT_MAX MAXFLOAT
42# else
43# error "Can't find #define for MAXFLOAT/FLT_MAX"
44# endif
45#endif
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +000046
Todd Vierling7f573251998-12-15 15:15:16 +000047#undef CHAR_MAX
48#undef CHAR_MIN
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +000049static const char CHAR_MAX = 127;
50static const char CHAR_MIN = -128;
51static const BYTE UI1_MAX = 255;
52static const BYTE UI1_MIN = 0;
53static const unsigned short UI2_MAX = 65535;
54static const unsigned short UI2_MIN = 0;
55static const short I2_MAX = 32767;
56static const short I2_MIN = -32768;
Todd Vierling7f573251998-12-15 15:15:16 +000057static const unsigned long UI4_MAX = 4294967295U;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +000058static const unsigned long UI4_MIN = 0;
59static const long I4_MAX = 2147483647;
Todd Vierling7f573251998-12-15 15:15:16 +000060static const long I4_MIN = -(2147483648U);
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +000061static const DATE DATE_MIN = -657434;
62static const DATE DATE_MAX = 2958465;
63
64
65/* This mask is used to set a flag in wReserved1 of
66 * the VARIANTARG structure. The flag indicates if
67 * the API function is using an inner variant or not.
68 */
69#define PROCESSING_INNER_VARIANT 0x0001
70
71/* General use buffer.
72 */
73#define BUFFER_MAX 1024
74static char pBuffer[BUFFER_MAX];
75
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +000076/*
77 * Note a leap year is one that is a multiple of 4
78 * but not of a 100. Except if it is a multiple of
79 * 400 then it is a leap year.
80 */
81/* According to postgeSQL date parsing functions there is
82 * a leap year when this expression is true.
83 * (((y % 4) == 0) && (((y % 100) != 0) || ((y % 400) == 0)))
84 * So according to this there is 365.2515 days in one year.
85 * One + every four years: 1/4 -> 365.25
86 * One - every 100 years: 1/100 -> 365.001
87 * One + every 400 years: 1/400 -> 365.0025
88 */
89static const double DAYS_IN_ONE_YEAR = 365.2515;
90
91
92
93/******************************************************************************
94 * DateTimeStringToTm [INTERNAL]
95 *
96 * Converts a string representation of a date and/or time to a tm structure.
97 *
98 * Note this function uses the postgresql date parsing functions found
99 * in the parsedt.c file.
100 *
101 * Returns TRUE if successfull.
102 *
103 * Note: This function does not parse the day of the week,
104 * daylight savings time. It will only fill the followin fields in
105 * the tm struct, tm_sec, tm_min, tm_hour, tm_year, tm_day, tm_mon.
106 *
107 ******************************************************************************/
Alexandre Julliarda3960291999-02-26 11:11:13 +0000108static BOOL DateTimeStringToTm( OLECHAR* strIn, LCID lcid, struct tm* pTm )
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +0000109{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000110 BOOL res = FALSE;
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +0000111 double fsec;
112 int tzp;
113 int dtype;
114 int nf;
115 char *field[MAXDATEFIELDS];
116 int ftype[MAXDATEFIELDS];
117 char lowstr[MAXDATELEN + 1];
118 char* strDateTime = NULL;
119
120 /* Convert the string to ASCII since this is the only format
121 * postgesql can handle.
122 */
123 strDateTime = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
124
125 if( strDateTime != NULL )
126 {
127 /* Make sure we don't go over the maximum length
128 * accepted by postgesql.
129 */
130 if( strlen( strDateTime ) <= MAXDATELEN )
131 {
132 if( ParseDateTime( strDateTime, lowstr, field, ftype, MAXDATEFIELDS, &nf) == 0 )
133 {
134 if( lcid & VAR_DATEVALUEONLY )
135 {
136 /* Get the date information.
137 * It returns 0 if date information was
138 * present and 1 if only time information was present.
139 * -1 if an error occures.
140 */
141 if( DecodeDateTime(field, ftype, nf, &dtype, pTm, &fsec, &tzp) == 0 )
142 {
143 /* Eliminate the time information since we
144 * were asked to get date information only.
145 */
146 pTm->tm_sec = 0;
147 pTm->tm_min = 0;
148 pTm->tm_hour = 0;
149 res = TRUE;
150 }
151 }
152 if( lcid & VAR_TIMEVALUEONLY )
153 {
154 /* Get time information only.
155 */
156 if( DecodeTimeOnly(field, ftype, nf, &dtype, pTm, &fsec) == 0 )
157 {
158 res = TRUE;
159 }
160 }
161 else
162 {
163 /* Get both date and time information.
164 * It returns 0 if date information was
165 * present and 1 if only time information was present.
166 * -1 if an error occures.
167 */
168 if( DecodeDateTime(field, ftype, nf, &dtype, pTm, &fsec, &tzp) != -1 )
169 {
170 res = TRUE;
171 }
172 }
173 }
174 }
175 HeapFree( GetProcessHeap(), 0, strDateTime );
176 }
177
178 return res;
179}
180
181
182
183
184
185
186/******************************************************************************
187 * TmToDATE [INTERNAL]
188 *
189 * The date is implemented using an 8 byte floating-point number.
190 * Days are represented by whole numbers increments starting with 0.00 has
191 * being December 30 1899, midnight.
192 * The hours are expressed as the fractional part of the number.
193 * December 30 1899 at midnight = 0.00
194 * January 1 1900 at midnight = 2.00
195 * January 4 1900 at 6 AM = 5.25
196 * January 4 1900 at noon = 5.50
197 * December 29 1899 at midnight = -1.00
198 * December 18 1899 at midnight = -12.00
199 * December 18 1899 at 6AM = -12.25
200 * December 18 1899 at 6PM = -12.75
201 * December 19 1899 at midnight = -11.00
202 * The tm structure is as follows:
203 * struct tm {
204 * int tm_sec; seconds after the minute - [0,59]
205 * int tm_min; minutes after the hour - [0,59]
206 * int tm_hour; hours since midnight - [0,23]
207 * int tm_mday; day of the month - [1,31]
208 * int tm_mon; months since January - [0,11]
209 * int tm_year; years
210 * int tm_wday; days since Sunday - [0,6]
211 * int tm_yday; days since January 1 - [0,365]
212 * int tm_isdst; daylight savings time flag
213 * };
214 *
215 * Note: This function does not use the tm_wday, tm_yday, tm_wday,
216 * and tm_isdst fields of the tm structure. And only converts years
217 * after 1900.
218 *
219 * Returns TRUE if successfull.
220 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000221static BOOL TmToDATE( struct tm* pTm, DATE *pDateOut )
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +0000222{
223 if( (pTm->tm_year - 1900) >= 0 )
224 {
225 int leapYear = 0;
226
227 /* Start at 1. This is the way DATE is defined.
228 * January 1, 1900 at Midnight is 1.00.
229 * January 1, 1900 at 6AM is 1.25.
230 * and so on.
231 */
232 *pDateOut = 1;
233
234 /* Add the number of days corresponding to
235 * tm_year.
236 */
237 *pDateOut += (pTm->tm_year - 1900) * 365;
238
239 /* Add the leap days in the previous years between now and 1900.
240 * Note a leap year is one that is a multiple of 4
241 * but not of a 100. Except if it is a multiple of
242 * 400 then it is a leap year.
243 */
244 *pDateOut += ( (pTm->tm_year - 1) / 4 ) - ( 1900 / 4 );
245 *pDateOut -= ( (pTm->tm_year - 1) / 100 ) - ( 1900 / 100 );
246 *pDateOut += ( (pTm->tm_year - 1) / 400 ) - ( 1900 / 400 );
247
248 /* Set the leap year flag if the
249 * current year specified by tm_year is a
250 * leap year. This will be used to add a day
251 * to the day count.
252 */
253 if( isleap( pTm->tm_year ) )
254 leapYear = 1;
255
256 /* Add the number of days corresponding to
257 * the month.
258 */
259 switch( pTm->tm_mon )
260 {
261 case 2:
262 *pDateOut += 31;
263 break;
264 case 3:
265 *pDateOut += ( 59 + leapYear );
266 break;
267 case 4:
268 *pDateOut += ( 90 + leapYear );
269 break;
270 case 5:
271 *pDateOut += ( 120 + leapYear );
272 break;
273 case 6:
274 *pDateOut += ( 151 + leapYear );
275 break;
276 case 7:
277 *pDateOut += ( 181 + leapYear );
278 break;
279 case 8:
280 *pDateOut += ( 212 + leapYear );
281 break;
282 case 9:
283 *pDateOut += ( 243 + leapYear );
284 break;
285 case 10:
286 *pDateOut += ( 273 + leapYear );
287 break;
288 case 11:
289 *pDateOut += ( 304 + leapYear );
290 break;
291 case 12:
292 *pDateOut += ( 334 + leapYear );
293 break;
294 }
295 /* Add the number of days in this month.
296 */
297 *pDateOut += pTm->tm_mday;
298
299 /* Add the number of seconds, minutes, and hours
300 * to the DATE. Note these are the fracionnal part
301 * of the DATE so seconds / number of seconds in a day.
302 */
303 *pDateOut += pTm->tm_hour / 24.0;
304 *pDateOut += pTm->tm_min / 1440.0;
305 *pDateOut += pTm->tm_sec / 86400.0;
306 return TRUE;
307 }
308 return FALSE;
309}
310
311/******************************************************************************
312 * DateToTm [INTERNAL]
313 *
314 * This function converst a windows DATE to a tm structure.
315 *
316 * It does not fill all the fields of the tm structure.
317 * Here is a list of the fields that are filled:
318 * tm_sec, tm_min, tm_hour, tm_year, tm_day, tm_mon.
319 *
320 * Note this function does not support dates before the January 1, 1900
321 * or ( dateIn < 2.0 ).
322 *
323 * Returns TRUE if successfull.
324 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000325static BOOL DateToTm( DATE dateIn, LCID lcid, struct tm* pTm )
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +0000326{
327 /* Do not process dates smaller than January 1, 1900.
328 * Which corresponds to 2.0 in the windows DATE format.
329 */
330 if( dateIn >= 2.0 )
331 {
332 double decimalPart = 0.0;
333 double wholePart = 0.0;
334
Alexandre Julliard638f1691999-01-17 16:32:32 +0000335 memset(pTm,0,sizeof(*pTm));
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +0000336
337 /* Because of the nature of DATE format witch
338 * associates 2.0 to January 1, 1900. We will
339 * remove 1.0 from the whole part of the DATE
340 * so that in the following code 1.0
341 * will correspond to January 1, 1900.
342 * This simplyfies the processing of the DATE value.
343 */
344 dateIn -= 1.0;
345
346 wholePart = (double) floor( dateIn );
347 decimalPart = fmod( dateIn, wholePart );
348
349 if( !(lcid & VAR_TIMEVALUEONLY) )
350 {
351 int nDay = 0;
352 int leapYear = 0;
353 double yearsSince1900 = 0;
354 /* Start at 1900, this where the DATE time 0.0 starts.
355 */
356 pTm->tm_year = 1900;
357 /* find in what year the day in the "wholePart" falls into.
358 * add the value to the year field.
359 */
360 yearsSince1900 = floor( wholePart / DAYS_IN_ONE_YEAR );
361 pTm->tm_year += yearsSince1900;
362 /* determine if this is a leap year.
363 */
364 if( isleap( pTm->tm_year ) )
365 leapYear = 1;
366 /* find what day of that year does the "wholePart" corresponds to.
367 * Note: nDay is in [1-366] format
368 */
369 nDay = (int) ( wholePart - floor( yearsSince1900 * DAYS_IN_ONE_YEAR ) );
370 /* Set the tm_yday value.
371 * Note: The day is must be converted from [1-366] to [0-365]
372 */
Marcus Meissnerae3921d1999-01-01 18:43:12 +0000373 /*pTm->tm_yday = nDay - 1;*/
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +0000374 /* find which mount this day corresponds to.
375 */
376 if( nDay <= 31 )
377 {
378 pTm->tm_mday = nDay;
379 pTm->tm_mon = 0;
380 }
381 else if( nDay <= ( 59 + leapYear ) )
382 {
383 pTm->tm_mday = nDay - 31;
384 pTm->tm_mon = 1;
385 }
386 else if( nDay <= ( 90 + leapYear ) )
387 {
388 pTm->tm_mday = nDay - ( 59 + leapYear );
389 pTm->tm_mon = 2;
390 }
391 else if( nDay <= ( 120 + leapYear ) )
392 {
393 pTm->tm_mday = nDay - ( 90 + leapYear );
394 pTm->tm_mon = 3;
395 }
396 else if( nDay <= ( 151 + leapYear ) )
397 {
398 pTm->tm_mday = nDay - ( 120 + leapYear );
399 pTm->tm_mon = 4;
400 }
401 else if( nDay <= ( 181 + leapYear ) )
402 {
403 pTm->tm_mday = nDay - ( 151 + leapYear );
404 pTm->tm_mon = 5;
405 }
406 else if( nDay <= ( 212 + leapYear ) )
407 {
408 pTm->tm_mday = nDay - ( 181 + leapYear );
409 pTm->tm_mon = 6;
410 }
411 else if( nDay <= ( 243 + leapYear ) )
412 {
413 pTm->tm_mday = nDay - ( 212 + leapYear );
414 pTm->tm_mon = 7;
415 }
416 else if( nDay <= ( 273 + leapYear ) )
417 {
418 pTm->tm_mday = nDay - ( 243 + leapYear );
419 pTm->tm_mon = 8;
420 }
421 else if( nDay <= ( 304 + leapYear ) )
422 {
423 pTm->tm_mday = nDay - ( 273 + leapYear );
424 pTm->tm_mon = 9;
425 }
426 else if( nDay <= ( 334 + leapYear ) )
427 {
428 pTm->tm_mday = nDay - ( 304 + leapYear );
429 pTm->tm_mon = 10;
430 }
431 else if( nDay <= ( 365 + leapYear ) )
432 {
433 pTm->tm_mday = nDay - ( 334 + leapYear );
434 pTm->tm_mon = 11;
435 }
436 }
437 if( !(lcid & VAR_DATEVALUEONLY) )
438 {
439 /* find the number of seconds in this day.
440 * fractional part times, hours, minutes, seconds.
441 */
442 pTm->tm_hour = (int) ( decimalPart * 24 );
443 pTm->tm_min = (int) ( ( ( decimalPart * 24 ) - pTm->tm_hour ) * 60 );
444 pTm->tm_sec = (int) ( ( ( decimalPart * 24 * 60 ) - ( pTm->tm_hour * 60 ) - pTm->tm_min ) * 60 );
445 }
446 return TRUE;
447 }
448 return FALSE;
449}
450
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000451
452
453/******************************************************************************
454 * SizeOfVariantData [INTERNAL]
455 *
456 * This function finds the size of the data referenced by a Variant based
457 * the type "vt" of the Variant.
458 */
459static int SizeOfVariantData( VARIANT* parg )
460{
461 int size = 0;
462 switch( parg->vt & VT_TYPEMASK )
463 {
464 case( VT_I2 ):
465 size = sizeof(short);
466 break;
467 case( VT_INT ):
468 size = sizeof(int);
469 break;
470 case( VT_I4 ):
471 size = sizeof(long);
472 break;
473 case( VT_UI1 ):
474 size = sizeof(BYTE);
475 break;
476 case( VT_UI2 ):
477 size = sizeof(unsigned short);
478 break;
479 case( VT_UINT ):
480 size = sizeof(unsigned int);
481 break;
482 case( VT_UI4 ):
483 size = sizeof(unsigned long);
484 break;
485 case( VT_R4 ):
486 size = sizeof(float);
487 break;
488 case( VT_R8 ):
489 size = sizeof(double);
490 break;
491 case( VT_DATE ):
492 size = sizeof(DATE);
493 break;
494 case( VT_BOOL ):
495 size = sizeof(VARIANT_BOOL);
496 break;
497 case( VT_BSTR ):
498 size = sizeof(void*);
499 break;
500 case( VT_CY ):
501 case( VT_DISPATCH ):
502 case( VT_UNKNOWN ):
503 case( VT_DECIMAL ):
504 default:
505 FIXME(ole,"Add size information for type vt=%d\n", parg->vt & VT_TYPEMASK );
506 break;
507 }
508
509 return size;
510}
511/******************************************************************************
512 * StringDupAtoBstr [INTERNAL]
513 *
514 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000515static BSTR StringDupAtoBstr( char* strIn )
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000516{
Alexandre Julliarda3960291999-02-26 11:11:13 +0000517 BSTR bstr = NULL;
518 OLECHAR* pNewString = NULL;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000519 pNewString = HEAP_strdupAtoW( GetProcessHeap(), 0, strIn );
Alexandre Julliarda3960291999-02-26 11:11:13 +0000520 bstr = SysAllocString( pNewString );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000521 HeapFree( GetProcessHeap(), 0, pNewString );
522 return bstr;
523}
524
525/******************************************************************************
526 * round [INTERNAL]
527 *
528 * Round the double value to the nearest integer value.
529 */
530static double round( double d )
531{
Justin Bradfordbc93bc81998-12-11 14:02:16 +0000532 double decimals = 0.0, integerValue = 0.0, roundedValue = 0.0;
Alexandre Julliarda3960291999-02-26 11:11:13 +0000533 BOOL bEvenNumber = FALSE;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000534 int nSign = 0;
535
536 /* Save the sign of the number
537 */
Justin Bradfordbc93bc81998-12-11 14:02:16 +0000538 nSign = (d >= 0.0) ? 1 : -1;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000539 d = fabs( d );
540
541 /* Remove the decimals.
542 */
Justin Bradfordbc93bc81998-12-11 14:02:16 +0000543 integerValue = floor( d );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000544
545 /* Set the Even flag. This is used to round the number when
546 * the decimals are exactly 1/2. If the integer part is
547 * odd the number is rounded up. If the integer part
548 * is even the number is rounded down. Using this method
549 * numbers are rounded up|down half the time.
550 */
Justin Bradfordbc93bc81998-12-11 14:02:16 +0000551 bEvenNumber = (((short)fmod(integerValue, 2)) == 0) ? TRUE : FALSE;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000552
553 /* Remove the integral part of the number.
554 */
555 decimals = d - integerValue;
556
557 /* Note: Ceil returns the smallest integer that is greater that x.
558 * and floor returns the largest integer that is less than or equal to x.
559 */
560 if( decimals > 0.5 )
561 {
562 /* If the decimal part is greater than 1/2
563 */
564 roundedValue = ceil( d );
565 }
566 else if( decimals < 0.5 )
567 {
568 /* If the decimal part is smaller than 1/2
569 */
570 roundedValue = floor( d );
571 }
572 else
573 {
574 /* the decimals are exactly 1/2 so round according to
575 * the bEvenNumber flag.
576 */
577 if( bEvenNumber )
578 {
579 roundedValue = floor( d );
580 }
581 else
582 {
583 roundedValue = ceil( d );
584 }
585 }
586
587 return roundedValue * nSign;
588}
589
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000590/******************************************************************************
591 * RemoveCharacterFromString [INTERNAL]
592 *
593 * Removes any of the characters in "strOfCharToRemove" from the "str" argument.
594 */
595static void RemoveCharacterFromString( LPSTR str, LPSTR strOfCharToRemove )
596{
597 LPSTR pNewString = NULL;
598 LPSTR strToken = NULL;
599
600
601 /* Check if we have a valid argument
602 */
603 if( str != NULL )
604 {
605 pNewString = strdup( str );
606 str[0] = '\0';
607 strToken = strtok( pNewString, strOfCharToRemove );
608 while( strToken != NULL ) {
609 strcat( str, strToken );
610 strToken = strtok( NULL, strOfCharToRemove );
611 }
612 free( pNewString );
613 }
614 return;
615}
616
617/******************************************************************************
618 * GetValidRealString [INTERNAL]
619 *
620 * Checks if the string is of proper format to be converted to a real value.
621 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000622static BOOL IsValidRealString( LPSTR strRealString )
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000623{
624 /* Real values that have a decimal point are required to either have
625 * digits before or after the decimal point. We will assume that
626 * we do not have any digits at either position. If we do encounter
627 * some we will disable this flag.
628 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000629 BOOL bDigitsRequired = TRUE;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000630 /* Processed fields in the string representation of the real number.
631 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000632 BOOL bWhiteSpaceProcessed = FALSE;
633 BOOL bFirstSignProcessed = FALSE;
634 BOOL bFirstDigitsProcessed = FALSE;
635 BOOL bDecimalPointProcessed = FALSE;
636 BOOL bSecondDigitsProcessed = FALSE;
637 BOOL bExponentProcessed = FALSE;
638 BOOL bSecondSignProcessed = FALSE;
639 BOOL bThirdDigitsProcessed = FALSE;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000640 /* Assume string parameter "strRealString" is valid and try to disprove it.
641 */
Alexandre Julliarda3960291999-02-26 11:11:13 +0000642 BOOL bValidRealString = TRUE;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000643
644 /* Used to count the number of tokens in the "strRealString".
645 */
646 LPSTR strToken = NULL;
647 int nTokens = 0;
648 LPSTR pChar = NULL;
649
650 /* Check if we have a valid argument
651 */
652 if( strRealString == NULL )
653 {
654 bValidRealString = FALSE;
655 }
656
657 if( bValidRealString == TRUE )
658 {
659 /* Make sure we only have ONE token in the string.
660 */
661 strToken = strtok( strRealString, " " );
662 while( strToken != NULL ) {
663 nTokens++;
664 strToken = strtok( NULL, " " );
665 }
666
667 if( nTokens != 1 )
668 {
669 bValidRealString = FALSE;
670 }
671 }
672
673
674 /* Make sure this token contains only valid characters.
675 * The string argument to atof has the following form:
676 * [whitespace] [sign] [digits] [.digits] [ {d | D | e | E }[sign]digits]
677 * Whitespace consists of space and|or <TAB> characters, which are ignored.
678 * Sign is either plus '+' or minus '-'.
679 * Digits are one or more decimal digits.
680 * Note: If no digits appear before the decimal point, at least one must
681 * appear after the decimal point.
682 * The decimal digits may be followed by an exponent.
683 * An Exponent consists of an introductory letter ( D, d, E, or e) and
684 * an optionally signed decimal integer.
685 */
686 pChar = strRealString;
687 while( bValidRealString == TRUE && *pChar != '\0' )
688 {
689 switch( *pChar )
690 {
691 /* If whitespace...
692 */
693 case ' ':
694 case '\t':
695 if( bWhiteSpaceProcessed ||
696 bFirstSignProcessed ||
697 bFirstDigitsProcessed ||
698 bDecimalPointProcessed ||
699 bSecondDigitsProcessed ||
700 bExponentProcessed ||
701 bSecondSignProcessed ||
702 bThirdDigitsProcessed )
703 {
704 bValidRealString = FALSE;
705 }
706 break;
707 /* If sign...
708 */
709 case '+':
710 case '-':
711 if( bFirstSignProcessed == FALSE )
712 {
713 if( bFirstDigitsProcessed ||
714 bDecimalPointProcessed ||
715 bSecondDigitsProcessed ||
716 bExponentProcessed ||
717 bSecondSignProcessed ||
718 bThirdDigitsProcessed )
719 {
720 bValidRealString = FALSE;
721 }
722 bWhiteSpaceProcessed = TRUE;
723 bFirstSignProcessed = TRUE;
724 }
725 else if( bSecondSignProcessed == FALSE )
726 {
727 /* Note: The exponent must be present in
728 * order to accept the second sign...
729 */
730 if( bExponentProcessed == FALSE ||
731 bThirdDigitsProcessed ||
732 bDigitsRequired )
733 {
734 bValidRealString = FALSE;
735 }
736 bFirstSignProcessed = TRUE;
737 bWhiteSpaceProcessed = TRUE;
738 bFirstDigitsProcessed = TRUE;
739 bDecimalPointProcessed = TRUE;
740 bSecondDigitsProcessed = TRUE;
741 bSecondSignProcessed = TRUE;
742 }
743 break;
744
745 /* If decimals...
746 */
747 case '0':
748 case '1':
749 case '2':
750 case '3':
751 case '4':
752 case '5':
753 case '6':
754 case '7':
755 case '8':
756 case '9':
757 if( bFirstDigitsProcessed == FALSE )
758 {
759 if( bDecimalPointProcessed ||
760 bSecondDigitsProcessed ||
761 bExponentProcessed ||
762 bSecondSignProcessed ||
763 bThirdDigitsProcessed )
764 {
765 bValidRealString = FALSE;
766 }
767 bFirstSignProcessed = TRUE;
768 bWhiteSpaceProcessed = TRUE;
769 /* We have found some digits before the decimal point
770 * so disable the "Digits required" flag.
771 */
772 bDigitsRequired = FALSE;
773 }
774 else if( bSecondDigitsProcessed == FALSE )
775 {
776 if( bExponentProcessed ||
777 bSecondSignProcessed ||
778 bThirdDigitsProcessed )
779 {
780 bValidRealString = FALSE;
781 }
782 bFirstSignProcessed = TRUE;
783 bWhiteSpaceProcessed = TRUE;
784 bFirstDigitsProcessed = TRUE;
785 bDecimalPointProcessed = TRUE;
786 /* We have found some digits after the decimal point
787 * so disable the "Digits required" flag.
788 */
789 bDigitsRequired = FALSE;
790 }
791 else if( bThirdDigitsProcessed == FALSE )
792 {
793 /* Getting here means everything else should be processed.
794 * If we get anything else than a decimal following this
795 * digit it will be flagged by the other cases, so
796 * we do not really need to do anything in here.
797 */
798 }
799 break;
800 /* If DecimalPoint...
801 */
802 case '.':
803 if( bDecimalPointProcessed ||
804 bSecondDigitsProcessed ||
805 bExponentProcessed ||
806 bSecondSignProcessed ||
807 bThirdDigitsProcessed )
808 {
809 bValidRealString = FALSE;
810 }
811 bFirstSignProcessed = TRUE;
812 bWhiteSpaceProcessed = TRUE;
813 bFirstDigitsProcessed = TRUE;
814 bDecimalPointProcessed = TRUE;
815 break;
816 /* If Exponent...
817 */
818 case 'e':
819 case 'E':
820 case 'd':
821 case 'D':
822 if( bExponentProcessed ||
823 bSecondSignProcessed ||
824 bThirdDigitsProcessed ||
825 bDigitsRequired )
826 {
827 bValidRealString = FALSE;
828 }
829 bFirstSignProcessed = TRUE;
830 bWhiteSpaceProcessed = TRUE;
831 bFirstDigitsProcessed = TRUE;
832 bDecimalPointProcessed = TRUE;
833 bSecondDigitsProcessed = TRUE;
834 bExponentProcessed = TRUE;
835 break;
836 default:
837 bValidRealString = FALSE;
838 break;
839 }
840 /* Process next character.
841 */
842 pChar++;
843 }
844
845 /* If the required digits were not present we have an invalid
846 * string representation of a real number.
847 */
848 if( bDigitsRequired == TRUE )
849 {
850 bValidRealString = FALSE;
851 }
852
853 return bValidRealString;
854}
855
856
857/******************************************************************************
858 * Coerce [INTERNAL]
859 *
860 * This function dispatches execution to the proper conversion API
861 * to do the necessary coercion.
862 */
863static HRESULT Coerce( VARIANTARG* pd, LCID lcid, ULONG dwFlags, VARIANTARG* ps, VARTYPE vt )
864{
865 HRESULT res = S_OK;
866 unsigned short vtFrom = 0;
867 vtFrom = ps->vt & VT_TYPEMASK;
868
869 /* Note: Since "long" and "int" values both have 4 bytes and are both signed integers
870 * "int" will be treated as "long" in the following code.
871 * The same goes for there unsigned versions.
872 */
873
874 switch( vt )
875 {
876
877 case( VT_EMPTY ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000878 res = VariantClear( pd );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000879 break;
880 case( VT_NULL ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000881 res = VariantClear( pd );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000882 if( res == S_OK )
883 {
884 pd->vt = VT_NULL;
885 }
886 break;
887 case( VT_I1 ):
888 switch( vtFrom )
889 {
890 case( VT_I1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000891 res = VariantCopy( pd, ps );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000892 break;
893 case( VT_I2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000894 res = VarI1FromI2( ps->u.iVal, &(pd->u.cVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000895 break;
896 case( VT_INT ):
897 case( VT_I4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000898 res = VarI1FromI4( ps->u.lVal, &(pd->u.cVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000899 break;
900 case( VT_UI1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000901 res = VarI1FromUI1( ps->u.bVal, &(pd->u.cVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000902 break;
903 case( VT_UI2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000904 res = VarI1FromUI2( ps->u.uiVal, &(pd->u.cVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000905 break;
906 case( VT_UINT ):
907 case( VT_UI4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000908 res = VarI1FromUI4( ps->u.ulVal, &(pd->u.cVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000909 break;
910 case( VT_R4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000911 res = VarI1FromR4( ps->u.fltVal, &(pd->u.cVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000912 break;
913 case( VT_R8 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000914 res = VarI1FromR8( ps->u.dblVal, &(pd->u.cVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000915 break;
916 case( VT_DATE ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000917 res = VarI1FromDate( ps->u.date, &(pd->u.cVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000918 break;
919 case( VT_BOOL ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000920 res = VarI1FromBool( ps->u.boolVal, &(pd->u.cVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000921 break;
922 case( VT_BSTR ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000923 res = VarI1FromStr( ps->u.bstrVal, lcid, dwFlags, &(pd->u.cVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000924 break;
925 case( VT_CY ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000926 res = VarI1FromCy( ps->u.cyVal, &(pd->u.cVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000927 case( VT_DISPATCH ):
928 /*res = VarI1FromDisp32( ps->u.pdispVal, lcid, &(pd->u.cVal) );*/
929 case( VT_UNKNOWN ):
930 /*res = VarI1From32( ps->u.lVal, &(pd->u.cVal) );*/
931 case( VT_DECIMAL ):
932 /*res = VarI1FromDec32( ps->u.decVal, &(pd->u.cVal) );*/
933 default:
934 res = DISP_E_TYPEMISMATCH;
935 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
936 break;
937 }
938 break;
939
940 case( VT_I2 ):
941 switch( vtFrom )
942 {
943 case( VT_I1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000944 res = VarI2FromI1( ps->u.cVal, &(pd->u.iVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000945 break;
946 case( VT_I2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000947 res = VariantCopy( pd, ps );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000948 break;
949 case( VT_INT ):
950 case( VT_I4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000951 res = VarI2FromI4( ps->u.lVal, &(pd->u.iVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000952 break;
953 case( VT_UI1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000954 res = VarI2FromUI1( ps->u.bVal, &(pd->u.iVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000955 break;
956 case( VT_UI2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000957 res = VarI2FromUI2( ps->u.uiVal, &(pd->u.iVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000958 break;
959 case( VT_UINT ):
960 case( VT_UI4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000961 res = VarI2FromUI4( ps->u.ulVal, &(pd->u.iVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000962 break;
963 case( VT_R4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000964 res = VarI2FromR4( ps->u.fltVal, &(pd->u.iVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000965 break;
966 case( VT_R8 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000967 res = VarI2FromR8( ps->u.dblVal, &(pd->u.iVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000968 break;
969 case( VT_DATE ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000970 res = VarI2FromDate( ps->u.date, &(pd->u.iVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000971 break;
972 case( VT_BOOL ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000973 res = VarI2FromBool( ps->u.boolVal, &(pd->u.iVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000974 break;
975 case( VT_BSTR ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000976 res = VarI2FromStr( ps->u.bstrVal, lcid, dwFlags, &(pd->u.iVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000977 break;
978 case( VT_CY ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000979 res = VarI2FromCy( ps->u.cyVal, &(pd->u.iVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000980 case( VT_DISPATCH ):
981 /*res = VarI2FromDisp32( ps->u.pdispVal, lcid, &(pd->u.iVal) );*/
982 case( VT_UNKNOWN ):
983 /*res = VarI2From32( ps->u.lVal, &(pd->u.iVal) );*/
984 case( VT_DECIMAL ):
985 /*res = VarI2FromDec32( ps->u.deiVal, &(pd->u.iVal) );*/
986 default:
987 res = DISP_E_TYPEMISMATCH;
988 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
989 break;
990 }
991 break;
992
993 case( VT_INT ):
994 case( VT_I4 ):
995 switch( vtFrom )
996 {
997 case( VT_I1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +0000998 res = VarI4FromI1( ps->u.cVal, &(pd->u.lVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000999 break;
1000 case( VT_I2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001001 res = VarI4FromI2( ps->u.iVal, &(pd->u.lVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001002 break;
1003 case( VT_INT ):
1004 case( VT_I4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001005 res = VariantCopy( pd, ps );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001006 break;
1007 case( VT_UI1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001008 res = VarI4FromUI1( ps->u.bVal, &(pd->u.lVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001009 break;
1010 case( VT_UI2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001011 res = VarI4FromUI2( ps->u.uiVal, &(pd->u.lVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001012 break;
1013 case( VT_UINT ):
1014 case( VT_UI4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001015 res = VarI4FromUI4( ps->u.ulVal, &(pd->u.lVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001016 break;
1017 case( VT_R4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001018 res = VarI4FromR4( ps->u.fltVal, &(pd->u.lVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001019 break;
1020 case( VT_R8 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001021 res = VarI4FromR8( ps->u.dblVal, &(pd->u.lVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001022 break;
1023 case( VT_DATE ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001024 res = VarI4FromDate( ps->u.date, &(pd->u.lVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001025 break;
1026 case( VT_BOOL ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001027 res = VarI4FromBool( ps->u.boolVal, &(pd->u.lVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001028 break;
1029 case( VT_BSTR ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001030 res = VarI4FromStr( ps->u.bstrVal, lcid, dwFlags, &(pd->u.lVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001031 break;
1032 case( VT_CY ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001033 res = VarI4FromCy( ps->u.cyVal, &(pd->u.lVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001034 case( VT_DISPATCH ):
1035 /*res = VarI4FromDisp32( ps->u.pdispVal, lcid, &(pd->u.lVal) );*/
1036 case( VT_UNKNOWN ):
1037 /*res = VarI4From32( ps->u.lVal, &(pd->u.lVal) );*/
1038 case( VT_DECIMAL ):
1039 /*res = VarI4FromDec32( ps->u.deiVal, &(pd->u.lVal) );*/
1040 default:
1041 res = DISP_E_TYPEMISMATCH;
1042 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1043 break;
1044 }
1045 break;
1046
1047 case( VT_UI1 ):
1048 switch( vtFrom )
1049 {
1050 case( VT_I1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001051 res = VarUI1FromI1( ps->u.cVal, &(pd->u.bVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001052 break;
1053 case( VT_I2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001054 res = VarUI1FromI2( ps->u.iVal, &(pd->u.bVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001055 break;
1056 case( VT_INT ):
1057 case( VT_I4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001058 res = VarUI1FromI4( ps->u.lVal, &(pd->u.bVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001059 break;
1060 case( VT_UI1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001061 res = VariantCopy( pd, ps );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001062 break;
1063 case( VT_UI2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001064 res = VarUI1FromUI2( ps->u.uiVal, &(pd->u.bVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001065 break;
1066 case( VT_UINT ):
1067 case( VT_UI4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001068 res = VarUI1FromUI4( ps->u.ulVal, &(pd->u.bVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001069 break;
1070 case( VT_R4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001071 res = VarUI1FromR4( ps->u.fltVal, &(pd->u.bVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001072 break;
1073 case( VT_R8 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001074 res = VarUI1FromR8( ps->u.dblVal, &(pd->u.bVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001075 break;
1076 case( VT_DATE ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001077 res = VarUI1FromDate( ps->u.date, &(pd->u.bVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001078 break;
1079 case( VT_BOOL ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001080 res = VarUI1FromBool( ps->u.boolVal, &(pd->u.bVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001081 break;
1082 case( VT_BSTR ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001083 res = VarUI1FromStr( ps->u.bstrVal, lcid, dwFlags, &(pd->u.bVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001084 break;
1085 case( VT_CY ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001086 res = VarUI1FromCy( ps->u.cyVal, &(pd->u.bVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001087 case( VT_DISPATCH ):
1088 /*res = VarUI1FromDisp32( ps->u.pdispVal, lcid, &(pd->u.bVal) );*/
1089 case( VT_UNKNOWN ):
1090 /*res = VarUI1From32( ps->u.lVal, &(pd->u.bVal) );*/
1091 case( VT_DECIMAL ):
1092 /*res = VarUI1FromDec32( ps->u.deiVal, &(pd->u.bVal) );*/
1093 default:
1094 res = DISP_E_TYPEMISMATCH;
1095 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1096 break;
1097 }
1098 break;
1099
1100 case( VT_UI2 ):
1101 switch( vtFrom )
1102 {
1103 case( VT_I1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001104 res = VarUI2FromI1( ps->u.cVal, &(pd->u.uiVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001105 break;
1106 case( VT_I2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001107 res = VarUI2FromI2( ps->u.iVal, &(pd->u.uiVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001108 break;
1109 case( VT_INT ):
1110 case( VT_I4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001111 res = VarUI2FromI4( ps->u.lVal, &(pd->u.uiVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001112 break;
1113 case( VT_UI1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001114 res = VarUI2FromUI1( ps->u.bVal, &(pd->u.uiVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001115 break;
1116 case( VT_UI2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001117 res = VariantCopy( pd, ps );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001118 break;
1119 case( VT_UINT ):
1120 case( VT_UI4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001121 res = VarUI2FromUI4( ps->u.ulVal, &(pd->u.uiVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001122 break;
1123 case( VT_R4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001124 res = VarUI2FromR4( ps->u.fltVal, &(pd->u.uiVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001125 break;
1126 case( VT_R8 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001127 res = VarUI2FromR8( ps->u.dblVal, &(pd->u.uiVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001128 break;
1129 case( VT_DATE ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001130 res = VarUI2FromDate( ps->u.date, &(pd->u.uiVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001131 break;
1132 case( VT_BOOL ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001133 res = VarUI2FromBool( ps->u.boolVal, &(pd->u.uiVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001134 break;
1135 case( VT_BSTR ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001136 res = VarUI2FromStr( ps->u.bstrVal, lcid, dwFlags, &(pd->u.uiVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001137 break;
1138 case( VT_CY ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001139 res = VarUI2FromCy( ps->u.cyVal, &(pd->u.uiVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001140 case( VT_DISPATCH ):
1141 /*res = VarUI2FromDisp32( ps->u.pdispVal, lcid, &(pd->u.uiVal) );*/
1142 case( VT_UNKNOWN ):
1143 /*res = VarUI2From32( ps->u.lVal, &(pd->u.uiVal) );*/
1144 case( VT_DECIMAL ):
1145 /*res = VarUI2FromDec32( ps->u.deiVal, &(pd->u.uiVal) );*/
1146 default:
1147 res = DISP_E_TYPEMISMATCH;
1148 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1149 break;
1150 }
1151 break;
1152
1153 case( VT_UINT ):
1154 case( VT_UI4 ):
1155 switch( vtFrom )
1156 {
1157 case( VT_I1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001158 res = VarUI4FromI1( ps->u.cVal, &(pd->u.ulVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001159 break;
1160 case( VT_I2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001161 res = VarUI4FromI2( ps->u.iVal, &(pd->u.ulVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001162 break;
1163 case( VT_INT ):
1164 case( VT_I4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001165 res = VarUI4FromI4( ps->u.lVal, &(pd->u.ulVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001166 break;
1167 case( VT_UI1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001168 res = VarUI4FromUI1( ps->u.bVal, &(pd->u.ulVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001169 break;
1170 case( VT_UI2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001171 res = VarUI4FromUI2( ps->u.uiVal, &(pd->u.ulVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001172 break;
1173 case( VT_UI4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001174 res = VariantCopy( pd, ps );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001175 break;
1176 case( VT_R4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001177 res = VarUI4FromR4( ps->u.fltVal, &(pd->u.ulVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001178 break;
1179 case( VT_R8 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001180 res = VarUI4FromR8( ps->u.dblVal, &(pd->u.ulVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001181 break;
1182 case( VT_DATE ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001183 res = VarUI4FromDate( ps->u.date, &(pd->u.ulVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001184 break;
1185 case( VT_BOOL ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001186 res = VarUI4FromBool( ps->u.boolVal, &(pd->u.ulVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001187 break;
1188 case( VT_BSTR ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001189 res = VarUI4FromStr( ps->u.bstrVal, lcid, dwFlags, &(pd->u.ulVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001190 break;
1191 case( VT_CY ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001192 res = VarUI4FromCy( ps->u.cyVal, &(pd->u.ulVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001193 case( VT_DISPATCH ):
1194 /*res = VarUI4FromDisp32( ps->u.pdispVal, lcid, &(pd->u.ulVal) );*/
1195 case( VT_UNKNOWN ):
1196 /*res = VarUI4From32( ps->u.lVal, &(pd->u.ulVal) );*/
1197 case( VT_DECIMAL ):
1198 /*res = VarUI4FromDec32( ps->u.deiVal, &(pd->u.ulVal) );*/
1199 default:
1200 res = DISP_E_TYPEMISMATCH;
1201 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1202 break;
1203 }
1204 break;
1205
1206 case( VT_R4 ):
1207 switch( vtFrom )
1208 {
1209 case( VT_I1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001210 res = VarR4FromI1( ps->u.cVal, &(pd->u.fltVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001211 break;
1212 case( VT_I2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001213 res = VarR4FromI2( ps->u.iVal, &(pd->u.fltVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001214 break;
1215 case( VT_INT ):
1216 case( VT_I4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001217 res = VarR4FromI4( ps->u.lVal, &(pd->u.fltVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001218 break;
1219 case( VT_UI1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001220 res = VarR4FromUI1( ps->u.bVal, &(pd->u.fltVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001221 break;
1222 case( VT_UI2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001223 res = VarR4FromUI2( ps->u.uiVal, &(pd->u.fltVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001224 break;
1225 case( VT_UINT ):
1226 case( VT_UI4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001227 res = VarR4FromUI4( ps->u.ulVal, &(pd->u.fltVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001228 break;
1229 case( VT_R4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001230 res = VariantCopy( pd, ps );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001231 break;
1232 case( VT_R8 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001233 res = VarR4FromR8( ps->u.dblVal, &(pd->u.fltVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001234 break;
1235 case( VT_DATE ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001236 res = VarR4FromDate( ps->u.date, &(pd->u.fltVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001237 break;
1238 case( VT_BOOL ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001239 res = VarR4FromBool( ps->u.boolVal, &(pd->u.fltVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001240 break;
1241 case( VT_BSTR ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001242 res = VarR4FromStr( ps->u.bstrVal, lcid, dwFlags, &(pd->u.fltVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001243 break;
1244 case( VT_CY ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001245 res = VarR4FromCy( ps->u.cyVal, &(pd->u.fltVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001246 case( VT_DISPATCH ):
1247 /*res = VarR4FromDisp32( ps->u.pdispVal, lcid, &(pd->u.fltVal) );*/
1248 case( VT_UNKNOWN ):
1249 /*res = VarR4From32( ps->u.lVal, &(pd->u.fltVal) );*/
1250 case( VT_DECIMAL ):
1251 /*res = VarR4FromDec32( ps->u.deiVal, &(pd->u.fltVal) );*/
1252 default:
1253 res = DISP_E_TYPEMISMATCH;
1254 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1255 break;
1256 }
1257 break;
1258
1259 case( VT_R8 ):
1260 switch( vtFrom )
1261 {
1262 case( VT_I1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001263 res = VarR8FromI1( ps->u.cVal, &(pd->u.dblVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001264 break;
1265 case( VT_I2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001266 res = VarR8FromI2( ps->u.iVal, &(pd->u.dblVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001267 break;
1268 case( VT_INT ):
1269 case( VT_I4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001270 res = VarR8FromI4( ps->u.lVal, &(pd->u.dblVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001271 break;
1272 case( VT_UI1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001273 res = VarR8FromUI1( ps->u.bVal, &(pd->u.dblVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001274 break;
1275 case( VT_UI2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001276 res = VarR8FromUI2( ps->u.uiVal, &(pd->u.dblVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001277 break;
1278 case( VT_UINT ):
1279 case( VT_UI4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001280 res = VarR8FromUI4( ps->u.ulVal, &(pd->u.dblVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001281 break;
1282 case( VT_R4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001283 res = VarR8FromR4( ps->u.fltVal, &(pd->u.dblVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001284 break;
1285 case( VT_R8 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001286 res = VariantCopy( pd, ps );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001287 break;
1288 case( VT_DATE ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001289 res = VarR8FromDate( ps->u.date, &(pd->u.dblVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001290 break;
1291 case( VT_BOOL ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001292 res = VarR8FromBool( ps->u.boolVal, &(pd->u.dblVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001293 break;
1294 case( VT_BSTR ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001295 res = VarR8FromStr( ps->u.bstrVal, lcid, dwFlags, &(pd->u.dblVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001296 break;
1297 case( VT_CY ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001298 res = VarR8FromCy( ps->u.cyVal, &(pd->u.dblVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001299 case( VT_DISPATCH ):
1300 /*res = VarR8FromDisp32( ps->u.pdispVal, lcid, &(pd->u.dblVal) );*/
1301 case( VT_UNKNOWN ):
1302 /*res = VarR8From32( ps->u.lVal, &(pd->u.dblVal) );*/
1303 case( VT_DECIMAL ):
1304 /*res = VarR8FromDec32( ps->u.deiVal, &(pd->u.dblVal) );*/
1305 default:
1306 res = DISP_E_TYPEMISMATCH;
1307 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1308 break;
1309 }
1310 break;
1311
1312 case( VT_DATE ):
1313 switch( vtFrom )
1314 {
1315 case( VT_I1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001316 res = VarDateFromI1( ps->u.cVal, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001317 break;
1318 case( VT_I2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001319 res = VarDateFromI2( ps->u.iVal, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001320 break;
1321 case( VT_INT ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001322 res = VarDateFromInt( ps->u.intVal, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001323 break;
1324 case( VT_I4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001325 res = VarDateFromI4( ps->u.lVal, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001326 break;
1327 case( VT_UI1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001328 res = VarDateFromUI1( ps->u.bVal, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001329 break;
1330 case( VT_UI2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001331 res = VarDateFromUI2( ps->u.uiVal, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001332 break;
1333 case( VT_UINT ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001334 res = VarDateFromUint( ps->u.uintVal, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001335 break;
1336 case( VT_UI4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001337 res = VarDateFromUI4( ps->u.ulVal, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001338 break;
1339 case( VT_R4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001340 res = VarDateFromR4( ps->u.fltVal, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001341 break;
1342 case( VT_R8 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001343 res = VarDateFromR8( ps->u.dblVal, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001344 break;
1345 case( VT_DATE ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001346 res = VariantCopy( pd, ps );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001347 break;
1348 case( VT_BOOL ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001349 res = VarDateFromBool( ps->u.boolVal, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001350 break;
1351 case( VT_BSTR ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001352 res = VarDateFromStr( ps->u.bstrVal, lcid, dwFlags, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001353 break;
1354 case( VT_CY ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001355 res = VarDateFromCy( ps->u.cyVal, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001356 case( VT_DISPATCH ):
1357 /*res = VarDateFromDisp32( ps->u.pdispVal, lcid, &(pd->u.date) );*/
1358 case( VT_UNKNOWN ):
1359 /*res = VarDateFrom32( ps->u.lVal, &(pd->u.date) );*/
1360 case( VT_DECIMAL ):
1361 /*res = VarDateFromDec32( ps->u.deiVal, &(pd->u.date) );*/
1362 default:
1363 res = DISP_E_TYPEMISMATCH;
1364 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1365 break;
1366 }
1367 break;
1368
1369 case( VT_BOOL ):
1370 switch( vtFrom )
1371 {
1372 case( VT_I1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001373 res = VarBoolFromI1( ps->u.cVal, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001374 break;
1375 case( VT_I2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001376 res = VarBoolFromI2( ps->u.iVal, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001377 break;
1378 case( VT_INT ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001379 res = VarBoolFromInt( ps->u.intVal, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001380 break;
1381 case( VT_I4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001382 res = VarBoolFromI4( ps->u.lVal, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001383 break;
1384 case( VT_UI1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001385 res = VarBoolFromUI1( ps->u.bVal, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001386 break;
1387 case( VT_UI2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001388 res = VarBoolFromUI2( ps->u.uiVal, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001389 break;
1390 case( VT_UINT ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001391 res = VarBoolFromUint( ps->u.uintVal, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001392 break;
1393 case( VT_UI4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001394 res = VarBoolFromUI4( ps->u.ulVal, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001395 break;
1396 case( VT_R4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001397 res = VarBoolFromR4( ps->u.fltVal, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001398 break;
1399 case( VT_R8 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001400 res = VarBoolFromR8( ps->u.dblVal, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001401 break;
1402 case( VT_DATE ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001403 res = VarBoolFromDate( ps->u.date, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001404 break;
1405 case( VT_BOOL ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001406 res = VariantCopy( pd, ps );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001407 break;
1408 case( VT_BSTR ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001409 res = VarBoolFromStr( ps->u.bstrVal, lcid, dwFlags, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001410 break;
1411 case( VT_CY ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001412 res = VarBoolFromCy( ps->u.cyVal, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001413 case( VT_DISPATCH ):
1414 /*res = VarBoolFromDisp32( ps->u.pdispVal, lcid, &(pd->u.boolVal) );*/
1415 case( VT_UNKNOWN ):
1416 /*res = VarBoolFrom32( ps->u.lVal, &(pd->u.boolVal) );*/
1417 case( VT_DECIMAL ):
1418 /*res = VarBoolFromDec32( ps->u.deiVal, &(pd->u.boolVal) );*/
1419 default:
1420 res = DISP_E_TYPEMISMATCH;
1421 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1422 break;
1423 }
1424 break;
1425
1426 case( VT_BSTR ):
1427 switch( vtFrom )
1428 {
1429 case( VT_I1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001430 res = VarBstrFromI1( ps->u.cVal, lcid, dwFlags, &(pd->u.bstrVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001431 break;
1432 case( VT_I2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001433 res = VarBstrFromI2( ps->u.iVal, lcid, dwFlags, &(pd->u.bstrVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001434 break;
1435 case( VT_INT ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001436 res = VarBstrFromInt( ps->u.intVal, lcid, dwFlags, &(pd->u.bstrVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001437 break;
1438 case( VT_I4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001439 res = VarBstrFromI4( ps->u.lVal, lcid, dwFlags, &(pd->u.bstrVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001440 break;
1441 case( VT_UI1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001442 res = VarBstrFromUI1( ps->u.bVal, lcid, dwFlags, &(pd->u.bstrVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001443 break;
1444 case( VT_UI2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001445 res = VarBstrFromUI2( ps->u.uiVal, lcid, dwFlags, &(pd->u.bstrVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001446 break;
1447 case( VT_UINT ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001448 res = VarBstrFromUint( ps->u.uintVal, lcid, dwFlags, &(pd->u.bstrVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001449 break;
1450 case( VT_UI4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001451 res = VarBstrFromUI4( ps->u.ulVal, lcid, dwFlags, &(pd->u.bstrVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001452 break;
1453 case( VT_R4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001454 res = VarBstrFromR4( ps->u.fltVal, lcid, dwFlags, &(pd->u.bstrVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001455 break;
1456 case( VT_R8 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001457 res = VarBstrFromR8( ps->u.dblVal, lcid, dwFlags, &(pd->u.bstrVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001458 break;
1459 case( VT_DATE ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001460 res = VarBstrFromDate( ps->u.date, lcid, dwFlags, &(pd->u.bstrVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001461 break;
1462 case( VT_BOOL ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001463 res = VarBstrFromBool( ps->u.boolVal, lcid, dwFlags, &(pd->u.bstrVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001464 break;
1465 case( VT_BSTR ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001466 res = VariantCopy( pd, ps );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001467 break;
1468 case( VT_CY ):
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001469 /*res = VarBstrFromCy32( ps->u.cyVal, lcid, dwFlags, &(pd->u.bstrVal) );*/
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001470 case( VT_DISPATCH ):
1471 /*res = VarBstrFromDisp32( ps->u.pdispVal, lcid, lcid, dwFlags, &(pd->u.bstrVal) );*/
1472 case( VT_UNKNOWN ):
1473 /*res = VarBstrFrom32( ps->u.lVal, lcid, dwFlags, &(pd->u.bstrVal) );*/
1474 case( VT_DECIMAL ):
1475 /*res = VarBstrFromDec32( ps->u.deiVal, lcid, dwFlags, &(pd->u.bstrVal) );*/
1476 default:
1477 res = DISP_E_TYPEMISMATCH;
1478 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1479 break;
1480 }
1481 break;
1482
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001483 case( VT_CY ):
1484 switch( vtFrom )
1485 {
1486 case( VT_I1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001487 res = VarCyFromI1( ps->u.cVal, &(pd->u.cyVal) );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001488 break;
1489 case( VT_I2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001490 res = VarCyFromI2( ps->u.iVal, &(pd->u.cyVal) );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001491 break;
1492 case( VT_INT ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001493 res = VarCyFromInt( ps->u.intVal, &(pd->u.cyVal) );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001494 break;
1495 case( VT_I4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001496 res = VarCyFromI4( ps->u.lVal, &(pd->u.cyVal) );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001497 break;
1498 case( VT_UI1 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001499 res = VarCyFromUI1( ps->u.bVal, &(pd->u.cyVal) );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001500 break;
1501 case( VT_UI2 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001502 res = VarCyFromUI2( ps->u.uiVal, &(pd->u.cyVal) );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001503 break;
1504 case( VT_UINT ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001505 res = VarCyFromUint( ps->u.uintVal, &(pd->u.cyVal) );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001506 break;
1507 case( VT_UI4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001508 res = VarCyFromUI4( ps->u.ulVal, &(pd->u.cyVal) );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001509 break;
1510 case( VT_R4 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001511 res = VarCyFromR4( ps->u.fltVal, &(pd->u.cyVal) );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001512 break;
1513 case( VT_R8 ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001514 res = VarCyFromR8( ps->u.dblVal, &(pd->u.cyVal) );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001515 break;
1516 case( VT_DATE ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001517 res = VarCyFromDate( ps->u.date, &(pd->u.cyVal) );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001518 break;
1519 case( VT_BOOL ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001520 res = VarCyFromBool( ps->u.date, &(pd->u.cyVal) );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001521 break;
1522 case( VT_CY ):
Alexandre Julliarda3960291999-02-26 11:11:13 +00001523 res = VariantCopy( pd, ps );
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001524 break;
1525 case( VT_BSTR ):
1526 /*res = VarCyFromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.cyVal) );*/
1527 case( VT_DISPATCH ):
1528 /*res = VarCyFromDisp32( ps->u.pdispVal, lcid, &(pd->u.boolVal) );*/
1529 case( VT_UNKNOWN ):
1530 /*res = VarCyFrom32( ps->u.lVal, &(pd->u.boolVal) );*/
1531 case( VT_DECIMAL ):
1532 /*res = VarCyFromDec32( ps->u.deiVal, &(pd->u.boolVal) );*/
1533 default:
1534 res = DISP_E_TYPEMISMATCH;
1535 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1536 break;
1537 }
1538 break;
1539
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001540 default:
1541 res = DISP_E_TYPEMISMATCH;
1542 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1543 break;
1544 }
1545
1546 return res;
1547}
1548
1549/******************************************************************************
1550 * ValidateVtRange [INTERNAL]
1551 *
1552 * Used internally by the hi-level Variant API to determine
1553 * if the vartypes are valid.
1554 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00001555static HRESULT WINAPI ValidateVtRange( VARTYPE vt )
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001556{
1557 /* if by value we must make sure it is in the
1558 * range of the valid types.
1559 */
1560 if( ( vt & VT_TYPEMASK ) > VT_MAXVALIDTYPE )
1561 {
1562 return DISP_E_BADVARTYPE;
1563 }
1564 return S_OK;
1565}
1566
1567
1568/******************************************************************************
1569 * ValidateVartype [INTERNAL]
1570 *
1571 * Used internally by the hi-level Variant API to determine
1572 * if the vartypes are valid.
1573 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00001574static HRESULT WINAPI ValidateVariantType( VARTYPE vt )
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001575{
1576 HRESULT res = S_OK;
1577
1578 /* check if we have a valid argument.
1579 */
1580 if( vt & VT_BYREF )
1581 {
1582 /* if by reference check that the type is in
1583 * the valid range and that it is not of empty or null type
1584 */
1585 if( ( vt & VT_TYPEMASK ) == VT_EMPTY ||
1586 ( vt & VT_TYPEMASK ) == VT_NULL ||
1587 ( vt & VT_TYPEMASK ) > VT_MAXVALIDTYPE )
1588 {
1589 res = E_INVALIDARG;
1590 }
1591
1592 }
1593 else
1594 {
1595 res = ValidateVtRange( vt );
1596 }
1597
1598 return res;
1599}
1600
1601/******************************************************************************
1602 * ValidateVt [INTERNAL]
1603 *
1604 * Used internally by the hi-level Variant API to determine
1605 * if the vartypes are valid.
1606 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00001607static HRESULT WINAPI ValidateVt( VARTYPE vt )
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001608{
1609 HRESULT res = S_OK;
1610
1611 /* check if we have a valid argument.
1612 */
1613 if( vt & VT_BYREF )
1614 {
1615 /* if by reference check that the type is in
1616 * the valid range and that it is not of empty or null type
1617 */
1618 if( ( vt & VT_TYPEMASK ) == VT_EMPTY ||
1619 ( vt & VT_TYPEMASK ) == VT_NULL ||
1620 ( vt & VT_TYPEMASK ) > VT_MAXVALIDTYPE )
1621 {
1622 res = DISP_E_BADVARTYPE;
1623 }
1624
1625 }
1626 else
1627 {
1628 res = ValidateVtRange( vt );
1629 }
1630
1631 return res;
1632}
1633
1634
1635
1636
1637
1638/******************************************************************************
1639 * VariantInit32 [OLEAUT32.8]
1640 *
1641 * Initializes the Variant. Unlike VariantClear it does not interpret the current
1642 * contents of the Variant.
1643 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001644void WINAPI VariantInit(VARIANTARG* pvarg)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001645{
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001646 TRACE(ole,"(%p),stub\n",pvarg);
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001647
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001648 memset(pvarg, 0, sizeof (VARIANTARG));
1649 pvarg->vt = VT_EMPTY;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001650
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001651 return;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001652}
1653
1654/******************************************************************************
1655 * VariantClear32 [OLEAUT32.9]
1656 *
1657 * This function clears the VARIANT by setting the vt field to VT_EMPTY. It also
1658 * sets the wReservedX field to 0. The current contents of the VARIANT are
1659 * freed. If the vt is VT_BSTR the string is freed. If VT_DISPATCH the object is
1660 * released. If VT_ARRAY the array is freed.
1661 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001662HRESULT WINAPI VariantClear(VARIANTARG* pvarg)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001663{
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001664 HRESULT res = S_OK;
1665 TRACE(ole,"(%p)\n",pvarg);
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001666
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001667 res = ValidateVariantType( pvarg->vt );
1668 if( res == S_OK )
1669 {
1670 if( !( pvarg->vt & VT_BYREF ) )
1671 {
1672 /*
1673 * The VT_ARRAY flag is a special case of a safe array.
1674 */
1675 if ( (pvarg->vt & VT_ARRAY) != 0)
1676 {
1677 SafeArrayDestroy(pvarg->u.parray);
1678 }
1679 else
1680 {
1681 switch( pvarg->vt & VT_TYPEMASK )
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001682 {
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001683 case( VT_BSTR ):
1684 SysFreeString( pvarg->u.bstrVal );
1685 break;
1686 case( VT_DISPATCH ):
1687 break;
1688 case( VT_VARIANT ):
1689 break;
1690 case( VT_UNKNOWN ):
1691 break;
1692 case( VT_SAFEARRAY ):
1693 SafeArrayDestroy(pvarg->u.parray);
1694 break;
1695 default:
1696 break;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001697 }
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001698 }
1699 }
1700
1701 /*
1702 * Empty all the fields and mark the type as empty.
1703 */
1704 memset(pvarg, 0, sizeof (VARIANTARG));
1705 pvarg->vt = VT_EMPTY;
1706 }
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001707
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001708 return res;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001709}
1710
1711/******************************************************************************
1712 * VariantCopy32 [OLEAUT32.10]
1713 *
1714 * Frees up the designation variant and makes a copy of the source.
1715 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001716HRESULT WINAPI VariantCopy(VARIANTARG* pvargDest, VARIANTARG* pvargSrc)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001717{
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001718 HRESULT res = S_OK;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001719
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001720 TRACE(ole,"(%p, %p)\n", pvargDest, pvargSrc);
1721
1722 res = ValidateVariantType( pvargSrc->vt );
1723
1724 /* If the pointer are to the same variant we don't need
1725 * to do anything.
1726 */
1727 if( pvargDest != pvargSrc && res == S_OK )
1728 {
1729 res = VariantClear( pvargDest );
1730
1731 if( res == S_OK )
1732 {
1733 if( pvargSrc->vt & VT_BYREF )
1734 {
1735 /* In the case of byreference we only need
1736 * to copy the pointer.
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001737 */
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001738 pvargDest->u = pvargSrc->u;
1739 pvargDest->vt = pvargSrc->vt;
1740 }
1741 else
1742 {
1743 /*
1744 * The VT_ARRAY flag is another way to designate a safe array.
1745 */
1746 if (pvargSrc->vt & VT_ARRAY)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001747 {
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001748 SafeArrayCopy(pvargSrc->u.parray, &pvargDest->u.parray);
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001749 }
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001750 else
1751 {
1752 /* In the case of by value we need to
1753 * copy the actuall value. In the case of
1754 * VT_BSTR a copy of the string is made,
1755 * if VT_DISPATCH or VT_IUNKNOWN AddReff is
1756 * called to increment the object's reference count.
1757 */
1758 switch( pvargSrc->vt & VT_TYPEMASK )
1759 {
1760 case( VT_BSTR ):
1761 pvargDest->u.bstrVal = SysAllocString( pvargSrc->u.bstrVal );
1762 break;
1763 case( VT_DISPATCH ):
1764 break;
1765 case( VT_VARIANT ):
1766 break;
1767 case( VT_UNKNOWN ):
1768 break;
1769 case( VT_SAFEARRAY ):
1770 SafeArrayCopy(pvargSrc->u.parray, &pvargDest->u.parray);
1771 break;
1772 default:
1773 pvargDest->u = pvargSrc->u;
1774 break;
1775 }
1776 }
1777
1778 pvargDest->vt = pvargSrc->vt;
1779 }
1780 }
1781 }
1782
1783 return res;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001784}
1785
1786
1787/******************************************************************************
1788 * VariantCopyInd32 [OLEAUT32.11]
1789 *
1790 * Frees up the destination variant and makes a copy of the source. If
1791 * the source is of type VT_BYREF it performs the necessary indirections.
1792 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001793HRESULT WINAPI VariantCopyInd(VARIANT* pvargDest, VARIANTARG* pvargSrc)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001794{
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001795 HRESULT res = S_OK;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001796
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001797 TRACE(ole,"(%p, %p)\n", pvargDest, pvargSrc);
1798
1799 res = ValidateVariantType( pvargSrc->vt );
1800
1801 if( res != S_OK )
1802 return res;
1803
1804 if( pvargSrc->vt & VT_BYREF )
1805 {
1806 VARIANTARG varg;
1807 VariantInit( &varg );
1808
1809 /* handle the in place copy.
1810 */
1811 if( pvargDest == pvargSrc )
1812 {
1813 /* we will use a copy of the source instead.
1814 */
1815 res = VariantCopy( &varg, pvargSrc );
1816 pvargSrc = &varg;
1817 }
1818
1819 if( res == S_OK )
1820 {
1821 res = VariantClear( pvargDest );
1822
1823 if( res == S_OK )
1824 {
1825 /*
1826 * The VT_ARRAY flag is another way to designate a safearray variant.
1827 */
1828 if ( pvargSrc->vt & VT_ARRAY)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001829 {
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001830 SafeArrayCopy(*pvargSrc->u.pparray, &pvargDest->u.parray);
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001831 }
1832 else
1833 {
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001834 /* In the case of by reference we need
1835 * to copy the date pointed to by the variant.
1836 */
1837
1838 /* Get the variant type.
1839 */
1840 switch( pvargSrc->vt & VT_TYPEMASK )
1841 {
1842 case( VT_BSTR ):
1843 pvargDest->u.bstrVal = SysAllocString( *(pvargSrc->u.pbstrVal) );
1844 break;
1845 case( VT_DISPATCH ):
1846 break;
1847 case( VT_VARIANT ):
1848 {
1849 /* Prevent from cycling. According to tests on
1850 * VariantCopyInd in Windows and the documentation
1851 * this API dereferences the inner Variants to only one depth.
1852 * If the inner Variant itself contains an
1853 * other inner variant the E_INVALIDARG error is
1854 * returned.
1855 */
1856 if( pvargSrc->wReserved1 & PROCESSING_INNER_VARIANT )
1857 {
1858 /* If we get here we are attempting to deference
1859 * an inner variant that that is itself contained
1860 * in an inner variant so report E_INVALIDARG error.
1861 */
1862 res = E_INVALIDARG;
1863 }
1864 else
1865 {
1866 /* Set the processing inner variant flag.
1867 * We will set this flag in the inner variant
1868 * that will be passed to the VariantCopyInd function.
1869 */
1870 (pvargSrc->u.pvarVal)->wReserved1 |= PROCESSING_INNER_VARIANT;
1871
1872 /* Dereference the inner variant.
1873 */
1874 res = VariantCopyInd( pvargDest, pvargSrc->u.pvarVal );
1875 }
1876 }
1877 break;
1878 case( VT_UNKNOWN ):
1879 break;
1880 case( VT_SAFEARRAY ):
1881 SafeArrayCopy(*pvargSrc->u.pparray, &pvargDest->u.parray);
1882 break;
1883 default:
1884 /* This is a by reference Variant which means that the union
1885 * part of the Variant contains a pointer to some data of
1886 * type "pvargSrc->vt & VT_TYPEMASK".
1887 * We will deference this data in a generic fashion using
1888 * the void pointer "Variant.u.byref".
1889 * We will copy this data into the union of the destination
1890 * Variant.
1891 */
1892 memcpy( &pvargDest->u, pvargSrc->u.byref, SizeOfVariantData( pvargSrc ) );
1893 break;
1894 }
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001895 }
Francis Beaudetbc5477f1999-02-28 10:07:12 +00001896
1897 pvargDest->vt = pvargSrc->vt & VT_TYPEMASK;
1898 }
1899 }
1900
1901 /* this should not fail.
1902 */
1903 VariantClear( &varg );
1904 }
1905 else
1906 {
1907 res = VariantCopy( pvargDest, pvargSrc );
1908 }
1909
1910 return res;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001911}
1912
1913/******************************************************************************
1914 * VariantChangeType32 [OLEAUT32.12]
1915 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001916HRESULT WINAPI VariantChangeType(VARIANTARG* pvargDest, VARIANTARG* pvargSrc,
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001917 USHORT wFlags, VARTYPE vt)
1918{
Alexandre Julliarda3960291999-02-26 11:11:13 +00001919 return VariantChangeTypeEx( pvargDest, pvargSrc, 0, wFlags, vt );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001920}
1921
1922/******************************************************************************
1923 * VariantChangeTypeEx32 [OLEAUT32.147]
1924 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001925HRESULT WINAPI VariantChangeTypeEx(VARIANTARG* pvargDest, VARIANTARG* pvargSrc,
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001926 LCID lcid, USHORT wFlags, VARTYPE vt)
1927{
1928 HRESULT res = S_OK;
1929 VARIANTARG varg;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001930 VariantInit( &varg );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001931
1932 TRACE(ole,"(%p, %p, %ld, %u, %u),stub\n", pvargDest, pvargSrc, lcid, wFlags, vt);
1933
1934 /* validate our source argument.
1935 */
1936 res = ValidateVariantType( pvargSrc->vt );
1937
1938 /* validate the vartype.
1939 */
1940 if( res == S_OK )
1941 {
1942 res = ValidateVt( vt );
1943 }
1944
1945 /* if we are doing an in-place conversion make a copy of the source.
1946 */
1947 if( res == S_OK && pvargDest == pvargSrc )
1948 {
Alexandre Julliarda3960291999-02-26 11:11:13 +00001949 res = VariantCopy( &varg, pvargSrc );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001950 pvargSrc = &varg;
1951 }
1952
1953 if( res == S_OK )
1954 {
1955 /* free up the destination variant.
1956 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001957 res = VariantClear( pvargDest );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001958 }
1959
1960 if( res == S_OK )
1961 {
1962 if( pvargSrc->vt & VT_BYREF )
1963 {
1964 /* Convert the source variant to a "byvalue" variant.
1965 */
1966 VARIANTARG Variant;
Alexandre Julliarda3960291999-02-26 11:11:13 +00001967 VariantInit( &Variant );
1968 res = VariantCopyInd( &Variant, pvargSrc );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001969 if( res == S_OK )
1970 {
1971 res = Coerce( pvargDest, lcid, wFlags, &Variant, vt );
1972 /* this should not fail.
1973 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001974 VariantClear( &Variant );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001975 }
1976
1977 }
1978 else
1979 {
1980 /* Use the current "byvalue" source variant.
1981 */
1982 res = Coerce( pvargDest, lcid, wFlags, pvargSrc, vt );
1983 }
1984 }
1985 /* this should not fail.
1986 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001987 VariantClear( &varg );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001988
1989 return res;
1990}
1991
1992
1993
1994
1995/******************************************************************************
1996 * VarUI1FromI232 [OLEAUT32.130]
1997 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00001998HRESULT WINAPI VarUI1FromI2(short sIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001999{
2000 TRACE( ole, "( %d, %p ), stub\n", sIn, pbOut );
2001
2002 /* Check range of value.
2003 */
2004 if( sIn < UI1_MIN || sIn > UI1_MAX )
2005 {
2006 return DISP_E_OVERFLOW;
2007 }
2008
2009 *pbOut = (BYTE) sIn;
2010
2011 return S_OK;
2012}
2013
2014/******************************************************************************
2015 * VarUI1FromI432 [OLEAUT32.131]
2016 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002017HRESULT WINAPI VarUI1FromI4(LONG lIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002018{
2019 TRACE( ole, "( %ld, %p ), stub\n", lIn, pbOut );
2020
2021 /* Check range of value.
2022 */
2023 if( lIn < UI1_MIN || lIn > UI1_MAX )
2024 {
2025 return DISP_E_OVERFLOW;
2026 }
2027
2028 *pbOut = (BYTE) lIn;
2029
2030 return S_OK;
2031}
2032
2033
2034/******************************************************************************
2035 * VarUI1FromR432 [OLEAUT32.132]
2036 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002037HRESULT WINAPI VarUI1FromR4(FLOAT fltIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002038{
2039 TRACE( ole, "( %f, %p ), stub\n", fltIn, pbOut );
2040
2041 /* Check range of value.
2042 */
2043 fltIn = round( fltIn );
2044 if( fltIn < UI1_MIN || fltIn > UI1_MAX )
2045 {
2046 return DISP_E_OVERFLOW;
2047 }
2048
2049 *pbOut = (BYTE) fltIn;
2050
2051 return S_OK;
2052}
2053
2054/******************************************************************************
2055 * VarUI1FromR832 [OLEAUT32.133]
2056 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002057HRESULT WINAPI VarUI1FromR8(double dblIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002058{
2059 TRACE( ole, "( %f, %p ), stub\n", dblIn, pbOut );
2060
2061 /* Check range of value.
2062 */
2063 dblIn = round( dblIn );
2064 if( dblIn < UI1_MIN || dblIn > UI1_MAX )
2065 {
2066 return DISP_E_OVERFLOW;
2067 }
2068
2069 *pbOut = (BYTE) dblIn;
2070
2071 return S_OK;
2072}
2073
2074/******************************************************************************
2075 * VarUI1FromDate32 [OLEAUT32.135]
2076 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002077HRESULT WINAPI VarUI1FromDate(DATE dateIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002078{
2079 TRACE( ole, "( %f, %p ), stub\n", dateIn, pbOut );
2080
2081 /* Check range of value.
2082 */
2083 dateIn = round( dateIn );
2084 if( dateIn < UI1_MIN || dateIn > UI1_MAX )
2085 {
2086 return DISP_E_OVERFLOW;
2087 }
2088
2089 *pbOut = (BYTE) dateIn;
2090
2091 return S_OK;
2092}
2093
2094/******************************************************************************
2095 * VarUI1FromBool32 [OLEAUT32.138]
2096 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002097HRESULT WINAPI VarUI1FromBool(VARIANT_BOOL boolIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002098{
2099 TRACE( ole, "( %d, %p ), stub\n", boolIn, pbOut );
2100
2101 *pbOut = (BYTE) boolIn;
2102
2103 return S_OK;
2104}
2105
2106/******************************************************************************
2107 * VarUI1FromI132 [OLEAUT32.237]
2108 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002109HRESULT WINAPI VarUI1FromI1(CHAR cIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002110{
2111 TRACE( ole, "( %c, %p ), stub\n", cIn, pbOut );
2112
2113 *pbOut = cIn;
2114
2115 return S_OK;
2116}
2117
2118/******************************************************************************
2119 * VarUI1FromUI232 [OLEAUT32.238]
2120 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002121HRESULT WINAPI VarUI1FromUI2(USHORT uiIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002122{
2123 TRACE( ole, "( %d, %p ), stub\n", uiIn, pbOut );
2124
2125 /* Check range of value.
2126 */
2127 if( uiIn > UI1_MAX )
2128 {
2129 return DISP_E_OVERFLOW;
2130 }
2131
2132 *pbOut = (BYTE) uiIn;
2133
2134 return S_OK;
2135}
2136
2137/******************************************************************************
2138 * VarUI1FromUI432 [OLEAUT32.239]
2139 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002140HRESULT WINAPI VarUI1FromUI4(ULONG ulIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002141{
2142 TRACE( ole, "( %ld, %p ), stub\n", ulIn, pbOut );
2143
2144 /* Check range of value.
2145 */
2146 if( ulIn > UI1_MAX )
2147 {
2148 return DISP_E_OVERFLOW;
2149 }
2150
2151 *pbOut = (BYTE) ulIn;
2152
2153 return S_OK;
2154}
2155
2156
2157/******************************************************************************
2158 * VarUI1FromStr32 [OLEAUT32.54]
2159 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002160HRESULT WINAPI VarUI1FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002161{
2162 double dValue = 0.0;
2163 LPSTR pNewString = NULL;
2164
2165 TRACE( ole, "( %p, 0x%08lx, 0x%08lx, %p ), stub\n", strIn, lcid, dwFlags, pbOut );
2166
2167 /* Check if we have a valid argument
2168 */
2169 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
2170 RemoveCharacterFromString( pNewString, "," );
2171 if( IsValidRealString( pNewString ) == FALSE )
2172 {
2173 return DISP_E_TYPEMISMATCH;
2174 }
2175
2176 /* Convert the valid string to a floating point number.
2177 */
2178 dValue = atof( pNewString );
2179
2180 /* We don't need the string anymore so free it.
2181 */
2182 HeapFree( GetProcessHeap(), 0 , pNewString );
2183
2184 /* Check range of value.
2185 */
2186 dValue = round( dValue );
2187 if( dValue < UI1_MIN || dValue > UI1_MAX )
2188 {
2189 return DISP_E_OVERFLOW;
2190 }
2191
2192 *pbOut = (BYTE) dValue;
2193
2194 return S_OK;
2195}
2196
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002197/**********************************************************************
2198 * VarUI1FromCy32 [OLEAUT32.134]
2199 * Convert currency to unsigned char
2200 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002201HRESULT WINAPI VarUI1FromCy(CY cyIn, BYTE* pbOut) {
Todd Vierling7f573251998-12-15 15:15:16 +00002202 double t = round((((double)cyIn.u.Hi * 4294967296.0) + (double)cyIn.u.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002203
2204 if (t > UI1_MAX || t < UI1_MIN) return DISP_E_OVERFLOW;
2205
2206 *pbOut = (BYTE)t;
2207 return S_OK;
2208}
2209
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002210/******************************************************************************
2211 * VarI2FromUI132 [OLEAUT32.48]
2212 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002213HRESULT WINAPI VarI2FromUI1(BYTE bIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002214{
2215 TRACE( ole, "( 0x%08x, %p ), stub\n", bIn, psOut );
2216
2217 *psOut = (short) bIn;
2218
2219 return S_OK;
2220}
2221
2222/******************************************************************************
2223 * VarI2FromI432 [OLEAUT32.49]
2224 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002225HRESULT WINAPI VarI2FromI4(LONG lIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002226{
2227 TRACE( ole, "( %lx, %p ), stub\n", lIn, psOut );
2228
2229 /* Check range of value.
2230 */
2231 if( lIn < I2_MIN || lIn > I2_MAX )
2232 {
2233 return DISP_E_OVERFLOW;
2234 }
2235
2236 *psOut = (short) lIn;
2237
2238 return S_OK;
2239}
2240
2241/******************************************************************************
2242 * VarI2FromR432 [OLEAUT32.50]
2243 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002244HRESULT WINAPI VarI2FromR4(FLOAT fltIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002245{
2246 TRACE( ole, "( %f, %p ), stub\n", fltIn, psOut );
2247
2248 /* Check range of value.
2249 */
2250 fltIn = round( fltIn );
2251 if( fltIn < I2_MIN || fltIn > I2_MAX )
2252 {
2253 return DISP_E_OVERFLOW;
2254 }
2255
2256 *psOut = (short) fltIn;
2257
2258 return S_OK;
2259}
2260
2261/******************************************************************************
2262 * VarI2FromR832 [OLEAUT32.51]
2263 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002264HRESULT WINAPI VarI2FromR8(double dblIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002265{
2266 TRACE( ole, "( %f, %p ), stub\n", dblIn, psOut );
2267
2268 /* Check range of value.
2269 */
2270 dblIn = round( dblIn );
2271 if( dblIn < I2_MIN || dblIn > I2_MAX )
2272 {
2273 return DISP_E_OVERFLOW;
2274 }
2275
2276 *psOut = (short) dblIn;
2277
2278 return S_OK;
2279}
2280
2281/******************************************************************************
2282 * VarI2FromDate32 [OLEAUT32.53]
2283 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002284HRESULT WINAPI VarI2FromDate(DATE dateIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002285{
2286 TRACE( ole, "( %f, %p ), stub\n", dateIn, psOut );
2287
2288 /* Check range of value.
2289 */
2290 dateIn = round( dateIn );
2291 if( dateIn < I2_MIN || dateIn > I2_MAX )
2292 {
2293 return DISP_E_OVERFLOW;
2294 }
2295
2296 *psOut = (short) dateIn;
2297
2298 return S_OK;
2299}
2300
2301/******************************************************************************
2302 * VarI2FromBool32 [OLEAUT32.56]
2303 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002304HRESULT WINAPI VarI2FromBool(VARIANT_BOOL boolIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002305{
2306 TRACE( ole, "( %d, %p ), stub\n", boolIn, psOut );
2307
2308 *psOut = (short) boolIn;
2309
2310 return S_OK;
2311}
2312
2313/******************************************************************************
2314 * VarI2FromI132 [OLEAUT32.48]
2315 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002316HRESULT WINAPI VarI2FromI1(CHAR cIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002317{
2318 TRACE( ole, "( %c, %p ), stub\n", cIn, psOut );
2319
2320 *psOut = (short) cIn;
2321
2322 return S_OK;
2323}
2324
2325/******************************************************************************
2326 * VarI2FromUI232 [OLEAUT32.206]
2327 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002328HRESULT WINAPI VarI2FromUI2(USHORT uiIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002329{
2330 TRACE( ole, "( %d, %p ), stub\n", uiIn, psOut );
2331
2332 /* Check range of value.
2333 */
2334 if( uiIn > I2_MAX )
2335 {
2336 return DISP_E_OVERFLOW;
2337 }
2338
2339 *psOut = (short) uiIn;
2340
2341 return S_OK;
2342}
2343
2344/******************************************************************************
2345 * VarI2FromUI432 [OLEAUT32.49]
2346 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002347HRESULT WINAPI VarI2FromUI4(ULONG ulIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002348{
2349 TRACE( ole, "( %lx, %p ), stub\n", ulIn, psOut );
2350
2351 /* Check range of value.
2352 */
2353 if( ulIn < I2_MIN || ulIn > I2_MAX )
2354 {
2355 return DISP_E_OVERFLOW;
2356 }
2357
2358 *psOut = (short) ulIn;
2359
2360 return S_OK;
2361}
2362
2363/******************************************************************************
2364 * VarI2FromStr32 [OLEAUT32.54]
2365 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002366HRESULT WINAPI VarI2FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002367{
2368 double dValue = 0.0;
2369 LPSTR pNewString = NULL;
2370
2371 TRACE( ole, "( %p, 0x%08lx, 0x%08lx, %p ), stub\n", strIn, lcid, dwFlags, psOut );
2372
2373 /* Check if we have a valid argument
2374 */
2375 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
2376 RemoveCharacterFromString( pNewString, "," );
2377 if( IsValidRealString( pNewString ) == FALSE )
2378 {
2379 return DISP_E_TYPEMISMATCH;
2380 }
2381
2382 /* Convert the valid string to a floating point number.
2383 */
2384 dValue = atof( pNewString );
2385
2386 /* We don't need the string anymore so free it.
2387 */
2388 HeapFree( GetProcessHeap(), 0, pNewString );
2389
2390 /* Check range of value.
2391 */
2392 dValue = round( dValue );
2393 if( dValue < I2_MIN || dValue > I2_MAX )
2394 {
2395 return DISP_E_OVERFLOW;
2396 }
2397
2398 *psOut = (short) dValue;
2399
2400 return S_OK;
2401}
2402
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002403/**********************************************************************
2404 * VarI2FromCy32 [OLEAUT32.52]
2405 * Convert currency to signed short
2406 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002407HRESULT WINAPI VarI2FromCy(CY cyIn, short* psOut) {
Todd Vierling7f573251998-12-15 15:15:16 +00002408 double t = round((((double)cyIn.u.Hi * 4294967296.0) + (double)cyIn.u.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002409
2410 if (t > I2_MAX || t < I2_MIN) return DISP_E_OVERFLOW;
2411
2412 *psOut = (SHORT)t;
2413 return S_OK;
2414}
2415
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002416/******************************************************************************
2417 * VarI4FromUI132 [OLEAUT32.58]
2418 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002419HRESULT WINAPI VarI4FromUI1(BYTE bIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002420{
2421 TRACE( ole, "( %X, %p ), stub\n", bIn, plOut );
2422
2423 *plOut = (LONG) bIn;
2424
2425 return S_OK;
2426}
2427
2428
2429/******************************************************************************
2430 * VarI4FromR432 [OLEAUT32.60]
2431 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002432HRESULT WINAPI VarI4FromR4(FLOAT fltIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002433{
2434 TRACE( ole, "( %f, %p ), stub\n", fltIn, plOut );
2435
2436 /* Check range of value.
2437 */
2438 fltIn = round( fltIn );
2439 if( fltIn < I4_MIN || fltIn > I4_MAX )
2440 {
2441 return DISP_E_OVERFLOW;
2442 }
2443
2444 *plOut = (LONG) fltIn;
2445
2446 return S_OK;
2447}
2448
2449/******************************************************************************
2450 * VarI4FromR832 [OLEAUT32.61]
2451 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002452HRESULT WINAPI VarI4FromR8(double dblIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002453{
2454 TRACE( ole, "( %f, %p ), stub\n", dblIn, plOut );
2455
2456 /* Check range of value.
2457 */
2458 dblIn = round( dblIn );
2459 if( dblIn < I4_MIN || dblIn > I4_MAX )
2460 {
2461 return DISP_E_OVERFLOW;
2462 }
2463
2464 *plOut = (LONG) dblIn;
2465
2466 return S_OK;
2467}
2468
2469/******************************************************************************
2470 * VarI4FromDate32 [OLEAUT32.63]
2471 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002472HRESULT WINAPI VarI4FromDate(DATE dateIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002473{
2474 TRACE( ole, "( %f, %p ), stub\n", dateIn, plOut );
2475
2476 /* Check range of value.
2477 */
2478 dateIn = round( dateIn );
2479 if( dateIn < I4_MIN || dateIn > I4_MAX )
2480 {
2481 return DISP_E_OVERFLOW;
2482 }
2483
2484 *plOut = (LONG) dateIn;
2485
2486 return S_OK;
2487}
2488
2489/******************************************************************************
2490 * VarI4FromBool32 [OLEAUT32.66]
2491 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002492HRESULT WINAPI VarI4FromBool(VARIANT_BOOL boolIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002493{
2494 TRACE( ole, "( %d, %p ), stub\n", boolIn, plOut );
2495
2496 *plOut = (LONG) boolIn;
2497
2498 return S_OK;
2499}
2500
2501/******************************************************************************
2502 * VarI4FromI132 [OLEAUT32.209]
2503 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002504HRESULT WINAPI VarI4FromI1(CHAR cIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002505{
2506 TRACE( ole, "( %c, %p ), stub\n", cIn, plOut );
2507
2508 *plOut = (LONG) cIn;
2509
2510 return S_OK;
2511}
2512
2513/******************************************************************************
2514 * VarI4FromUI232 [OLEAUT32.210]
2515 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002516HRESULT WINAPI VarI4FromUI2(USHORT uiIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002517{
2518 TRACE( ole, "( %d, %p ), stub\n", uiIn, plOut );
2519
2520 *plOut = (LONG) uiIn;
2521
2522 return S_OK;
2523}
2524
2525/******************************************************************************
2526 * VarI4FromUI432 [OLEAUT32.211]
2527 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002528HRESULT WINAPI VarI4FromUI4(ULONG ulIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002529{
2530 TRACE( ole, "( %lx, %p ), stub\n", ulIn, plOut );
2531
2532 /* Check range of value.
2533 */
2534 if( ulIn < I4_MIN || ulIn > I4_MAX )
2535 {
2536 return DISP_E_OVERFLOW;
2537 }
2538
2539 *plOut = (LONG) ulIn;
2540
2541 return S_OK;
2542}
2543
2544/******************************************************************************
2545 * VarI4FromI232 [OLEAUT32.59]
2546 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002547HRESULT WINAPI VarI4FromI2(short sIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002548{
2549 TRACE( ole, "( %d, %p ), stub\n", sIn, plOut );
2550
2551 *plOut = (LONG) sIn;
2552
2553 return S_OK;
2554}
2555
2556/******************************************************************************
2557 * VarI4FromStr32 [OLEAUT32.64]
2558 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002559HRESULT WINAPI VarI4FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002560{
2561 double dValue = 0.0;
2562 LPSTR pNewString = NULL;
2563
2564 TRACE( ole, "( %p, 0x%08lx, 0x%08lx, %p ), stub\n", strIn, lcid, dwFlags, plOut );
2565
2566 /* Check if we have a valid argument
2567 */
2568 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
2569 RemoveCharacterFromString( pNewString, "," );
2570 if( IsValidRealString( pNewString ) == FALSE )
2571 {
2572 return DISP_E_TYPEMISMATCH;
2573 }
2574
2575 /* Convert the valid string to a floating point number.
2576 */
2577 dValue = atof( pNewString );
2578
2579 /* We don't need the string anymore so free it.
2580 */
2581 HeapFree( GetProcessHeap(), 0, pNewString );
2582
2583 /* Check range of value.
2584 */
2585 dValue = round( dValue );
2586 if( dValue < I4_MIN || dValue > I4_MAX )
2587 {
2588 return DISP_E_OVERFLOW;
2589 }
2590
2591 *plOut = (LONG) dValue;
2592
2593 return S_OK;
2594}
2595
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002596/**********************************************************************
2597 * VarI4FromCy32 [OLEAUT32.62]
2598 * Convert currency to signed long
2599 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002600HRESULT WINAPI VarI4FromCy(CY cyIn, LONG* plOut) {
Todd Vierling7f573251998-12-15 15:15:16 +00002601 double t = round((((double)cyIn.u.Hi * 4294967296.0) + (double)cyIn.u.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002602
2603 if (t > I4_MAX || t < I4_MIN) return DISP_E_OVERFLOW;
2604
2605 *plOut = (LONG)t;
2606 return S_OK;
2607}
2608
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002609/******************************************************************************
2610 * VarR4FromUI132 [OLEAUT32.68]
2611 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002612HRESULT WINAPI VarR4FromUI1(BYTE bIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002613{
2614 TRACE( ole, "( %X, %p ), stub\n", bIn, pfltOut );
2615
2616 *pfltOut = (FLOAT) bIn;
2617
2618 return S_OK;
2619}
2620
2621/******************************************************************************
2622 * VarR4FromI232 [OLEAUT32.69]
2623 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002624HRESULT WINAPI VarR4FromI2(short sIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002625{
2626 TRACE( ole, "( %d, %p ), stub\n", sIn, pfltOut );
2627
2628 *pfltOut = (FLOAT) sIn;
2629
2630 return S_OK;
2631}
2632
2633/******************************************************************************
2634 * VarR4FromI432 [OLEAUT32.70]
2635 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002636HRESULT WINAPI VarR4FromI4(LONG lIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002637{
2638 TRACE( ole, "( %lx, %p ), stub\n", lIn, pfltOut );
2639
2640 *pfltOut = (FLOAT) lIn;
2641
2642 return S_OK;
2643}
2644
2645/******************************************************************************
2646 * VarR4FromR832 [OLEAUT32.71]
2647 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002648HRESULT WINAPI VarR4FromR8(double dblIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002649{
2650 TRACE( ole, "( %f, %p ), stub\n", dblIn, pfltOut );
2651
2652 /* Check range of value.
2653 */
2654 if( dblIn < -(FLT_MAX) || dblIn > FLT_MAX )
2655 {
2656 return DISP_E_OVERFLOW;
2657 }
2658
2659 *pfltOut = (FLOAT) dblIn;
2660
2661 return S_OK;
2662}
2663
2664/******************************************************************************
2665 * VarR4FromDate32 [OLEAUT32.73]
2666 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002667HRESULT WINAPI VarR4FromDate(DATE dateIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002668{
2669 TRACE( ole, "( %f, %p ), stub\n", dateIn, pfltOut );
2670
2671 /* Check range of value.
2672 */
2673 if( dateIn < -(FLT_MAX) || dateIn > FLT_MAX )
2674 {
2675 return DISP_E_OVERFLOW;
2676 }
2677
2678 *pfltOut = (FLOAT) dateIn;
2679
2680 return S_OK;
2681}
2682
2683/******************************************************************************
2684 * VarR4FromBool32 [OLEAUT32.76]
2685 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002686HRESULT WINAPI VarR4FromBool(VARIANT_BOOL boolIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002687{
2688 TRACE( ole, "( %d, %p ), stub\n", boolIn, pfltOut );
2689
2690 *pfltOut = (FLOAT) boolIn;
2691
2692 return S_OK;
2693}
2694
2695/******************************************************************************
2696 * VarR4FromI132 [OLEAUT32.213]
2697 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002698HRESULT WINAPI VarR4FromI1(CHAR cIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002699{
2700 TRACE( ole, "( %c, %p ), stub\n", cIn, pfltOut );
2701
2702 *pfltOut = (FLOAT) cIn;
2703
2704 return S_OK;
2705}
2706
2707/******************************************************************************
2708 * VarR4FromUI232 [OLEAUT32.214]
2709 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002710HRESULT WINAPI VarR4FromUI2(USHORT uiIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002711{
2712 TRACE( ole, "( %d, %p ), stub\n", uiIn, pfltOut );
2713
2714 *pfltOut = (FLOAT) uiIn;
2715
2716 return S_OK;
2717}
2718
2719/******************************************************************************
2720 * VarR4FromUI432 [OLEAUT32.215]
2721 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002722HRESULT WINAPI VarR4FromUI4(ULONG ulIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002723{
2724 TRACE( ole, "( %ld, %p ), stub\n", ulIn, pfltOut );
2725
2726 *pfltOut = (FLOAT) ulIn;
2727
2728 return S_OK;
2729}
2730
2731/******************************************************************************
2732 * VarR4FromStr32 [OLEAUT32.74]
2733 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002734HRESULT WINAPI VarR4FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002735{
2736 double dValue = 0.0;
2737 LPSTR pNewString = NULL;
2738
2739 TRACE( ole, "( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, pfltOut );
2740
2741 /* Check if we have a valid argument
2742 */
2743 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
2744 RemoveCharacterFromString( pNewString, "," );
2745 if( IsValidRealString( pNewString ) == FALSE )
2746 {
2747 return DISP_E_TYPEMISMATCH;
2748 }
2749
2750 /* Convert the valid string to a floating point number.
2751 */
2752 dValue = atof( pNewString );
2753
2754 /* We don't need the string anymore so free it.
2755 */
2756 HeapFree( GetProcessHeap(), 0, pNewString );
2757
2758 /* Check range of value.
2759 */
2760 if( dValue < -(FLT_MAX) || dValue > FLT_MAX )
2761 {
2762 return DISP_E_OVERFLOW;
2763 }
2764
2765 *pfltOut = (FLOAT) dValue;
2766
2767 return S_OK;
2768}
2769
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002770/**********************************************************************
2771 * VarR4FromCy32 [OLEAUT32.72]
2772 * Convert currency to float
2773 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002774HRESULT WINAPI VarR4FromCy(CY cyIn, FLOAT* pfltOut) {
Todd Vierling7f573251998-12-15 15:15:16 +00002775 *pfltOut = (FLOAT)((((double)cyIn.u.Hi * 4294967296.0) + (double)cyIn.u.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002776
2777 return S_OK;
2778}
2779
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002780/******************************************************************************
2781 * VarR8FromUI132 [OLEAUT32.68]
2782 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002783HRESULT WINAPI VarR8FromUI1(BYTE bIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002784{
2785 TRACE( ole, "( %d, %p ), stub\n", bIn, pdblOut );
2786
2787 *pdblOut = (double) bIn;
2788
2789 return S_OK;
2790}
2791
2792/******************************************************************************
2793 * VarR8FromI232 [OLEAUT32.69]
2794 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002795HRESULT WINAPI VarR8FromI2(short sIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002796{
2797 TRACE( ole, "( %d, %p ), stub\n", sIn, pdblOut );
2798
2799 *pdblOut = (double) sIn;
2800
2801 return S_OK;
2802}
2803
2804/******************************************************************************
2805 * VarR8FromI432 [OLEAUT32.70]
2806 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002807HRESULT WINAPI VarR8FromI4(LONG lIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002808{
2809 TRACE( ole, "( %ld, %p ), stub\n", lIn, pdblOut );
2810
2811 *pdblOut = (double) lIn;
2812
2813 return S_OK;
2814}
2815
2816/******************************************************************************
2817 * VarR8FromR432 [OLEAUT32.81]
2818 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002819HRESULT WINAPI VarR8FromR4(FLOAT fltIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002820{
2821 TRACE( ole, "( %f, %p ), stub\n", fltIn, pdblOut );
2822
2823 *pdblOut = (double) fltIn;
2824
2825 return S_OK;
2826}
2827
2828/******************************************************************************
2829 * VarR8FromDate32 [OLEAUT32.83]
2830 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002831HRESULT WINAPI VarR8FromDate(DATE dateIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002832{
2833 TRACE( ole, "( %f, %p ), stub\n", dateIn, pdblOut );
2834
2835 *pdblOut = (double) dateIn;
2836
2837 return S_OK;
2838}
2839
2840/******************************************************************************
2841 * VarR8FromBool32 [OLEAUT32.86]
2842 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002843HRESULT WINAPI VarR8FromBool(VARIANT_BOOL boolIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002844{
2845 TRACE( ole, "( %d, %p ), stub\n", boolIn, pdblOut );
2846
2847 *pdblOut = (double) boolIn;
2848
2849 return S_OK;
2850}
2851
2852/******************************************************************************
2853 * VarR8FromI132 [OLEAUT32.217]
2854 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002855HRESULT WINAPI VarR8FromI1(CHAR cIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002856{
2857 TRACE( ole, "( %c, %p ), stub\n", cIn, pdblOut );
2858
2859 *pdblOut = (double) cIn;
2860
2861 return S_OK;
2862}
2863
2864/******************************************************************************
2865 * VarR8FromUI232 [OLEAUT32.218]
2866 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002867HRESULT WINAPI VarR8FromUI2(USHORT uiIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002868{
2869 TRACE( ole, "( %d, %p ), stub\n", uiIn, pdblOut );
2870
2871 *pdblOut = (double) uiIn;
2872
2873 return S_OK;
2874}
2875
2876/******************************************************************************
2877 * VarR8FromUI432 [OLEAUT32.219]
2878 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002879HRESULT WINAPI VarR8FromUI4(ULONG ulIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002880{
2881 TRACE( ole, "( %ld, %p ), stub\n", ulIn, pdblOut );
2882
2883 *pdblOut = (double) ulIn;
2884
2885 return S_OK;
2886}
2887
2888/******************************************************************************
2889 * VarR8FromStr32 [OLEAUT32.84]
2890 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002891HRESULT WINAPI VarR8FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002892{
2893 double dValue = 0.0;
2894 LPSTR pNewString = NULL;
2895
2896 TRACE( ole, "( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, pdblOut );
2897
2898 /* Check if we have a valid argument
2899 */
2900 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
2901 RemoveCharacterFromString( pNewString, "," );
2902 if( IsValidRealString( pNewString ) == FALSE )
2903 {
2904 return DISP_E_TYPEMISMATCH;
2905 }
2906
2907 /* Convert the valid string to a floating point number.
2908 */
2909 dValue = atof( pNewString );
2910
2911 /* We don't need the string anymore so free it.
2912 */
2913 HeapFree( GetProcessHeap(), 0, pNewString );
2914
2915 *pdblOut = dValue;
2916
2917 return S_OK;
2918}
2919
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002920/**********************************************************************
2921 * VarR8FromCy32 [OLEAUT32.82]
2922 * Convert currency to double
2923 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002924HRESULT WINAPI VarR8FromCy(CY cyIn, double* pdblOut) {
Todd Vierling7f573251998-12-15 15:15:16 +00002925 *pdblOut = (double)((((double)cyIn.u.Hi * 4294967296.0) + (double)cyIn.u.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002926
2927 return S_OK;
2928}
2929
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002930/******************************************************************************
2931 * VarDateFromUI132 [OLEAUT32.]
2932 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002933HRESULT WINAPI VarDateFromUI1(BYTE bIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002934{
2935 TRACE( ole, "( %d, %p ), stub\n", bIn, pdateOut );
2936
2937 *pdateOut = (DATE) bIn;
2938
2939 return S_OK;
2940}
2941
2942/******************************************************************************
2943 * VarDateFromI232 [OLEAUT32.222]
2944 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002945HRESULT WINAPI VarDateFromI2(short sIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002946{
2947 TRACE( ole, "( %d, %p ), stub\n", sIn, pdateOut );
2948
2949 *pdateOut = (DATE) sIn;
2950
2951 return S_OK;
2952}
2953
2954/******************************************************************************
2955 * VarDateFromI432 [OLEAUT32.90]
2956 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002957HRESULT WINAPI VarDateFromI4(LONG lIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002958{
2959 TRACE( ole, "( %ld, %p ), stub\n", lIn, pdateOut );
2960
2961 if( lIn < DATE_MIN || lIn > DATE_MAX )
2962 {
2963 return DISP_E_OVERFLOW;
2964 }
2965
2966 *pdateOut = (DATE) lIn;
2967
2968 return S_OK;
2969}
2970
2971/******************************************************************************
2972 * VarDateFromR432 [OLEAUT32.91]
2973 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002974HRESULT WINAPI VarDateFromR4(FLOAT fltIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002975{
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002976 TRACE( ole, "( %f, %p ), stub\n", fltIn, pdateOut );
2977
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +00002978 if( ceil(fltIn) < DATE_MIN || floor(fltIn) > DATE_MAX )
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002979 {
2980 return DISP_E_OVERFLOW;
2981 }
2982
2983 *pdateOut = (DATE) fltIn;
2984
2985 return S_OK;
2986}
2987
2988/******************************************************************************
2989 * VarDateFromR832 [OLEAUT32.92]
2990 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00002991HRESULT WINAPI VarDateFromR8(double dblIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002992{
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002993 TRACE( ole, "( %f, %p ), stub\n", dblIn, pdateOut );
2994
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +00002995 if( ceil(dblIn) < DATE_MIN || floor(dblIn) > DATE_MAX )
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002996 {
2997 return DISP_E_OVERFLOW;
2998 }
2999
3000 *pdateOut = (DATE) dblIn;
3001
3002 return S_OK;
3003}
3004
3005/******************************************************************************
3006 * VarDateFromStr32 [OLEAUT32.94]
3007 * The string representing the date is composed of two parts, a date and time.
3008 *
3009 * The format of the time is has follows:
3010 * hh[:mm][:ss][AM|PM]
3011 * Whitespace can be inserted anywhere between these tokens. A whitespace consists
3012 * of space and/or tab characters, which are ignored.
3013 *
3014 * The formats for the date part are has follows:
3015 * mm/[dd/][yy]yy
3016 * [dd/]mm/[yy]yy
3017 * [yy]yy/mm/dd
3018 * January dd[,] [yy]yy
3019 * dd January [yy]yy
3020 * [yy]yy January dd
3021 * Whitespace can be inserted anywhere between these tokens.
3022 *
3023 * The formats for the date and time string are has follows.
3024 * date[whitespace][time]
3025 * [time][whitespace]date
3026 *
3027 * These are the only characters allowed in a string representing a date and time:
3028 * [A-Z] [a-z] [0-9] ':' '-' '/' ',' ' ' '\t'
3029 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003030HRESULT WINAPI VarDateFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003031{
3032 HRESULT ret = S_OK;
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +00003033 struct tm TM = { 0,0,0,0,0,0,0,0,0 };
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003034
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +00003035 TRACE( ole, "( %p, %lx, %lx, %p ), stub\n", strIn, lcid, dwFlags, pdateOut );
3036
3037 if( DateTimeStringToTm( strIn, lcid, &TM ) )
3038 {
3039 if( TmToDATE( &TM, pdateOut ) == FALSE )
3040 {
3041 ret = E_INVALIDARG;
3042 }
3043 }
3044 else
3045 {
3046 ret = DISP_E_TYPEMISMATCH;
3047 }
3048
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003049
3050 return ret;
3051}
3052
3053/******************************************************************************
3054 * VarDateFromI132 [OLEAUT32.221]
3055 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003056HRESULT WINAPI VarDateFromI1(CHAR cIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003057{
3058 TRACE( ole, "( %c, %p ), stub\n", cIn, pdateOut );
3059
3060 *pdateOut = (DATE) cIn;
3061
3062 return S_OK;
3063}
3064
3065/******************************************************************************
3066 * VarDateFromUI232 [OLEAUT32.222]
3067 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003068HRESULT WINAPI VarDateFromUI2(USHORT uiIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003069{
3070 TRACE( ole, "( %d, %p ), stub\n", uiIn, pdateOut );
3071
3072 if( uiIn > DATE_MAX )
3073 {
3074 return DISP_E_OVERFLOW;
3075 }
3076
3077 *pdateOut = (DATE) uiIn;
3078
3079 return S_OK;
3080}
3081
3082/******************************************************************************
3083 * VarDateFromUI432 [OLEAUT32.223]
3084 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003085HRESULT WINAPI VarDateFromUI4(ULONG ulIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003086{
3087 TRACE( ole, "( %ld, %p ), stub\n", ulIn, pdateOut );
3088
3089 if( ulIn < DATE_MIN || ulIn > DATE_MAX )
3090 {
3091 return DISP_E_OVERFLOW;
3092 }
3093
3094 *pdateOut = (DATE) ulIn;
3095
3096 return S_OK;
3097}
3098
3099/******************************************************************************
3100 * VarDateFromBool32 [OLEAUT32.96]
3101 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003102HRESULT WINAPI VarDateFromBool(VARIANT_BOOL boolIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003103{
3104 TRACE( ole, "( %d, %p ), stub\n", boolIn, pdateOut );
3105
3106 *pdateOut = (DATE) boolIn;
3107
3108 return S_OK;
3109}
3110
Justin Bradfordbc93bc81998-12-11 14:02:16 +00003111/**********************************************************************
3112 * VarDateFromCy32 [OLEAUT32.93]
3113 * Convert currency to date
3114 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003115HRESULT WINAPI VarDateFromCy(CY cyIn, DATE* pdateOut) {
Todd Vierling7f573251998-12-15 15:15:16 +00003116 *pdateOut = (DATE)((((double)cyIn.u.Hi * 4294967296.0) + (double)cyIn.u.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00003117
3118 if (*pdateOut > DATE_MAX || *pdateOut < DATE_MIN) return DISP_E_TYPEMISMATCH;
3119 return S_OK;
3120}
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003121
3122/******************************************************************************
3123 * VarBstrFromUI132 [OLEAUT32.108]
3124 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003125HRESULT WINAPI VarBstrFromUI1(BYTE bVal, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003126{
3127 TRACE( ole, "( %d, %ld, %ld, %p ), stub\n", bVal, lcid, dwFlags, pbstrOut );
3128 sprintf( pBuffer, "%d", bVal );
3129
3130 *pbstrOut = StringDupAtoBstr( pBuffer );
3131
3132 return S_OK;
3133}
3134
3135/******************************************************************************
3136 * VarBstrFromI232 [OLEAUT32.109]
3137 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003138HRESULT WINAPI VarBstrFromI2(short iVal, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003139{
3140 TRACE( ole, "( %d, %ld, %ld, %p ), stub\n", iVal, lcid, dwFlags, pbstrOut );
3141 sprintf( pBuffer, "%d", iVal );
3142 *pbstrOut = StringDupAtoBstr( pBuffer );
3143
3144 return S_OK;
3145}
3146
3147/******************************************************************************
3148 * VarBstrFromI432 [OLEAUT32.110]
3149 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003150HRESULT WINAPI VarBstrFromI4(LONG lIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003151{
3152 TRACE( ole, "( %ld, %ld, %ld, %p ), stub\n", lIn, lcid, dwFlags, pbstrOut );
3153
3154 sprintf( pBuffer, "%ld", lIn );
3155 *pbstrOut = StringDupAtoBstr( pBuffer );
3156
3157 return S_OK;
3158}
3159
3160/******************************************************************************
3161 * VarBstrFromR432 [OLEAUT32.111]
3162 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003163HRESULT WINAPI VarBstrFromR4(FLOAT fltIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003164{
3165 TRACE( ole, "( %f, %ld, %ld, %p ), stub\n", fltIn, lcid, dwFlags, pbstrOut );
3166
3167 sprintf( pBuffer, "%.7g", fltIn );
3168 *pbstrOut = StringDupAtoBstr( pBuffer );
3169
3170 return S_OK;
3171}
3172
3173/******************************************************************************
3174 * VarBstrFromR832 [OLEAUT32.112]
3175 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003176HRESULT WINAPI VarBstrFromR8(double dblIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003177{
3178 TRACE( ole, "( %f, %ld, %ld, %p ), stub\n", dblIn, lcid, dwFlags, pbstrOut );
3179
3180 sprintf( pBuffer, "%.15g", dblIn );
3181 *pbstrOut = StringDupAtoBstr( pBuffer );
3182
3183 return S_OK;
3184}
3185
3186/******************************************************************************
3187 * VarBstrFromDate32 [OLEAUT32.114]
3188 *
3189 * The date is implemented using an 8 byte floating-point number.
3190 * Days are represented by whole numbers increments starting with 0.00 has
3191 * being December 30 1899, midnight.
3192 * The hours are expressed as the fractional part of the number.
3193 * December 30 1899 at midnight = 0.00
3194 * January 1 1900 at midnight = 2.00
3195 * January 4 1900 at 6 AM = 5.25
3196 * January 4 1900 at noon = 5.50
3197 * December 29 1899 at midnight = -1.00
3198 * December 18 1899 at midnight = -12.00
3199 * December 18 1899 at 6AM = -12.25
3200 * December 18 1899 at 6PM = -12.75
3201 * December 19 1899 at midnight = -11.00
3202 * The tm structure is as follows:
3203 * struct tm {
3204 * int tm_sec; seconds after the minute - [0,59]
3205 * int tm_min; minutes after the hour - [0,59]
3206 * int tm_hour; hours since midnight - [0,23]
3207 * int tm_mday; day of the month - [1,31]
3208 * int tm_mon; months since January - [0,11]
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +00003209 * int tm_year; years
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003210 * int tm_wday; days since Sunday - [0,6]
3211 * int tm_yday; days since January 1 - [0,365]
3212 * int tm_isdst; daylight savings time flag
3213 * };
3214 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003215HRESULT WINAPI VarBstrFromDate(DATE dateIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003216{
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003217 struct tm TM = {0,0,0,0,0,0,0,0,0};
3218
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +00003219 TRACE( ole, "( %f, %ld, %ld, %p ), stub\n", dateIn, lcid, dwFlags, pbstrOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003220
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +00003221 if( DateToTm( dateIn, lcid, &TM ) == FALSE )
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003222 {
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +00003223 return E_INVALIDARG;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003224 }
3225
3226 if( lcid & VAR_DATEVALUEONLY )
3227 strftime( pBuffer, BUFFER_MAX, "%x", &TM );
3228 else if( lcid & VAR_TIMEVALUEONLY )
3229 strftime( pBuffer, BUFFER_MAX, "%X", &TM );
3230 else
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +00003231 strftime( pBuffer, BUFFER_MAX, "%x %X", &TM );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003232
3233 *pbstrOut = StringDupAtoBstr( pBuffer );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003234
3235 return S_OK;
3236}
3237
3238/******************************************************************************
3239 * VarBstrFromBool32 [OLEAUT32.116]
3240 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003241HRESULT WINAPI VarBstrFromBool(VARIANT_BOOL boolIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003242{
3243 TRACE( ole, "( %d, %ld, %ld, %p ), stub\n", boolIn, lcid, dwFlags, pbstrOut );
3244
3245 if( boolIn == VARIANT_FALSE )
3246 {
3247 sprintf( pBuffer, "False" );
3248 }
3249 else
3250 {
3251 sprintf( pBuffer, "True" );
3252 }
3253
3254 *pbstrOut = StringDupAtoBstr( pBuffer );
3255
3256 return S_OK;
3257}
3258
3259/******************************************************************************
3260 * VarBstrFromI132 [OLEAUT32.229]
3261 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003262HRESULT WINAPI VarBstrFromI1(CHAR cIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003263{
3264 TRACE( ole, "( %c, %ld, %ld, %p ), stub\n", cIn, lcid, dwFlags, pbstrOut );
3265 sprintf( pBuffer, "%d", cIn );
3266 *pbstrOut = StringDupAtoBstr( pBuffer );
3267
3268 return S_OK;
3269}
3270
3271/******************************************************************************
3272 * VarBstrFromUI232 [OLEAUT32.230]
3273 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003274HRESULT WINAPI VarBstrFromUI2(USHORT uiIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003275{
3276 TRACE( ole, "( %d, %ld, %ld, %p ), stub\n", uiIn, lcid, dwFlags, pbstrOut );
3277 sprintf( pBuffer, "%d", uiIn );
3278 *pbstrOut = StringDupAtoBstr( pBuffer );
3279
3280 return S_OK;
3281}
3282
3283/******************************************************************************
3284 * VarBstrFromUI432 [OLEAUT32.231]
3285 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003286HRESULT WINAPI VarBstrFromUI4(ULONG ulIn, LCID lcid, ULONG dwFlags, BSTR* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003287{
3288 TRACE( ole, "( %ld, %ld, %ld, %p ), stub\n", ulIn, lcid, dwFlags, pbstrOut );
3289 sprintf( pBuffer, "%ld", ulIn );
3290 *pbstrOut = StringDupAtoBstr( pBuffer );
3291
3292 return S_OK;
3293}
3294
3295/******************************************************************************
3296 * VarBoolFromUI132 [OLEAUT32.118]
3297 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003298HRESULT WINAPI VarBoolFromUI1(BYTE bIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003299{
3300 TRACE( ole, "( %d, %p ), stub\n", bIn, pboolOut );
3301
3302 if( bIn == 0 )
3303 {
3304 *pboolOut = VARIANT_FALSE;
3305 }
3306 else
3307 {
3308 *pboolOut = VARIANT_TRUE;
3309 }
3310
3311 return S_OK;
3312}
3313
3314/******************************************************************************
3315 * VarBoolFromI232 [OLEAUT32.119]
3316 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003317HRESULT WINAPI VarBoolFromI2(short sIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003318{
3319 TRACE( ole, "( %d, %p ), stub\n", sIn, pboolOut );
3320
3321 if( sIn == 0 )
3322 {
3323 *pboolOut = VARIANT_FALSE;
3324 }
3325 else
3326 {
3327 *pboolOut = VARIANT_TRUE;
3328 }
3329
3330 return S_OK;
3331}
3332
3333/******************************************************************************
3334 * VarBoolFromI432 [OLEAUT32.120]
3335 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003336HRESULT WINAPI VarBoolFromI4(LONG lIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003337{
3338 TRACE( ole, "( %ld, %p ), stub\n", lIn, pboolOut );
3339
3340 if( lIn == 0 )
3341 {
3342 *pboolOut = VARIANT_FALSE;
3343 }
3344 else
3345 {
3346 *pboolOut = VARIANT_TRUE;
3347 }
3348
3349 return S_OK;
3350}
3351
3352/******************************************************************************
3353 * VarBoolFromR432 [OLEAUT32.121]
3354 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003355HRESULT WINAPI VarBoolFromR4(FLOAT fltIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003356{
3357 TRACE( ole, "( %f, %p ), stub\n", fltIn, pboolOut );
3358
3359 if( fltIn == 0.0 )
3360 {
3361 *pboolOut = VARIANT_FALSE;
3362 }
3363 else
3364 {
3365 *pboolOut = VARIANT_TRUE;
3366 }
3367
3368 return S_OK;
3369}
3370
3371/******************************************************************************
3372 * VarBoolFromR832 [OLEAUT32.122]
3373 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003374HRESULT WINAPI VarBoolFromR8(double dblIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003375{
3376 TRACE( ole, "( %f, %p ), stub\n", dblIn, pboolOut );
3377
3378 if( dblIn == 0.0 )
3379 {
3380 *pboolOut = VARIANT_FALSE;
3381 }
3382 else
3383 {
3384 *pboolOut = VARIANT_TRUE;
3385 }
3386
3387 return S_OK;
3388}
3389
3390/******************************************************************************
3391 * VarBoolFromDate32 [OLEAUT32.123]
3392 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003393HRESULT WINAPI VarBoolFromDate(DATE dateIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003394{
3395 TRACE( ole, "( %f, %p ), stub\n", dateIn, pboolOut );
3396
3397 if( dateIn == 0.0 )
3398 {
3399 *pboolOut = VARIANT_FALSE;
3400 }
3401 else
3402 {
3403 *pboolOut = VARIANT_TRUE;
3404 }
3405
3406 return S_OK;
3407}
3408
3409/******************************************************************************
3410 * VarBoolFromStr32 [OLEAUT32.125]
3411 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003412HRESULT WINAPI VarBoolFromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003413{
3414 HRESULT ret = S_OK;
3415 char* pNewString = NULL;
3416
3417 TRACE( ole, "( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, pboolOut );
3418
3419 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
3420
3421 if( pNewString == NULL || strlen( pNewString ) == 0 )
3422 {
3423 ret = DISP_E_TYPEMISMATCH;
3424 }
3425
3426 if( ret == S_OK )
3427 {
3428 if( strncasecmp( pNewString, "True", strlen( pNewString ) ) == 0 )
3429 {
3430 *pboolOut = VARIANT_TRUE;
3431 }
3432 else if( strncasecmp( pNewString, "False", strlen( pNewString ) ) == 0 )
3433 {
3434 *pboolOut = VARIANT_FALSE;
3435 }
3436 else
3437 {
3438 /* Try converting the string to a floating point number.
3439 */
3440 double dValue = 0.0;
Alexandre Julliarda3960291999-02-26 11:11:13 +00003441 HRESULT res = VarR8FromStr( strIn, lcid, dwFlags, &dValue );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003442 if( res != S_OK )
3443 {
3444 ret = DISP_E_TYPEMISMATCH;
3445 }
3446 else if( dValue == 0.0 )
3447 {
3448 *pboolOut = VARIANT_FALSE;
3449 }
3450 else
3451 {
3452 *pboolOut = VARIANT_TRUE;
3453 }
3454 }
3455 }
3456
3457 HeapFree( GetProcessHeap(), 0, pNewString );
3458
3459 return ret;
3460}
3461
3462/******************************************************************************
3463 * VarBoolFromI132 [OLEAUT32.233]
3464 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003465HRESULT WINAPI VarBoolFromI1(CHAR cIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003466{
3467 TRACE( ole, "( %c, %p ), stub\n", cIn, pboolOut );
3468
3469 if( cIn == 0 )
3470 {
3471 *pboolOut = VARIANT_FALSE;
3472 }
3473 else
3474 {
3475 *pboolOut = VARIANT_TRUE;
3476 }
3477
3478 return S_OK;
3479}
3480
3481/******************************************************************************
3482 * VarBoolFromUI232 [OLEAUT32.234]
3483 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003484HRESULT WINAPI VarBoolFromUI2(USHORT uiIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003485{
3486 TRACE( ole, "( %d, %p ), stub\n", uiIn, pboolOut );
3487
3488 if( uiIn == 0 )
3489 {
3490 *pboolOut = VARIANT_FALSE;
3491 }
3492 else
3493 {
3494 *pboolOut = VARIANT_TRUE;
3495 }
3496
3497 return S_OK;
3498}
3499
3500/******************************************************************************
3501 * VarBoolFromUI432 [OLEAUT32.235]
3502 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003503HRESULT WINAPI VarBoolFromUI4(ULONG ulIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003504{
3505 TRACE( ole, "( %ld, %p ), stub\n", ulIn, pboolOut );
3506
3507 if( ulIn == 0 )
3508 {
3509 *pboolOut = VARIANT_FALSE;
3510 }
3511 else
3512 {
3513 *pboolOut = VARIANT_TRUE;
3514 }
3515
3516 return S_OK;
3517}
3518
Justin Bradfordbc93bc81998-12-11 14:02:16 +00003519/**********************************************************************
3520 * VarBoolFromCy32 [OLEAUT32.124]
3521 * Convert currency to boolean
3522 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003523HRESULT WINAPI VarBoolFromCy(CY cyIn, VARIANT_BOOL* pboolOut) {
Justin Bradfordbc93bc81998-12-11 14:02:16 +00003524 if (cyIn.u.Hi || cyIn.u.Lo) *pboolOut = -1;
3525 else *pboolOut = 0;
3526
3527 return S_OK;
3528}
3529
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003530/******************************************************************************
3531 * VarI1FromUI132 [OLEAUT32.244]
3532 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003533HRESULT WINAPI VarI1FromUI1(BYTE bIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003534{
3535 TRACE( ole, "( %d, %p ), stub\n", bIn, pcOut );
3536
3537 /* Check range of value.
3538 */
3539 if( bIn > CHAR_MAX )
3540 {
3541 return DISP_E_OVERFLOW;
3542 }
3543
3544 *pcOut = (CHAR) bIn;
3545
3546 return S_OK;
3547}
3548
3549/******************************************************************************
3550 * VarI1FromI232 [OLEAUT32.245]
3551 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003552HRESULT WINAPI VarI1FromI2(short uiIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003553{
3554 TRACE( ole, "( %d, %p ), stub\n", uiIn, pcOut );
3555
3556 if( uiIn > CHAR_MAX )
3557 {
3558 return DISP_E_OVERFLOW;
3559 }
3560
3561 *pcOut = (CHAR) uiIn;
3562
3563 return S_OK;
3564}
3565
3566/******************************************************************************
3567 * VarI1FromI432 [OLEAUT32.246]
3568 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003569HRESULT WINAPI VarI1FromI4(LONG lIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003570{
3571 TRACE( ole, "( %ld, %p ), stub\n", lIn, pcOut );
3572
3573 if( lIn < CHAR_MIN || lIn > CHAR_MAX )
3574 {
3575 return DISP_E_OVERFLOW;
3576 }
3577
3578 *pcOut = (CHAR) lIn;
3579
3580 return S_OK;
3581}
3582
3583/******************************************************************************
3584 * VarI1FromR432 [OLEAUT32.247]
3585 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003586HRESULT WINAPI VarI1FromR4(FLOAT fltIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003587{
3588 TRACE( ole, "( %f, %p ), stub\n", fltIn, pcOut );
3589
3590 fltIn = round( fltIn );
3591 if( fltIn < CHAR_MIN || fltIn > CHAR_MAX )
3592 {
3593 return DISP_E_OVERFLOW;
3594 }
3595
3596 *pcOut = (CHAR) fltIn;
3597
3598 return S_OK;
3599}
3600
3601/******************************************************************************
3602 * VarI1FromR832 [OLEAUT32.248]
3603 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003604HRESULT WINAPI VarI1FromR8(double dblIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003605{
3606 TRACE( ole, "( %f, %p ), stub\n", dblIn, pcOut );
3607
3608 dblIn = round( dblIn );
3609 if( dblIn < CHAR_MIN || dblIn > CHAR_MAX )
3610 {
3611 return DISP_E_OVERFLOW;
3612 }
3613
3614 *pcOut = (CHAR) dblIn;
3615
3616 return S_OK;
3617}
3618
3619/******************************************************************************
3620 * VarI1FromDate32 [OLEAUT32.249]
3621 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003622HRESULT WINAPI VarI1FromDate(DATE dateIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003623{
3624 TRACE( ole, "( %f, %p ), stub\n", dateIn, pcOut );
3625
3626 dateIn = round( dateIn );
3627 if( dateIn < CHAR_MIN || dateIn > CHAR_MAX )
3628 {
3629 return DISP_E_OVERFLOW;
3630 }
3631
3632 *pcOut = (CHAR) dateIn;
3633
3634 return S_OK;
3635}
3636
3637/******************************************************************************
3638 * VarI1FromStr32 [OLEAUT32.251]
3639 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003640HRESULT WINAPI VarI1FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003641{
3642 double dValue = 0.0;
3643 LPSTR pNewString = NULL;
3644
3645 TRACE( ole, "( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, pcOut );
3646
3647 /* Check if we have a valid argument
3648 */
3649 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
3650 RemoveCharacterFromString( pNewString, "," );
3651 if( IsValidRealString( pNewString ) == FALSE )
3652 {
3653 return DISP_E_TYPEMISMATCH;
3654 }
3655
3656 /* Convert the valid string to a floating point number.
3657 */
3658 dValue = atof( pNewString );
3659
3660 /* We don't need the string anymore so free it.
3661 */
3662 HeapFree( GetProcessHeap(), 0, pNewString );
3663
3664 /* Check range of value.
3665 */
3666 dValue = round( dValue );
3667 if( dValue < CHAR_MIN || dValue > CHAR_MAX )
3668 {
3669 return DISP_E_OVERFLOW;
3670 }
3671
3672 *pcOut = (CHAR) dValue;
3673
3674 return S_OK;
3675}
3676
3677/******************************************************************************
3678 * VarI1FromBool32 [OLEAUT32.253]
3679 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003680HRESULT WINAPI VarI1FromBool(VARIANT_BOOL boolIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003681{
3682 TRACE( ole, "( %d, %p ), stub\n", boolIn, pcOut );
3683
3684 *pcOut = (CHAR) boolIn;
3685
3686 return S_OK;
3687}
3688
3689/******************************************************************************
3690 * VarI1FromUI232 [OLEAUT32.254]
3691 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003692HRESULT WINAPI VarI1FromUI2(USHORT uiIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003693{
3694 TRACE( ole, "( %d, %p ), stub\n", uiIn, pcOut );
3695
3696 if( uiIn > CHAR_MAX )
3697 {
3698 return DISP_E_OVERFLOW;
3699 }
3700
3701 *pcOut = (CHAR) uiIn;
3702
3703 return S_OK;
3704}
3705
3706/******************************************************************************
3707 * VarI1FromUI432 [OLEAUT32.255]
3708 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003709HRESULT WINAPI VarI1FromUI4(ULONG ulIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003710{
3711 TRACE( ole, "( %ld, %p ), stub\n", ulIn, pcOut );
3712
3713 if( ulIn > CHAR_MAX )
3714 {
3715 return DISP_E_OVERFLOW;
3716 }
3717
3718 *pcOut = (CHAR) ulIn;
3719
3720 return S_OK;
3721}
3722
Justin Bradfordbc93bc81998-12-11 14:02:16 +00003723/**********************************************************************
3724 * VarI1FromCy32 [OLEAUT32.250]
3725 * Convert currency to signed char
3726 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003727HRESULT WINAPI VarI1FromCy(CY cyIn, CHAR* pcOut) {
Todd Vierling7f573251998-12-15 15:15:16 +00003728 double t = round((((double)cyIn.u.Hi * 4294967296.0) + (double)cyIn.u.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00003729
3730 if (t > CHAR_MAX || t < CHAR_MIN) return DISP_E_OVERFLOW;
3731
3732 *pcOut = (CHAR)t;
3733 return S_OK;
3734}
3735
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003736/******************************************************************************
3737 * VarUI2FromUI132 [OLEAUT32.257]
3738 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003739HRESULT WINAPI VarUI2FromUI1(BYTE bIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003740{
3741 TRACE( ole, "( %d, %p ), stub\n", bIn, puiOut );
3742
3743 *puiOut = (USHORT) bIn;
3744
3745 return S_OK;
3746}
3747
3748/******************************************************************************
3749 * VarUI2FromI232 [OLEAUT32.258]
3750 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003751HRESULT WINAPI VarUI2FromI2(short uiIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003752{
3753 TRACE( ole, "( %d, %p ), stub\n", uiIn, puiOut );
3754
3755 if( uiIn < UI2_MIN )
3756 {
3757 return DISP_E_OVERFLOW;
3758 }
3759
3760 *puiOut = (USHORT) uiIn;
3761
3762 return S_OK;
3763}
3764
3765/******************************************************************************
3766 * VarUI2FromI432 [OLEAUT32.259]
3767 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003768HRESULT WINAPI VarUI2FromI4(LONG lIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003769{
3770 TRACE( ole, "( %ld, %p ), stub\n", lIn, puiOut );
3771
3772 if( lIn < UI2_MIN || lIn > UI2_MAX )
3773 {
3774 return DISP_E_OVERFLOW;
3775 }
3776
3777 *puiOut = (USHORT) lIn;
3778
3779 return S_OK;
3780}
3781
3782/******************************************************************************
3783 * VarUI2FromR432 [OLEAUT32.260]
3784 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003785HRESULT WINAPI VarUI2FromR4(FLOAT fltIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003786{
3787 TRACE( ole, "( %f, %p ), stub\n", fltIn, puiOut );
3788
3789 fltIn = round( fltIn );
3790 if( fltIn < UI2_MIN || fltIn > UI2_MAX )
3791 {
3792 return DISP_E_OVERFLOW;
3793 }
3794
3795 *puiOut = (USHORT) fltIn;
3796
3797 return S_OK;
3798}
3799
3800/******************************************************************************
3801 * VarUI2FromR832 [OLEAUT32.261]
3802 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003803HRESULT WINAPI VarUI2FromR8(double dblIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003804{
3805 TRACE( ole, "( %f, %p ), stub\n", dblIn, puiOut );
3806
3807 dblIn = round( dblIn );
3808 if( dblIn < UI2_MIN || dblIn > UI2_MAX )
3809 {
3810 return DISP_E_OVERFLOW;
3811 }
3812
3813 *puiOut = (USHORT) dblIn;
3814
3815 return S_OK;
3816}
3817
3818/******************************************************************************
3819 * VarUI2FromDate32 [OLEAUT32.262]
3820 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003821HRESULT WINAPI VarUI2FromDate(DATE dateIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003822{
3823 TRACE( ole, "( %f, %p ), stub\n", dateIn, puiOut );
3824
3825 dateIn = round( dateIn );
3826 if( dateIn < UI2_MIN || dateIn > UI2_MAX )
3827 {
3828 return DISP_E_OVERFLOW;
3829 }
3830
3831 *puiOut = (USHORT) dateIn;
3832
3833 return S_OK;
3834}
3835
3836/******************************************************************************
3837 * VarUI2FromStr32 [OLEAUT32.264]
3838 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003839HRESULT WINAPI VarUI2FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003840{
3841 double dValue = 0.0;
3842 LPSTR pNewString = NULL;
3843
3844 TRACE( ole, "( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, puiOut );
3845
3846 /* Check if we have a valid argument
3847 */
3848 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
3849 RemoveCharacterFromString( pNewString, "," );
3850 if( IsValidRealString( pNewString ) == FALSE )
3851 {
3852 return DISP_E_TYPEMISMATCH;
3853 }
3854
3855 /* Convert the valid string to a floating point number.
3856 */
3857 dValue = atof( pNewString );
3858
3859 /* We don't need the string anymore so free it.
3860 */
3861 HeapFree( GetProcessHeap(), 0, pNewString );
3862
3863 /* Check range of value.
3864 */
3865 dValue = round( dValue );
3866 if( dValue < UI2_MIN || dValue > UI2_MAX )
3867 {
3868 return DISP_E_OVERFLOW;
3869 }
3870
3871 *puiOut = (USHORT) dValue;
3872
3873 return S_OK;
3874}
3875
3876/******************************************************************************
3877 * VarUI2FromBool32 [OLEAUT32.266]
3878 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003879HRESULT WINAPI VarUI2FromBool(VARIANT_BOOL boolIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003880{
3881 TRACE( ole, "( %d, %p ), stub\n", boolIn, puiOut );
3882
3883 *puiOut = (USHORT) boolIn;
3884
3885 return S_OK;
3886}
3887
3888/******************************************************************************
3889 * VarUI2FromI132 [OLEAUT32.267]
3890 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003891HRESULT WINAPI VarUI2FromI1(CHAR cIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003892{
3893 TRACE( ole, "( %c, %p ), stub\n", cIn, puiOut );
3894
3895 *puiOut = (USHORT) cIn;
3896
3897 return S_OK;
3898}
3899
3900/******************************************************************************
3901 * VarUI2FromUI432 [OLEAUT32.268]
3902 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003903HRESULT WINAPI VarUI2FromUI4(ULONG ulIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003904{
3905 TRACE( ole, "( %ld, %p ), stub\n", ulIn, puiOut );
3906
3907 if( ulIn < UI2_MIN || ulIn > UI2_MAX )
3908 {
3909 return DISP_E_OVERFLOW;
3910 }
3911
3912 *puiOut = (USHORT) ulIn;
3913
3914 return S_OK;
3915}
3916
3917/******************************************************************************
3918 * VarUI4FromStr32 [OLEAUT32.277]
3919 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003920HRESULT WINAPI VarUI4FromStr(OLECHAR* strIn, LCID lcid, ULONG dwFlags, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003921{
3922 double dValue = 0.0;
3923 LPSTR pNewString = NULL;
3924
3925 TRACE( ole, "( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, pulOut );
3926
3927 /* Check if we have a valid argument
3928 */
3929 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
3930 RemoveCharacterFromString( pNewString, "," );
3931 if( IsValidRealString( pNewString ) == FALSE )
3932 {
3933 return DISP_E_TYPEMISMATCH;
3934 }
3935
3936 /* Convert the valid string to a floating point number.
3937 */
3938 dValue = atof( pNewString );
3939
3940 /* We don't need the string anymore so free it.
3941 */
3942 HeapFree( GetProcessHeap(), 0, pNewString );
3943
3944 /* Check range of value.
3945 */
3946 dValue = round( dValue );
3947 if( dValue < UI4_MIN || dValue > UI4_MAX )
3948 {
3949 return DISP_E_OVERFLOW;
3950 }
3951
3952 *pulOut = (ULONG) dValue;
3953
3954 return S_OK;
3955}
3956
Justin Bradfordbc93bc81998-12-11 14:02:16 +00003957/**********************************************************************
3958 * VarUI2FromCy32 [OLEAUT32.263]
3959 * Convert currency to unsigned short
3960 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003961HRESULT WINAPI VarUI2FromCy(CY cyIn, USHORT* pusOut) {
Todd Vierling7f573251998-12-15 15:15:16 +00003962 double t = round((((double)cyIn.u.Hi * 4294967296.0) + (double)cyIn.u.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00003963
3964 if (t > UI2_MAX || t < UI2_MIN) return DISP_E_OVERFLOW;
3965
3966 *pusOut = (USHORT)t;
3967
3968 return S_OK;
3969}
3970
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003971/******************************************************************************
3972 * VarUI4FromUI132 [OLEAUT32.270]
3973 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003974HRESULT WINAPI VarUI4FromUI1(BYTE bIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003975{
3976 TRACE( ole, "( %d, %p ), stub\n", bIn, pulOut );
3977
3978 *pulOut = (USHORT) bIn;
3979
3980 return S_OK;
3981}
3982
3983/******************************************************************************
3984 * VarUI4FromI232 [OLEAUT32.271]
3985 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00003986HRESULT WINAPI VarUI4FromI2(short uiIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003987{
3988 TRACE( ole, "( %d, %p ), stub\n", uiIn, pulOut );
3989
3990 if( uiIn < UI4_MIN )
3991 {
3992 return DISP_E_OVERFLOW;
3993 }
3994
3995 *pulOut = (ULONG) uiIn;
3996
3997 return S_OK;
3998}
3999
4000/******************************************************************************
4001 * VarUI4FromI432 [OLEAUT32.272]
4002 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004003HRESULT WINAPI VarUI4FromI4(LONG lIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004004{
4005 TRACE( ole, "( %ld, %p ), stub\n", lIn, pulOut );
4006
4007 if( lIn < UI4_MIN )
4008 {
4009 return DISP_E_OVERFLOW;
4010 }
4011
4012 *pulOut = (ULONG) lIn;
4013
4014 return S_OK;
4015}
4016
4017/******************************************************************************
4018 * VarUI4FromR432 [OLEAUT32.273]
4019 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004020HRESULT WINAPI VarUI4FromR4(FLOAT fltIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004021{
4022 fltIn = round( fltIn );
4023 if( fltIn < UI4_MIN || fltIn > UI4_MAX )
4024 {
4025 return DISP_E_OVERFLOW;
4026 }
4027
4028 *pulOut = (ULONG) fltIn;
4029
4030 return S_OK;
4031}
4032
4033/******************************************************************************
4034 * VarUI4FromR832 [OLEAUT32.274]
4035 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004036HRESULT WINAPI VarUI4FromR8(double dblIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004037{
4038 TRACE( ole, "( %f, %p ), stub\n", dblIn, pulOut );
4039
4040 dblIn = round( dblIn );
4041 if( dblIn < UI4_MIN || dblIn > UI4_MAX )
4042 {
4043 return DISP_E_OVERFLOW;
4044 }
4045
4046 *pulOut = (ULONG) dblIn;
4047
4048 return S_OK;
4049}
4050
4051/******************************************************************************
4052 * VarUI4FromDate32 [OLEAUT32.275]
4053 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004054HRESULT WINAPI VarUI4FromDate(DATE dateIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004055{
4056 TRACE( ole, "( %f, %p ), stub\n", dateIn, pulOut );
4057
4058 dateIn = round( dateIn );
4059 if( dateIn < UI4_MIN || dateIn > UI4_MAX )
4060 {
4061 return DISP_E_OVERFLOW;
4062 }
4063
4064 *pulOut = (ULONG) dateIn;
4065
4066 return S_OK;
4067}
4068
4069/******************************************************************************
4070 * VarUI4FromBool32 [OLEAUT32.279]
4071 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004072HRESULT WINAPI VarUI4FromBool(VARIANT_BOOL boolIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004073{
4074 TRACE( ole, "( %d, %p ), stub\n", boolIn, pulOut );
4075
4076 *pulOut = (ULONG) boolIn;
4077
4078 return S_OK;
4079}
4080
4081/******************************************************************************
4082 * VarUI4FromI132 [OLEAUT32.280]
4083 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004084HRESULT WINAPI VarUI4FromI1(CHAR cIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004085{
4086 TRACE( ole, "( %c, %p ), stub\n", cIn, pulOut );
4087
4088 *pulOut = (ULONG) cIn;
4089
4090 return S_OK;
4091}
4092
4093/******************************************************************************
4094 * VarUI4FromUI232 [OLEAUT32.281]
4095 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004096HRESULT WINAPI VarUI4FromUI2(USHORT uiIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004097{
4098 TRACE( ole, "( %d, %p ), stub\n", uiIn, pulOut );
4099
4100 *pulOut = (ULONG) uiIn;
4101
4102 return S_OK;
4103}
4104
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004105/**********************************************************************
4106 * VarUI4FromCy32 [OLEAUT32.276]
4107 * Convert currency to unsigned long
4108 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004109HRESULT WINAPI VarUI4FromCy(CY cyIn, ULONG* pulOut) {
Todd Vierling7f573251998-12-15 15:15:16 +00004110 double t = round((((double)cyIn.u.Hi * 4294967296.0) + (double)cyIn.u.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004111
4112 if (t > UI4_MAX || t < UI4_MIN) return DISP_E_OVERFLOW;
4113
4114 *pulOut = (ULONG)t;
4115
4116 return S_OK;
4117}
4118
4119/**********************************************************************
4120 * VarCyFromUI132 [OLEAUT32.98]
4121 * Convert unsigned char to currency
4122 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004123HRESULT WINAPI VarCyFromUI1(BYTE bIn, CY* pcyOut) {
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004124 pcyOut->u.Hi = 0;
4125 pcyOut->u.Lo = ((ULONG)bIn) * 10000;
4126
4127 return S_OK;
4128}
4129
4130/**********************************************************************
4131 * VarCyFromI232 [OLEAUT32.99]
4132 * Convert signed short to currency
4133 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004134HRESULT WINAPI VarCyFromI2(short sIn, CY* pcyOut) {
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004135 if (sIn < 0) pcyOut->u.Hi = -1;
4136 else pcyOut->u.Hi = 0;
4137 pcyOut->u.Lo = ((ULONG)sIn) * 10000;
4138
4139 return S_OK;
4140}
4141
4142/**********************************************************************
4143 * VarCyFromI432 [OLEAUT32.100]
4144 * Convert signed long to currency
4145 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004146HRESULT WINAPI VarCyFromI4(LONG lIn, CY* pcyOut) {
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004147 double t = (double)lIn * (double)10000;
Todd Vierling7f573251998-12-15 15:15:16 +00004148 pcyOut->u.Hi = (LONG)(t / (double)4294967296.0);
4149 pcyOut->u.Lo = (ULONG)fmod(t, (double)4294967296.0);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004150 if (lIn < 0) pcyOut->u.Hi--;
4151
4152 return S_OK;
4153}
4154
4155/**********************************************************************
4156 * VarCyFromR432 [OLEAUT32.101]
4157 * Convert float to currency
4158 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004159HRESULT WINAPI VarCyFromR4(FLOAT fltIn, CY* pcyOut) {
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004160 double t = round((double)fltIn * (double)10000);
Todd Vierling7f573251998-12-15 15:15:16 +00004161 pcyOut->u.Hi = (LONG)(t / (double)4294967296.0);
4162 pcyOut->u.Lo = (ULONG)fmod(t, (double)4294967296.0);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004163 if (fltIn < 0) pcyOut->u.Hi--;
4164
4165 return S_OK;
4166}
4167
4168/**********************************************************************
4169 * VarCyFromR832 [OLEAUT32.102]
4170 * Convert double to currency
4171 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004172HRESULT WINAPI VarCyFromR8(double dblIn, CY* pcyOut) {
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004173 double t = round(dblIn * (double)10000);
Todd Vierling7f573251998-12-15 15:15:16 +00004174 pcyOut->u.Hi = (LONG)(t / (double)4294967296.0);
4175 pcyOut->u.Lo = (ULONG)fmod(t, (double)4294967296.0);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004176 if (dblIn < 0) pcyOut->u.Hi--;
4177
4178 return S_OK;
4179}
4180
4181/**********************************************************************
4182 * VarCyFromDate32 [OLEAUT32.103]
4183 * Convert date to currency
4184 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004185HRESULT WINAPI VarCyFromDate(DATE dateIn, CY* pcyOut) {
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004186 double t = round((double)dateIn * (double)10000);
Todd Vierling7f573251998-12-15 15:15:16 +00004187 pcyOut->u.Hi = (LONG)(t / (double)4294967296.0);
4188 pcyOut->u.Lo = (ULONG)fmod(t, (double)4294967296.0);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004189 if (dateIn < 0) pcyOut->u.Hi--;
4190
4191 return S_OK;
4192}
4193
4194/**********************************************************************
4195 * VarCyFromBool32 [OLEAUT32.106]
4196 * Convert boolean to currency
4197 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004198HRESULT WINAPI VarCyFromBool(VARIANT_BOOL boolIn, CY* pcyOut) {
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004199 if (boolIn < 0) pcyOut->u.Hi = -1;
4200 else pcyOut->u.Hi = 0;
4201 pcyOut->u.Lo = (ULONG)boolIn * (ULONG)10000;
4202
4203 return S_OK;
4204}
4205
4206/**********************************************************************
4207 * VarCyFromI132 [OLEAUT32.225]
4208 * Convert signed char to currency
4209 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004210HRESULT WINAPI VarCyFromI1(CHAR cIn, CY* pcyOut) {
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004211 if (cIn < 0) pcyOut->u.Hi = -1;
4212 else pcyOut->u.Hi = 0;
4213 pcyOut->u.Lo = (ULONG)cIn * (ULONG)10000;
4214
4215 return S_OK;
4216}
4217
4218/**********************************************************************
4219 * VarCyFromUI232 [OLEAUT32.226]
4220 * Convert unsigned short to currency
4221 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004222HRESULT WINAPI VarCyFromUI2(USHORT usIn, CY* pcyOut) {
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004223 pcyOut->u.Hi = 0;
4224 pcyOut->u.Lo = (ULONG)usIn * (ULONG)10000;
4225
4226 return S_OK;
4227}
4228
4229/**********************************************************************
4230 * VarCyFromUI432 [OLEAUT32.227]
4231 * Convert unsigned long to currency
4232 */
Alexandre Julliarda3960291999-02-26 11:11:13 +00004233HRESULT WINAPI VarCyFromUI4(ULONG ulIn, CY* pcyOut) {
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004234 double t = (double)ulIn * (double)10000;
Todd Vierling7f573251998-12-15 15:15:16 +00004235 pcyOut->u.Hi = (LONG)(t / (double)4294967296.0);
4236 pcyOut->u.Lo = (ULONG)fmod(t, (double)4294967296.0);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004237
4238 return S_OK;
4239}
Stephane Lussier986de4b1999-03-12 17:02:32 +00004240
4241
4242/**********************************************************************
4243 * DosDateTimeToVariantTime [OLEAUT32.14]
4244 * Convert dos representation of time to the date and time representation
4245 * stored in a variant.
4246 */
4247INT WINAPI DosDateTimeToVariantTime(USHORT wDosDate, USHORT wDosTime,
4248 DATE *pvtime)
4249{
4250 struct tm t;
4251
4252 TRACE( ole, "( 0x%x, 0x%x, 0x%p ), stub\n", wDosDate, wDosTime, pvtime );
4253
4254 t.tm_sec = (wDosTime & 0x001f) * 2;
4255 t.tm_min = (wDosTime & 0x07e0) >> 5;
4256 t.tm_hour = (wDosTime & 0xf800) >> 11;
4257
4258 t.tm_mday = (wDosDate & 0x001f);
4259 t.tm_mon = (wDosDate & 0x01e0) >> 5;
4260 t.tm_year = ((wDosDate & 0xfe00) >> 9) + 1980;
4261
4262 return TmToDATE( &t, pvtime );
4263}
4264