blob: 6729e1938730b38ac33b0efeca861bb87190a864 [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"
Justin Bradfordbc93bc81998-12-11 14:02:16 +000028#include "mapidefs.h"
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +000029#include "parsedt.h"
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +000030
31#include <string.h>
32#include <stdlib.h>
33#include <math.h>
34#include <time.h>
35
Marcus Meissnerae8b10b1998-12-15 13:01:21 +000036#ifdef HAVE_FLOAT_H
37# include <float.h>
38#endif
39
40#ifndef FLT_MAX
41# ifdef MAXFLOAT
42# define FLT_MAX MAXFLOAT
43# else
44# error "Can't find #define for MAXFLOAT/FLT_MAX"
45# endif
46#endif
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +000047
Todd Vierling7f573251998-12-15 15:15:16 +000048#undef CHAR_MAX
49#undef CHAR_MIN
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +000050static const char CHAR_MAX = 127;
51static const char CHAR_MIN = -128;
52static const BYTE UI1_MAX = 255;
53static const BYTE UI1_MIN = 0;
54static const unsigned short UI2_MAX = 65535;
55static const unsigned short UI2_MIN = 0;
56static const short I2_MAX = 32767;
57static const short I2_MIN = -32768;
Todd Vierling7f573251998-12-15 15:15:16 +000058static const unsigned long UI4_MAX = 4294967295U;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +000059static const unsigned long UI4_MIN = 0;
60static const long I4_MAX = 2147483647;
Todd Vierling7f573251998-12-15 15:15:16 +000061static const long I4_MIN = -(2147483648U);
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +000062static const DATE DATE_MIN = -657434;
63static const DATE DATE_MAX = 2958465;
64
65
66/* This mask is used to set a flag in wReserved1 of
67 * the VARIANTARG structure. The flag indicates if
68 * the API function is using an inner variant or not.
69 */
70#define PROCESSING_INNER_VARIANT 0x0001
71
72/* General use buffer.
73 */
74#define BUFFER_MAX 1024
75static char pBuffer[BUFFER_MAX];
76
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +000077/*
78 * Note a leap year is one that is a multiple of 4
79 * but not of a 100. Except if it is a multiple of
80 * 400 then it is a leap year.
81 */
82/* According to postgeSQL date parsing functions there is
83 * a leap year when this expression is true.
84 * (((y % 4) == 0) && (((y % 100) != 0) || ((y % 400) == 0)))
85 * So according to this there is 365.2515 days in one year.
86 * One + every four years: 1/4 -> 365.25
87 * One - every 100 years: 1/100 -> 365.001
88 * One + every 400 years: 1/400 -> 365.0025
89 */
90static const double DAYS_IN_ONE_YEAR = 365.2515;
91
92
93
94/******************************************************************************
95 * DateTimeStringToTm [INTERNAL]
96 *
97 * Converts a string representation of a date and/or time to a tm structure.
98 *
99 * Note this function uses the postgresql date parsing functions found
100 * in the parsedt.c file.
101 *
102 * Returns TRUE if successfull.
103 *
104 * Note: This function does not parse the day of the week,
105 * daylight savings time. It will only fill the followin fields in
106 * the tm struct, tm_sec, tm_min, tm_hour, tm_year, tm_day, tm_mon.
107 *
108 ******************************************************************************/
109static BOOL32 DateTimeStringToTm( OLECHAR32* strIn, LCID lcid, struct tm* pTm )
110{
111 BOOL32 res = FALSE;
112 double fsec;
113 int tzp;
114 int dtype;
115 int nf;
116 char *field[MAXDATEFIELDS];
117 int ftype[MAXDATEFIELDS];
118 char lowstr[MAXDATELEN + 1];
119 char* strDateTime = NULL;
120
121 /* Convert the string to ASCII since this is the only format
122 * postgesql can handle.
123 */
124 strDateTime = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
125
126 if( strDateTime != NULL )
127 {
128 /* Make sure we don't go over the maximum length
129 * accepted by postgesql.
130 */
131 if( strlen( strDateTime ) <= MAXDATELEN )
132 {
133 if( ParseDateTime( strDateTime, lowstr, field, ftype, MAXDATEFIELDS, &nf) == 0 )
134 {
135 if( lcid & VAR_DATEVALUEONLY )
136 {
137 /* Get the date information.
138 * It returns 0 if date information was
139 * present and 1 if only time information was present.
140 * -1 if an error occures.
141 */
142 if( DecodeDateTime(field, ftype, nf, &dtype, pTm, &fsec, &tzp) == 0 )
143 {
144 /* Eliminate the time information since we
145 * were asked to get date information only.
146 */
147 pTm->tm_sec = 0;
148 pTm->tm_min = 0;
149 pTm->tm_hour = 0;
150 res = TRUE;
151 }
152 }
153 if( lcid & VAR_TIMEVALUEONLY )
154 {
155 /* Get time information only.
156 */
157 if( DecodeTimeOnly(field, ftype, nf, &dtype, pTm, &fsec) == 0 )
158 {
159 res = TRUE;
160 }
161 }
162 else
163 {
164 /* Get both date and time information.
165 * It returns 0 if date information was
166 * present and 1 if only time information was present.
167 * -1 if an error occures.
168 */
169 if( DecodeDateTime(field, ftype, nf, &dtype, pTm, &fsec, &tzp) != -1 )
170 {
171 res = TRUE;
172 }
173 }
174 }
175 }
176 HeapFree( GetProcessHeap(), 0, strDateTime );
177 }
178
179 return res;
180}
181
182
183
184
185
186
187/******************************************************************************
188 * TmToDATE [INTERNAL]
189 *
190 * The date is implemented using an 8 byte floating-point number.
191 * Days are represented by whole numbers increments starting with 0.00 has
192 * being December 30 1899, midnight.
193 * The hours are expressed as the fractional part of the number.
194 * December 30 1899 at midnight = 0.00
195 * January 1 1900 at midnight = 2.00
196 * January 4 1900 at 6 AM = 5.25
197 * January 4 1900 at noon = 5.50
198 * December 29 1899 at midnight = -1.00
199 * December 18 1899 at midnight = -12.00
200 * December 18 1899 at 6AM = -12.25
201 * December 18 1899 at 6PM = -12.75
202 * December 19 1899 at midnight = -11.00
203 * The tm structure is as follows:
204 * struct tm {
205 * int tm_sec; seconds after the minute - [0,59]
206 * int tm_min; minutes after the hour - [0,59]
207 * int tm_hour; hours since midnight - [0,23]
208 * int tm_mday; day of the month - [1,31]
209 * int tm_mon; months since January - [0,11]
210 * int tm_year; years
211 * int tm_wday; days since Sunday - [0,6]
212 * int tm_yday; days since January 1 - [0,365]
213 * int tm_isdst; daylight savings time flag
214 * };
215 *
216 * Note: This function does not use the tm_wday, tm_yday, tm_wday,
217 * and tm_isdst fields of the tm structure. And only converts years
218 * after 1900.
219 *
220 * Returns TRUE if successfull.
221 */
222static BOOL32 TmToDATE( struct tm* pTm, DATE *pDateOut )
223{
224 if( (pTm->tm_year - 1900) >= 0 )
225 {
226 int leapYear = 0;
227
228 /* Start at 1. This is the way DATE is defined.
229 * January 1, 1900 at Midnight is 1.00.
230 * January 1, 1900 at 6AM is 1.25.
231 * and so on.
232 */
233 *pDateOut = 1;
234
235 /* Add the number of days corresponding to
236 * tm_year.
237 */
238 *pDateOut += (pTm->tm_year - 1900) * 365;
239
240 /* Add the leap days in the previous years between now and 1900.
241 * Note a leap year is one that is a multiple of 4
242 * but not of a 100. Except if it is a multiple of
243 * 400 then it is a leap year.
244 */
245 *pDateOut += ( (pTm->tm_year - 1) / 4 ) - ( 1900 / 4 );
246 *pDateOut -= ( (pTm->tm_year - 1) / 100 ) - ( 1900 / 100 );
247 *pDateOut += ( (pTm->tm_year - 1) / 400 ) - ( 1900 / 400 );
248
249 /* Set the leap year flag if the
250 * current year specified by tm_year is a
251 * leap year. This will be used to add a day
252 * to the day count.
253 */
254 if( isleap( pTm->tm_year ) )
255 leapYear = 1;
256
257 /* Add the number of days corresponding to
258 * the month.
259 */
260 switch( pTm->tm_mon )
261 {
262 case 2:
263 *pDateOut += 31;
264 break;
265 case 3:
266 *pDateOut += ( 59 + leapYear );
267 break;
268 case 4:
269 *pDateOut += ( 90 + leapYear );
270 break;
271 case 5:
272 *pDateOut += ( 120 + leapYear );
273 break;
274 case 6:
275 *pDateOut += ( 151 + leapYear );
276 break;
277 case 7:
278 *pDateOut += ( 181 + leapYear );
279 break;
280 case 8:
281 *pDateOut += ( 212 + leapYear );
282 break;
283 case 9:
284 *pDateOut += ( 243 + leapYear );
285 break;
286 case 10:
287 *pDateOut += ( 273 + leapYear );
288 break;
289 case 11:
290 *pDateOut += ( 304 + leapYear );
291 break;
292 case 12:
293 *pDateOut += ( 334 + leapYear );
294 break;
295 }
296 /* Add the number of days in this month.
297 */
298 *pDateOut += pTm->tm_mday;
299
300 /* Add the number of seconds, minutes, and hours
301 * to the DATE. Note these are the fracionnal part
302 * of the DATE so seconds / number of seconds in a day.
303 */
304 *pDateOut += pTm->tm_hour / 24.0;
305 *pDateOut += pTm->tm_min / 1440.0;
306 *pDateOut += pTm->tm_sec / 86400.0;
307 return TRUE;
308 }
309 return FALSE;
310}
311
312/******************************************************************************
313 * DateToTm [INTERNAL]
314 *
315 * This function converst a windows DATE to a tm structure.
316 *
317 * It does not fill all the fields of the tm structure.
318 * Here is a list of the fields that are filled:
319 * tm_sec, tm_min, tm_hour, tm_year, tm_day, tm_mon.
320 *
321 * Note this function does not support dates before the January 1, 1900
322 * or ( dateIn < 2.0 ).
323 *
324 * Returns TRUE if successfull.
325 */
326static BOOL32 DateToTm( DATE dateIn, LCID lcid, struct tm* pTm )
327{
328 /* Do not process dates smaller than January 1, 1900.
329 * Which corresponds to 2.0 in the windows DATE format.
330 */
331 if( dateIn >= 2.0 )
332 {
333 double decimalPart = 0.0;
334 double wholePart = 0.0;
335
336 pTm->tm_sec = 0;
337 pTm->tm_min = 0;
338 pTm->tm_hour = 0;
339 pTm->tm_mday = 0;
340 pTm->tm_mon = 0;
341 pTm->tm_year = 0;
342 pTm->tm_wday = 0;
343 pTm->tm_yday = 0;
344 pTm->tm_isdst = 0;
345 pTm->tm_gmtoff = 0;
346 pTm->tm_zone = 0;
347
348 /* Because of the nature of DATE format witch
349 * associates 2.0 to January 1, 1900. We will
350 * remove 1.0 from the whole part of the DATE
351 * so that in the following code 1.0
352 * will correspond to January 1, 1900.
353 * This simplyfies the processing of the DATE value.
354 */
355 dateIn -= 1.0;
356
357 wholePart = (double) floor( dateIn );
358 decimalPart = fmod( dateIn, wholePart );
359
360 if( !(lcid & VAR_TIMEVALUEONLY) )
361 {
362 int nDay = 0;
363 int leapYear = 0;
364 double yearsSince1900 = 0;
365 /* Start at 1900, this where the DATE time 0.0 starts.
366 */
367 pTm->tm_year = 1900;
368 /* find in what year the day in the "wholePart" falls into.
369 * add the value to the year field.
370 */
371 yearsSince1900 = floor( wholePart / DAYS_IN_ONE_YEAR );
372 pTm->tm_year += yearsSince1900;
373 /* determine if this is a leap year.
374 */
375 if( isleap( pTm->tm_year ) )
376 leapYear = 1;
377 /* find what day of that year does the "wholePart" corresponds to.
378 * Note: nDay is in [1-366] format
379 */
380 nDay = (int) ( wholePart - floor( yearsSince1900 * DAYS_IN_ONE_YEAR ) );
381 /* Set the tm_yday value.
382 * Note: The day is must be converted from [1-366] to [0-365]
383 */
Marcus Meissnerae3921d1999-01-01 18:43:12 +0000384 /*pTm->tm_yday = nDay - 1;*/
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +0000385 /* find which mount this day corresponds to.
386 */
387 if( nDay <= 31 )
388 {
389 pTm->tm_mday = nDay;
390 pTm->tm_mon = 0;
391 }
392 else if( nDay <= ( 59 + leapYear ) )
393 {
394 pTm->tm_mday = nDay - 31;
395 pTm->tm_mon = 1;
396 }
397 else if( nDay <= ( 90 + leapYear ) )
398 {
399 pTm->tm_mday = nDay - ( 59 + leapYear );
400 pTm->tm_mon = 2;
401 }
402 else if( nDay <= ( 120 + leapYear ) )
403 {
404 pTm->tm_mday = nDay - ( 90 + leapYear );
405 pTm->tm_mon = 3;
406 }
407 else if( nDay <= ( 151 + leapYear ) )
408 {
409 pTm->tm_mday = nDay - ( 120 + leapYear );
410 pTm->tm_mon = 4;
411 }
412 else if( nDay <= ( 181 + leapYear ) )
413 {
414 pTm->tm_mday = nDay - ( 151 + leapYear );
415 pTm->tm_mon = 5;
416 }
417 else if( nDay <= ( 212 + leapYear ) )
418 {
419 pTm->tm_mday = nDay - ( 181 + leapYear );
420 pTm->tm_mon = 6;
421 }
422 else if( nDay <= ( 243 + leapYear ) )
423 {
424 pTm->tm_mday = nDay - ( 212 + leapYear );
425 pTm->tm_mon = 7;
426 }
427 else if( nDay <= ( 273 + leapYear ) )
428 {
429 pTm->tm_mday = nDay - ( 243 + leapYear );
430 pTm->tm_mon = 8;
431 }
432 else if( nDay <= ( 304 + leapYear ) )
433 {
434 pTm->tm_mday = nDay - ( 273 + leapYear );
435 pTm->tm_mon = 9;
436 }
437 else if( nDay <= ( 334 + leapYear ) )
438 {
439 pTm->tm_mday = nDay - ( 304 + leapYear );
440 pTm->tm_mon = 10;
441 }
442 else if( nDay <= ( 365 + leapYear ) )
443 {
444 pTm->tm_mday = nDay - ( 334 + leapYear );
445 pTm->tm_mon = 11;
446 }
447 }
448 if( !(lcid & VAR_DATEVALUEONLY) )
449 {
450 /* find the number of seconds in this day.
451 * fractional part times, hours, minutes, seconds.
452 */
453 pTm->tm_hour = (int) ( decimalPart * 24 );
454 pTm->tm_min = (int) ( ( ( decimalPart * 24 ) - pTm->tm_hour ) * 60 );
455 pTm->tm_sec = (int) ( ( ( decimalPart * 24 * 60 ) - ( pTm->tm_hour * 60 ) - pTm->tm_min ) * 60 );
456 }
457 return TRUE;
458 }
459 return FALSE;
460}
461
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000462
463
464/******************************************************************************
465 * SizeOfVariantData [INTERNAL]
466 *
467 * This function finds the size of the data referenced by a Variant based
468 * the type "vt" of the Variant.
469 */
470static int SizeOfVariantData( VARIANT* parg )
471{
472 int size = 0;
473 switch( parg->vt & VT_TYPEMASK )
474 {
475 case( VT_I2 ):
476 size = sizeof(short);
477 break;
478 case( VT_INT ):
479 size = sizeof(int);
480 break;
481 case( VT_I4 ):
482 size = sizeof(long);
483 break;
484 case( VT_UI1 ):
485 size = sizeof(BYTE);
486 break;
487 case( VT_UI2 ):
488 size = sizeof(unsigned short);
489 break;
490 case( VT_UINT ):
491 size = sizeof(unsigned int);
492 break;
493 case( VT_UI4 ):
494 size = sizeof(unsigned long);
495 break;
496 case( VT_R4 ):
497 size = sizeof(float);
498 break;
499 case( VT_R8 ):
500 size = sizeof(double);
501 break;
502 case( VT_DATE ):
503 size = sizeof(DATE);
504 break;
505 case( VT_BOOL ):
506 size = sizeof(VARIANT_BOOL);
507 break;
508 case( VT_BSTR ):
509 size = sizeof(void*);
510 break;
511 case( VT_CY ):
512 case( VT_DISPATCH ):
513 case( VT_UNKNOWN ):
514 case( VT_DECIMAL ):
515 default:
516 FIXME(ole,"Add size information for type vt=%d\n", parg->vt & VT_TYPEMASK );
517 break;
518 }
519
520 return size;
521}
522/******************************************************************************
523 * StringDupAtoBstr [INTERNAL]
524 *
525 */
526static BSTR32 StringDupAtoBstr( char* strIn )
527{
528 BSTR32 bstr = NULL;
529 OLECHAR32* pNewString = NULL;
530 pNewString = HEAP_strdupAtoW( GetProcessHeap(), 0, strIn );
531 bstr = SysAllocString32( pNewString );
532 HeapFree( GetProcessHeap(), 0, pNewString );
533 return bstr;
534}
535
536/******************************************************************************
537 * round [INTERNAL]
538 *
539 * Round the double value to the nearest integer value.
540 */
541static double round( double d )
542{
Justin Bradfordbc93bc81998-12-11 14:02:16 +0000543 double decimals = 0.0, integerValue = 0.0, roundedValue = 0.0;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000544 BOOL32 bEvenNumber = FALSE;
545 int nSign = 0;
546
547 /* Save the sign of the number
548 */
Justin Bradfordbc93bc81998-12-11 14:02:16 +0000549 nSign = (d >= 0.0) ? 1 : -1;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000550 d = fabs( d );
551
552 /* Remove the decimals.
553 */
Justin Bradfordbc93bc81998-12-11 14:02:16 +0000554 integerValue = floor( d );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000555
556 /* Set the Even flag. This is used to round the number when
557 * the decimals are exactly 1/2. If the integer part is
558 * odd the number is rounded up. If the integer part
559 * is even the number is rounded down. Using this method
560 * numbers are rounded up|down half the time.
561 */
Justin Bradfordbc93bc81998-12-11 14:02:16 +0000562 bEvenNumber = (((short)fmod(integerValue, 2)) == 0) ? TRUE : FALSE;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000563
564 /* Remove the integral part of the number.
565 */
566 decimals = d - integerValue;
567
568 /* Note: Ceil returns the smallest integer that is greater that x.
569 * and floor returns the largest integer that is less than or equal to x.
570 */
571 if( decimals > 0.5 )
572 {
573 /* If the decimal part is greater than 1/2
574 */
575 roundedValue = ceil( d );
576 }
577 else if( decimals < 0.5 )
578 {
579 /* If the decimal part is smaller than 1/2
580 */
581 roundedValue = floor( d );
582 }
583 else
584 {
585 /* the decimals are exactly 1/2 so round according to
586 * the bEvenNumber flag.
587 */
588 if( bEvenNumber )
589 {
590 roundedValue = floor( d );
591 }
592 else
593 {
594 roundedValue = ceil( d );
595 }
596 }
597
598 return roundedValue * nSign;
599}
600
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000601/******************************************************************************
602 * RemoveCharacterFromString [INTERNAL]
603 *
604 * Removes any of the characters in "strOfCharToRemove" from the "str" argument.
605 */
606static void RemoveCharacterFromString( LPSTR str, LPSTR strOfCharToRemove )
607{
608 LPSTR pNewString = NULL;
609 LPSTR strToken = NULL;
610
611
612 /* Check if we have a valid argument
613 */
614 if( str != NULL )
615 {
616 pNewString = strdup( str );
617 str[0] = '\0';
618 strToken = strtok( pNewString, strOfCharToRemove );
619 while( strToken != NULL ) {
620 strcat( str, strToken );
621 strToken = strtok( NULL, strOfCharToRemove );
622 }
623 free( pNewString );
624 }
625 return;
626}
627
628/******************************************************************************
629 * GetValidRealString [INTERNAL]
630 *
631 * Checks if the string is of proper format to be converted to a real value.
632 */
633static BOOL32 IsValidRealString( LPSTR strRealString )
634{
635 /* Real values that have a decimal point are required to either have
636 * digits before or after the decimal point. We will assume that
637 * we do not have any digits at either position. If we do encounter
638 * some we will disable this flag.
639 */
640 BOOL32 bDigitsRequired = TRUE;
641 /* Processed fields in the string representation of the real number.
642 */
643 BOOL32 bWhiteSpaceProcessed = FALSE;
644 BOOL32 bFirstSignProcessed = FALSE;
645 BOOL32 bFirstDigitsProcessed = FALSE;
646 BOOL32 bDecimalPointProcessed = FALSE;
647 BOOL32 bSecondDigitsProcessed = FALSE;
648 BOOL32 bExponentProcessed = FALSE;
649 BOOL32 bSecondSignProcessed = FALSE;
650 BOOL32 bThirdDigitsProcessed = FALSE;
651 /* Assume string parameter "strRealString" is valid and try to disprove it.
652 */
653 BOOL32 bValidRealString = TRUE;
654
655 /* Used to count the number of tokens in the "strRealString".
656 */
657 LPSTR strToken = NULL;
658 int nTokens = 0;
659 LPSTR pChar = NULL;
660
661 /* Check if we have a valid argument
662 */
663 if( strRealString == NULL )
664 {
665 bValidRealString = FALSE;
666 }
667
668 if( bValidRealString == TRUE )
669 {
670 /* Make sure we only have ONE token in the string.
671 */
672 strToken = strtok( strRealString, " " );
673 while( strToken != NULL ) {
674 nTokens++;
675 strToken = strtok( NULL, " " );
676 }
677
678 if( nTokens != 1 )
679 {
680 bValidRealString = FALSE;
681 }
682 }
683
684
685 /* Make sure this token contains only valid characters.
686 * The string argument to atof has the following form:
687 * [whitespace] [sign] [digits] [.digits] [ {d | D | e | E }[sign]digits]
688 * Whitespace consists of space and|or <TAB> characters, which are ignored.
689 * Sign is either plus '+' or minus '-'.
690 * Digits are one or more decimal digits.
691 * Note: If no digits appear before the decimal point, at least one must
692 * appear after the decimal point.
693 * The decimal digits may be followed by an exponent.
694 * An Exponent consists of an introductory letter ( D, d, E, or e) and
695 * an optionally signed decimal integer.
696 */
697 pChar = strRealString;
698 while( bValidRealString == TRUE && *pChar != '\0' )
699 {
700 switch( *pChar )
701 {
702 /* If whitespace...
703 */
704 case ' ':
705 case '\t':
706 if( bWhiteSpaceProcessed ||
707 bFirstSignProcessed ||
708 bFirstDigitsProcessed ||
709 bDecimalPointProcessed ||
710 bSecondDigitsProcessed ||
711 bExponentProcessed ||
712 bSecondSignProcessed ||
713 bThirdDigitsProcessed )
714 {
715 bValidRealString = FALSE;
716 }
717 break;
718 /* If sign...
719 */
720 case '+':
721 case '-':
722 if( bFirstSignProcessed == FALSE )
723 {
724 if( bFirstDigitsProcessed ||
725 bDecimalPointProcessed ||
726 bSecondDigitsProcessed ||
727 bExponentProcessed ||
728 bSecondSignProcessed ||
729 bThirdDigitsProcessed )
730 {
731 bValidRealString = FALSE;
732 }
733 bWhiteSpaceProcessed = TRUE;
734 bFirstSignProcessed = TRUE;
735 }
736 else if( bSecondSignProcessed == FALSE )
737 {
738 /* Note: The exponent must be present in
739 * order to accept the second sign...
740 */
741 if( bExponentProcessed == FALSE ||
742 bThirdDigitsProcessed ||
743 bDigitsRequired )
744 {
745 bValidRealString = FALSE;
746 }
747 bFirstSignProcessed = TRUE;
748 bWhiteSpaceProcessed = TRUE;
749 bFirstDigitsProcessed = TRUE;
750 bDecimalPointProcessed = TRUE;
751 bSecondDigitsProcessed = TRUE;
752 bSecondSignProcessed = TRUE;
753 }
754 break;
755
756 /* If decimals...
757 */
758 case '0':
759 case '1':
760 case '2':
761 case '3':
762 case '4':
763 case '5':
764 case '6':
765 case '7':
766 case '8':
767 case '9':
768 if( bFirstDigitsProcessed == FALSE )
769 {
770 if( bDecimalPointProcessed ||
771 bSecondDigitsProcessed ||
772 bExponentProcessed ||
773 bSecondSignProcessed ||
774 bThirdDigitsProcessed )
775 {
776 bValidRealString = FALSE;
777 }
778 bFirstSignProcessed = TRUE;
779 bWhiteSpaceProcessed = TRUE;
780 /* We have found some digits before the decimal point
781 * so disable the "Digits required" flag.
782 */
783 bDigitsRequired = FALSE;
784 }
785 else if( bSecondDigitsProcessed == FALSE )
786 {
787 if( bExponentProcessed ||
788 bSecondSignProcessed ||
789 bThirdDigitsProcessed )
790 {
791 bValidRealString = FALSE;
792 }
793 bFirstSignProcessed = TRUE;
794 bWhiteSpaceProcessed = TRUE;
795 bFirstDigitsProcessed = TRUE;
796 bDecimalPointProcessed = TRUE;
797 /* We have found some digits after the decimal point
798 * so disable the "Digits required" flag.
799 */
800 bDigitsRequired = FALSE;
801 }
802 else if( bThirdDigitsProcessed == FALSE )
803 {
804 /* Getting here means everything else should be processed.
805 * If we get anything else than a decimal following this
806 * digit it will be flagged by the other cases, so
807 * we do not really need to do anything in here.
808 */
809 }
810 break;
811 /* If DecimalPoint...
812 */
813 case '.':
814 if( bDecimalPointProcessed ||
815 bSecondDigitsProcessed ||
816 bExponentProcessed ||
817 bSecondSignProcessed ||
818 bThirdDigitsProcessed )
819 {
820 bValidRealString = FALSE;
821 }
822 bFirstSignProcessed = TRUE;
823 bWhiteSpaceProcessed = TRUE;
824 bFirstDigitsProcessed = TRUE;
825 bDecimalPointProcessed = TRUE;
826 break;
827 /* If Exponent...
828 */
829 case 'e':
830 case 'E':
831 case 'd':
832 case 'D':
833 if( bExponentProcessed ||
834 bSecondSignProcessed ||
835 bThirdDigitsProcessed ||
836 bDigitsRequired )
837 {
838 bValidRealString = FALSE;
839 }
840 bFirstSignProcessed = TRUE;
841 bWhiteSpaceProcessed = TRUE;
842 bFirstDigitsProcessed = TRUE;
843 bDecimalPointProcessed = TRUE;
844 bSecondDigitsProcessed = TRUE;
845 bExponentProcessed = TRUE;
846 break;
847 default:
848 bValidRealString = FALSE;
849 break;
850 }
851 /* Process next character.
852 */
853 pChar++;
854 }
855
856 /* If the required digits were not present we have an invalid
857 * string representation of a real number.
858 */
859 if( bDigitsRequired == TRUE )
860 {
861 bValidRealString = FALSE;
862 }
863
864 return bValidRealString;
865}
866
867
868/******************************************************************************
869 * Coerce [INTERNAL]
870 *
871 * This function dispatches execution to the proper conversion API
872 * to do the necessary coercion.
873 */
874static HRESULT Coerce( VARIANTARG* pd, LCID lcid, ULONG dwFlags, VARIANTARG* ps, VARTYPE vt )
875{
876 HRESULT res = S_OK;
877 unsigned short vtFrom = 0;
878 vtFrom = ps->vt & VT_TYPEMASK;
879
880 /* Note: Since "long" and "int" values both have 4 bytes and are both signed integers
881 * "int" will be treated as "long" in the following code.
882 * The same goes for there unsigned versions.
883 */
884
885 switch( vt )
886 {
887
888 case( VT_EMPTY ):
889 res = VariantClear32( pd );
890 break;
891 case( VT_NULL ):
892 res = VariantClear32( pd );
893 if( res == S_OK )
894 {
895 pd->vt = VT_NULL;
896 }
897 break;
898 case( VT_I1 ):
899 switch( vtFrom )
900 {
901 case( VT_I1 ):
902 res = VariantCopy32( pd, ps );
903 break;
904 case( VT_I2 ):
905 res = VarI1FromI232( ps->u.iVal, &(pd->u.cVal) );
906 break;
907 case( VT_INT ):
908 case( VT_I4 ):
909 res = VarI1FromI432( ps->u.lVal, &(pd->u.cVal) );
910 break;
911 case( VT_UI1 ):
912 res = VarI1FromUI132( ps->u.bVal, &(pd->u.cVal) );
913 break;
914 case( VT_UI2 ):
915 res = VarI1FromUI232( ps->u.uiVal, &(pd->u.cVal) );
916 break;
917 case( VT_UINT ):
918 case( VT_UI4 ):
919 res = VarI1FromUI432( ps->u.ulVal, &(pd->u.cVal) );
920 break;
921 case( VT_R4 ):
922 res = VarI1FromR432( ps->u.fltVal, &(pd->u.cVal) );
923 break;
924 case( VT_R8 ):
925 res = VarI1FromR832( ps->u.dblVal, &(pd->u.cVal) );
926 break;
927 case( VT_DATE ):
928 res = VarI1FromDate32( ps->u.date, &(pd->u.cVal) );
929 break;
930 case( VT_BOOL ):
931 res = VarI1FromBool32( ps->u.boolVal, &(pd->u.cVal) );
932 break;
933 case( VT_BSTR ):
934 res = VarI1FromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.cVal) );
935 break;
936 case( VT_CY ):
Justin Bradfordbc93bc81998-12-11 14:02:16 +0000937 res = VarI1FromCy32( ps->u.cyVal, &(pd->u.cVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000938 case( VT_DISPATCH ):
939 /*res = VarI1FromDisp32( ps->u.pdispVal, lcid, &(pd->u.cVal) );*/
940 case( VT_UNKNOWN ):
941 /*res = VarI1From32( ps->u.lVal, &(pd->u.cVal) );*/
942 case( VT_DECIMAL ):
943 /*res = VarI1FromDec32( ps->u.decVal, &(pd->u.cVal) );*/
944 default:
945 res = DISP_E_TYPEMISMATCH;
946 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
947 break;
948 }
949 break;
950
951 case( VT_I2 ):
952 switch( vtFrom )
953 {
954 case( VT_I1 ):
955 res = VarI2FromI132( ps->u.cVal, &(pd->u.iVal) );
956 break;
957 case( VT_I2 ):
958 res = VariantCopy32( pd, ps );
959 break;
960 case( VT_INT ):
961 case( VT_I4 ):
962 res = VarI2FromI432( ps->u.lVal, &(pd->u.iVal) );
963 break;
964 case( VT_UI1 ):
965 res = VarI2FromUI132( ps->u.bVal, &(pd->u.iVal) );
966 break;
967 case( VT_UI2 ):
968 res = VarI2FromUI232( ps->u.uiVal, &(pd->u.iVal) );
969 break;
970 case( VT_UINT ):
971 case( VT_UI4 ):
972 res = VarI2FromUI432( ps->u.ulVal, &(pd->u.iVal) );
973 break;
974 case( VT_R4 ):
975 res = VarI2FromR432( ps->u.fltVal, &(pd->u.iVal) );
976 break;
977 case( VT_R8 ):
978 res = VarI2FromR832( ps->u.dblVal, &(pd->u.iVal) );
979 break;
980 case( VT_DATE ):
981 res = VarI2FromDate32( ps->u.date, &(pd->u.iVal) );
982 break;
983 case( VT_BOOL ):
984 res = VarI2FromBool32( ps->u.boolVal, &(pd->u.iVal) );
985 break;
986 case( VT_BSTR ):
987 res = VarI2FromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.iVal) );
988 break;
989 case( VT_CY ):
Justin Bradfordbc93bc81998-12-11 14:02:16 +0000990 res = VarI2FromCy32( ps->u.cyVal, &(pd->u.iVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +0000991 case( VT_DISPATCH ):
992 /*res = VarI2FromDisp32( ps->u.pdispVal, lcid, &(pd->u.iVal) );*/
993 case( VT_UNKNOWN ):
994 /*res = VarI2From32( ps->u.lVal, &(pd->u.iVal) );*/
995 case( VT_DECIMAL ):
996 /*res = VarI2FromDec32( ps->u.deiVal, &(pd->u.iVal) );*/
997 default:
998 res = DISP_E_TYPEMISMATCH;
999 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1000 break;
1001 }
1002 break;
1003
1004 case( VT_INT ):
1005 case( VT_I4 ):
1006 switch( vtFrom )
1007 {
1008 case( VT_I1 ):
1009 res = VarI4FromI132( ps->u.cVal, &(pd->u.lVal) );
1010 break;
1011 case( VT_I2 ):
1012 res = VarI4FromI232( ps->u.iVal, &(pd->u.lVal) );
1013 break;
1014 case( VT_INT ):
1015 case( VT_I4 ):
1016 res = VariantCopy32( pd, ps );
1017 break;
1018 case( VT_UI1 ):
1019 res = VarI4FromUI132( ps->u.bVal, &(pd->u.lVal) );
1020 break;
1021 case( VT_UI2 ):
1022 res = VarI4FromUI232( ps->u.uiVal, &(pd->u.lVal) );
1023 break;
1024 case( VT_UINT ):
1025 case( VT_UI4 ):
1026 res = VarI4FromUI432( ps->u.ulVal, &(pd->u.lVal) );
1027 break;
1028 case( VT_R4 ):
1029 res = VarI4FromR432( ps->u.fltVal, &(pd->u.lVal) );
1030 break;
1031 case( VT_R8 ):
1032 res = VarI4FromR832( ps->u.dblVal, &(pd->u.lVal) );
1033 break;
1034 case( VT_DATE ):
1035 res = VarI4FromDate32( ps->u.date, &(pd->u.lVal) );
1036 break;
1037 case( VT_BOOL ):
1038 res = VarI4FromBool32( ps->u.boolVal, &(pd->u.lVal) );
1039 break;
1040 case( VT_BSTR ):
1041 res = VarI4FromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.lVal) );
1042 break;
1043 case( VT_CY ):
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001044 res = VarI4FromCy32( ps->u.cyVal, &(pd->u.lVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001045 case( VT_DISPATCH ):
1046 /*res = VarI4FromDisp32( ps->u.pdispVal, lcid, &(pd->u.lVal) );*/
1047 case( VT_UNKNOWN ):
1048 /*res = VarI4From32( ps->u.lVal, &(pd->u.lVal) );*/
1049 case( VT_DECIMAL ):
1050 /*res = VarI4FromDec32( ps->u.deiVal, &(pd->u.lVal) );*/
1051 default:
1052 res = DISP_E_TYPEMISMATCH;
1053 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1054 break;
1055 }
1056 break;
1057
1058 case( VT_UI1 ):
1059 switch( vtFrom )
1060 {
1061 case( VT_I1 ):
1062 res = VarUI1FromI132( ps->u.cVal, &(pd->u.bVal) );
1063 break;
1064 case( VT_I2 ):
1065 res = VarUI1FromI232( ps->u.iVal, &(pd->u.bVal) );
1066 break;
1067 case( VT_INT ):
1068 case( VT_I4 ):
1069 res = VarUI1FromI432( ps->u.lVal, &(pd->u.bVal) );
1070 break;
1071 case( VT_UI1 ):
1072 res = VariantCopy32( pd, ps );
1073 break;
1074 case( VT_UI2 ):
1075 res = VarUI1FromUI232( ps->u.uiVal, &(pd->u.bVal) );
1076 break;
1077 case( VT_UINT ):
1078 case( VT_UI4 ):
1079 res = VarUI1FromUI432( ps->u.ulVal, &(pd->u.bVal) );
1080 break;
1081 case( VT_R4 ):
1082 res = VarUI1FromR432( ps->u.fltVal, &(pd->u.bVal) );
1083 break;
1084 case( VT_R8 ):
1085 res = VarUI1FromR832( ps->u.dblVal, &(pd->u.bVal) );
1086 break;
1087 case( VT_DATE ):
1088 res = VarUI1FromDate32( ps->u.date, &(pd->u.bVal) );
1089 break;
1090 case( VT_BOOL ):
1091 res = VarUI1FromBool32( ps->u.boolVal, &(pd->u.bVal) );
1092 break;
1093 case( VT_BSTR ):
1094 res = VarUI1FromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.bVal) );
1095 break;
1096 case( VT_CY ):
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001097 res = VarUI1FromCy32( ps->u.cyVal, &(pd->u.bVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001098 case( VT_DISPATCH ):
1099 /*res = VarUI1FromDisp32( ps->u.pdispVal, lcid, &(pd->u.bVal) );*/
1100 case( VT_UNKNOWN ):
1101 /*res = VarUI1From32( ps->u.lVal, &(pd->u.bVal) );*/
1102 case( VT_DECIMAL ):
1103 /*res = VarUI1FromDec32( ps->u.deiVal, &(pd->u.bVal) );*/
1104 default:
1105 res = DISP_E_TYPEMISMATCH;
1106 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1107 break;
1108 }
1109 break;
1110
1111 case( VT_UI2 ):
1112 switch( vtFrom )
1113 {
1114 case( VT_I1 ):
1115 res = VarUI2FromI132( ps->u.cVal, &(pd->u.uiVal) );
1116 break;
1117 case( VT_I2 ):
1118 res = VarUI2FromI232( ps->u.iVal, &(pd->u.uiVal) );
1119 break;
1120 case( VT_INT ):
1121 case( VT_I4 ):
1122 res = VarUI2FromI432( ps->u.lVal, &(pd->u.uiVal) );
1123 break;
1124 case( VT_UI1 ):
1125 res = VarUI2FromUI132( ps->u.bVal, &(pd->u.uiVal) );
1126 break;
1127 case( VT_UI2 ):
1128 res = VariantCopy32( pd, ps );
1129 break;
1130 case( VT_UINT ):
1131 case( VT_UI4 ):
1132 res = VarUI2FromUI432( ps->u.ulVal, &(pd->u.uiVal) );
1133 break;
1134 case( VT_R4 ):
1135 res = VarUI2FromR432( ps->u.fltVal, &(pd->u.uiVal) );
1136 break;
1137 case( VT_R8 ):
1138 res = VarUI2FromR832( ps->u.dblVal, &(pd->u.uiVal) );
1139 break;
1140 case( VT_DATE ):
1141 res = VarUI2FromDate32( ps->u.date, &(pd->u.uiVal) );
1142 break;
1143 case( VT_BOOL ):
1144 res = VarUI2FromBool32( ps->u.boolVal, &(pd->u.uiVal) );
1145 break;
1146 case( VT_BSTR ):
1147 res = VarUI2FromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.uiVal) );
1148 break;
1149 case( VT_CY ):
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001150 res = VarUI2FromCy32( ps->u.cyVal, &(pd->u.uiVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001151 case( VT_DISPATCH ):
1152 /*res = VarUI2FromDisp32( ps->u.pdispVal, lcid, &(pd->u.uiVal) );*/
1153 case( VT_UNKNOWN ):
1154 /*res = VarUI2From32( ps->u.lVal, &(pd->u.uiVal) );*/
1155 case( VT_DECIMAL ):
1156 /*res = VarUI2FromDec32( ps->u.deiVal, &(pd->u.uiVal) );*/
1157 default:
1158 res = DISP_E_TYPEMISMATCH;
1159 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1160 break;
1161 }
1162 break;
1163
1164 case( VT_UINT ):
1165 case( VT_UI4 ):
1166 switch( vtFrom )
1167 {
1168 case( VT_I1 ):
1169 res = VarUI4FromI132( ps->u.cVal, &(pd->u.ulVal) );
1170 break;
1171 case( VT_I2 ):
1172 res = VarUI4FromI232( ps->u.iVal, &(pd->u.ulVal) );
1173 break;
1174 case( VT_INT ):
1175 case( VT_I4 ):
1176 res = VarUI4FromI432( ps->u.lVal, &(pd->u.ulVal) );
1177 break;
1178 case( VT_UI1 ):
1179 res = VarUI4FromUI132( ps->u.bVal, &(pd->u.ulVal) );
1180 break;
1181 case( VT_UI2 ):
1182 res = VarUI4FromUI232( ps->u.uiVal, &(pd->u.ulVal) );
1183 break;
1184 case( VT_UI4 ):
1185 res = VariantCopy32( pd, ps );
1186 break;
1187 case( VT_R4 ):
1188 res = VarUI4FromR432( ps->u.fltVal, &(pd->u.ulVal) );
1189 break;
1190 case( VT_R8 ):
1191 res = VarUI4FromR832( ps->u.dblVal, &(pd->u.ulVal) );
1192 break;
1193 case( VT_DATE ):
1194 res = VarUI4FromDate32( ps->u.date, &(pd->u.ulVal) );
1195 break;
1196 case( VT_BOOL ):
1197 res = VarUI4FromBool32( ps->u.boolVal, &(pd->u.ulVal) );
1198 break;
1199 case( VT_BSTR ):
1200 res = VarUI4FromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.ulVal) );
1201 break;
1202 case( VT_CY ):
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001203 res = VarUI4FromCy32( ps->u.cyVal, &(pd->u.ulVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001204 case( VT_DISPATCH ):
1205 /*res = VarUI4FromDisp32( ps->u.pdispVal, lcid, &(pd->u.ulVal) );*/
1206 case( VT_UNKNOWN ):
1207 /*res = VarUI4From32( ps->u.lVal, &(pd->u.ulVal) );*/
1208 case( VT_DECIMAL ):
1209 /*res = VarUI4FromDec32( ps->u.deiVal, &(pd->u.ulVal) );*/
1210 default:
1211 res = DISP_E_TYPEMISMATCH;
1212 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1213 break;
1214 }
1215 break;
1216
1217 case( VT_R4 ):
1218 switch( vtFrom )
1219 {
1220 case( VT_I1 ):
1221 res = VarR4FromI132( ps->u.cVal, &(pd->u.fltVal) );
1222 break;
1223 case( VT_I2 ):
1224 res = VarR4FromI232( ps->u.iVal, &(pd->u.fltVal) );
1225 break;
1226 case( VT_INT ):
1227 case( VT_I4 ):
1228 res = VarR4FromI432( ps->u.lVal, &(pd->u.fltVal) );
1229 break;
1230 case( VT_UI1 ):
1231 res = VarR4FromUI132( ps->u.bVal, &(pd->u.fltVal) );
1232 break;
1233 case( VT_UI2 ):
1234 res = VarR4FromUI232( ps->u.uiVal, &(pd->u.fltVal) );
1235 break;
1236 case( VT_UINT ):
1237 case( VT_UI4 ):
1238 res = VarR4FromUI432( ps->u.ulVal, &(pd->u.fltVal) );
1239 break;
1240 case( VT_R4 ):
1241 res = VariantCopy32( pd, ps );
1242 break;
1243 case( VT_R8 ):
1244 res = VarR4FromR832( ps->u.dblVal, &(pd->u.fltVal) );
1245 break;
1246 case( VT_DATE ):
1247 res = VarR4FromDate32( ps->u.date, &(pd->u.fltVal) );
1248 break;
1249 case( VT_BOOL ):
1250 res = VarR4FromBool32( ps->u.boolVal, &(pd->u.fltVal) );
1251 break;
1252 case( VT_BSTR ):
1253 res = VarR4FromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.fltVal) );
1254 break;
1255 case( VT_CY ):
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001256 res = VarR4FromCy32( ps->u.cyVal, &(pd->u.fltVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001257 case( VT_DISPATCH ):
1258 /*res = VarR4FromDisp32( ps->u.pdispVal, lcid, &(pd->u.fltVal) );*/
1259 case( VT_UNKNOWN ):
1260 /*res = VarR4From32( ps->u.lVal, &(pd->u.fltVal) );*/
1261 case( VT_DECIMAL ):
1262 /*res = VarR4FromDec32( ps->u.deiVal, &(pd->u.fltVal) );*/
1263 default:
1264 res = DISP_E_TYPEMISMATCH;
1265 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1266 break;
1267 }
1268 break;
1269
1270 case( VT_R8 ):
1271 switch( vtFrom )
1272 {
1273 case( VT_I1 ):
1274 res = VarR8FromI132( ps->u.cVal, &(pd->u.dblVal) );
1275 break;
1276 case( VT_I2 ):
1277 res = VarR8FromI232( ps->u.iVal, &(pd->u.dblVal) );
1278 break;
1279 case( VT_INT ):
1280 case( VT_I4 ):
1281 res = VarR8FromI432( ps->u.lVal, &(pd->u.dblVal) );
1282 break;
1283 case( VT_UI1 ):
1284 res = VarR8FromUI132( ps->u.bVal, &(pd->u.dblVal) );
1285 break;
1286 case( VT_UI2 ):
1287 res = VarR8FromUI232( ps->u.uiVal, &(pd->u.dblVal) );
1288 break;
1289 case( VT_UINT ):
1290 case( VT_UI4 ):
1291 res = VarR8FromUI432( ps->u.ulVal, &(pd->u.dblVal) );
1292 break;
1293 case( VT_R4 ):
1294 res = VarR8FromR432( ps->u.fltVal, &(pd->u.dblVal) );
1295 break;
1296 case( VT_R8 ):
1297 res = VariantCopy32( pd, ps );
1298 break;
1299 case( VT_DATE ):
1300 res = VarR8FromDate32( ps->u.date, &(pd->u.dblVal) );
1301 break;
1302 case( VT_BOOL ):
1303 res = VarR8FromBool32( ps->u.boolVal, &(pd->u.dblVal) );
1304 break;
1305 case( VT_BSTR ):
1306 res = VarR8FromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.dblVal) );
1307 break;
1308 case( VT_CY ):
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001309 res = VarR8FromCy32( ps->u.cyVal, &(pd->u.dblVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001310 case( VT_DISPATCH ):
1311 /*res = VarR8FromDisp32( ps->u.pdispVal, lcid, &(pd->u.dblVal) );*/
1312 case( VT_UNKNOWN ):
1313 /*res = VarR8From32( ps->u.lVal, &(pd->u.dblVal) );*/
1314 case( VT_DECIMAL ):
1315 /*res = VarR8FromDec32( ps->u.deiVal, &(pd->u.dblVal) );*/
1316 default:
1317 res = DISP_E_TYPEMISMATCH;
1318 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1319 break;
1320 }
1321 break;
1322
1323 case( VT_DATE ):
1324 switch( vtFrom )
1325 {
1326 case( VT_I1 ):
1327 res = VarDateFromI132( ps->u.cVal, &(pd->u.date) );
1328 break;
1329 case( VT_I2 ):
1330 res = VarDateFromI232( ps->u.iVal, &(pd->u.date) );
1331 break;
1332 case( VT_INT ):
1333 res = VarDateFromInt32( ps->u.intVal, &(pd->u.date) );
1334 break;
1335 case( VT_I4 ):
1336 res = VarDateFromI432( ps->u.lVal, &(pd->u.date) );
1337 break;
1338 case( VT_UI1 ):
1339 res = VarDateFromUI132( ps->u.bVal, &(pd->u.date) );
1340 break;
1341 case( VT_UI2 ):
1342 res = VarDateFromUI232( ps->u.uiVal, &(pd->u.date) );
1343 break;
1344 case( VT_UINT ):
1345 res = VarDateFromUint32( ps->u.uintVal, &(pd->u.date) );
1346 break;
1347 case( VT_UI4 ):
1348 res = VarDateFromUI432( ps->u.ulVal, &(pd->u.date) );
1349 break;
1350 case( VT_R4 ):
1351 res = VarDateFromR432( ps->u.fltVal, &(pd->u.date) );
1352 break;
1353 case( VT_R8 ):
1354 res = VarDateFromR832( ps->u.dblVal, &(pd->u.date) );
1355 break;
1356 case( VT_DATE ):
1357 res = VariantCopy32( pd, ps );
1358 break;
1359 case( VT_BOOL ):
1360 res = VarDateFromBool32( ps->u.boolVal, &(pd->u.date) );
1361 break;
1362 case( VT_BSTR ):
1363 res = VarDateFromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.date) );
1364 break;
1365 case( VT_CY ):
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001366 res = VarDateFromCy32( ps->u.cyVal, &(pd->u.date) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001367 case( VT_DISPATCH ):
1368 /*res = VarDateFromDisp32( ps->u.pdispVal, lcid, &(pd->u.date) );*/
1369 case( VT_UNKNOWN ):
1370 /*res = VarDateFrom32( ps->u.lVal, &(pd->u.date) );*/
1371 case( VT_DECIMAL ):
1372 /*res = VarDateFromDec32( ps->u.deiVal, &(pd->u.date) );*/
1373 default:
1374 res = DISP_E_TYPEMISMATCH;
1375 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1376 break;
1377 }
1378 break;
1379
1380 case( VT_BOOL ):
1381 switch( vtFrom )
1382 {
1383 case( VT_I1 ):
1384 res = VarBoolFromI132( ps->u.cVal, &(pd->u.boolVal) );
1385 break;
1386 case( VT_I2 ):
1387 res = VarBoolFromI232( ps->u.iVal, &(pd->u.boolVal) );
1388 break;
1389 case( VT_INT ):
1390 res = VarBoolFromInt32( ps->u.intVal, &(pd->u.boolVal) );
1391 break;
1392 case( VT_I4 ):
1393 res = VarBoolFromI432( ps->u.lVal, &(pd->u.boolVal) );
1394 break;
1395 case( VT_UI1 ):
1396 res = VarBoolFromUI132( ps->u.bVal, &(pd->u.boolVal) );
1397 break;
1398 case( VT_UI2 ):
1399 res = VarBoolFromUI232( ps->u.uiVal, &(pd->u.boolVal) );
1400 break;
1401 case( VT_UINT ):
1402 res = VarBoolFromUint32( ps->u.uintVal, &(pd->u.boolVal) );
1403 break;
1404 case( VT_UI4 ):
1405 res = VarBoolFromUI432( ps->u.ulVal, &(pd->u.boolVal) );
1406 break;
1407 case( VT_R4 ):
1408 res = VarBoolFromR432( ps->u.fltVal, &(pd->u.boolVal) );
1409 break;
1410 case( VT_R8 ):
1411 res = VarBoolFromR832( ps->u.dblVal, &(pd->u.boolVal) );
1412 break;
1413 case( VT_DATE ):
1414 res = VarBoolFromDate32( ps->u.date, &(pd->u.boolVal) );
1415 break;
1416 case( VT_BOOL ):
1417 res = VariantCopy32( pd, ps );
1418 break;
1419 case( VT_BSTR ):
1420 res = VarBoolFromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.boolVal) );
1421 break;
1422 case( VT_CY ):
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001423 res = VarBoolFromCy32( ps->u.cyVal, &(pd->u.boolVal) );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001424 case( VT_DISPATCH ):
1425 /*res = VarBoolFromDisp32( ps->u.pdispVal, lcid, &(pd->u.boolVal) );*/
1426 case( VT_UNKNOWN ):
1427 /*res = VarBoolFrom32( ps->u.lVal, &(pd->u.boolVal) );*/
1428 case( VT_DECIMAL ):
1429 /*res = VarBoolFromDec32( ps->u.deiVal, &(pd->u.boolVal) );*/
1430 default:
1431 res = DISP_E_TYPEMISMATCH;
1432 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1433 break;
1434 }
1435 break;
1436
1437 case( VT_BSTR ):
1438 switch( vtFrom )
1439 {
1440 case( VT_I1 ):
1441 res = VarBstrFromI132( ps->u.cVal, lcid, dwFlags, &(pd->u.bstrVal) );
1442 break;
1443 case( VT_I2 ):
1444 res = VarBstrFromI232( ps->u.iVal, lcid, dwFlags, &(pd->u.bstrVal) );
1445 break;
1446 case( VT_INT ):
1447 res = VarBstrFromInt32( ps->u.intVal, lcid, dwFlags, &(pd->u.bstrVal) );
1448 break;
1449 case( VT_I4 ):
1450 res = VarBstrFromI432( ps->u.lVal, lcid, dwFlags, &(pd->u.bstrVal) );
1451 break;
1452 case( VT_UI1 ):
1453 res = VarBstrFromUI132( ps->u.bVal, lcid, dwFlags, &(pd->u.bstrVal) );
1454 break;
1455 case( VT_UI2 ):
1456 res = VarBstrFromUI232( ps->u.uiVal, lcid, dwFlags, &(pd->u.bstrVal) );
1457 break;
1458 case( VT_UINT ):
1459 res = VarBstrFromUint32( ps->u.uintVal, lcid, dwFlags, &(pd->u.bstrVal) );
1460 break;
1461 case( VT_UI4 ):
1462 res = VarBstrFromUI432( ps->u.ulVal, lcid, dwFlags, &(pd->u.bstrVal) );
1463 break;
1464 case( VT_R4 ):
1465 res = VarBstrFromR432( ps->u.fltVal, lcid, dwFlags, &(pd->u.bstrVal) );
1466 break;
1467 case( VT_R8 ):
1468 res = VarBstrFromR832( ps->u.dblVal, lcid, dwFlags, &(pd->u.bstrVal) );
1469 break;
1470 case( VT_DATE ):
1471 res = VarBstrFromDate32( ps->u.date, lcid, dwFlags, &(pd->u.bstrVal) );
1472 break;
1473 case( VT_BOOL ):
1474 res = VarBstrFromBool32( ps->u.boolVal, lcid, dwFlags, &(pd->u.bstrVal) );
1475 break;
1476 case( VT_BSTR ):
1477 res = VariantCopy32( pd, ps );
1478 break;
1479 case( VT_CY ):
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001480 /*res = VarBstrFromCy32( ps->u.cyVal, lcid, dwFlags, &(pd->u.bstrVal) );*/
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001481 case( VT_DISPATCH ):
1482 /*res = VarBstrFromDisp32( ps->u.pdispVal, lcid, lcid, dwFlags, &(pd->u.bstrVal) );*/
1483 case( VT_UNKNOWN ):
1484 /*res = VarBstrFrom32( ps->u.lVal, lcid, dwFlags, &(pd->u.bstrVal) );*/
1485 case( VT_DECIMAL ):
1486 /*res = VarBstrFromDec32( ps->u.deiVal, lcid, dwFlags, &(pd->u.bstrVal) );*/
1487 default:
1488 res = DISP_E_TYPEMISMATCH;
1489 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1490 break;
1491 }
1492 break;
1493
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001494 case( VT_CY ):
1495 switch( vtFrom )
1496 {
1497 case( VT_I1 ):
1498 res = VarCyFromI132( ps->u.cVal, &(pd->u.cyVal) );
1499 break;
1500 case( VT_I2 ):
1501 res = VarCyFromI232( ps->u.iVal, &(pd->u.cyVal) );
1502 break;
1503 case( VT_INT ):
1504 res = VarCyFromInt32( ps->u.intVal, &(pd->u.cyVal) );
1505 break;
1506 case( VT_I4 ):
1507 res = VarCyFromI432( ps->u.lVal, &(pd->u.cyVal) );
1508 break;
1509 case( VT_UI1 ):
1510 res = VarCyFromUI132( ps->u.bVal, &(pd->u.cyVal) );
1511 break;
1512 case( VT_UI2 ):
1513 res = VarCyFromUI232( ps->u.uiVal, &(pd->u.cyVal) );
1514 break;
1515 case( VT_UINT ):
1516 res = VarCyFromUint32( ps->u.uintVal, &(pd->u.cyVal) );
1517 break;
1518 case( VT_UI4 ):
1519 res = VarCyFromUI432( ps->u.ulVal, &(pd->u.cyVal) );
1520 break;
1521 case( VT_R4 ):
1522 res = VarCyFromR432( ps->u.fltVal, &(pd->u.cyVal) );
1523 break;
1524 case( VT_R8 ):
1525 res = VarCyFromR832( ps->u.dblVal, &(pd->u.cyVal) );
1526 break;
1527 case( VT_DATE ):
1528 res = VarCyFromDate32( ps->u.date, &(pd->u.cyVal) );
1529 break;
1530 case( VT_BOOL ):
1531 res = VarCyFromBool32( ps->u.date, &(pd->u.cyVal) );
1532 break;
1533 case( VT_CY ):
1534 res = VariantCopy32( pd, ps );
1535 break;
1536 case( VT_BSTR ):
1537 /*res = VarCyFromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.cyVal) );*/
1538 case( VT_DISPATCH ):
1539 /*res = VarCyFromDisp32( ps->u.pdispVal, lcid, &(pd->u.boolVal) );*/
1540 case( VT_UNKNOWN ):
1541 /*res = VarCyFrom32( ps->u.lVal, &(pd->u.boolVal) );*/
1542 case( VT_DECIMAL ):
1543 /*res = VarCyFromDec32( ps->u.deiVal, &(pd->u.boolVal) );*/
1544 default:
1545 res = DISP_E_TYPEMISMATCH;
1546 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1547 break;
1548 }
1549 break;
1550
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001551 default:
1552 res = DISP_E_TYPEMISMATCH;
1553 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1554 break;
1555 }
1556
1557 return res;
1558}
1559
1560/******************************************************************************
1561 * ValidateVtRange [INTERNAL]
1562 *
1563 * Used internally by the hi-level Variant API to determine
1564 * if the vartypes are valid.
1565 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00001566static HRESULT WINAPI ValidateVtRange( VARTYPE vt )
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001567{
1568 /* if by value we must make sure it is in the
1569 * range of the valid types.
1570 */
1571 if( ( vt & VT_TYPEMASK ) > VT_MAXVALIDTYPE )
1572 {
1573 return DISP_E_BADVARTYPE;
1574 }
1575 return S_OK;
1576}
1577
1578
1579/******************************************************************************
1580 * ValidateVartype [INTERNAL]
1581 *
1582 * Used internally by the hi-level Variant API to determine
1583 * if the vartypes are valid.
1584 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00001585static HRESULT WINAPI ValidateVariantType( VARTYPE vt )
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001586{
1587 HRESULT res = S_OK;
1588
1589 /* check if we have a valid argument.
1590 */
1591 if( vt & VT_BYREF )
1592 {
1593 /* if by reference check that the type is in
1594 * the valid range and that it is not of empty or null type
1595 */
1596 if( ( vt & VT_TYPEMASK ) == VT_EMPTY ||
1597 ( vt & VT_TYPEMASK ) == VT_NULL ||
1598 ( vt & VT_TYPEMASK ) > VT_MAXVALIDTYPE )
1599 {
1600 res = E_INVALIDARG;
1601 }
1602
1603 }
1604 else
1605 {
1606 res = ValidateVtRange( vt );
1607 }
1608
1609 return res;
1610}
1611
1612/******************************************************************************
1613 * ValidateVt [INTERNAL]
1614 *
1615 * Used internally by the hi-level Variant API to determine
1616 * if the vartypes are valid.
1617 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00001618static HRESULT WINAPI ValidateVt( VARTYPE vt )
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001619{
1620 HRESULT res = S_OK;
1621
1622 /* check if we have a valid argument.
1623 */
1624 if( vt & VT_BYREF )
1625 {
1626 /* if by reference check that the type is in
1627 * the valid range and that it is not of empty or null type
1628 */
1629 if( ( vt & VT_TYPEMASK ) == VT_EMPTY ||
1630 ( vt & VT_TYPEMASK ) == VT_NULL ||
1631 ( vt & VT_TYPEMASK ) > VT_MAXVALIDTYPE )
1632 {
1633 res = DISP_E_BADVARTYPE;
1634 }
1635
1636 }
1637 else
1638 {
1639 res = ValidateVtRange( vt );
1640 }
1641
1642 return res;
1643}
1644
1645
1646
1647
1648
1649/******************************************************************************
1650 * VariantInit32 [OLEAUT32.8]
1651 *
1652 * Initializes the Variant. Unlike VariantClear it does not interpret the current
1653 * contents of the Variant.
1654 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00001655void WINAPI VariantInit32(VARIANTARG* pvarg)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001656{
1657 TRACE(ole,"(%p),stub\n",pvarg);
1658
1659 pvarg->vt = VT_EMPTY;
1660 pvarg->wReserved1 = 0;
1661 pvarg->wReserved2= 0;
1662 pvarg->wReserved3= 0;
1663
1664 return;
1665}
1666
1667/******************************************************************************
1668 * VariantClear32 [OLEAUT32.9]
1669 *
1670 * This function clears the VARIANT by setting the vt field to VT_EMPTY. It also
1671 * sets the wReservedX field to 0. The current contents of the VARIANT are
1672 * freed. If the vt is VT_BSTR the string is freed. If VT_DISPATCH the object is
1673 * released. If VT_ARRAY the array is freed.
1674 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00001675HRESULT WINAPI VariantClear32(VARIANTARG* pvarg)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001676{
1677 HRESULT res = S_OK;
1678 TRACE(ole,"(%p),stub\n",pvarg);
1679
1680 res = ValidateVariantType( pvarg->vt );
1681 if( res == S_OK )
1682 {
1683 if( !( pvarg->vt & VT_BYREF ) )
1684 {
1685 switch( pvarg->vt & VT_TYPEMASK )
1686 {
1687 case( VT_BSTR ):
1688 SysFreeString32( pvarg->u.bstrVal );
1689 break;
1690 case( VT_DISPATCH ):
1691 break;
1692 case( VT_VARIANT ):
1693 break;
1694 case( VT_UNKNOWN ):
1695 break;
1696 case( VT_SAFEARRAY ):
1697 break;
1698 default:
1699 break;
1700 }
1701 }
1702
1703 /* Set the fields to empty.
1704 */
1705 pvarg->wReserved1 = 0;
1706 pvarg->wReserved2 = 0;
1707 pvarg->wReserved3 = 0;
1708 pvarg->vt = VT_EMPTY;
1709 }
1710
1711 return res;
1712}
1713
1714/******************************************************************************
1715 * VariantCopy32 [OLEAUT32.10]
1716 *
1717 * Frees up the designation variant and makes a copy of the source.
1718 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00001719HRESULT WINAPI VariantCopy32(VARIANTARG* pvargDest, VARIANTARG* pvargSrc)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001720{
1721 HRESULT res = S_OK;
1722 TRACE(ole,"(%p, %p),stub\n", pvargDest, pvargSrc);
1723
1724 res = ValidateVariantType( pvargSrc->vt );
1725 /* If the pointer are to the same variant we don't need
1726 * to do anything.
1727 */
1728 if( pvargDest != pvargSrc && res == S_OK )
1729 {
1730 res = VariantClear32( pvargDest );
1731
1732 if( res == S_OK )
1733 {
1734 if( pvargSrc->vt & VT_BYREF )
1735 {
1736 /* In the case of byreference we only need
1737 * to copy the pointer.
1738 */
1739 pvargDest->u = pvargSrc->u;
1740 pvargDest->vt = pvargSrc->vt;
1741 }
1742 else
1743 {
1744 /* In the case of by value we need to
1745 * copy the actuall value. In the case of
1746 * VT_BSTR a copy of the string is made,
1747 * if VT_ARRAY the entire array is copied
1748 * if VT_DISPATCH or VT_IUNKNOWN AddReff is
1749 * called to increment the object's reference count.
1750 */
1751 switch( pvargSrc->vt & VT_TYPEMASK )
1752 {
1753 case( VT_BSTR ):
1754 pvargDest->u.bstrVal = SysAllocString32( pvargSrc->u.bstrVal );
1755 break;
1756 case( VT_DISPATCH ):
1757 break;
1758 case( VT_VARIANT ):
1759 break;
1760 case( VT_UNKNOWN ):
1761 break;
1762 case( VT_SAFEARRAY ):
1763 break;
1764 default:
1765 pvargDest->u = pvargSrc->u;
1766 break;
1767 }
1768 pvargDest->vt = pvargSrc->vt;
1769 }
1770
1771 }
1772 }
1773 return res;
1774}
1775
1776
1777/******************************************************************************
1778 * VariantCopyInd32 [OLEAUT32.11]
1779 *
1780 * Frees up the destination variant and makes a copy of the source. If
1781 * the source is of type VT_BYREF it performs the necessary indirections.
1782 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00001783HRESULT WINAPI VariantCopyInd32(VARIANT* pvargDest, VARIANTARG* pvargSrc)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001784{
1785 HRESULT res = S_OK;
1786 TRACE(ole,"(%p, %p),stub\n", pvargDest, pvargSrc);
1787
1788 res = ValidateVariantType( pvargSrc->vt );
1789 if( res != S_OK )
1790 return res;
1791
1792 if( pvargSrc->vt & VT_BYREF )
1793 {
1794 VARIANTARG varg;
1795 VariantInit32( &varg );
1796 /* handle the in place copy.
1797 */
1798 if( pvargDest == pvargSrc )
1799 {
1800 /* we will use a copy of the source instead.
1801 */
1802 res = VariantCopy32( &varg, pvargSrc );
1803 pvargSrc = &varg;
1804 }
1805 if( res == S_OK )
1806 {
1807 res = VariantClear32( pvargDest );
1808 if( res == S_OK )
1809 {
1810 /* In the case of by reference we need
1811 * to copy the date pointed to by the variant.
1812 */
1813 /* Get the variant type.
1814 */
1815 switch( pvargSrc->vt & VT_TYPEMASK )
1816 {
1817 case( VT_BSTR ):
1818 pvargDest->u.bstrVal = SysAllocString32( *(pvargSrc->u.pbstrVal) );
1819 break;
1820 case( VT_DISPATCH ):
1821 break;
1822 case( VT_VARIANT ):
1823 {
1824 /* Prevent from cycling. According to tests on
1825 * VariantCopyInd in Windows and the documentation
Justin Bradfordbc93bc81998-12-11 14:02:16 +00001826 * this API dereferences the inner Variants to only one depth.
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001827 * If the inner Variant itself contains an
1828 * other inner variant the E_INVALIDARG error is
1829 * returned.
1830 */
1831 if( pvargSrc->wReserved1 & PROCESSING_INNER_VARIANT )
1832 {
1833 /* If we get here we are attempting to deference
1834 * an inner variant that that is itself contained
1835 * in an inner variant so report E_INVALIDARG error.
1836 */
1837 res = E_INVALIDARG;
1838 }
1839 else
1840 {
1841 /* Set the processing inner variant flag.
1842 * We will set this flag in the inner variant
1843 * that will be passed to the VariantCopyInd function.
1844 */
1845 (pvargSrc->u.pvarVal)->wReserved1 |= PROCESSING_INNER_VARIANT;
1846 /* Dereference the inner variant.
1847 */
1848 res = VariantCopyInd32( pvargDest, pvargSrc->u.pvarVal );
1849 }
1850 }
1851 break;
1852 case( VT_UNKNOWN ):
1853 break;
1854 case( VT_SAFEARRAY ):
1855 break;
1856 default:
1857 /* This is a by reference Variant which means that the union
1858 * part of the Variant contains a pointer to some data of
1859 * type "pvargSrc->vt & VT_TYPEMASK".
1860 * We will deference this data in a generic fashion using
1861 * the void pointer "Variant.u.byref".
1862 * We will copy this data into the union of the destination
1863 * Variant.
1864 */
1865 memcpy( &pvargDest->u, pvargSrc->u.byref, SizeOfVariantData( pvargSrc ) );
1866 break;
1867 }
1868 pvargDest->vt = pvargSrc->vt & VT_TYPEMASK;
1869 }
1870 }
1871 /* this should not fail.
1872 */
1873 VariantClear32( &varg );
1874 }
1875 else
1876 {
1877 res = VariantCopy32( pvargDest, pvargSrc );
1878 }
1879 return res;
1880}
1881
1882/******************************************************************************
1883 * VariantChangeType32 [OLEAUT32.12]
1884 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00001885HRESULT WINAPI VariantChangeType32(VARIANTARG* pvargDest, VARIANTARG* pvargSrc,
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001886 USHORT wFlags, VARTYPE vt)
1887{
1888 return VariantChangeTypeEx32( pvargDest, pvargSrc, 0, wFlags, vt );
1889}
1890
1891/******************************************************************************
1892 * VariantChangeTypeEx32 [OLEAUT32.147]
1893 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00001894HRESULT WINAPI VariantChangeTypeEx32(VARIANTARG* pvargDest, VARIANTARG* pvargSrc,
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001895 LCID lcid, USHORT wFlags, VARTYPE vt)
1896{
1897 HRESULT res = S_OK;
1898 VARIANTARG varg;
1899 VariantInit32( &varg );
1900
1901 TRACE(ole,"(%p, %p, %ld, %u, %u),stub\n", pvargDest, pvargSrc, lcid, wFlags, vt);
1902
1903 /* validate our source argument.
1904 */
1905 res = ValidateVariantType( pvargSrc->vt );
1906
1907 /* validate the vartype.
1908 */
1909 if( res == S_OK )
1910 {
1911 res = ValidateVt( vt );
1912 }
1913
1914 /* if we are doing an in-place conversion make a copy of the source.
1915 */
1916 if( res == S_OK && pvargDest == pvargSrc )
1917 {
1918 res = VariantCopy32( &varg, pvargSrc );
1919 pvargSrc = &varg;
1920 }
1921
1922 if( res == S_OK )
1923 {
1924 /* free up the destination variant.
1925 */
1926 res = VariantClear32( pvargDest );
1927 }
1928
1929 if( res == S_OK )
1930 {
1931 if( pvargSrc->vt & VT_BYREF )
1932 {
1933 /* Convert the source variant to a "byvalue" variant.
1934 */
1935 VARIANTARG Variant;
1936 VariantInit32( &Variant );
1937 res = VariantCopyInd32( &Variant, pvargSrc );
1938 if( res == S_OK )
1939 {
1940 res = Coerce( pvargDest, lcid, wFlags, &Variant, vt );
1941 /* this should not fail.
1942 */
1943 VariantClear32( &Variant );
1944 }
1945
1946 }
1947 else
1948 {
1949 /* Use the current "byvalue" source variant.
1950 */
1951 res = Coerce( pvargDest, lcid, wFlags, pvargSrc, vt );
1952 }
1953 }
1954 /* this should not fail.
1955 */
1956 VariantClear32( &varg );
1957
1958 return res;
1959}
1960
1961
1962
1963
1964/******************************************************************************
1965 * VarUI1FromI232 [OLEAUT32.130]
1966 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00001967HRESULT WINAPI VarUI1FromI232(short sIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001968{
1969 TRACE( ole, "( %d, %p ), stub\n", sIn, pbOut );
1970
1971 /* Check range of value.
1972 */
1973 if( sIn < UI1_MIN || sIn > UI1_MAX )
1974 {
1975 return DISP_E_OVERFLOW;
1976 }
1977
1978 *pbOut = (BYTE) sIn;
1979
1980 return S_OK;
1981}
1982
1983/******************************************************************************
1984 * VarUI1FromI432 [OLEAUT32.131]
1985 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00001986HRESULT WINAPI VarUI1FromI432(LONG lIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00001987{
1988 TRACE( ole, "( %ld, %p ), stub\n", lIn, pbOut );
1989
1990 /* Check range of value.
1991 */
1992 if( lIn < UI1_MIN || lIn > UI1_MAX )
1993 {
1994 return DISP_E_OVERFLOW;
1995 }
1996
1997 *pbOut = (BYTE) lIn;
1998
1999 return S_OK;
2000}
2001
2002
2003/******************************************************************************
2004 * VarUI1FromR432 [OLEAUT32.132]
2005 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002006HRESULT WINAPI VarUI1FromR432(FLOAT fltIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002007{
2008 TRACE( ole, "( %f, %p ), stub\n", fltIn, pbOut );
2009
2010 /* Check range of value.
2011 */
2012 fltIn = round( fltIn );
2013 if( fltIn < UI1_MIN || fltIn > UI1_MAX )
2014 {
2015 return DISP_E_OVERFLOW;
2016 }
2017
2018 *pbOut = (BYTE) fltIn;
2019
2020 return S_OK;
2021}
2022
2023/******************************************************************************
2024 * VarUI1FromR832 [OLEAUT32.133]
2025 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002026HRESULT WINAPI VarUI1FromR832(double dblIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002027{
2028 TRACE( ole, "( %f, %p ), stub\n", dblIn, pbOut );
2029
2030 /* Check range of value.
2031 */
2032 dblIn = round( dblIn );
2033 if( dblIn < UI1_MIN || dblIn > UI1_MAX )
2034 {
2035 return DISP_E_OVERFLOW;
2036 }
2037
2038 *pbOut = (BYTE) dblIn;
2039
2040 return S_OK;
2041}
2042
2043/******************************************************************************
2044 * VarUI1FromDate32 [OLEAUT32.135]
2045 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002046HRESULT WINAPI VarUI1FromDate32(DATE dateIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002047{
2048 TRACE( ole, "( %f, %p ), stub\n", dateIn, pbOut );
2049
2050 /* Check range of value.
2051 */
2052 dateIn = round( dateIn );
2053 if( dateIn < UI1_MIN || dateIn > UI1_MAX )
2054 {
2055 return DISP_E_OVERFLOW;
2056 }
2057
2058 *pbOut = (BYTE) dateIn;
2059
2060 return S_OK;
2061}
2062
2063/******************************************************************************
2064 * VarUI1FromBool32 [OLEAUT32.138]
2065 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002066HRESULT WINAPI VarUI1FromBool32(VARIANT_BOOL boolIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002067{
2068 TRACE( ole, "( %d, %p ), stub\n", boolIn, pbOut );
2069
2070 *pbOut = (BYTE) boolIn;
2071
2072 return S_OK;
2073}
2074
2075/******************************************************************************
2076 * VarUI1FromI132 [OLEAUT32.237]
2077 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002078HRESULT WINAPI VarUI1FromI132(CHAR cIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002079{
2080 TRACE( ole, "( %c, %p ), stub\n", cIn, pbOut );
2081
2082 *pbOut = cIn;
2083
2084 return S_OK;
2085}
2086
2087/******************************************************************************
2088 * VarUI1FromUI232 [OLEAUT32.238]
2089 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002090HRESULT WINAPI VarUI1FromUI232(USHORT uiIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002091{
2092 TRACE( ole, "( %d, %p ), stub\n", uiIn, pbOut );
2093
2094 /* Check range of value.
2095 */
2096 if( uiIn > UI1_MAX )
2097 {
2098 return DISP_E_OVERFLOW;
2099 }
2100
2101 *pbOut = (BYTE) uiIn;
2102
2103 return S_OK;
2104}
2105
2106/******************************************************************************
2107 * VarUI1FromUI432 [OLEAUT32.239]
2108 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002109HRESULT WINAPI VarUI1FromUI432(ULONG ulIn, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002110{
2111 TRACE( ole, "( %ld, %p ), stub\n", ulIn, pbOut );
2112
2113 /* Check range of value.
2114 */
2115 if( ulIn > UI1_MAX )
2116 {
2117 return DISP_E_OVERFLOW;
2118 }
2119
2120 *pbOut = (BYTE) ulIn;
2121
2122 return S_OK;
2123}
2124
2125
2126/******************************************************************************
2127 * VarUI1FromStr32 [OLEAUT32.54]
2128 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002129HRESULT WINAPI VarUI1FromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, BYTE* pbOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002130{
2131 double dValue = 0.0;
2132 LPSTR pNewString = NULL;
2133
2134 TRACE( ole, "( %p, 0x%08lx, 0x%08lx, %p ), stub\n", strIn, lcid, dwFlags, pbOut );
2135
2136 /* Check if we have a valid argument
2137 */
2138 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
2139 RemoveCharacterFromString( pNewString, "," );
2140 if( IsValidRealString( pNewString ) == FALSE )
2141 {
2142 return DISP_E_TYPEMISMATCH;
2143 }
2144
2145 /* Convert the valid string to a floating point number.
2146 */
2147 dValue = atof( pNewString );
2148
2149 /* We don't need the string anymore so free it.
2150 */
2151 HeapFree( GetProcessHeap(), 0 , pNewString );
2152
2153 /* Check range of value.
2154 */
2155 dValue = round( dValue );
2156 if( dValue < UI1_MIN || dValue > UI1_MAX )
2157 {
2158 return DISP_E_OVERFLOW;
2159 }
2160
2161 *pbOut = (BYTE) dValue;
2162
2163 return S_OK;
2164}
2165
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002166/**********************************************************************
2167 * VarUI1FromCy32 [OLEAUT32.134]
2168 * Convert currency to unsigned char
2169 */
2170HRESULT WINAPI VarUI1FromCy32(CY cyIn, BYTE* pbOut) {
Todd Vierling7f573251998-12-15 15:15:16 +00002171 double t = round((((double)cyIn.u.Hi * 4294967296.0) + (double)cyIn.u.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002172
2173 if (t > UI1_MAX || t < UI1_MIN) return DISP_E_OVERFLOW;
2174
2175 *pbOut = (BYTE)t;
2176 return S_OK;
2177}
2178
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002179/******************************************************************************
2180 * VarI2FromUI132 [OLEAUT32.48]
2181 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002182HRESULT WINAPI VarI2FromUI132(BYTE bIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002183{
2184 TRACE( ole, "( 0x%08x, %p ), stub\n", bIn, psOut );
2185
2186 *psOut = (short) bIn;
2187
2188 return S_OK;
2189}
2190
2191/******************************************************************************
2192 * VarI2FromI432 [OLEAUT32.49]
2193 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002194HRESULT WINAPI VarI2FromI432(LONG lIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002195{
2196 TRACE( ole, "( %lx, %p ), stub\n", lIn, psOut );
2197
2198 /* Check range of value.
2199 */
2200 if( lIn < I2_MIN || lIn > I2_MAX )
2201 {
2202 return DISP_E_OVERFLOW;
2203 }
2204
2205 *psOut = (short) lIn;
2206
2207 return S_OK;
2208}
2209
2210/******************************************************************************
2211 * VarI2FromR432 [OLEAUT32.50]
2212 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002213HRESULT WINAPI VarI2FromR432(FLOAT fltIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002214{
2215 TRACE( ole, "( %f, %p ), stub\n", fltIn, psOut );
2216
2217 /* Check range of value.
2218 */
2219 fltIn = round( fltIn );
2220 if( fltIn < I2_MIN || fltIn > I2_MAX )
2221 {
2222 return DISP_E_OVERFLOW;
2223 }
2224
2225 *psOut = (short) fltIn;
2226
2227 return S_OK;
2228}
2229
2230/******************************************************************************
2231 * VarI2FromR832 [OLEAUT32.51]
2232 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002233HRESULT WINAPI VarI2FromR832(double dblIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002234{
2235 TRACE( ole, "( %f, %p ), stub\n", dblIn, psOut );
2236
2237 /* Check range of value.
2238 */
2239 dblIn = round( dblIn );
2240 if( dblIn < I2_MIN || dblIn > I2_MAX )
2241 {
2242 return DISP_E_OVERFLOW;
2243 }
2244
2245 *psOut = (short) dblIn;
2246
2247 return S_OK;
2248}
2249
2250/******************************************************************************
2251 * VarI2FromDate32 [OLEAUT32.53]
2252 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002253HRESULT WINAPI VarI2FromDate32(DATE dateIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002254{
2255 TRACE( ole, "( %f, %p ), stub\n", dateIn, psOut );
2256
2257 /* Check range of value.
2258 */
2259 dateIn = round( dateIn );
2260 if( dateIn < I2_MIN || dateIn > I2_MAX )
2261 {
2262 return DISP_E_OVERFLOW;
2263 }
2264
2265 *psOut = (short) dateIn;
2266
2267 return S_OK;
2268}
2269
2270/******************************************************************************
2271 * VarI2FromBool32 [OLEAUT32.56]
2272 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002273HRESULT WINAPI VarI2FromBool32(VARIANT_BOOL boolIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002274{
2275 TRACE( ole, "( %d, %p ), stub\n", boolIn, psOut );
2276
2277 *psOut = (short) boolIn;
2278
2279 return S_OK;
2280}
2281
2282/******************************************************************************
2283 * VarI2FromI132 [OLEAUT32.48]
2284 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002285HRESULT WINAPI VarI2FromI132(CHAR cIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002286{
2287 TRACE( ole, "( %c, %p ), stub\n", cIn, psOut );
2288
2289 *psOut = (short) cIn;
2290
2291 return S_OK;
2292}
2293
2294/******************************************************************************
2295 * VarI2FromUI232 [OLEAUT32.206]
2296 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002297HRESULT WINAPI VarI2FromUI232(USHORT uiIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002298{
2299 TRACE( ole, "( %d, %p ), stub\n", uiIn, psOut );
2300
2301 /* Check range of value.
2302 */
2303 if( uiIn > I2_MAX )
2304 {
2305 return DISP_E_OVERFLOW;
2306 }
2307
2308 *psOut = (short) uiIn;
2309
2310 return S_OK;
2311}
2312
2313/******************************************************************************
2314 * VarI2FromUI432 [OLEAUT32.49]
2315 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002316HRESULT WINAPI VarI2FromUI432(ULONG ulIn, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002317{
2318 TRACE( ole, "( %lx, %p ), stub\n", ulIn, psOut );
2319
2320 /* Check range of value.
2321 */
2322 if( ulIn < I2_MIN || ulIn > I2_MAX )
2323 {
2324 return DISP_E_OVERFLOW;
2325 }
2326
2327 *psOut = (short) ulIn;
2328
2329 return S_OK;
2330}
2331
2332/******************************************************************************
2333 * VarI2FromStr32 [OLEAUT32.54]
2334 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002335HRESULT WINAPI VarI2FromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, short* psOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002336{
2337 double dValue = 0.0;
2338 LPSTR pNewString = NULL;
2339
2340 TRACE( ole, "( %p, 0x%08lx, 0x%08lx, %p ), stub\n", strIn, lcid, dwFlags, psOut );
2341
2342 /* Check if we have a valid argument
2343 */
2344 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
2345 RemoveCharacterFromString( pNewString, "," );
2346 if( IsValidRealString( pNewString ) == FALSE )
2347 {
2348 return DISP_E_TYPEMISMATCH;
2349 }
2350
2351 /* Convert the valid string to a floating point number.
2352 */
2353 dValue = atof( pNewString );
2354
2355 /* We don't need the string anymore so free it.
2356 */
2357 HeapFree( GetProcessHeap(), 0, pNewString );
2358
2359 /* Check range of value.
2360 */
2361 dValue = round( dValue );
2362 if( dValue < I2_MIN || dValue > I2_MAX )
2363 {
2364 return DISP_E_OVERFLOW;
2365 }
2366
2367 *psOut = (short) dValue;
2368
2369 return S_OK;
2370}
2371
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002372/**********************************************************************
2373 * VarI2FromCy32 [OLEAUT32.52]
2374 * Convert currency to signed short
2375 */
2376HRESULT WINAPI VarI2FromCy32(CY cyIn, short* psOut) {
Todd Vierling7f573251998-12-15 15:15:16 +00002377 double t = round((((double)cyIn.u.Hi * 4294967296.0) + (double)cyIn.u.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002378
2379 if (t > I2_MAX || t < I2_MIN) return DISP_E_OVERFLOW;
2380
2381 *psOut = (SHORT)t;
2382 return S_OK;
2383}
2384
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002385/******************************************************************************
2386 * VarI4FromUI132 [OLEAUT32.58]
2387 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002388HRESULT WINAPI VarI4FromUI132(BYTE bIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002389{
2390 TRACE( ole, "( %X, %p ), stub\n", bIn, plOut );
2391
2392 *plOut = (LONG) bIn;
2393
2394 return S_OK;
2395}
2396
2397
2398/******************************************************************************
2399 * VarI4FromR432 [OLEAUT32.60]
2400 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002401HRESULT WINAPI VarI4FromR432(FLOAT fltIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002402{
2403 TRACE( ole, "( %f, %p ), stub\n", fltIn, plOut );
2404
2405 /* Check range of value.
2406 */
2407 fltIn = round( fltIn );
2408 if( fltIn < I4_MIN || fltIn > I4_MAX )
2409 {
2410 return DISP_E_OVERFLOW;
2411 }
2412
2413 *plOut = (LONG) fltIn;
2414
2415 return S_OK;
2416}
2417
2418/******************************************************************************
2419 * VarI4FromR832 [OLEAUT32.61]
2420 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002421HRESULT WINAPI VarI4FromR832(double dblIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002422{
2423 TRACE( ole, "( %f, %p ), stub\n", dblIn, plOut );
2424
2425 /* Check range of value.
2426 */
2427 dblIn = round( dblIn );
2428 if( dblIn < I4_MIN || dblIn > I4_MAX )
2429 {
2430 return DISP_E_OVERFLOW;
2431 }
2432
2433 *plOut = (LONG) dblIn;
2434
2435 return S_OK;
2436}
2437
2438/******************************************************************************
2439 * VarI4FromDate32 [OLEAUT32.63]
2440 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002441HRESULT WINAPI VarI4FromDate32(DATE dateIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002442{
2443 TRACE( ole, "( %f, %p ), stub\n", dateIn, plOut );
2444
2445 /* Check range of value.
2446 */
2447 dateIn = round( dateIn );
2448 if( dateIn < I4_MIN || dateIn > I4_MAX )
2449 {
2450 return DISP_E_OVERFLOW;
2451 }
2452
2453 *plOut = (LONG) dateIn;
2454
2455 return S_OK;
2456}
2457
2458/******************************************************************************
2459 * VarI4FromBool32 [OLEAUT32.66]
2460 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002461HRESULT WINAPI VarI4FromBool32(VARIANT_BOOL boolIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002462{
2463 TRACE( ole, "( %d, %p ), stub\n", boolIn, plOut );
2464
2465 *plOut = (LONG) boolIn;
2466
2467 return S_OK;
2468}
2469
2470/******************************************************************************
2471 * VarI4FromI132 [OLEAUT32.209]
2472 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002473HRESULT WINAPI VarI4FromI132(CHAR cIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002474{
2475 TRACE( ole, "( %c, %p ), stub\n", cIn, plOut );
2476
2477 *plOut = (LONG) cIn;
2478
2479 return S_OK;
2480}
2481
2482/******************************************************************************
2483 * VarI4FromUI232 [OLEAUT32.210]
2484 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002485HRESULT WINAPI VarI4FromUI232(USHORT uiIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002486{
2487 TRACE( ole, "( %d, %p ), stub\n", uiIn, plOut );
2488
2489 *plOut = (LONG) uiIn;
2490
2491 return S_OK;
2492}
2493
2494/******************************************************************************
2495 * VarI4FromUI432 [OLEAUT32.211]
2496 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002497HRESULT WINAPI VarI4FromUI432(ULONG ulIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002498{
2499 TRACE( ole, "( %lx, %p ), stub\n", ulIn, plOut );
2500
2501 /* Check range of value.
2502 */
2503 if( ulIn < I4_MIN || ulIn > I4_MAX )
2504 {
2505 return DISP_E_OVERFLOW;
2506 }
2507
2508 *plOut = (LONG) ulIn;
2509
2510 return S_OK;
2511}
2512
2513/******************************************************************************
2514 * VarI4FromI232 [OLEAUT32.59]
2515 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002516HRESULT WINAPI VarI4FromI232(short sIn, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002517{
2518 TRACE( ole, "( %d, %p ), stub\n", sIn, plOut );
2519
2520 *plOut = (LONG) sIn;
2521
2522 return S_OK;
2523}
2524
2525/******************************************************************************
2526 * VarI4FromStr32 [OLEAUT32.64]
2527 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002528HRESULT WINAPI VarI4FromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, LONG* plOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002529{
2530 double dValue = 0.0;
2531 LPSTR pNewString = NULL;
2532
2533 TRACE( ole, "( %p, 0x%08lx, 0x%08lx, %p ), stub\n", strIn, lcid, dwFlags, plOut );
2534
2535 /* Check if we have a valid argument
2536 */
2537 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
2538 RemoveCharacterFromString( pNewString, "," );
2539 if( IsValidRealString( pNewString ) == FALSE )
2540 {
2541 return DISP_E_TYPEMISMATCH;
2542 }
2543
2544 /* Convert the valid string to a floating point number.
2545 */
2546 dValue = atof( pNewString );
2547
2548 /* We don't need the string anymore so free it.
2549 */
2550 HeapFree( GetProcessHeap(), 0, pNewString );
2551
2552 /* Check range of value.
2553 */
2554 dValue = round( dValue );
2555 if( dValue < I4_MIN || dValue > I4_MAX )
2556 {
2557 return DISP_E_OVERFLOW;
2558 }
2559
2560 *plOut = (LONG) dValue;
2561
2562 return S_OK;
2563}
2564
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002565/**********************************************************************
2566 * VarI4FromCy32 [OLEAUT32.62]
2567 * Convert currency to signed long
2568 */
2569HRESULT WINAPI VarI4FromCy32(CY cyIn, LONG* plOut) {
Todd Vierling7f573251998-12-15 15:15:16 +00002570 double t = round((((double)cyIn.u.Hi * 4294967296.0) + (double)cyIn.u.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002571
2572 if (t > I4_MAX || t < I4_MIN) return DISP_E_OVERFLOW;
2573
2574 *plOut = (LONG)t;
2575 return S_OK;
2576}
2577
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002578/******************************************************************************
2579 * VarR4FromUI132 [OLEAUT32.68]
2580 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002581HRESULT WINAPI VarR4FromUI132(BYTE bIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002582{
2583 TRACE( ole, "( %X, %p ), stub\n", bIn, pfltOut );
2584
2585 *pfltOut = (FLOAT) bIn;
2586
2587 return S_OK;
2588}
2589
2590/******************************************************************************
2591 * VarR4FromI232 [OLEAUT32.69]
2592 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002593HRESULT WINAPI VarR4FromI232(short sIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002594{
2595 TRACE( ole, "( %d, %p ), stub\n", sIn, pfltOut );
2596
2597 *pfltOut = (FLOAT) sIn;
2598
2599 return S_OK;
2600}
2601
2602/******************************************************************************
2603 * VarR4FromI432 [OLEAUT32.70]
2604 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002605HRESULT WINAPI VarR4FromI432(LONG lIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002606{
2607 TRACE( ole, "( %lx, %p ), stub\n", lIn, pfltOut );
2608
2609 *pfltOut = (FLOAT) lIn;
2610
2611 return S_OK;
2612}
2613
2614/******************************************************************************
2615 * VarR4FromR832 [OLEAUT32.71]
2616 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002617HRESULT WINAPI VarR4FromR832(double dblIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002618{
2619 TRACE( ole, "( %f, %p ), stub\n", dblIn, pfltOut );
2620
2621 /* Check range of value.
2622 */
2623 if( dblIn < -(FLT_MAX) || dblIn > FLT_MAX )
2624 {
2625 return DISP_E_OVERFLOW;
2626 }
2627
2628 *pfltOut = (FLOAT) dblIn;
2629
2630 return S_OK;
2631}
2632
2633/******************************************************************************
2634 * VarR4FromDate32 [OLEAUT32.73]
2635 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002636HRESULT WINAPI VarR4FromDate32(DATE dateIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002637{
2638 TRACE( ole, "( %f, %p ), stub\n", dateIn, pfltOut );
2639
2640 /* Check range of value.
2641 */
2642 if( dateIn < -(FLT_MAX) || dateIn > FLT_MAX )
2643 {
2644 return DISP_E_OVERFLOW;
2645 }
2646
2647 *pfltOut = (FLOAT) dateIn;
2648
2649 return S_OK;
2650}
2651
2652/******************************************************************************
2653 * VarR4FromBool32 [OLEAUT32.76]
2654 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002655HRESULT WINAPI VarR4FromBool32(VARIANT_BOOL boolIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002656{
2657 TRACE( ole, "( %d, %p ), stub\n", boolIn, pfltOut );
2658
2659 *pfltOut = (FLOAT) boolIn;
2660
2661 return S_OK;
2662}
2663
2664/******************************************************************************
2665 * VarR4FromI132 [OLEAUT32.213]
2666 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002667HRESULT WINAPI VarR4FromI132(CHAR cIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002668{
2669 TRACE( ole, "( %c, %p ), stub\n", cIn, pfltOut );
2670
2671 *pfltOut = (FLOAT) cIn;
2672
2673 return S_OK;
2674}
2675
2676/******************************************************************************
2677 * VarR4FromUI232 [OLEAUT32.214]
2678 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002679HRESULT WINAPI VarR4FromUI232(USHORT uiIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002680{
2681 TRACE( ole, "( %d, %p ), stub\n", uiIn, pfltOut );
2682
2683 *pfltOut = (FLOAT) uiIn;
2684
2685 return S_OK;
2686}
2687
2688/******************************************************************************
2689 * VarR4FromUI432 [OLEAUT32.215]
2690 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002691HRESULT WINAPI VarR4FromUI432(ULONG ulIn, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002692{
2693 TRACE( ole, "( %ld, %p ), stub\n", ulIn, pfltOut );
2694
2695 *pfltOut = (FLOAT) ulIn;
2696
2697 return S_OK;
2698}
2699
2700/******************************************************************************
2701 * VarR4FromStr32 [OLEAUT32.74]
2702 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002703HRESULT WINAPI VarR4FromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, FLOAT* pfltOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002704{
2705 double dValue = 0.0;
2706 LPSTR pNewString = NULL;
2707
2708 TRACE( ole, "( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, pfltOut );
2709
2710 /* Check if we have a valid argument
2711 */
2712 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
2713 RemoveCharacterFromString( pNewString, "," );
2714 if( IsValidRealString( pNewString ) == FALSE )
2715 {
2716 return DISP_E_TYPEMISMATCH;
2717 }
2718
2719 /* Convert the valid string to a floating point number.
2720 */
2721 dValue = atof( pNewString );
2722
2723 /* We don't need the string anymore so free it.
2724 */
2725 HeapFree( GetProcessHeap(), 0, pNewString );
2726
2727 /* Check range of value.
2728 */
2729 if( dValue < -(FLT_MAX) || dValue > FLT_MAX )
2730 {
2731 return DISP_E_OVERFLOW;
2732 }
2733
2734 *pfltOut = (FLOAT) dValue;
2735
2736 return S_OK;
2737}
2738
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002739/**********************************************************************
2740 * VarR4FromCy32 [OLEAUT32.72]
2741 * Convert currency to float
2742 */
2743HRESULT WINAPI VarR4FromCy32(CY cyIn, FLOAT* pfltOut) {
Todd Vierling7f573251998-12-15 15:15:16 +00002744 *pfltOut = (FLOAT)((((double)cyIn.u.Hi * 4294967296.0) + (double)cyIn.u.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002745
2746 return S_OK;
2747}
2748
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002749/******************************************************************************
2750 * VarR8FromUI132 [OLEAUT32.68]
2751 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002752HRESULT WINAPI VarR8FromUI132(BYTE bIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002753{
2754 TRACE( ole, "( %d, %p ), stub\n", bIn, pdblOut );
2755
2756 *pdblOut = (double) bIn;
2757
2758 return S_OK;
2759}
2760
2761/******************************************************************************
2762 * VarR8FromI232 [OLEAUT32.69]
2763 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002764HRESULT WINAPI VarR8FromI232(short sIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002765{
2766 TRACE( ole, "( %d, %p ), stub\n", sIn, pdblOut );
2767
2768 *pdblOut = (double) sIn;
2769
2770 return S_OK;
2771}
2772
2773/******************************************************************************
2774 * VarR8FromI432 [OLEAUT32.70]
2775 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002776HRESULT WINAPI VarR8FromI432(LONG lIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002777{
2778 TRACE( ole, "( %ld, %p ), stub\n", lIn, pdblOut );
2779
2780 *pdblOut = (double) lIn;
2781
2782 return S_OK;
2783}
2784
2785/******************************************************************************
2786 * VarR8FromR432 [OLEAUT32.81]
2787 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002788HRESULT WINAPI VarR8FromR432(FLOAT fltIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002789{
2790 TRACE( ole, "( %f, %p ), stub\n", fltIn, pdblOut );
2791
2792 *pdblOut = (double) fltIn;
2793
2794 return S_OK;
2795}
2796
2797/******************************************************************************
2798 * VarR8FromDate32 [OLEAUT32.83]
2799 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002800HRESULT WINAPI VarR8FromDate32(DATE dateIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002801{
2802 TRACE( ole, "( %f, %p ), stub\n", dateIn, pdblOut );
2803
2804 *pdblOut = (double) dateIn;
2805
2806 return S_OK;
2807}
2808
2809/******************************************************************************
2810 * VarR8FromBool32 [OLEAUT32.86]
2811 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002812HRESULT WINAPI VarR8FromBool32(VARIANT_BOOL boolIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002813{
2814 TRACE( ole, "( %d, %p ), stub\n", boolIn, pdblOut );
2815
2816 *pdblOut = (double) boolIn;
2817
2818 return S_OK;
2819}
2820
2821/******************************************************************************
2822 * VarR8FromI132 [OLEAUT32.217]
2823 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002824HRESULT WINAPI VarR8FromI132(CHAR cIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002825{
2826 TRACE( ole, "( %c, %p ), stub\n", cIn, pdblOut );
2827
2828 *pdblOut = (double) cIn;
2829
2830 return S_OK;
2831}
2832
2833/******************************************************************************
2834 * VarR8FromUI232 [OLEAUT32.218]
2835 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002836HRESULT WINAPI VarR8FromUI232(USHORT uiIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002837{
2838 TRACE( ole, "( %d, %p ), stub\n", uiIn, pdblOut );
2839
2840 *pdblOut = (double) uiIn;
2841
2842 return S_OK;
2843}
2844
2845/******************************************************************************
2846 * VarR8FromUI432 [OLEAUT32.219]
2847 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002848HRESULT WINAPI VarR8FromUI432(ULONG ulIn, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002849{
2850 TRACE( ole, "( %ld, %p ), stub\n", ulIn, pdblOut );
2851
2852 *pdblOut = (double) ulIn;
2853
2854 return S_OK;
2855}
2856
2857/******************************************************************************
2858 * VarR8FromStr32 [OLEAUT32.84]
2859 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002860HRESULT WINAPI VarR8FromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, double* pdblOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002861{
2862 double dValue = 0.0;
2863 LPSTR pNewString = NULL;
2864
2865 TRACE( ole, "( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, pdblOut );
2866
2867 /* Check if we have a valid argument
2868 */
2869 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
2870 RemoveCharacterFromString( pNewString, "," );
2871 if( IsValidRealString( pNewString ) == FALSE )
2872 {
2873 return DISP_E_TYPEMISMATCH;
2874 }
2875
2876 /* Convert the valid string to a floating point number.
2877 */
2878 dValue = atof( pNewString );
2879
2880 /* We don't need the string anymore so free it.
2881 */
2882 HeapFree( GetProcessHeap(), 0, pNewString );
2883
2884 *pdblOut = dValue;
2885
2886 return S_OK;
2887}
2888
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002889/**********************************************************************
2890 * VarR8FromCy32 [OLEAUT32.82]
2891 * Convert currency to double
2892 */
2893HRESULT WINAPI VarR8FromCy32(CY cyIn, double* pdblOut) {
Todd Vierling7f573251998-12-15 15:15:16 +00002894 *pdblOut = (double)((((double)cyIn.u.Hi * 4294967296.0) + (double)cyIn.u.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00002895
2896 return S_OK;
2897}
2898
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002899/******************************************************************************
2900 * VarDateFromUI132 [OLEAUT32.]
2901 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002902HRESULT WINAPI VarDateFromUI132(BYTE bIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002903{
2904 TRACE( ole, "( %d, %p ), stub\n", bIn, pdateOut );
2905
2906 *pdateOut = (DATE) bIn;
2907
2908 return S_OK;
2909}
2910
2911/******************************************************************************
2912 * VarDateFromI232 [OLEAUT32.222]
2913 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002914HRESULT WINAPI VarDateFromI232(short sIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002915{
2916 TRACE( ole, "( %d, %p ), stub\n", sIn, pdateOut );
2917
2918 *pdateOut = (DATE) sIn;
2919
2920 return S_OK;
2921}
2922
2923/******************************************************************************
2924 * VarDateFromI432 [OLEAUT32.90]
2925 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002926HRESULT WINAPI VarDateFromI432(LONG lIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002927{
2928 TRACE( ole, "( %ld, %p ), stub\n", lIn, pdateOut );
2929
2930 if( lIn < DATE_MIN || lIn > DATE_MAX )
2931 {
2932 return DISP_E_OVERFLOW;
2933 }
2934
2935 *pdateOut = (DATE) lIn;
2936
2937 return S_OK;
2938}
2939
2940/******************************************************************************
2941 * VarDateFromR432 [OLEAUT32.91]
2942 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002943HRESULT WINAPI VarDateFromR432(FLOAT fltIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002944{
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002945 TRACE( ole, "( %f, %p ), stub\n", fltIn, pdateOut );
2946
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +00002947 if( ceil(fltIn) < DATE_MIN || floor(fltIn) > DATE_MAX )
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002948 {
2949 return DISP_E_OVERFLOW;
2950 }
2951
2952 *pdateOut = (DATE) fltIn;
2953
2954 return S_OK;
2955}
2956
2957/******************************************************************************
2958 * VarDateFromR832 [OLEAUT32.92]
2959 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002960HRESULT WINAPI VarDateFromR832(double dblIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002961{
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002962 TRACE( ole, "( %f, %p ), stub\n", dblIn, pdateOut );
2963
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +00002964 if( ceil(dblIn) < DATE_MIN || floor(dblIn) > DATE_MAX )
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00002965 {
2966 return DISP_E_OVERFLOW;
2967 }
2968
2969 *pdateOut = (DATE) dblIn;
2970
2971 return S_OK;
2972}
2973
2974/******************************************************************************
2975 * VarDateFromStr32 [OLEAUT32.94]
2976 * The string representing the date is composed of two parts, a date and time.
2977 *
2978 * The format of the time is has follows:
2979 * hh[:mm][:ss][AM|PM]
2980 * Whitespace can be inserted anywhere between these tokens. A whitespace consists
2981 * of space and/or tab characters, which are ignored.
2982 *
2983 * The formats for the date part are has follows:
2984 * mm/[dd/][yy]yy
2985 * [dd/]mm/[yy]yy
2986 * [yy]yy/mm/dd
2987 * January dd[,] [yy]yy
2988 * dd January [yy]yy
2989 * [yy]yy January dd
2990 * Whitespace can be inserted anywhere between these tokens.
2991 *
2992 * The formats for the date and time string are has follows.
2993 * date[whitespace][time]
2994 * [time][whitespace]date
2995 *
2996 * These are the only characters allowed in a string representing a date and time:
2997 * [A-Z] [a-z] [0-9] ':' '-' '/' ',' ' ' '\t'
2998 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00002999HRESULT WINAPI VarDateFromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003000{
3001 HRESULT ret = S_OK;
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +00003002 struct tm TM = { 0,0,0,0,0,0,0,0,0 };
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003003
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +00003004 TRACE( ole, "( %p, %lx, %lx, %p ), stub\n", strIn, lcid, dwFlags, pdateOut );
3005
3006 if( DateTimeStringToTm( strIn, lcid, &TM ) )
3007 {
3008 if( TmToDATE( &TM, pdateOut ) == FALSE )
3009 {
3010 ret = E_INVALIDARG;
3011 }
3012 }
3013 else
3014 {
3015 ret = DISP_E_TYPEMISMATCH;
3016 }
3017
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003018
3019 return ret;
3020}
3021
3022/******************************************************************************
3023 * VarDateFromI132 [OLEAUT32.221]
3024 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003025HRESULT WINAPI VarDateFromI132(CHAR cIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003026{
3027 TRACE( ole, "( %c, %p ), stub\n", cIn, pdateOut );
3028
3029 *pdateOut = (DATE) cIn;
3030
3031 return S_OK;
3032}
3033
3034/******************************************************************************
3035 * VarDateFromUI232 [OLEAUT32.222]
3036 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003037HRESULT WINAPI VarDateFromUI232(USHORT uiIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003038{
3039 TRACE( ole, "( %d, %p ), stub\n", uiIn, pdateOut );
3040
3041 if( uiIn > DATE_MAX )
3042 {
3043 return DISP_E_OVERFLOW;
3044 }
3045
3046 *pdateOut = (DATE) uiIn;
3047
3048 return S_OK;
3049}
3050
3051/******************************************************************************
3052 * VarDateFromUI432 [OLEAUT32.223]
3053 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003054HRESULT WINAPI VarDateFromUI432(ULONG ulIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003055{
3056 TRACE( ole, "( %ld, %p ), stub\n", ulIn, pdateOut );
3057
3058 if( ulIn < DATE_MIN || ulIn > DATE_MAX )
3059 {
3060 return DISP_E_OVERFLOW;
3061 }
3062
3063 *pdateOut = (DATE) ulIn;
3064
3065 return S_OK;
3066}
3067
3068/******************************************************************************
3069 * VarDateFromBool32 [OLEAUT32.96]
3070 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003071HRESULT WINAPI VarDateFromBool32(VARIANT_BOOL boolIn, DATE* pdateOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003072{
3073 TRACE( ole, "( %d, %p ), stub\n", boolIn, pdateOut );
3074
3075 *pdateOut = (DATE) boolIn;
3076
3077 return S_OK;
3078}
3079
Justin Bradfordbc93bc81998-12-11 14:02:16 +00003080/**********************************************************************
3081 * VarDateFromCy32 [OLEAUT32.93]
3082 * Convert currency to date
3083 */
3084HRESULT WINAPI VarDateFromCy32(CY cyIn, DATE* pdateOut) {
Todd Vierling7f573251998-12-15 15:15:16 +00003085 *pdateOut = (DATE)((((double)cyIn.u.Hi * 4294967296.0) + (double)cyIn.u.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00003086
3087 if (*pdateOut > DATE_MAX || *pdateOut < DATE_MIN) return DISP_E_TYPEMISMATCH;
3088 return S_OK;
3089}
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003090
3091/******************************************************************************
3092 * VarBstrFromUI132 [OLEAUT32.108]
3093 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003094HRESULT WINAPI VarBstrFromUI132(BYTE bVal, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003095{
3096 TRACE( ole, "( %d, %ld, %ld, %p ), stub\n", bVal, lcid, dwFlags, pbstrOut );
3097 sprintf( pBuffer, "%d", bVal );
3098
3099 *pbstrOut = StringDupAtoBstr( pBuffer );
3100
3101 return S_OK;
3102}
3103
3104/******************************************************************************
3105 * VarBstrFromI232 [OLEAUT32.109]
3106 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003107HRESULT WINAPI VarBstrFromI232(short iVal, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003108{
3109 TRACE( ole, "( %d, %ld, %ld, %p ), stub\n", iVal, lcid, dwFlags, pbstrOut );
3110 sprintf( pBuffer, "%d", iVal );
3111 *pbstrOut = StringDupAtoBstr( pBuffer );
3112
3113 return S_OK;
3114}
3115
3116/******************************************************************************
3117 * VarBstrFromI432 [OLEAUT32.110]
3118 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003119HRESULT WINAPI VarBstrFromI432(LONG lIn, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003120{
3121 TRACE( ole, "( %ld, %ld, %ld, %p ), stub\n", lIn, lcid, dwFlags, pbstrOut );
3122
3123 sprintf( pBuffer, "%ld", lIn );
3124 *pbstrOut = StringDupAtoBstr( pBuffer );
3125
3126 return S_OK;
3127}
3128
3129/******************************************************************************
3130 * VarBstrFromR432 [OLEAUT32.111]
3131 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003132HRESULT WINAPI VarBstrFromR432(FLOAT fltIn, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003133{
3134 TRACE( ole, "( %f, %ld, %ld, %p ), stub\n", fltIn, lcid, dwFlags, pbstrOut );
3135
3136 sprintf( pBuffer, "%.7g", fltIn );
3137 *pbstrOut = StringDupAtoBstr( pBuffer );
3138
3139 return S_OK;
3140}
3141
3142/******************************************************************************
3143 * VarBstrFromR832 [OLEAUT32.112]
3144 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003145HRESULT WINAPI VarBstrFromR832(double dblIn, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003146{
3147 TRACE( ole, "( %f, %ld, %ld, %p ), stub\n", dblIn, lcid, dwFlags, pbstrOut );
3148
3149 sprintf( pBuffer, "%.15g", dblIn );
3150 *pbstrOut = StringDupAtoBstr( pBuffer );
3151
3152 return S_OK;
3153}
3154
3155/******************************************************************************
3156 * VarBstrFromDate32 [OLEAUT32.114]
3157 *
3158 * The date is implemented using an 8 byte floating-point number.
3159 * Days are represented by whole numbers increments starting with 0.00 has
3160 * being December 30 1899, midnight.
3161 * The hours are expressed as the fractional part of the number.
3162 * December 30 1899 at midnight = 0.00
3163 * January 1 1900 at midnight = 2.00
3164 * January 4 1900 at 6 AM = 5.25
3165 * January 4 1900 at noon = 5.50
3166 * December 29 1899 at midnight = -1.00
3167 * December 18 1899 at midnight = -12.00
3168 * December 18 1899 at 6AM = -12.25
3169 * December 18 1899 at 6PM = -12.75
3170 * December 19 1899 at midnight = -11.00
3171 * The tm structure is as follows:
3172 * struct tm {
3173 * int tm_sec; seconds after the minute - [0,59]
3174 * int tm_min; minutes after the hour - [0,59]
3175 * int tm_hour; hours since midnight - [0,23]
3176 * int tm_mday; day of the month - [1,31]
3177 * int tm_mon; months since January - [0,11]
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +00003178 * int tm_year; years
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003179 * int tm_wday; days since Sunday - [0,6]
3180 * int tm_yday; days since January 1 - [0,365]
3181 * int tm_isdst; daylight savings time flag
3182 * };
3183 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003184HRESULT WINAPI VarBstrFromDate32(DATE dateIn, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003185{
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003186 struct tm TM = {0,0,0,0,0,0,0,0,0};
3187
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +00003188 TRACE( ole, "( %f, %ld, %ld, %p ), stub\n", dateIn, lcid, dwFlags, pbstrOut );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003189
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +00003190 if( DateToTm( dateIn, lcid, &TM ) == FALSE )
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003191 {
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +00003192 return E_INVALIDARG;
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003193 }
3194
3195 if( lcid & VAR_DATEVALUEONLY )
3196 strftime( pBuffer, BUFFER_MAX, "%x", &TM );
3197 else if( lcid & VAR_TIMEVALUEONLY )
3198 strftime( pBuffer, BUFFER_MAX, "%X", &TM );
3199 else
Jean-Claude Cote9c7c8a41998-12-24 16:59:17 +00003200 strftime( pBuffer, BUFFER_MAX, "%x %X", &TM );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003201
3202 *pbstrOut = StringDupAtoBstr( pBuffer );
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003203
3204 return S_OK;
3205}
3206
3207/******************************************************************************
3208 * VarBstrFromBool32 [OLEAUT32.116]
3209 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003210HRESULT WINAPI VarBstrFromBool32(VARIANT_BOOL boolIn, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003211{
3212 TRACE( ole, "( %d, %ld, %ld, %p ), stub\n", boolIn, lcid, dwFlags, pbstrOut );
3213
3214 if( boolIn == VARIANT_FALSE )
3215 {
3216 sprintf( pBuffer, "False" );
3217 }
3218 else
3219 {
3220 sprintf( pBuffer, "True" );
3221 }
3222
3223 *pbstrOut = StringDupAtoBstr( pBuffer );
3224
3225 return S_OK;
3226}
3227
3228/******************************************************************************
3229 * VarBstrFromI132 [OLEAUT32.229]
3230 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003231HRESULT WINAPI VarBstrFromI132(CHAR cIn, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003232{
3233 TRACE( ole, "( %c, %ld, %ld, %p ), stub\n", cIn, lcid, dwFlags, pbstrOut );
3234 sprintf( pBuffer, "%d", cIn );
3235 *pbstrOut = StringDupAtoBstr( pBuffer );
3236
3237 return S_OK;
3238}
3239
3240/******************************************************************************
3241 * VarBstrFromUI232 [OLEAUT32.230]
3242 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003243HRESULT WINAPI VarBstrFromUI232(USHORT uiIn, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003244{
3245 TRACE( ole, "( %d, %ld, %ld, %p ), stub\n", uiIn, lcid, dwFlags, pbstrOut );
3246 sprintf( pBuffer, "%d", uiIn );
3247 *pbstrOut = StringDupAtoBstr( pBuffer );
3248
3249 return S_OK;
3250}
3251
3252/******************************************************************************
3253 * VarBstrFromUI432 [OLEAUT32.231]
3254 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003255HRESULT WINAPI VarBstrFromUI432(ULONG ulIn, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003256{
3257 TRACE( ole, "( %ld, %ld, %ld, %p ), stub\n", ulIn, lcid, dwFlags, pbstrOut );
3258 sprintf( pBuffer, "%ld", ulIn );
3259 *pbstrOut = StringDupAtoBstr( pBuffer );
3260
3261 return S_OK;
3262}
3263
3264/******************************************************************************
3265 * VarBoolFromUI132 [OLEAUT32.118]
3266 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003267HRESULT WINAPI VarBoolFromUI132(BYTE bIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003268{
3269 TRACE( ole, "( %d, %p ), stub\n", bIn, pboolOut );
3270
3271 if( bIn == 0 )
3272 {
3273 *pboolOut = VARIANT_FALSE;
3274 }
3275 else
3276 {
3277 *pboolOut = VARIANT_TRUE;
3278 }
3279
3280 return S_OK;
3281}
3282
3283/******************************************************************************
3284 * VarBoolFromI232 [OLEAUT32.119]
3285 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003286HRESULT WINAPI VarBoolFromI232(short sIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003287{
3288 TRACE( ole, "( %d, %p ), stub\n", sIn, pboolOut );
3289
3290 if( sIn == 0 )
3291 {
3292 *pboolOut = VARIANT_FALSE;
3293 }
3294 else
3295 {
3296 *pboolOut = VARIANT_TRUE;
3297 }
3298
3299 return S_OK;
3300}
3301
3302/******************************************************************************
3303 * VarBoolFromI432 [OLEAUT32.120]
3304 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003305HRESULT WINAPI VarBoolFromI432(LONG lIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003306{
3307 TRACE( ole, "( %ld, %p ), stub\n", lIn, pboolOut );
3308
3309 if( lIn == 0 )
3310 {
3311 *pboolOut = VARIANT_FALSE;
3312 }
3313 else
3314 {
3315 *pboolOut = VARIANT_TRUE;
3316 }
3317
3318 return S_OK;
3319}
3320
3321/******************************************************************************
3322 * VarBoolFromR432 [OLEAUT32.121]
3323 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003324HRESULT WINAPI VarBoolFromR432(FLOAT fltIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003325{
3326 TRACE( ole, "( %f, %p ), stub\n", fltIn, pboolOut );
3327
3328 if( fltIn == 0.0 )
3329 {
3330 *pboolOut = VARIANT_FALSE;
3331 }
3332 else
3333 {
3334 *pboolOut = VARIANT_TRUE;
3335 }
3336
3337 return S_OK;
3338}
3339
3340/******************************************************************************
3341 * VarBoolFromR832 [OLEAUT32.122]
3342 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003343HRESULT WINAPI VarBoolFromR832(double dblIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003344{
3345 TRACE( ole, "( %f, %p ), stub\n", dblIn, pboolOut );
3346
3347 if( dblIn == 0.0 )
3348 {
3349 *pboolOut = VARIANT_FALSE;
3350 }
3351 else
3352 {
3353 *pboolOut = VARIANT_TRUE;
3354 }
3355
3356 return S_OK;
3357}
3358
3359/******************************************************************************
3360 * VarBoolFromDate32 [OLEAUT32.123]
3361 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003362HRESULT WINAPI VarBoolFromDate32(DATE dateIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003363{
3364 TRACE( ole, "( %f, %p ), stub\n", dateIn, pboolOut );
3365
3366 if( dateIn == 0.0 )
3367 {
3368 *pboolOut = VARIANT_FALSE;
3369 }
3370 else
3371 {
3372 *pboolOut = VARIANT_TRUE;
3373 }
3374
3375 return S_OK;
3376}
3377
3378/******************************************************************************
3379 * VarBoolFromStr32 [OLEAUT32.125]
3380 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003381HRESULT WINAPI VarBoolFromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003382{
3383 HRESULT ret = S_OK;
3384 char* pNewString = NULL;
3385
3386 TRACE( ole, "( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, pboolOut );
3387
3388 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
3389
3390 if( pNewString == NULL || strlen( pNewString ) == 0 )
3391 {
3392 ret = DISP_E_TYPEMISMATCH;
3393 }
3394
3395 if( ret == S_OK )
3396 {
3397 if( strncasecmp( pNewString, "True", strlen( pNewString ) ) == 0 )
3398 {
3399 *pboolOut = VARIANT_TRUE;
3400 }
3401 else if( strncasecmp( pNewString, "False", strlen( pNewString ) ) == 0 )
3402 {
3403 *pboolOut = VARIANT_FALSE;
3404 }
3405 else
3406 {
3407 /* Try converting the string to a floating point number.
3408 */
3409 double dValue = 0.0;
3410 HRESULT res = VarR8FromStr32( strIn, lcid, dwFlags, &dValue );
3411 if( res != S_OK )
3412 {
3413 ret = DISP_E_TYPEMISMATCH;
3414 }
3415 else if( dValue == 0.0 )
3416 {
3417 *pboolOut = VARIANT_FALSE;
3418 }
3419 else
3420 {
3421 *pboolOut = VARIANT_TRUE;
3422 }
3423 }
3424 }
3425
3426 HeapFree( GetProcessHeap(), 0, pNewString );
3427
3428 return ret;
3429}
3430
3431/******************************************************************************
3432 * VarBoolFromI132 [OLEAUT32.233]
3433 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003434HRESULT WINAPI VarBoolFromI132(CHAR cIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003435{
3436 TRACE( ole, "( %c, %p ), stub\n", cIn, pboolOut );
3437
3438 if( cIn == 0 )
3439 {
3440 *pboolOut = VARIANT_FALSE;
3441 }
3442 else
3443 {
3444 *pboolOut = VARIANT_TRUE;
3445 }
3446
3447 return S_OK;
3448}
3449
3450/******************************************************************************
3451 * VarBoolFromUI232 [OLEAUT32.234]
3452 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003453HRESULT WINAPI VarBoolFromUI232(USHORT uiIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003454{
3455 TRACE( ole, "( %d, %p ), stub\n", uiIn, pboolOut );
3456
3457 if( uiIn == 0 )
3458 {
3459 *pboolOut = VARIANT_FALSE;
3460 }
3461 else
3462 {
3463 *pboolOut = VARIANT_TRUE;
3464 }
3465
3466 return S_OK;
3467}
3468
3469/******************************************************************************
3470 * VarBoolFromUI432 [OLEAUT32.235]
3471 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003472HRESULT WINAPI VarBoolFromUI432(ULONG ulIn, VARIANT_BOOL* pboolOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003473{
3474 TRACE( ole, "( %ld, %p ), stub\n", ulIn, pboolOut );
3475
3476 if( ulIn == 0 )
3477 {
3478 *pboolOut = VARIANT_FALSE;
3479 }
3480 else
3481 {
3482 *pboolOut = VARIANT_TRUE;
3483 }
3484
3485 return S_OK;
3486}
3487
Justin Bradfordbc93bc81998-12-11 14:02:16 +00003488/**********************************************************************
3489 * VarBoolFromCy32 [OLEAUT32.124]
3490 * Convert currency to boolean
3491 */
3492HRESULT WINAPI VarBoolFromCy32(CY cyIn, VARIANT_BOOL* pboolOut) {
3493 if (cyIn.u.Hi || cyIn.u.Lo) *pboolOut = -1;
3494 else *pboolOut = 0;
3495
3496 return S_OK;
3497}
3498
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003499/******************************************************************************
3500 * VarI1FromUI132 [OLEAUT32.244]
3501 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003502HRESULT WINAPI VarI1FromUI132(BYTE bIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003503{
3504 TRACE( ole, "( %d, %p ), stub\n", bIn, pcOut );
3505
3506 /* Check range of value.
3507 */
3508 if( bIn > CHAR_MAX )
3509 {
3510 return DISP_E_OVERFLOW;
3511 }
3512
3513 *pcOut = (CHAR) bIn;
3514
3515 return S_OK;
3516}
3517
3518/******************************************************************************
3519 * VarI1FromI232 [OLEAUT32.245]
3520 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003521HRESULT WINAPI VarI1FromI232(short uiIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003522{
3523 TRACE( ole, "( %d, %p ), stub\n", uiIn, pcOut );
3524
3525 if( uiIn > CHAR_MAX )
3526 {
3527 return DISP_E_OVERFLOW;
3528 }
3529
3530 *pcOut = (CHAR) uiIn;
3531
3532 return S_OK;
3533}
3534
3535/******************************************************************************
3536 * VarI1FromI432 [OLEAUT32.246]
3537 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003538HRESULT WINAPI VarI1FromI432(LONG lIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003539{
3540 TRACE( ole, "( %ld, %p ), stub\n", lIn, pcOut );
3541
3542 if( lIn < CHAR_MIN || lIn > CHAR_MAX )
3543 {
3544 return DISP_E_OVERFLOW;
3545 }
3546
3547 *pcOut = (CHAR) lIn;
3548
3549 return S_OK;
3550}
3551
3552/******************************************************************************
3553 * VarI1FromR432 [OLEAUT32.247]
3554 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003555HRESULT WINAPI VarI1FromR432(FLOAT fltIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003556{
3557 TRACE( ole, "( %f, %p ), stub\n", fltIn, pcOut );
3558
3559 fltIn = round( fltIn );
3560 if( fltIn < CHAR_MIN || fltIn > CHAR_MAX )
3561 {
3562 return DISP_E_OVERFLOW;
3563 }
3564
3565 *pcOut = (CHAR) fltIn;
3566
3567 return S_OK;
3568}
3569
3570/******************************************************************************
3571 * VarI1FromR832 [OLEAUT32.248]
3572 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003573HRESULT WINAPI VarI1FromR832(double dblIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003574{
3575 TRACE( ole, "( %f, %p ), stub\n", dblIn, pcOut );
3576
3577 dblIn = round( dblIn );
3578 if( dblIn < CHAR_MIN || dblIn > CHAR_MAX )
3579 {
3580 return DISP_E_OVERFLOW;
3581 }
3582
3583 *pcOut = (CHAR) dblIn;
3584
3585 return S_OK;
3586}
3587
3588/******************************************************************************
3589 * VarI1FromDate32 [OLEAUT32.249]
3590 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003591HRESULT WINAPI VarI1FromDate32(DATE dateIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003592{
3593 TRACE( ole, "( %f, %p ), stub\n", dateIn, pcOut );
3594
3595 dateIn = round( dateIn );
3596 if( dateIn < CHAR_MIN || dateIn > CHAR_MAX )
3597 {
3598 return DISP_E_OVERFLOW;
3599 }
3600
3601 *pcOut = (CHAR) dateIn;
3602
3603 return S_OK;
3604}
3605
3606/******************************************************************************
3607 * VarI1FromStr32 [OLEAUT32.251]
3608 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003609HRESULT WINAPI VarI1FromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003610{
3611 double dValue = 0.0;
3612 LPSTR pNewString = NULL;
3613
3614 TRACE( ole, "( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, pcOut );
3615
3616 /* Check if we have a valid argument
3617 */
3618 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
3619 RemoveCharacterFromString( pNewString, "," );
3620 if( IsValidRealString( pNewString ) == FALSE )
3621 {
3622 return DISP_E_TYPEMISMATCH;
3623 }
3624
3625 /* Convert the valid string to a floating point number.
3626 */
3627 dValue = atof( pNewString );
3628
3629 /* We don't need the string anymore so free it.
3630 */
3631 HeapFree( GetProcessHeap(), 0, pNewString );
3632
3633 /* Check range of value.
3634 */
3635 dValue = round( dValue );
3636 if( dValue < CHAR_MIN || dValue > CHAR_MAX )
3637 {
3638 return DISP_E_OVERFLOW;
3639 }
3640
3641 *pcOut = (CHAR) dValue;
3642
3643 return S_OK;
3644}
3645
3646/******************************************************************************
3647 * VarI1FromBool32 [OLEAUT32.253]
3648 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003649HRESULT WINAPI VarI1FromBool32(VARIANT_BOOL boolIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003650{
3651 TRACE( ole, "( %d, %p ), stub\n", boolIn, pcOut );
3652
3653 *pcOut = (CHAR) boolIn;
3654
3655 return S_OK;
3656}
3657
3658/******************************************************************************
3659 * VarI1FromUI232 [OLEAUT32.254]
3660 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003661HRESULT WINAPI VarI1FromUI232(USHORT uiIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003662{
3663 TRACE( ole, "( %d, %p ), stub\n", uiIn, pcOut );
3664
3665 if( uiIn > CHAR_MAX )
3666 {
3667 return DISP_E_OVERFLOW;
3668 }
3669
3670 *pcOut = (CHAR) uiIn;
3671
3672 return S_OK;
3673}
3674
3675/******************************************************************************
3676 * VarI1FromUI432 [OLEAUT32.255]
3677 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003678HRESULT WINAPI VarI1FromUI432(ULONG ulIn, CHAR* pcOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003679{
3680 TRACE( ole, "( %ld, %p ), stub\n", ulIn, pcOut );
3681
3682 if( ulIn > CHAR_MAX )
3683 {
3684 return DISP_E_OVERFLOW;
3685 }
3686
3687 *pcOut = (CHAR) ulIn;
3688
3689 return S_OK;
3690}
3691
Justin Bradfordbc93bc81998-12-11 14:02:16 +00003692/**********************************************************************
3693 * VarI1FromCy32 [OLEAUT32.250]
3694 * Convert currency to signed char
3695 */
3696HRESULT WINAPI VarI1FromCy32(CY cyIn, CHAR* pcOut) {
Todd Vierling7f573251998-12-15 15:15:16 +00003697 double t = round((((double)cyIn.u.Hi * 4294967296.0) + (double)cyIn.u.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00003698
3699 if (t > CHAR_MAX || t < CHAR_MIN) return DISP_E_OVERFLOW;
3700
3701 *pcOut = (CHAR)t;
3702 return S_OK;
3703}
3704
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003705/******************************************************************************
3706 * VarUI2FromUI132 [OLEAUT32.257]
3707 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003708HRESULT WINAPI VarUI2FromUI132(BYTE bIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003709{
3710 TRACE( ole, "( %d, %p ), stub\n", bIn, puiOut );
3711
3712 *puiOut = (USHORT) bIn;
3713
3714 return S_OK;
3715}
3716
3717/******************************************************************************
3718 * VarUI2FromI232 [OLEAUT32.258]
3719 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003720HRESULT WINAPI VarUI2FromI232(short uiIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003721{
3722 TRACE( ole, "( %d, %p ), stub\n", uiIn, puiOut );
3723
3724 if( uiIn < UI2_MIN )
3725 {
3726 return DISP_E_OVERFLOW;
3727 }
3728
3729 *puiOut = (USHORT) uiIn;
3730
3731 return S_OK;
3732}
3733
3734/******************************************************************************
3735 * VarUI2FromI432 [OLEAUT32.259]
3736 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003737HRESULT WINAPI VarUI2FromI432(LONG lIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003738{
3739 TRACE( ole, "( %ld, %p ), stub\n", lIn, puiOut );
3740
3741 if( lIn < UI2_MIN || lIn > UI2_MAX )
3742 {
3743 return DISP_E_OVERFLOW;
3744 }
3745
3746 *puiOut = (USHORT) lIn;
3747
3748 return S_OK;
3749}
3750
3751/******************************************************************************
3752 * VarUI2FromR432 [OLEAUT32.260]
3753 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003754HRESULT WINAPI VarUI2FromR432(FLOAT fltIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003755{
3756 TRACE( ole, "( %f, %p ), stub\n", fltIn, puiOut );
3757
3758 fltIn = round( fltIn );
3759 if( fltIn < UI2_MIN || fltIn > UI2_MAX )
3760 {
3761 return DISP_E_OVERFLOW;
3762 }
3763
3764 *puiOut = (USHORT) fltIn;
3765
3766 return S_OK;
3767}
3768
3769/******************************************************************************
3770 * VarUI2FromR832 [OLEAUT32.261]
3771 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003772HRESULT WINAPI VarUI2FromR832(double dblIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003773{
3774 TRACE( ole, "( %f, %p ), stub\n", dblIn, puiOut );
3775
3776 dblIn = round( dblIn );
3777 if( dblIn < UI2_MIN || dblIn > UI2_MAX )
3778 {
3779 return DISP_E_OVERFLOW;
3780 }
3781
3782 *puiOut = (USHORT) dblIn;
3783
3784 return S_OK;
3785}
3786
3787/******************************************************************************
3788 * VarUI2FromDate32 [OLEAUT32.262]
3789 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003790HRESULT WINAPI VarUI2FromDate32(DATE dateIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003791{
3792 TRACE( ole, "( %f, %p ), stub\n", dateIn, puiOut );
3793
3794 dateIn = round( dateIn );
3795 if( dateIn < UI2_MIN || dateIn > UI2_MAX )
3796 {
3797 return DISP_E_OVERFLOW;
3798 }
3799
3800 *puiOut = (USHORT) dateIn;
3801
3802 return S_OK;
3803}
3804
3805/******************************************************************************
3806 * VarUI2FromStr32 [OLEAUT32.264]
3807 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003808HRESULT WINAPI VarUI2FromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003809{
3810 double dValue = 0.0;
3811 LPSTR pNewString = NULL;
3812
3813 TRACE( ole, "( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, puiOut );
3814
3815 /* Check if we have a valid argument
3816 */
3817 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
3818 RemoveCharacterFromString( pNewString, "," );
3819 if( IsValidRealString( pNewString ) == FALSE )
3820 {
3821 return DISP_E_TYPEMISMATCH;
3822 }
3823
3824 /* Convert the valid string to a floating point number.
3825 */
3826 dValue = atof( pNewString );
3827
3828 /* We don't need the string anymore so free it.
3829 */
3830 HeapFree( GetProcessHeap(), 0, pNewString );
3831
3832 /* Check range of value.
3833 */
3834 dValue = round( dValue );
3835 if( dValue < UI2_MIN || dValue > UI2_MAX )
3836 {
3837 return DISP_E_OVERFLOW;
3838 }
3839
3840 *puiOut = (USHORT) dValue;
3841
3842 return S_OK;
3843}
3844
3845/******************************************************************************
3846 * VarUI2FromBool32 [OLEAUT32.266]
3847 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003848HRESULT WINAPI VarUI2FromBool32(VARIANT_BOOL boolIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003849{
3850 TRACE( ole, "( %d, %p ), stub\n", boolIn, puiOut );
3851
3852 *puiOut = (USHORT) boolIn;
3853
3854 return S_OK;
3855}
3856
3857/******************************************************************************
3858 * VarUI2FromI132 [OLEAUT32.267]
3859 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003860HRESULT WINAPI VarUI2FromI132(CHAR cIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003861{
3862 TRACE( ole, "( %c, %p ), stub\n", cIn, puiOut );
3863
3864 *puiOut = (USHORT) cIn;
3865
3866 return S_OK;
3867}
3868
3869/******************************************************************************
3870 * VarUI2FromUI432 [OLEAUT32.268]
3871 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003872HRESULT WINAPI VarUI2FromUI432(ULONG ulIn, USHORT* puiOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003873{
3874 TRACE( ole, "( %ld, %p ), stub\n", ulIn, puiOut );
3875
3876 if( ulIn < UI2_MIN || ulIn > UI2_MAX )
3877 {
3878 return DISP_E_OVERFLOW;
3879 }
3880
3881 *puiOut = (USHORT) ulIn;
3882
3883 return S_OK;
3884}
3885
3886/******************************************************************************
3887 * VarUI4FromStr32 [OLEAUT32.277]
3888 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003889HRESULT WINAPI VarUI4FromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003890{
3891 double dValue = 0.0;
3892 LPSTR pNewString = NULL;
3893
3894 TRACE( ole, "( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, pulOut );
3895
3896 /* Check if we have a valid argument
3897 */
3898 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
3899 RemoveCharacterFromString( pNewString, "," );
3900 if( IsValidRealString( pNewString ) == FALSE )
3901 {
3902 return DISP_E_TYPEMISMATCH;
3903 }
3904
3905 /* Convert the valid string to a floating point number.
3906 */
3907 dValue = atof( pNewString );
3908
3909 /* We don't need the string anymore so free it.
3910 */
3911 HeapFree( GetProcessHeap(), 0, pNewString );
3912
3913 /* Check range of value.
3914 */
3915 dValue = round( dValue );
3916 if( dValue < UI4_MIN || dValue > UI4_MAX )
3917 {
3918 return DISP_E_OVERFLOW;
3919 }
3920
3921 *pulOut = (ULONG) dValue;
3922
3923 return S_OK;
3924}
3925
Justin Bradfordbc93bc81998-12-11 14:02:16 +00003926/**********************************************************************
3927 * VarUI2FromCy32 [OLEAUT32.263]
3928 * Convert currency to unsigned short
3929 */
3930HRESULT WINAPI VarUI2FromCy32(CY cyIn, USHORT* pusOut) {
Todd Vierling7f573251998-12-15 15:15:16 +00003931 double t = round((((double)cyIn.u.Hi * 4294967296.0) + (double)cyIn.u.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00003932
3933 if (t > UI2_MAX || t < UI2_MIN) return DISP_E_OVERFLOW;
3934
3935 *pusOut = (USHORT)t;
3936
3937 return S_OK;
3938}
3939
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003940/******************************************************************************
3941 * VarUI4FromUI132 [OLEAUT32.270]
3942 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003943HRESULT WINAPI VarUI4FromUI132(BYTE bIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003944{
3945 TRACE( ole, "( %d, %p ), stub\n", bIn, pulOut );
3946
3947 *pulOut = (USHORT) bIn;
3948
3949 return S_OK;
3950}
3951
3952/******************************************************************************
3953 * VarUI4FromI232 [OLEAUT32.271]
3954 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003955HRESULT WINAPI VarUI4FromI232(short uiIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003956{
3957 TRACE( ole, "( %d, %p ), stub\n", uiIn, pulOut );
3958
3959 if( uiIn < UI4_MIN )
3960 {
3961 return DISP_E_OVERFLOW;
3962 }
3963
3964 *pulOut = (ULONG) uiIn;
3965
3966 return S_OK;
3967}
3968
3969/******************************************************************************
3970 * VarUI4FromI432 [OLEAUT32.272]
3971 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003972HRESULT WINAPI VarUI4FromI432(LONG lIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003973{
3974 TRACE( ole, "( %ld, %p ), stub\n", lIn, pulOut );
3975
3976 if( lIn < UI4_MIN )
3977 {
3978 return DISP_E_OVERFLOW;
3979 }
3980
3981 *pulOut = (ULONG) lIn;
3982
3983 return S_OK;
3984}
3985
3986/******************************************************************************
3987 * VarUI4FromR432 [OLEAUT32.273]
3988 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00003989HRESULT WINAPI VarUI4FromR432(FLOAT fltIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00003990{
3991 fltIn = round( fltIn );
3992 if( fltIn < UI4_MIN || fltIn > UI4_MAX )
3993 {
3994 return DISP_E_OVERFLOW;
3995 }
3996
3997 *pulOut = (ULONG) fltIn;
3998
3999 return S_OK;
4000}
4001
4002/******************************************************************************
4003 * VarUI4FromR832 [OLEAUT32.274]
4004 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00004005HRESULT WINAPI VarUI4FromR832(double dblIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004006{
4007 TRACE( ole, "( %f, %p ), stub\n", dblIn, pulOut );
4008
4009 dblIn = round( dblIn );
4010 if( dblIn < UI4_MIN || dblIn > UI4_MAX )
4011 {
4012 return DISP_E_OVERFLOW;
4013 }
4014
4015 *pulOut = (ULONG) dblIn;
4016
4017 return S_OK;
4018}
4019
4020/******************************************************************************
4021 * VarUI4FromDate32 [OLEAUT32.275]
4022 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00004023HRESULT WINAPI VarUI4FromDate32(DATE dateIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004024{
4025 TRACE( ole, "( %f, %p ), stub\n", dateIn, pulOut );
4026
4027 dateIn = round( dateIn );
4028 if( dateIn < UI4_MIN || dateIn > UI4_MAX )
4029 {
4030 return DISP_E_OVERFLOW;
4031 }
4032
4033 *pulOut = (ULONG) dateIn;
4034
4035 return S_OK;
4036}
4037
4038/******************************************************************************
4039 * VarUI4FromBool32 [OLEAUT32.279]
4040 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00004041HRESULT WINAPI VarUI4FromBool32(VARIANT_BOOL boolIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004042{
4043 TRACE( ole, "( %d, %p ), stub\n", boolIn, pulOut );
4044
4045 *pulOut = (ULONG) boolIn;
4046
4047 return S_OK;
4048}
4049
4050/******************************************************************************
4051 * VarUI4FromI132 [OLEAUT32.280]
4052 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00004053HRESULT WINAPI VarUI4FromI132(CHAR cIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004054{
4055 TRACE( ole, "( %c, %p ), stub\n", cIn, pulOut );
4056
4057 *pulOut = (ULONG) cIn;
4058
4059 return S_OK;
4060}
4061
4062/******************************************************************************
4063 * VarUI4FromUI232 [OLEAUT32.281]
4064 */
Marcus Meissnere00d7d91998-12-11 10:40:43 +00004065HRESULT WINAPI VarUI4FromUI232(USHORT uiIn, ULONG* pulOut)
Jean-Claude Coteb00cbea1998-12-10 10:00:38 +00004066{
4067 TRACE( ole, "( %d, %p ), stub\n", uiIn, pulOut );
4068
4069 *pulOut = (ULONG) uiIn;
4070
4071 return S_OK;
4072}
4073
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004074/**********************************************************************
4075 * VarUI4FromCy32 [OLEAUT32.276]
4076 * Convert currency to unsigned long
4077 */
4078HRESULT WINAPI VarUI4FromCy32(CY cyIn, ULONG* pulOut) {
Todd Vierling7f573251998-12-15 15:15:16 +00004079 double t = round((((double)cyIn.u.Hi * 4294967296.0) + (double)cyIn.u.Lo) / 10000);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004080
4081 if (t > UI4_MAX || t < UI4_MIN) return DISP_E_OVERFLOW;
4082
4083 *pulOut = (ULONG)t;
4084
4085 return S_OK;
4086}
4087
4088/**********************************************************************
4089 * VarCyFromUI132 [OLEAUT32.98]
4090 * Convert unsigned char to currency
4091 */
4092HRESULT WINAPI VarCyFromUI132(BYTE bIn, CY* pcyOut) {
4093 pcyOut->u.Hi = 0;
4094 pcyOut->u.Lo = ((ULONG)bIn) * 10000;
4095
4096 return S_OK;
4097}
4098
4099/**********************************************************************
4100 * VarCyFromI232 [OLEAUT32.99]
4101 * Convert signed short to currency
4102 */
4103HRESULT WINAPI VarCyFromI232(short sIn, CY* pcyOut) {
4104 if (sIn < 0) pcyOut->u.Hi = -1;
4105 else pcyOut->u.Hi = 0;
4106 pcyOut->u.Lo = ((ULONG)sIn) * 10000;
4107
4108 return S_OK;
4109}
4110
4111/**********************************************************************
4112 * VarCyFromI432 [OLEAUT32.100]
4113 * Convert signed long to currency
4114 */
4115HRESULT WINAPI VarCyFromI432(LONG lIn, CY* pcyOut) {
4116 double t = (double)lIn * (double)10000;
Todd Vierling7f573251998-12-15 15:15:16 +00004117 pcyOut->u.Hi = (LONG)(t / (double)4294967296.0);
4118 pcyOut->u.Lo = (ULONG)fmod(t, (double)4294967296.0);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004119 if (lIn < 0) pcyOut->u.Hi--;
4120
4121 return S_OK;
4122}
4123
4124/**********************************************************************
4125 * VarCyFromR432 [OLEAUT32.101]
4126 * Convert float to currency
4127 */
4128HRESULT WINAPI VarCyFromR432(FLOAT fltIn, CY* pcyOut) {
4129 double t = round((double)fltIn * (double)10000);
Todd Vierling7f573251998-12-15 15:15:16 +00004130 pcyOut->u.Hi = (LONG)(t / (double)4294967296.0);
4131 pcyOut->u.Lo = (ULONG)fmod(t, (double)4294967296.0);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004132 if (fltIn < 0) pcyOut->u.Hi--;
4133
4134 return S_OK;
4135}
4136
4137/**********************************************************************
4138 * VarCyFromR832 [OLEAUT32.102]
4139 * Convert double to currency
4140 */
4141HRESULT WINAPI VarCyFromR832(double dblIn, CY* pcyOut) {
4142 double t = round(dblIn * (double)10000);
Todd Vierling7f573251998-12-15 15:15:16 +00004143 pcyOut->u.Hi = (LONG)(t / (double)4294967296.0);
4144 pcyOut->u.Lo = (ULONG)fmod(t, (double)4294967296.0);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004145 if (dblIn < 0) pcyOut->u.Hi--;
4146
4147 return S_OK;
4148}
4149
4150/**********************************************************************
4151 * VarCyFromDate32 [OLEAUT32.103]
4152 * Convert date to currency
4153 */
4154HRESULT WINAPI VarCyFromDate32(DATE dateIn, CY* pcyOut) {
4155 double t = round((double)dateIn * (double)10000);
Todd Vierling7f573251998-12-15 15:15:16 +00004156 pcyOut->u.Hi = (LONG)(t / (double)4294967296.0);
4157 pcyOut->u.Lo = (ULONG)fmod(t, (double)4294967296.0);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004158 if (dateIn < 0) pcyOut->u.Hi--;
4159
4160 return S_OK;
4161}
4162
4163/**********************************************************************
4164 * VarCyFromBool32 [OLEAUT32.106]
4165 * Convert boolean to currency
4166 */
4167HRESULT WINAPI VarCyFromBool32(VARIANT_BOOL boolIn, CY* pcyOut) {
4168 if (boolIn < 0) pcyOut->u.Hi = -1;
4169 else pcyOut->u.Hi = 0;
4170 pcyOut->u.Lo = (ULONG)boolIn * (ULONG)10000;
4171
4172 return S_OK;
4173}
4174
4175/**********************************************************************
4176 * VarCyFromI132 [OLEAUT32.225]
4177 * Convert signed char to currency
4178 */
4179HRESULT WINAPI VarCyFromI132(CHAR cIn, CY* pcyOut) {
4180 if (cIn < 0) pcyOut->u.Hi = -1;
4181 else pcyOut->u.Hi = 0;
4182 pcyOut->u.Lo = (ULONG)cIn * (ULONG)10000;
4183
4184 return S_OK;
4185}
4186
4187/**********************************************************************
4188 * VarCyFromUI232 [OLEAUT32.226]
4189 * Convert unsigned short to currency
4190 */
4191HRESULT WINAPI VarCyFromUI232(USHORT usIn, CY* pcyOut) {
4192 pcyOut->u.Hi = 0;
4193 pcyOut->u.Lo = (ULONG)usIn * (ULONG)10000;
4194
4195 return S_OK;
4196}
4197
4198/**********************************************************************
4199 * VarCyFromUI432 [OLEAUT32.227]
4200 * Convert unsigned long to currency
4201 */
4202HRESULT WINAPI VarCyFromUI432(ULONG ulIn, CY* pcyOut) {
4203 double t = (double)ulIn * (double)10000;
Todd Vierling7f573251998-12-15 15:15:16 +00004204 pcyOut->u.Hi = (LONG)(t / (double)4294967296.0);
4205 pcyOut->u.Lo = (ULONG)fmod(t, (double)4294967296.0);
Justin Bradfordbc93bc81998-12-11 14:02:16 +00004206
4207 return S_OK;
4208}