Adapted to CreateSystemTimer interface change.
[wine/multimedia.git] / ole / variant.c
blob010e9a1795625fbc8587dad28270d48a3c26bd67
1 /*
2 * VARIANT
4 * Copyright 1998 Jean-Claude Cote
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.
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.
18 * - The parsing of date for the VarDateFromStr still needs to be done. I'm currently
19 * working on this.
22 #include "oleauto.h"
23 #include "heap.h"
24 #include "debug.h"
25 #include "winerror.h"
27 #include <string.h>
28 #include <stdlib.h>
29 #include <math.h>
30 #include <time.h>
33 static const char CHAR_MAX = 127;
34 static const char CHAR_MIN = -128;
35 static const BYTE UI1_MAX = 255;
36 static const BYTE UI1_MIN = 0;
37 static const unsigned short UI2_MAX = 65535;
38 static const unsigned short UI2_MIN = 0;
39 static const short I2_MAX = 32767;
40 static const short I2_MIN = -32768;
41 static const unsigned long UI4_MAX = 4294967295;
42 static const unsigned long UI4_MIN = 0;
43 static const long I4_MAX = 2147483647;
44 static const long I4_MIN = -2147483648.0;
45 static const DATE DATE_MIN = -657434;
46 static const DATE DATE_MAX = 2958465;
49 /* This mask is used to set a flag in wReserved1 of
50 * the VARIANTARG structure. The flag indicates if
51 * the API function is using an inner variant or not.
53 #define PROCESSING_INNER_VARIANT 0x0001
55 /* General use buffer.
57 #define BUFFER_MAX 1024
58 static char pBuffer[BUFFER_MAX];
62 /******************************************************************************
63 * SizeOfVariantData [INTERNAL]
65 * This function finds the size of the data referenced by a Variant based
66 * the type "vt" of the Variant.
68 static int SizeOfVariantData( VARIANT* parg )
70 int size = 0;
71 switch( parg->vt & VT_TYPEMASK )
73 case( VT_I2 ):
74 size = sizeof(short);
75 break;
76 case( VT_INT ):
77 size = sizeof(int);
78 break;
79 case( VT_I4 ):
80 size = sizeof(long);
81 break;
82 case( VT_UI1 ):
83 size = sizeof(BYTE);
84 break;
85 case( VT_UI2 ):
86 size = sizeof(unsigned short);
87 break;
88 case( VT_UINT ):
89 size = sizeof(unsigned int);
90 break;
91 case( VT_UI4 ):
92 size = sizeof(unsigned long);
93 break;
94 case( VT_R4 ):
95 size = sizeof(float);
96 break;
97 case( VT_R8 ):
98 size = sizeof(double);
99 break;
100 case( VT_DATE ):
101 size = sizeof(DATE);
102 break;
103 case( VT_BOOL ):
104 size = sizeof(VARIANT_BOOL);
105 break;
106 case( VT_BSTR ):
107 size = sizeof(void*);
108 break;
109 case( VT_CY ):
110 case( VT_DISPATCH ):
111 case( VT_UNKNOWN ):
112 case( VT_DECIMAL ):
113 default:
114 FIXME(ole,"Add size information for type vt=%d\n", parg->vt & VT_TYPEMASK );
115 break;
118 return size;
120 /******************************************************************************
121 * StringDupAtoBstr [INTERNAL]
124 static BSTR32 StringDupAtoBstr( char* strIn )
126 BSTR32 bstr = NULL;
127 OLECHAR32* pNewString = NULL;
128 pNewString = HEAP_strdupAtoW( GetProcessHeap(), 0, strIn );
129 bstr = SysAllocString32( pNewString );
130 HeapFree( GetProcessHeap(), 0, pNewString );
131 return bstr;
134 /******************************************************************************
135 * round [INTERNAL]
137 * Round the double value to the nearest integer value.
139 static double round( double d )
141 double decimals = 0.0;
142 unsigned long integerValue = 0.0;
143 double roundedValue = 0.0;
144 BOOL32 bEvenNumber = FALSE;
145 int nSign = 0;
147 /* Save the sign of the number
149 nSign = d >= 0.0 ? 1 : -1;
150 d = fabs( d );
152 /* Remove the decimals.
154 integerValue = (unsigned long) d;
156 /* Set the Even flag. This is used to round the number when
157 * the decimals are exactly 1/2. If the integer part is
158 * odd the number is rounded up. If the integer part
159 * is even the number is rounded down. Using this method
160 * numbers are rounded up|down half the time.
162 bEvenNumber = ((integerValue % 2) == 0) ? TRUE : FALSE;
164 /* Remove the integral part of the number.
166 decimals = d - integerValue;
168 /* Note: Ceil returns the smallest integer that is greater that x.
169 * and floor returns the largest integer that is less than or equal to x.
171 if( decimals > 0.5 )
173 /* If the decimal part is greater than 1/2
175 roundedValue = ceil( d );
177 else if( decimals < 0.5 )
179 /* If the decimal part is smaller than 1/2
181 roundedValue = floor( d );
183 else
185 /* the decimals are exactly 1/2 so round according to
186 * the bEvenNumber flag.
188 if( bEvenNumber )
190 roundedValue = floor( d );
192 else
194 roundedValue = ceil( d );
198 return roundedValue * nSign;
202 /******************************************************************************
203 * RemoveCharacterFromString [INTERNAL]
205 * Removes any of the characters in "strOfCharToRemove" from the "str" argument.
207 static void RemoveCharacterFromString( LPSTR str, LPSTR strOfCharToRemove )
209 LPSTR pNewString = NULL;
210 LPSTR strToken = NULL;
213 /* Check if we have a valid argument
215 if( str != NULL )
217 pNewString = strdup( str );
218 str[0] = '\0';
219 strToken = strtok( pNewString, strOfCharToRemove );
220 while( strToken != NULL ) {
221 strcat( str, strToken );
222 strToken = strtok( NULL, strOfCharToRemove );
224 free( pNewString );
226 return;
229 /******************************************************************************
230 * GetValidRealString [INTERNAL]
232 * Checks if the string is of proper format to be converted to a real value.
234 static BOOL32 IsValidRealString( LPSTR strRealString )
236 /* Real values that have a decimal point are required to either have
237 * digits before or after the decimal point. We will assume that
238 * we do not have any digits at either position. If we do encounter
239 * some we will disable this flag.
241 BOOL32 bDigitsRequired = TRUE;
242 /* Processed fields in the string representation of the real number.
244 BOOL32 bWhiteSpaceProcessed = FALSE;
245 BOOL32 bFirstSignProcessed = FALSE;
246 BOOL32 bFirstDigitsProcessed = FALSE;
247 BOOL32 bDecimalPointProcessed = FALSE;
248 BOOL32 bSecondDigitsProcessed = FALSE;
249 BOOL32 bExponentProcessed = FALSE;
250 BOOL32 bSecondSignProcessed = FALSE;
251 BOOL32 bThirdDigitsProcessed = FALSE;
252 /* Assume string parameter "strRealString" is valid and try to disprove it.
254 BOOL32 bValidRealString = TRUE;
256 /* Used to count the number of tokens in the "strRealString".
258 LPSTR strToken = NULL;
259 int nTokens = 0;
260 LPSTR pChar = NULL;
262 /* Check if we have a valid argument
264 if( strRealString == NULL )
266 bValidRealString = FALSE;
269 if( bValidRealString == TRUE )
271 /* Make sure we only have ONE token in the string.
273 strToken = strtok( strRealString, " " );
274 while( strToken != NULL ) {
275 nTokens++;
276 strToken = strtok( NULL, " " );
279 if( nTokens != 1 )
281 bValidRealString = FALSE;
286 /* Make sure this token contains only valid characters.
287 * The string argument to atof has the following form:
288 * [whitespace] [sign] [digits] [.digits] [ {d | D | e | E }[sign]digits]
289 * Whitespace consists of space and|or <TAB> characters, which are ignored.
290 * Sign is either plus '+' or minus '-'.
291 * Digits are one or more decimal digits.
292 * Note: If no digits appear before the decimal point, at least one must
293 * appear after the decimal point.
294 * The decimal digits may be followed by an exponent.
295 * An Exponent consists of an introductory letter ( D, d, E, or e) and
296 * an optionally signed decimal integer.
298 pChar = strRealString;
299 while( bValidRealString == TRUE && *pChar != '\0' )
301 switch( *pChar )
303 /* If whitespace...
305 case ' ':
306 case '\t':
307 if( bWhiteSpaceProcessed ||
308 bFirstSignProcessed ||
309 bFirstDigitsProcessed ||
310 bDecimalPointProcessed ||
311 bSecondDigitsProcessed ||
312 bExponentProcessed ||
313 bSecondSignProcessed ||
314 bThirdDigitsProcessed )
316 bValidRealString = FALSE;
318 break;
319 /* If sign...
321 case '+':
322 case '-':
323 if( bFirstSignProcessed == FALSE )
325 if( bFirstDigitsProcessed ||
326 bDecimalPointProcessed ||
327 bSecondDigitsProcessed ||
328 bExponentProcessed ||
329 bSecondSignProcessed ||
330 bThirdDigitsProcessed )
332 bValidRealString = FALSE;
334 bWhiteSpaceProcessed = TRUE;
335 bFirstSignProcessed = TRUE;
337 else if( bSecondSignProcessed == FALSE )
339 /* Note: The exponent must be present in
340 * order to accept the second sign...
342 if( bExponentProcessed == FALSE ||
343 bThirdDigitsProcessed ||
344 bDigitsRequired )
346 bValidRealString = FALSE;
348 bFirstSignProcessed = TRUE;
349 bWhiteSpaceProcessed = TRUE;
350 bFirstDigitsProcessed = TRUE;
351 bDecimalPointProcessed = TRUE;
352 bSecondDigitsProcessed = TRUE;
353 bSecondSignProcessed = TRUE;
355 break;
357 /* If decimals...
359 case '0':
360 case '1':
361 case '2':
362 case '3':
363 case '4':
364 case '5':
365 case '6':
366 case '7':
367 case '8':
368 case '9':
369 if( bFirstDigitsProcessed == FALSE )
371 if( bDecimalPointProcessed ||
372 bSecondDigitsProcessed ||
373 bExponentProcessed ||
374 bSecondSignProcessed ||
375 bThirdDigitsProcessed )
377 bValidRealString = FALSE;
379 bFirstSignProcessed = TRUE;
380 bWhiteSpaceProcessed = TRUE;
381 /* We have found some digits before the decimal point
382 * so disable the "Digits required" flag.
384 bDigitsRequired = FALSE;
386 else if( bSecondDigitsProcessed == FALSE )
388 if( bExponentProcessed ||
389 bSecondSignProcessed ||
390 bThirdDigitsProcessed )
392 bValidRealString = FALSE;
394 bFirstSignProcessed = TRUE;
395 bWhiteSpaceProcessed = TRUE;
396 bFirstDigitsProcessed = TRUE;
397 bDecimalPointProcessed = TRUE;
398 /* We have found some digits after the decimal point
399 * so disable the "Digits required" flag.
401 bDigitsRequired = FALSE;
403 else if( bThirdDigitsProcessed == FALSE )
405 /* Getting here means everything else should be processed.
406 * If we get anything else than a decimal following this
407 * digit it will be flagged by the other cases, so
408 * we do not really need to do anything in here.
411 break;
412 /* If DecimalPoint...
414 case '.':
415 if( bDecimalPointProcessed ||
416 bSecondDigitsProcessed ||
417 bExponentProcessed ||
418 bSecondSignProcessed ||
419 bThirdDigitsProcessed )
421 bValidRealString = FALSE;
423 bFirstSignProcessed = TRUE;
424 bWhiteSpaceProcessed = TRUE;
425 bFirstDigitsProcessed = TRUE;
426 bDecimalPointProcessed = TRUE;
427 break;
428 /* If Exponent...
430 case 'e':
431 case 'E':
432 case 'd':
433 case 'D':
434 if( bExponentProcessed ||
435 bSecondSignProcessed ||
436 bThirdDigitsProcessed ||
437 bDigitsRequired )
439 bValidRealString = FALSE;
441 bFirstSignProcessed = TRUE;
442 bWhiteSpaceProcessed = TRUE;
443 bFirstDigitsProcessed = TRUE;
444 bDecimalPointProcessed = TRUE;
445 bSecondDigitsProcessed = TRUE;
446 bExponentProcessed = TRUE;
447 break;
448 default:
449 bValidRealString = FALSE;
450 break;
452 /* Process next character.
454 pChar++;
457 /* If the required digits were not present we have an invalid
458 * string representation of a real number.
460 if( bDigitsRequired == TRUE )
462 bValidRealString = FALSE;
465 return bValidRealString;
469 /******************************************************************************
470 * Coerce [INTERNAL]
472 * This function dispatches execution to the proper conversion API
473 * to do the necessary coercion.
475 static HRESULT Coerce( VARIANTARG* pd, LCID lcid, ULONG dwFlags, VARIANTARG* ps, VARTYPE vt )
477 HRESULT res = S_OK;
478 unsigned short vtFrom = 0;
479 vtFrom = ps->vt & VT_TYPEMASK;
481 /* Note: Since "long" and "int" values both have 4 bytes and are both signed integers
482 * "int" will be treated as "long" in the following code.
483 * The same goes for there unsigned versions.
486 switch( vt )
489 case( VT_EMPTY ):
490 res = VariantClear32( pd );
491 break;
492 case( VT_NULL ):
493 res = VariantClear32( pd );
494 if( res == S_OK )
496 pd->vt = VT_NULL;
498 break;
499 case( VT_I1 ):
500 switch( vtFrom )
502 case( VT_I1 ):
503 res = VariantCopy32( pd, ps );
504 break;
505 case( VT_I2 ):
506 res = VarI1FromI232( ps->u.iVal, &(pd->u.cVal) );
507 break;
508 case( VT_INT ):
509 case( VT_I4 ):
510 res = VarI1FromI432( ps->u.lVal, &(pd->u.cVal) );
511 break;
512 case( VT_UI1 ):
513 res = VarI1FromUI132( ps->u.bVal, &(pd->u.cVal) );
514 break;
515 case( VT_UI2 ):
516 res = VarI1FromUI232( ps->u.uiVal, &(pd->u.cVal) );
517 break;
518 case( VT_UINT ):
519 case( VT_UI4 ):
520 res = VarI1FromUI432( ps->u.ulVal, &(pd->u.cVal) );
521 break;
522 case( VT_R4 ):
523 res = VarI1FromR432( ps->u.fltVal, &(pd->u.cVal) );
524 break;
525 case( VT_R8 ):
526 res = VarI1FromR832( ps->u.dblVal, &(pd->u.cVal) );
527 break;
528 case( VT_DATE ):
529 res = VarI1FromDate32( ps->u.date, &(pd->u.cVal) );
530 break;
531 case( VT_BOOL ):
532 res = VarI1FromBool32( ps->u.boolVal, &(pd->u.cVal) );
533 break;
534 case( VT_BSTR ):
535 res = VarI1FromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.cVal) );
536 break;
537 case( VT_CY ):
538 /*res = VarI1FromCY32( ps->u.cyVal, &(pd->u.cVal) );*/
539 case( VT_DISPATCH ):
540 /*res = VarI1FromDisp32( ps->u.pdispVal, lcid, &(pd->u.cVal) );*/
541 case( VT_UNKNOWN ):
542 /*res = VarI1From32( ps->u.lVal, &(pd->u.cVal) );*/
543 case( VT_DECIMAL ):
544 /*res = VarI1FromDec32( ps->u.decVal, &(pd->u.cVal) );*/
545 default:
546 res = DISP_E_TYPEMISMATCH;
547 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
548 break;
550 break;
552 case( VT_I2 ):
553 switch( vtFrom )
555 case( VT_I1 ):
556 res = VarI2FromI132( ps->u.cVal, &(pd->u.iVal) );
557 break;
558 case( VT_I2 ):
559 res = VariantCopy32( pd, ps );
560 break;
561 case( VT_INT ):
562 case( VT_I4 ):
563 res = VarI2FromI432( ps->u.lVal, &(pd->u.iVal) );
564 break;
565 case( VT_UI1 ):
566 res = VarI2FromUI132( ps->u.bVal, &(pd->u.iVal) );
567 break;
568 case( VT_UI2 ):
569 res = VarI2FromUI232( ps->u.uiVal, &(pd->u.iVal) );
570 break;
571 case( VT_UINT ):
572 case( VT_UI4 ):
573 res = VarI2FromUI432( ps->u.ulVal, &(pd->u.iVal) );
574 break;
575 case( VT_R4 ):
576 res = VarI2FromR432( ps->u.fltVal, &(pd->u.iVal) );
577 break;
578 case( VT_R8 ):
579 res = VarI2FromR832( ps->u.dblVal, &(pd->u.iVal) );
580 break;
581 case( VT_DATE ):
582 res = VarI2FromDate32( ps->u.date, &(pd->u.iVal) );
583 break;
584 case( VT_BOOL ):
585 res = VarI2FromBool32( ps->u.boolVal, &(pd->u.iVal) );
586 break;
587 case( VT_BSTR ):
588 res = VarI2FromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.iVal) );
589 break;
590 case( VT_CY ):
591 /*res = VarI2FromCY32( ps->u.cyVal, &(pd->u.iVal) );*/
592 case( VT_DISPATCH ):
593 /*res = VarI2FromDisp32( ps->u.pdispVal, lcid, &(pd->u.iVal) );*/
594 case( VT_UNKNOWN ):
595 /*res = VarI2From32( ps->u.lVal, &(pd->u.iVal) );*/
596 case( VT_DECIMAL ):
597 /*res = VarI2FromDec32( ps->u.deiVal, &(pd->u.iVal) );*/
598 default:
599 res = DISP_E_TYPEMISMATCH;
600 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
601 break;
603 break;
605 case( VT_INT ):
606 case( VT_I4 ):
607 switch( vtFrom )
609 case( VT_I1 ):
610 res = VarI4FromI132( ps->u.cVal, &(pd->u.lVal) );
611 break;
612 case( VT_I2 ):
613 res = VarI4FromI232( ps->u.iVal, &(pd->u.lVal) );
614 break;
615 case( VT_INT ):
616 case( VT_I4 ):
617 res = VariantCopy32( pd, ps );
618 break;
619 case( VT_UI1 ):
620 res = VarI4FromUI132( ps->u.bVal, &(pd->u.lVal) );
621 break;
622 case( VT_UI2 ):
623 res = VarI4FromUI232( ps->u.uiVal, &(pd->u.lVal) );
624 break;
625 case( VT_UINT ):
626 case( VT_UI4 ):
627 res = VarI4FromUI432( ps->u.ulVal, &(pd->u.lVal) );
628 break;
629 case( VT_R4 ):
630 res = VarI4FromR432( ps->u.fltVal, &(pd->u.lVal) );
631 break;
632 case( VT_R8 ):
633 res = VarI4FromR832( ps->u.dblVal, &(pd->u.lVal) );
634 break;
635 case( VT_DATE ):
636 res = VarI4FromDate32( ps->u.date, &(pd->u.lVal) );
637 break;
638 case( VT_BOOL ):
639 res = VarI4FromBool32( ps->u.boolVal, &(pd->u.lVal) );
640 break;
641 case( VT_BSTR ):
642 res = VarI4FromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.lVal) );
643 break;
644 case( VT_CY ):
645 /*res = VarI4FromCY32( ps->u.cyVal, &(pd->u.lVal) );*/
646 case( VT_DISPATCH ):
647 /*res = VarI4FromDisp32( ps->u.pdispVal, lcid, &(pd->u.lVal) );*/
648 case( VT_UNKNOWN ):
649 /*res = VarI4From32( ps->u.lVal, &(pd->u.lVal) );*/
650 case( VT_DECIMAL ):
651 /*res = VarI4FromDec32( ps->u.deiVal, &(pd->u.lVal) );*/
652 default:
653 res = DISP_E_TYPEMISMATCH;
654 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
655 break;
657 break;
659 case( VT_UI1 ):
660 switch( vtFrom )
662 case( VT_I1 ):
663 res = VarUI1FromI132( ps->u.cVal, &(pd->u.bVal) );
664 break;
665 case( VT_I2 ):
666 res = VarUI1FromI232( ps->u.iVal, &(pd->u.bVal) );
667 break;
668 case( VT_INT ):
669 case( VT_I4 ):
670 res = VarUI1FromI432( ps->u.lVal, &(pd->u.bVal) );
671 break;
672 case( VT_UI1 ):
673 res = VariantCopy32( pd, ps );
674 break;
675 case( VT_UI2 ):
676 res = VarUI1FromUI232( ps->u.uiVal, &(pd->u.bVal) );
677 break;
678 case( VT_UINT ):
679 case( VT_UI4 ):
680 res = VarUI1FromUI432( ps->u.ulVal, &(pd->u.bVal) );
681 break;
682 case( VT_R4 ):
683 res = VarUI1FromR432( ps->u.fltVal, &(pd->u.bVal) );
684 break;
685 case( VT_R8 ):
686 res = VarUI1FromR832( ps->u.dblVal, &(pd->u.bVal) );
687 break;
688 case( VT_DATE ):
689 res = VarUI1FromDate32( ps->u.date, &(pd->u.bVal) );
690 break;
691 case( VT_BOOL ):
692 res = VarUI1FromBool32( ps->u.boolVal, &(pd->u.bVal) );
693 break;
694 case( VT_BSTR ):
695 res = VarUI1FromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.bVal) );
696 break;
697 case( VT_CY ):
698 /*res = VarUI1FromCY32( ps->u.cyVal, &(pd->u.bVal) );*/
699 case( VT_DISPATCH ):
700 /*res = VarUI1FromDisp32( ps->u.pdispVal, lcid, &(pd->u.bVal) );*/
701 case( VT_UNKNOWN ):
702 /*res = VarUI1From32( ps->u.lVal, &(pd->u.bVal) );*/
703 case( VT_DECIMAL ):
704 /*res = VarUI1FromDec32( ps->u.deiVal, &(pd->u.bVal) );*/
705 default:
706 res = DISP_E_TYPEMISMATCH;
707 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
708 break;
710 break;
712 case( VT_UI2 ):
713 switch( vtFrom )
715 case( VT_I1 ):
716 res = VarUI2FromI132( ps->u.cVal, &(pd->u.uiVal) );
717 break;
718 case( VT_I2 ):
719 res = VarUI2FromI232( ps->u.iVal, &(pd->u.uiVal) );
720 break;
721 case( VT_INT ):
722 case( VT_I4 ):
723 res = VarUI2FromI432( ps->u.lVal, &(pd->u.uiVal) );
724 break;
725 case( VT_UI1 ):
726 res = VarUI2FromUI132( ps->u.bVal, &(pd->u.uiVal) );
727 break;
728 case( VT_UI2 ):
729 res = VariantCopy32( pd, ps );
730 break;
731 case( VT_UINT ):
732 case( VT_UI4 ):
733 res = VarUI2FromUI432( ps->u.ulVal, &(pd->u.uiVal) );
734 break;
735 case( VT_R4 ):
736 res = VarUI2FromR432( ps->u.fltVal, &(pd->u.uiVal) );
737 break;
738 case( VT_R8 ):
739 res = VarUI2FromR832( ps->u.dblVal, &(pd->u.uiVal) );
740 break;
741 case( VT_DATE ):
742 res = VarUI2FromDate32( ps->u.date, &(pd->u.uiVal) );
743 break;
744 case( VT_BOOL ):
745 res = VarUI2FromBool32( ps->u.boolVal, &(pd->u.uiVal) );
746 break;
747 case( VT_BSTR ):
748 res = VarUI2FromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.uiVal) );
749 break;
750 case( VT_CY ):
751 /*res = VarUI2FromCY32( ps->u.cyVal, &(pd->u.uiVal) );*/
752 case( VT_DISPATCH ):
753 /*res = VarUI2FromDisp32( ps->u.pdispVal, lcid, &(pd->u.uiVal) );*/
754 case( VT_UNKNOWN ):
755 /*res = VarUI2From32( ps->u.lVal, &(pd->u.uiVal) );*/
756 case( VT_DECIMAL ):
757 /*res = VarUI2FromDec32( ps->u.deiVal, &(pd->u.uiVal) );*/
758 default:
759 res = DISP_E_TYPEMISMATCH;
760 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
761 break;
763 break;
765 case( VT_UINT ):
766 case( VT_UI4 ):
767 switch( vtFrom )
769 case( VT_I1 ):
770 res = VarUI4FromI132( ps->u.cVal, &(pd->u.ulVal) );
771 break;
772 case( VT_I2 ):
773 res = VarUI4FromI232( ps->u.iVal, &(pd->u.ulVal) );
774 break;
775 case( VT_INT ):
776 case( VT_I4 ):
777 res = VarUI4FromI432( ps->u.lVal, &(pd->u.ulVal) );
778 break;
779 case( VT_UI1 ):
780 res = VarUI4FromUI132( ps->u.bVal, &(pd->u.ulVal) );
781 break;
782 case( VT_UI2 ):
783 res = VarUI4FromUI232( ps->u.uiVal, &(pd->u.ulVal) );
784 break;
785 case( VT_UI4 ):
786 res = VariantCopy32( pd, ps );
787 break;
788 case( VT_R4 ):
789 res = VarUI4FromR432( ps->u.fltVal, &(pd->u.ulVal) );
790 break;
791 case( VT_R8 ):
792 res = VarUI4FromR832( ps->u.dblVal, &(pd->u.ulVal) );
793 break;
794 case( VT_DATE ):
795 res = VarUI4FromDate32( ps->u.date, &(pd->u.ulVal) );
796 break;
797 case( VT_BOOL ):
798 res = VarUI4FromBool32( ps->u.boolVal, &(pd->u.ulVal) );
799 break;
800 case( VT_BSTR ):
801 res = VarUI4FromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.ulVal) );
802 break;
803 case( VT_CY ):
804 /*res = VarUI4FromCY32( ps->u.cyVal, &(pd->u.ulVal) );*/
805 case( VT_DISPATCH ):
806 /*res = VarUI4FromDisp32( ps->u.pdispVal, lcid, &(pd->u.ulVal) );*/
807 case( VT_UNKNOWN ):
808 /*res = VarUI4From32( ps->u.lVal, &(pd->u.ulVal) );*/
809 case( VT_DECIMAL ):
810 /*res = VarUI4FromDec32( ps->u.deiVal, &(pd->u.ulVal) );*/
811 default:
812 res = DISP_E_TYPEMISMATCH;
813 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
814 break;
816 break;
818 case( VT_R4 ):
819 switch( vtFrom )
821 case( VT_I1 ):
822 res = VarR4FromI132( ps->u.cVal, &(pd->u.fltVal) );
823 break;
824 case( VT_I2 ):
825 res = VarR4FromI232( ps->u.iVal, &(pd->u.fltVal) );
826 break;
827 case( VT_INT ):
828 case( VT_I4 ):
829 res = VarR4FromI432( ps->u.lVal, &(pd->u.fltVal) );
830 break;
831 case( VT_UI1 ):
832 res = VarR4FromUI132( ps->u.bVal, &(pd->u.fltVal) );
833 break;
834 case( VT_UI2 ):
835 res = VarR4FromUI232( ps->u.uiVal, &(pd->u.fltVal) );
836 break;
837 case( VT_UINT ):
838 case( VT_UI4 ):
839 res = VarR4FromUI432( ps->u.ulVal, &(pd->u.fltVal) );
840 break;
841 case( VT_R4 ):
842 res = VariantCopy32( pd, ps );
843 break;
844 case( VT_R8 ):
845 res = VarR4FromR832( ps->u.dblVal, &(pd->u.fltVal) );
846 break;
847 case( VT_DATE ):
848 res = VarR4FromDate32( ps->u.date, &(pd->u.fltVal) );
849 break;
850 case( VT_BOOL ):
851 res = VarR4FromBool32( ps->u.boolVal, &(pd->u.fltVal) );
852 break;
853 case( VT_BSTR ):
854 res = VarR4FromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.fltVal) );
855 break;
856 case( VT_CY ):
857 /*res = VarR4FromCY32( ps->u.cyVal, &(pd->u.fltVal) );*/
858 case( VT_DISPATCH ):
859 /*res = VarR4FromDisp32( ps->u.pdispVal, lcid, &(pd->u.fltVal) );*/
860 case( VT_UNKNOWN ):
861 /*res = VarR4From32( ps->u.lVal, &(pd->u.fltVal) );*/
862 case( VT_DECIMAL ):
863 /*res = VarR4FromDec32( ps->u.deiVal, &(pd->u.fltVal) );*/
864 default:
865 res = DISP_E_TYPEMISMATCH;
866 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
867 break;
869 break;
871 case( VT_R8 ):
872 switch( vtFrom )
874 case( VT_I1 ):
875 res = VarR8FromI132( ps->u.cVal, &(pd->u.dblVal) );
876 break;
877 case( VT_I2 ):
878 res = VarR8FromI232( ps->u.iVal, &(pd->u.dblVal) );
879 break;
880 case( VT_INT ):
881 case( VT_I4 ):
882 res = VarR8FromI432( ps->u.lVal, &(pd->u.dblVal) );
883 break;
884 case( VT_UI1 ):
885 res = VarR8FromUI132( ps->u.bVal, &(pd->u.dblVal) );
886 break;
887 case( VT_UI2 ):
888 res = VarR8FromUI232( ps->u.uiVal, &(pd->u.dblVal) );
889 break;
890 case( VT_UINT ):
891 case( VT_UI4 ):
892 res = VarR8FromUI432( ps->u.ulVal, &(pd->u.dblVal) );
893 break;
894 case( VT_R4 ):
895 res = VarR8FromR432( ps->u.fltVal, &(pd->u.dblVal) );
896 break;
897 case( VT_R8 ):
898 res = VariantCopy32( pd, ps );
899 break;
900 case( VT_DATE ):
901 res = VarR8FromDate32( ps->u.date, &(pd->u.dblVal) );
902 break;
903 case( VT_BOOL ):
904 res = VarR8FromBool32( ps->u.boolVal, &(pd->u.dblVal) );
905 break;
906 case( VT_BSTR ):
907 res = VarR8FromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.dblVal) );
908 break;
909 case( VT_CY ):
910 /*res = VarR8FromCY32( ps->u.cyVal, &(pd->u.dblVal) );*/
911 case( VT_DISPATCH ):
912 /*res = VarR8FromDisp32( ps->u.pdispVal, lcid, &(pd->u.dblVal) );*/
913 case( VT_UNKNOWN ):
914 /*res = VarR8From32( ps->u.lVal, &(pd->u.dblVal) );*/
915 case( VT_DECIMAL ):
916 /*res = VarR8FromDec32( ps->u.deiVal, &(pd->u.dblVal) );*/
917 default:
918 res = DISP_E_TYPEMISMATCH;
919 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
920 break;
922 break;
924 case( VT_DATE ):
925 switch( vtFrom )
927 case( VT_I1 ):
928 res = VarDateFromI132( ps->u.cVal, &(pd->u.date) );
929 break;
930 case( VT_I2 ):
931 res = VarDateFromI232( ps->u.iVal, &(pd->u.date) );
932 break;
933 case( VT_INT ):
934 res = VarDateFromInt32( ps->u.intVal, &(pd->u.date) );
935 break;
936 case( VT_I4 ):
937 res = VarDateFromI432( ps->u.lVal, &(pd->u.date) );
938 break;
939 case( VT_UI1 ):
940 res = VarDateFromUI132( ps->u.bVal, &(pd->u.date) );
941 break;
942 case( VT_UI2 ):
943 res = VarDateFromUI232( ps->u.uiVal, &(pd->u.date) );
944 break;
945 case( VT_UINT ):
946 res = VarDateFromUint32( ps->u.uintVal, &(pd->u.date) );
947 break;
948 case( VT_UI4 ):
949 res = VarDateFromUI432( ps->u.ulVal, &(pd->u.date) );
950 break;
951 case( VT_R4 ):
952 res = VarDateFromR432( ps->u.fltVal, &(pd->u.date) );
953 break;
954 case( VT_R8 ):
955 res = VarDateFromR832( ps->u.dblVal, &(pd->u.date) );
956 break;
957 case( VT_DATE ):
958 res = VariantCopy32( pd, ps );
959 break;
960 case( VT_BOOL ):
961 res = VarDateFromBool32( ps->u.boolVal, &(pd->u.date) );
962 break;
963 case( VT_BSTR ):
964 res = VarDateFromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.date) );
965 break;
966 case( VT_CY ):
967 /*res = VarDateFromCY32( ps->u.cyVal, &(pd->u.date) );*/
968 case( VT_DISPATCH ):
969 /*res = VarDateFromDisp32( ps->u.pdispVal, lcid, &(pd->u.date) );*/
970 case( VT_UNKNOWN ):
971 /*res = VarDateFrom32( ps->u.lVal, &(pd->u.date) );*/
972 case( VT_DECIMAL ):
973 /*res = VarDateFromDec32( ps->u.deiVal, &(pd->u.date) );*/
974 default:
975 res = DISP_E_TYPEMISMATCH;
976 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
977 break;
979 break;
981 case( VT_BOOL ):
982 switch( vtFrom )
984 case( VT_I1 ):
985 res = VarBoolFromI132( ps->u.cVal, &(pd->u.boolVal) );
986 break;
987 case( VT_I2 ):
988 res = VarBoolFromI232( ps->u.iVal, &(pd->u.boolVal) );
989 break;
990 case( VT_INT ):
991 res = VarBoolFromInt32( ps->u.intVal, &(pd->u.boolVal) );
992 break;
993 case( VT_I4 ):
994 res = VarBoolFromI432( ps->u.lVal, &(pd->u.boolVal) );
995 break;
996 case( VT_UI1 ):
997 res = VarBoolFromUI132( ps->u.bVal, &(pd->u.boolVal) );
998 break;
999 case( VT_UI2 ):
1000 res = VarBoolFromUI232( ps->u.uiVal, &(pd->u.boolVal) );
1001 break;
1002 case( VT_UINT ):
1003 res = VarBoolFromUint32( ps->u.uintVal, &(pd->u.boolVal) );
1004 break;
1005 case( VT_UI4 ):
1006 res = VarBoolFromUI432( ps->u.ulVal, &(pd->u.boolVal) );
1007 break;
1008 case( VT_R4 ):
1009 res = VarBoolFromR432( ps->u.fltVal, &(pd->u.boolVal) );
1010 break;
1011 case( VT_R8 ):
1012 res = VarBoolFromR832( ps->u.dblVal, &(pd->u.boolVal) );
1013 break;
1014 case( VT_DATE ):
1015 res = VarBoolFromDate32( ps->u.date, &(pd->u.boolVal) );
1016 break;
1017 case( VT_BOOL ):
1018 res = VariantCopy32( pd, ps );
1019 break;
1020 case( VT_BSTR ):
1021 res = VarBoolFromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.boolVal) );
1022 break;
1023 case( VT_CY ):
1024 /*res = VarBoolFromCY32( ps->u.cyVal, &(pd->u.boolVal) );*/
1025 case( VT_DISPATCH ):
1026 /*res = VarBoolFromDisp32( ps->u.pdispVal, lcid, &(pd->u.boolVal) );*/
1027 case( VT_UNKNOWN ):
1028 /*res = VarBoolFrom32( ps->u.lVal, &(pd->u.boolVal) );*/
1029 case( VT_DECIMAL ):
1030 /*res = VarBoolFromDec32( ps->u.deiVal, &(pd->u.boolVal) );*/
1031 default:
1032 res = DISP_E_TYPEMISMATCH;
1033 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1034 break;
1036 break;
1038 case( VT_BSTR ):
1039 switch( vtFrom )
1041 case( VT_I1 ):
1042 res = VarBstrFromI132( ps->u.cVal, lcid, dwFlags, &(pd->u.bstrVal) );
1043 break;
1044 case( VT_I2 ):
1045 res = VarBstrFromI232( ps->u.iVal, lcid, dwFlags, &(pd->u.bstrVal) );
1046 break;
1047 case( VT_INT ):
1048 res = VarBstrFromInt32( ps->u.intVal, lcid, dwFlags, &(pd->u.bstrVal) );
1049 break;
1050 case( VT_I4 ):
1051 res = VarBstrFromI432( ps->u.lVal, lcid, dwFlags, &(pd->u.bstrVal) );
1052 break;
1053 case( VT_UI1 ):
1054 res = VarBstrFromUI132( ps->u.bVal, lcid, dwFlags, &(pd->u.bstrVal) );
1055 break;
1056 case( VT_UI2 ):
1057 res = VarBstrFromUI232( ps->u.uiVal, lcid, dwFlags, &(pd->u.bstrVal) );
1058 break;
1059 case( VT_UINT ):
1060 res = VarBstrFromUint32( ps->u.uintVal, lcid, dwFlags, &(pd->u.bstrVal) );
1061 break;
1062 case( VT_UI4 ):
1063 res = VarBstrFromUI432( ps->u.ulVal, lcid, dwFlags, &(pd->u.bstrVal) );
1064 break;
1065 case( VT_R4 ):
1066 res = VarBstrFromR432( ps->u.fltVal, lcid, dwFlags, &(pd->u.bstrVal) );
1067 break;
1068 case( VT_R8 ):
1069 res = VarBstrFromR832( ps->u.dblVal, lcid, dwFlags, &(pd->u.bstrVal) );
1070 break;
1071 case( VT_DATE ):
1072 res = VarBstrFromDate32( ps->u.date, lcid, dwFlags, &(pd->u.bstrVal) );
1073 break;
1074 case( VT_BOOL ):
1075 res = VarBstrFromBool32( ps->u.boolVal, lcid, dwFlags, &(pd->u.bstrVal) );
1076 break;
1077 case( VT_BSTR ):
1078 res = VariantCopy32( pd, ps );
1079 break;
1080 case( VT_CY ):
1081 /*res = VarBstrFromCY32( ps->u.cyVal, lcid, dwFlags, &(pd->u.bstrVal) );*/
1082 case( VT_DISPATCH ):
1083 /*res = VarBstrFromDisp32( ps->u.pdispVal, lcid, lcid, dwFlags, &(pd->u.bstrVal) );*/
1084 case( VT_UNKNOWN ):
1085 /*res = VarBstrFrom32( ps->u.lVal, lcid, dwFlags, &(pd->u.bstrVal) );*/
1086 case( VT_DECIMAL ):
1087 /*res = VarBstrFromDec32( ps->u.deiVal, lcid, dwFlags, &(pd->u.bstrVal) );*/
1088 default:
1089 res = DISP_E_TYPEMISMATCH;
1090 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1091 break;
1093 break;
1095 default:
1096 res = DISP_E_TYPEMISMATCH;
1097 FIXME(ole,"Coercion from %d to %d\n", vtFrom, vt );
1098 break;
1101 return res;
1104 /******************************************************************************
1105 * ValidateVtRange [INTERNAL]
1107 * Used internally by the hi-level Variant API to determine
1108 * if the vartypes are valid.
1110 static HRESULT ValidateVtRange( VARTYPE vt )
1112 /* if by value we must make sure it is in the
1113 * range of the valid types.
1115 if( ( vt & VT_TYPEMASK ) > VT_MAXVALIDTYPE )
1117 return DISP_E_BADVARTYPE;
1119 return S_OK;
1123 /******************************************************************************
1124 * ValidateVartype [INTERNAL]
1126 * Used internally by the hi-level Variant API to determine
1127 * if the vartypes are valid.
1129 static HRESULT ValidateVariantType( VARTYPE vt )
1131 HRESULT res = S_OK;
1133 /* check if we have a valid argument.
1135 if( vt & VT_BYREF )
1137 /* if by reference check that the type is in
1138 * the valid range and that it is not of empty or null type
1140 if( ( vt & VT_TYPEMASK ) == VT_EMPTY ||
1141 ( vt & VT_TYPEMASK ) == VT_NULL ||
1142 ( vt & VT_TYPEMASK ) > VT_MAXVALIDTYPE )
1144 res = E_INVALIDARG;
1148 else
1150 res = ValidateVtRange( vt );
1153 return res;
1156 /******************************************************************************
1157 * ValidateVt [INTERNAL]
1159 * Used internally by the hi-level Variant API to determine
1160 * if the vartypes are valid.
1162 static HRESULT ValidateVt( VARTYPE vt )
1164 HRESULT res = S_OK;
1166 /* check if we have a valid argument.
1168 if( vt & VT_BYREF )
1170 /* if by reference check that the type is in
1171 * the valid range and that it is not of empty or null type
1173 if( ( vt & VT_TYPEMASK ) == VT_EMPTY ||
1174 ( vt & VT_TYPEMASK ) == VT_NULL ||
1175 ( vt & VT_TYPEMASK ) > VT_MAXVALIDTYPE )
1177 res = DISP_E_BADVARTYPE;
1181 else
1183 res = ValidateVtRange( vt );
1186 return res;
1193 /******************************************************************************
1194 * VariantInit32 [OLEAUT32.8]
1196 * Initializes the Variant. Unlike VariantClear it does not interpret the current
1197 * contents of the Variant.
1199 void VariantInit32(VARIANTARG* pvarg)
1201 TRACE(ole,"(%p),stub\n",pvarg);
1203 pvarg->vt = VT_EMPTY;
1204 pvarg->wReserved1 = 0;
1205 pvarg->wReserved2= 0;
1206 pvarg->wReserved3= 0;
1208 return;
1211 /******************************************************************************
1212 * VariantClear32 [OLEAUT32.9]
1214 * This function clears the VARIANT by setting the vt field to VT_EMPTY. It also
1215 * sets the wReservedX field to 0. The current contents of the VARIANT are
1216 * freed. If the vt is VT_BSTR the string is freed. If VT_DISPATCH the object is
1217 * released. If VT_ARRAY the array is freed.
1219 HRESULT VariantClear32(VARIANTARG* pvarg)
1221 HRESULT res = S_OK;
1222 TRACE(ole,"(%p),stub\n",pvarg);
1224 res = ValidateVariantType( pvarg->vt );
1225 if( res == S_OK )
1227 if( !( pvarg->vt & VT_BYREF ) )
1229 switch( pvarg->vt & VT_TYPEMASK )
1231 case( VT_BSTR ):
1232 SysFreeString32( pvarg->u.bstrVal );
1233 break;
1234 case( VT_DISPATCH ):
1235 break;
1236 case( VT_VARIANT ):
1237 break;
1238 case( VT_UNKNOWN ):
1239 break;
1240 case( VT_SAFEARRAY ):
1241 break;
1242 default:
1243 break;
1247 /* Set the fields to empty.
1249 pvarg->wReserved1 = 0;
1250 pvarg->wReserved2 = 0;
1251 pvarg->wReserved3 = 0;
1252 pvarg->vt = VT_EMPTY;
1255 return res;
1258 /******************************************************************************
1259 * VariantCopy32 [OLEAUT32.10]
1261 * Frees up the designation variant and makes a copy of the source.
1263 HRESULT VariantCopy32(VARIANTARG* pvargDest, VARIANTARG* pvargSrc)
1265 HRESULT res = S_OK;
1266 TRACE(ole,"(%p, %p),stub\n", pvargDest, pvargSrc);
1268 res = ValidateVariantType( pvargSrc->vt );
1269 /* If the pointer are to the same variant we don't need
1270 * to do anything.
1272 if( pvargDest != pvargSrc && res == S_OK )
1274 res = VariantClear32( pvargDest );
1276 if( res == S_OK )
1278 if( pvargSrc->vt & VT_BYREF )
1280 /* In the case of byreference we only need
1281 * to copy the pointer.
1283 pvargDest->u = pvargSrc->u;
1284 pvargDest->vt = pvargSrc->vt;
1286 else
1288 /* In the case of by value we need to
1289 * copy the actuall value. In the case of
1290 * VT_BSTR a copy of the string is made,
1291 * if VT_ARRAY the entire array is copied
1292 * if VT_DISPATCH or VT_IUNKNOWN AddReff is
1293 * called to increment the object's reference count.
1295 switch( pvargSrc->vt & VT_TYPEMASK )
1297 case( VT_BSTR ):
1298 pvargDest->u.bstrVal = SysAllocString32( pvargSrc->u.bstrVal );
1299 break;
1300 case( VT_DISPATCH ):
1301 break;
1302 case( VT_VARIANT ):
1303 break;
1304 case( VT_UNKNOWN ):
1305 break;
1306 case( VT_SAFEARRAY ):
1307 break;
1308 default:
1309 pvargDest->u = pvargSrc->u;
1310 break;
1312 pvargDest->vt = pvargSrc->vt;
1317 return res;
1321 /******************************************************************************
1322 * VariantCopyInd32 [OLEAUT32.11]
1324 * Frees up the destination variant and makes a copy of the source. If
1325 * the source is of type VT_BYREF it performs the necessary indirections.
1327 HRESULT VariantCopyInd32(VARIANT* pvargDest, VARIANTARG* pvargSrc)
1329 HRESULT res = S_OK;
1330 TRACE(ole,"(%p, %p),stub\n", pvargDest, pvargSrc);
1332 res = ValidateVariantType( pvargSrc->vt );
1333 if( res != S_OK )
1334 return res;
1336 if( pvargSrc->vt & VT_BYREF )
1338 VARIANTARG varg;
1339 VariantInit32( &varg );
1340 /* handle the in place copy.
1342 if( pvargDest == pvargSrc )
1344 /* we will use a copy of the source instead.
1346 res = VariantCopy32( &varg, pvargSrc );
1347 pvargSrc = &varg;
1349 if( res == S_OK )
1351 res = VariantClear32( pvargDest );
1352 if( res == S_OK )
1354 /* In the case of by reference we need
1355 * to copy the date pointed to by the variant.
1357 /* Get the variant type.
1359 switch( pvargSrc->vt & VT_TYPEMASK )
1361 case( VT_BSTR ):
1362 pvargDest->u.bstrVal = SysAllocString32( *(pvargSrc->u.pbstrVal) );
1363 break;
1364 case( VT_DISPATCH ):
1365 break;
1366 case( VT_VARIANT ):
1368 /* Prevent from cycling. According to tests on
1369 * VariantCopyInd in Windows and the documentation
1370 * this API dereferences the inner Variants to only on depth.
1371 * If the inner Variant itself contains an
1372 * other inner variant the E_INVALIDARG error is
1373 * returned.
1375 if( pvargSrc->wReserved1 & PROCESSING_INNER_VARIANT )
1377 /* If we get here we are attempting to deference
1378 * an inner variant that that is itself contained
1379 * in an inner variant so report E_INVALIDARG error.
1381 res = E_INVALIDARG;
1383 else
1385 /* Set the processing inner variant flag.
1386 * We will set this flag in the inner variant
1387 * that will be passed to the VariantCopyInd function.
1389 (pvargSrc->u.pvarVal)->wReserved1 |= PROCESSING_INNER_VARIANT;
1390 /* Dereference the inner variant.
1392 res = VariantCopyInd32( pvargDest, pvargSrc->u.pvarVal );
1395 break;
1396 case( VT_UNKNOWN ):
1397 break;
1398 case( VT_SAFEARRAY ):
1399 break;
1400 default:
1401 /* This is a by reference Variant which means that the union
1402 * part of the Variant contains a pointer to some data of
1403 * type "pvargSrc->vt & VT_TYPEMASK".
1404 * We will deference this data in a generic fashion using
1405 * the void pointer "Variant.u.byref".
1406 * We will copy this data into the union of the destination
1407 * Variant.
1409 memcpy( &pvargDest->u, pvargSrc->u.byref, SizeOfVariantData( pvargSrc ) );
1410 break;
1412 pvargDest->vt = pvargSrc->vt & VT_TYPEMASK;
1415 /* this should not fail.
1417 VariantClear32( &varg );
1419 else
1421 res = VariantCopy32( pvargDest, pvargSrc );
1423 return res;
1426 /******************************************************************************
1427 * VariantChangeType32 [OLEAUT32.12]
1429 HRESULT VariantChangeType32(VARIANTARG* pvargDest, VARIANTARG* pvargSrc,
1430 USHORT wFlags, VARTYPE vt)
1432 return VariantChangeTypeEx32( pvargDest, pvargSrc, 0, wFlags, vt );
1435 /******************************************************************************
1436 * VariantChangeTypeEx32 [OLEAUT32.147]
1438 HRESULT VariantChangeTypeEx32(VARIANTARG* pvargDest, VARIANTARG* pvargSrc,
1439 LCID lcid, USHORT wFlags, VARTYPE vt)
1441 HRESULT res = S_OK;
1442 VARIANTARG varg;
1443 VariantInit32( &varg );
1445 TRACE(ole,"(%p, %p, %ld, %u, %u),stub\n", pvargDest, pvargSrc, lcid, wFlags, vt);
1447 /* validate our source argument.
1449 res = ValidateVariantType( pvargSrc->vt );
1451 /* validate the vartype.
1453 if( res == S_OK )
1455 res = ValidateVt( vt );
1458 /* if we are doing an in-place conversion make a copy of the source.
1460 if( res == S_OK && pvargDest == pvargSrc )
1462 res = VariantCopy32( &varg, pvargSrc );
1463 pvargSrc = &varg;
1466 if( res == S_OK )
1468 /* free up the destination variant.
1470 res = VariantClear32( pvargDest );
1473 if( res == S_OK )
1475 if( pvargSrc->vt & VT_BYREF )
1477 /* Convert the source variant to a "byvalue" variant.
1479 VARIANTARG Variant;
1480 VariantInit32( &Variant );
1481 res = VariantCopyInd32( &Variant, pvargSrc );
1482 if( res == S_OK )
1484 res = Coerce( pvargDest, lcid, wFlags, &Variant, vt );
1485 /* this should not fail.
1487 VariantClear32( &Variant );
1491 else
1493 /* Use the current "byvalue" source variant.
1495 res = Coerce( pvargDest, lcid, wFlags, pvargSrc, vt );
1498 /* this should not fail.
1500 VariantClear32( &varg );
1502 return res;
1508 /******************************************************************************
1509 * VarUI1FromI232 [OLEAUT32.130]
1511 HRESULT VarUI1FromI232(short sIn, BYTE* pbOut)
1513 TRACE( ole, "( %d, %p ), stub\n", sIn, pbOut );
1515 /* Check range of value.
1517 if( sIn < UI1_MIN || sIn > UI1_MAX )
1519 return DISP_E_OVERFLOW;
1522 *pbOut = (BYTE) sIn;
1524 return S_OK;
1527 /******************************************************************************
1528 * VarUI1FromI432 [OLEAUT32.131]
1530 HRESULT VarUI1FromI432(LONG lIn, BYTE* pbOut)
1532 TRACE( ole, "( %ld, %p ), stub\n", lIn, pbOut );
1534 /* Check range of value.
1536 if( lIn < UI1_MIN || lIn > UI1_MAX )
1538 return DISP_E_OVERFLOW;
1541 *pbOut = (BYTE) lIn;
1543 return S_OK;
1547 /******************************************************************************
1548 * VarUI1FromR432 [OLEAUT32.132]
1550 HRESULT VarUI1FromR432(FLOAT fltIn, BYTE* pbOut)
1552 TRACE( ole, "( %f, %p ), stub\n", fltIn, pbOut );
1554 /* Check range of value.
1556 fltIn = round( fltIn );
1557 if( fltIn < UI1_MIN || fltIn > UI1_MAX )
1559 return DISP_E_OVERFLOW;
1562 *pbOut = (BYTE) fltIn;
1564 return S_OK;
1567 /******************************************************************************
1568 * VarUI1FromR832 [OLEAUT32.133]
1570 HRESULT VarUI1FromR832(double dblIn, BYTE* pbOut)
1572 TRACE( ole, "( %f, %p ), stub\n", dblIn, pbOut );
1574 /* Check range of value.
1576 dblIn = round( dblIn );
1577 if( dblIn < UI1_MIN || dblIn > UI1_MAX )
1579 return DISP_E_OVERFLOW;
1582 *pbOut = (BYTE) dblIn;
1584 return S_OK;
1587 /******************************************************************************
1588 * VarUI1FromDate32 [OLEAUT32.135]
1590 HRESULT VarUI1FromDate32(DATE dateIn, BYTE* pbOut)
1592 TRACE( ole, "( %f, %p ), stub\n", dateIn, pbOut );
1594 /* Check range of value.
1596 dateIn = round( dateIn );
1597 if( dateIn < UI1_MIN || dateIn > UI1_MAX )
1599 return DISP_E_OVERFLOW;
1602 *pbOut = (BYTE) dateIn;
1604 return S_OK;
1607 /******************************************************************************
1608 * VarUI1FromBool32 [OLEAUT32.138]
1610 HRESULT VarUI1FromBool32(VARIANT_BOOL boolIn, BYTE* pbOut)
1612 TRACE( ole, "( %d, %p ), stub\n", boolIn, pbOut );
1614 *pbOut = (BYTE) boolIn;
1616 return S_OK;
1619 /******************************************************************************
1620 * VarUI1FromI132 [OLEAUT32.237]
1622 HRESULT VarUI1FromI132(CHAR cIn, BYTE* pbOut)
1624 TRACE( ole, "( %c, %p ), stub\n", cIn, pbOut );
1626 *pbOut = cIn;
1628 return S_OK;
1631 /******************************************************************************
1632 * VarUI1FromUI232 [OLEAUT32.238]
1634 HRESULT VarUI1FromUI232(USHORT uiIn, BYTE* pbOut)
1636 TRACE( ole, "( %d, %p ), stub\n", uiIn, pbOut );
1638 /* Check range of value.
1640 if( uiIn > UI1_MAX )
1642 return DISP_E_OVERFLOW;
1645 *pbOut = (BYTE) uiIn;
1647 return S_OK;
1650 /******************************************************************************
1651 * VarUI1FromUI432 [OLEAUT32.239]
1653 HRESULT VarUI1FromUI432(ULONG ulIn, BYTE* pbOut)
1655 TRACE( ole, "( %ld, %p ), stub\n", ulIn, pbOut );
1657 /* Check range of value.
1659 if( ulIn > UI1_MAX )
1661 return DISP_E_OVERFLOW;
1664 *pbOut = (BYTE) ulIn;
1666 return S_OK;
1670 /******************************************************************************
1671 * VarUI1FromStr32 [OLEAUT32.54]
1673 HRESULT VarUI1FromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, BYTE* pbOut)
1675 double dValue = 0.0;
1676 LPSTR pNewString = NULL;
1678 TRACE( ole, "( %p, 0x%08lx, 0x%08lx, %p ), stub\n", strIn, lcid, dwFlags, pbOut );
1680 /* Check if we have a valid argument
1682 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
1683 RemoveCharacterFromString( pNewString, "," );
1684 if( IsValidRealString( pNewString ) == FALSE )
1686 return DISP_E_TYPEMISMATCH;
1689 /* Convert the valid string to a floating point number.
1691 dValue = atof( pNewString );
1693 /* We don't need the string anymore so free it.
1695 HeapFree( GetProcessHeap(), 0 , pNewString );
1697 /* Check range of value.
1699 dValue = round( dValue );
1700 if( dValue < UI1_MIN || dValue > UI1_MAX )
1702 return DISP_E_OVERFLOW;
1705 *pbOut = (BYTE) dValue;
1707 return S_OK;
1710 /******************************************************************************
1711 * VarI2FromUI132 [OLEAUT32.48]
1713 HRESULT VarI2FromUI132(BYTE bIn, short* psOut)
1715 TRACE( ole, "( 0x%08x, %p ), stub\n", bIn, psOut );
1717 *psOut = (short) bIn;
1719 return S_OK;
1722 /******************************************************************************
1723 * VarI2FromI432 [OLEAUT32.49]
1725 HRESULT VarI2FromI432(LONG lIn, short* psOut)
1727 TRACE( ole, "( %lx, %p ), stub\n", lIn, psOut );
1729 /* Check range of value.
1731 if( lIn < I2_MIN || lIn > I2_MAX )
1733 return DISP_E_OVERFLOW;
1736 *psOut = (short) lIn;
1738 return S_OK;
1741 /******************************************************************************
1742 * VarI2FromR432 [OLEAUT32.50]
1744 HRESULT VarI2FromR432(FLOAT fltIn, short* psOut)
1746 TRACE( ole, "( %f, %p ), stub\n", fltIn, psOut );
1748 /* Check range of value.
1750 fltIn = round( fltIn );
1751 if( fltIn < I2_MIN || fltIn > I2_MAX )
1753 return DISP_E_OVERFLOW;
1756 *psOut = (short) fltIn;
1758 return S_OK;
1761 /******************************************************************************
1762 * VarI2FromR832 [OLEAUT32.51]
1764 HRESULT VarI2FromR832(double dblIn, short* psOut)
1766 TRACE( ole, "( %f, %p ), stub\n", dblIn, psOut );
1768 /* Check range of value.
1770 dblIn = round( dblIn );
1771 if( dblIn < I2_MIN || dblIn > I2_MAX )
1773 return DISP_E_OVERFLOW;
1776 *psOut = (short) dblIn;
1778 return S_OK;
1781 /******************************************************************************
1782 * VarI2FromDate32 [OLEAUT32.53]
1784 HRESULT VarI2FromDate32(DATE dateIn, short* psOut)
1786 TRACE( ole, "( %f, %p ), stub\n", dateIn, psOut );
1788 /* Check range of value.
1790 dateIn = round( dateIn );
1791 if( dateIn < I2_MIN || dateIn > I2_MAX )
1793 return DISP_E_OVERFLOW;
1796 *psOut = (short) dateIn;
1798 return S_OK;
1801 /******************************************************************************
1802 * VarI2FromBool32 [OLEAUT32.56]
1804 HRESULT VarI2FromBool32(VARIANT_BOOL boolIn, short* psOut)
1806 TRACE( ole, "( %d, %p ), stub\n", boolIn, psOut );
1808 *psOut = (short) boolIn;
1810 return S_OK;
1813 /******************************************************************************
1814 * VarI2FromI132 [OLEAUT32.48]
1816 HRESULT VarI2FromI132(CHAR cIn, short* psOut)
1818 TRACE( ole, "( %c, %p ), stub\n", cIn, psOut );
1820 *psOut = (short) cIn;
1822 return S_OK;
1825 /******************************************************************************
1826 * VarI2FromUI232 [OLEAUT32.206]
1828 HRESULT VarI2FromUI232(USHORT uiIn, short* psOut)
1830 TRACE( ole, "( %d, %p ), stub\n", uiIn, psOut );
1832 /* Check range of value.
1834 if( uiIn > I2_MAX )
1836 return DISP_E_OVERFLOW;
1839 *psOut = (short) uiIn;
1841 return S_OK;
1844 /******************************************************************************
1845 * VarI2FromUI432 [OLEAUT32.49]
1847 HRESULT VarI2FromUI432(ULONG ulIn, short* psOut)
1849 TRACE( ole, "( %lx, %p ), stub\n", ulIn, psOut );
1851 /* Check range of value.
1853 if( ulIn < I2_MIN || ulIn > I2_MAX )
1855 return DISP_E_OVERFLOW;
1858 *psOut = (short) ulIn;
1860 return S_OK;
1863 /******************************************************************************
1864 * VarI2FromStr32 [OLEAUT32.54]
1866 HRESULT VarI2FromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, short* psOut)
1868 double dValue = 0.0;
1869 LPSTR pNewString = NULL;
1871 TRACE( ole, "( %p, 0x%08lx, 0x%08lx, %p ), stub\n", strIn, lcid, dwFlags, psOut );
1873 /* Check if we have a valid argument
1875 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
1876 RemoveCharacterFromString( pNewString, "," );
1877 if( IsValidRealString( pNewString ) == FALSE )
1879 return DISP_E_TYPEMISMATCH;
1882 /* Convert the valid string to a floating point number.
1884 dValue = atof( pNewString );
1886 /* We don't need the string anymore so free it.
1888 HeapFree( GetProcessHeap(), 0, pNewString );
1890 /* Check range of value.
1892 dValue = round( dValue );
1893 if( dValue < I2_MIN || dValue > I2_MAX )
1895 return DISP_E_OVERFLOW;
1898 *psOut = (short) dValue;
1900 return S_OK;
1903 /******************************************************************************
1904 * VarI4FromUI132 [OLEAUT32.58]
1906 HRESULT VarI4FromUI132(BYTE bIn, LONG* plOut)
1908 TRACE( ole, "( %X, %p ), stub\n", bIn, plOut );
1910 *plOut = (LONG) bIn;
1912 return S_OK;
1916 /******************************************************************************
1917 * VarI4FromR432 [OLEAUT32.60]
1919 HRESULT VarI4FromR432(FLOAT fltIn, LONG* plOut)
1921 TRACE( ole, "( %f, %p ), stub\n", fltIn, plOut );
1923 /* Check range of value.
1925 fltIn = round( fltIn );
1926 if( fltIn < I4_MIN || fltIn > I4_MAX )
1928 return DISP_E_OVERFLOW;
1931 *plOut = (LONG) fltIn;
1933 return S_OK;
1936 /******************************************************************************
1937 * VarI4FromR832 [OLEAUT32.61]
1939 HRESULT VarI4FromR832(double dblIn, LONG* plOut)
1941 TRACE( ole, "( %f, %p ), stub\n", dblIn, plOut );
1943 /* Check range of value.
1945 dblIn = round( dblIn );
1946 if( dblIn < I4_MIN || dblIn > I4_MAX )
1948 return DISP_E_OVERFLOW;
1951 *plOut = (LONG) dblIn;
1953 return S_OK;
1956 /******************************************************************************
1957 * VarI4FromDate32 [OLEAUT32.63]
1959 HRESULT VarI4FromDate32(DATE dateIn, LONG* plOut)
1961 TRACE( ole, "( %f, %p ), stub\n", dateIn, plOut );
1963 /* Check range of value.
1965 dateIn = round( dateIn );
1966 if( dateIn < I4_MIN || dateIn > I4_MAX )
1968 return DISP_E_OVERFLOW;
1971 *plOut = (LONG) dateIn;
1973 return S_OK;
1976 /******************************************************************************
1977 * VarI4FromBool32 [OLEAUT32.66]
1979 HRESULT VarI4FromBool32(VARIANT_BOOL boolIn, LONG* plOut)
1981 TRACE( ole, "( %d, %p ), stub\n", boolIn, plOut );
1983 *plOut = (LONG) boolIn;
1985 return S_OK;
1988 /******************************************************************************
1989 * VarI4FromI132 [OLEAUT32.209]
1991 HRESULT VarI4FromI132(CHAR cIn, LONG* plOut)
1993 TRACE( ole, "( %c, %p ), stub\n", cIn, plOut );
1995 *plOut = (LONG) cIn;
1997 return S_OK;
2000 /******************************************************************************
2001 * VarI4FromUI232 [OLEAUT32.210]
2003 HRESULT VarI4FromUI232(USHORT uiIn, LONG* plOut)
2005 TRACE( ole, "( %d, %p ), stub\n", uiIn, plOut );
2007 *plOut = (LONG) uiIn;
2009 return S_OK;
2012 /******************************************************************************
2013 * VarI4FromUI432 [OLEAUT32.211]
2015 HRESULT VarI4FromUI432(ULONG ulIn, LONG* plOut)
2017 TRACE( ole, "( %lx, %p ), stub\n", ulIn, plOut );
2019 /* Check range of value.
2021 if( ulIn < I4_MIN || ulIn > I4_MAX )
2023 return DISP_E_OVERFLOW;
2026 *plOut = (LONG) ulIn;
2028 return S_OK;
2031 /******************************************************************************
2032 * VarI4FromI232 [OLEAUT32.59]
2034 HRESULT VarI4FromI232(short sIn, LONG* plOut)
2036 TRACE( ole, "( %d, %p ), stub\n", sIn, plOut );
2038 *plOut = (LONG) sIn;
2040 return S_OK;
2043 /******************************************************************************
2044 * VarI4FromStr32 [OLEAUT32.64]
2046 HRESULT VarI4FromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, LONG* plOut)
2048 double dValue = 0.0;
2049 LPSTR pNewString = NULL;
2051 TRACE( ole, "( %p, 0x%08lx, 0x%08lx, %p ), stub\n", strIn, lcid, dwFlags, plOut );
2053 /* Check if we have a valid argument
2055 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
2056 RemoveCharacterFromString( pNewString, "," );
2057 if( IsValidRealString( pNewString ) == FALSE )
2059 return DISP_E_TYPEMISMATCH;
2062 /* Convert the valid string to a floating point number.
2064 dValue = atof( pNewString );
2066 /* We don't need the string anymore so free it.
2068 HeapFree( GetProcessHeap(), 0, pNewString );
2070 /* Check range of value.
2072 dValue = round( dValue );
2073 if( dValue < I4_MIN || dValue > I4_MAX )
2075 return DISP_E_OVERFLOW;
2078 *plOut = (LONG) dValue;
2080 return S_OK;
2083 /******************************************************************************
2084 * VarR4FromUI132 [OLEAUT32.68]
2086 HRESULT VarR4FromUI132(BYTE bIn, FLOAT* pfltOut)
2088 TRACE( ole, "( %X, %p ), stub\n", bIn, pfltOut );
2090 *pfltOut = (FLOAT) bIn;
2092 return S_OK;
2095 /******************************************************************************
2096 * VarR4FromI232 [OLEAUT32.69]
2098 HRESULT VarR4FromI232(short sIn, FLOAT* pfltOut)
2100 TRACE( ole, "( %d, %p ), stub\n", sIn, pfltOut );
2102 *pfltOut = (FLOAT) sIn;
2104 return S_OK;
2107 /******************************************************************************
2108 * VarR4FromI432 [OLEAUT32.70]
2110 HRESULT VarR4FromI432(LONG lIn, FLOAT* pfltOut)
2112 TRACE( ole, "( %lx, %p ), stub\n", lIn, pfltOut );
2114 *pfltOut = (FLOAT) lIn;
2116 return S_OK;
2119 /******************************************************************************
2120 * VarR4FromR832 [OLEAUT32.71]
2122 HRESULT VarR4FromR832(double dblIn, FLOAT* pfltOut)
2124 TRACE( ole, "( %f, %p ), stub\n", dblIn, pfltOut );
2126 /* Check range of value.
2128 if( dblIn < -(FLT_MAX) || dblIn > FLT_MAX )
2130 return DISP_E_OVERFLOW;
2133 *pfltOut = (FLOAT) dblIn;
2135 return S_OK;
2138 /******************************************************************************
2139 * VarR4FromDate32 [OLEAUT32.73]
2141 HRESULT VarR4FromDate32(DATE dateIn, FLOAT* pfltOut)
2143 TRACE( ole, "( %f, %p ), stub\n", dateIn, pfltOut );
2145 /* Check range of value.
2147 if( dateIn < -(FLT_MAX) || dateIn > FLT_MAX )
2149 return DISP_E_OVERFLOW;
2152 *pfltOut = (FLOAT) dateIn;
2154 return S_OK;
2157 /******************************************************************************
2158 * VarR4FromBool32 [OLEAUT32.76]
2160 HRESULT VarR4FromBool32(VARIANT_BOOL boolIn, FLOAT* pfltOut)
2162 TRACE( ole, "( %d, %p ), stub\n", boolIn, pfltOut );
2164 *pfltOut = (FLOAT) boolIn;
2166 return S_OK;
2169 /******************************************************************************
2170 * VarR4FromI132 [OLEAUT32.213]
2172 HRESULT VarR4FromI132(CHAR cIn, FLOAT* pfltOut)
2174 TRACE( ole, "( %c, %p ), stub\n", cIn, pfltOut );
2176 *pfltOut = (FLOAT) cIn;
2178 return S_OK;
2181 /******************************************************************************
2182 * VarR4FromUI232 [OLEAUT32.214]
2184 HRESULT VarR4FromUI232(USHORT uiIn, FLOAT* pfltOut)
2186 TRACE( ole, "( %d, %p ), stub\n", uiIn, pfltOut );
2188 *pfltOut = (FLOAT) uiIn;
2190 return S_OK;
2193 /******************************************************************************
2194 * VarR4FromUI432 [OLEAUT32.215]
2196 HRESULT VarR4FromUI432(ULONG ulIn, FLOAT* pfltOut)
2198 TRACE( ole, "( %ld, %p ), stub\n", ulIn, pfltOut );
2200 *pfltOut = (FLOAT) ulIn;
2202 return S_OK;
2205 /******************************************************************************
2206 * VarR4FromStr32 [OLEAUT32.74]
2208 HRESULT VarR4FromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, FLOAT* pfltOut)
2210 double dValue = 0.0;
2211 LPSTR pNewString = NULL;
2213 TRACE( ole, "( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, pfltOut );
2215 /* Check if we have a valid argument
2217 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
2218 RemoveCharacterFromString( pNewString, "," );
2219 if( IsValidRealString( pNewString ) == FALSE )
2221 return DISP_E_TYPEMISMATCH;
2224 /* Convert the valid string to a floating point number.
2226 dValue = atof( pNewString );
2228 /* We don't need the string anymore so free it.
2230 HeapFree( GetProcessHeap(), 0, pNewString );
2232 /* Check range of value.
2234 if( dValue < -(FLT_MAX) || dValue > FLT_MAX )
2236 return DISP_E_OVERFLOW;
2239 *pfltOut = (FLOAT) dValue;
2241 return S_OK;
2244 /******************************************************************************
2245 * VarR8FromUI132 [OLEAUT32.68]
2247 HRESULT VarR8FromUI132(BYTE bIn, double* pdblOut)
2249 TRACE( ole, "( %d, %p ), stub\n", bIn, pdblOut );
2251 *pdblOut = (double) bIn;
2253 return S_OK;
2256 /******************************************************************************
2257 * VarR8FromI232 [OLEAUT32.69]
2259 HRESULT VarR8FromI232(short sIn, double* pdblOut)
2261 TRACE( ole, "( %d, %p ), stub\n", sIn, pdblOut );
2263 *pdblOut = (double) sIn;
2265 return S_OK;
2268 /******************************************************************************
2269 * VarR8FromI432 [OLEAUT32.70]
2271 HRESULT VarR8FromI432(LONG lIn, double* pdblOut)
2273 TRACE( ole, "( %ld, %p ), stub\n", lIn, pdblOut );
2275 *pdblOut = (double) lIn;
2277 return S_OK;
2280 /******************************************************************************
2281 * VarR8FromR432 [OLEAUT32.81]
2283 HRESULT VarR8FromR432(FLOAT fltIn, double* pdblOut)
2285 TRACE( ole, "( %f, %p ), stub\n", fltIn, pdblOut );
2287 *pdblOut = (double) fltIn;
2289 return S_OK;
2292 /******************************************************************************
2293 * VarR8FromDate32 [OLEAUT32.83]
2295 HRESULT VarR8FromDate32(DATE dateIn, double* pdblOut)
2297 TRACE( ole, "( %f, %p ), stub\n", dateIn, pdblOut );
2299 *pdblOut = (double) dateIn;
2301 return S_OK;
2304 /******************************************************************************
2305 * VarR8FromBool32 [OLEAUT32.86]
2307 HRESULT VarR8FromBool32(VARIANT_BOOL boolIn, double* pdblOut)
2309 TRACE( ole, "( %d, %p ), stub\n", boolIn, pdblOut );
2311 *pdblOut = (double) boolIn;
2313 return S_OK;
2316 /******************************************************************************
2317 * VarR8FromI132 [OLEAUT32.217]
2319 HRESULT VarR8FromI132(CHAR cIn, double* pdblOut)
2321 TRACE( ole, "( %c, %p ), stub\n", cIn, pdblOut );
2323 *pdblOut = (double) cIn;
2325 return S_OK;
2328 /******************************************************************************
2329 * VarR8FromUI232 [OLEAUT32.218]
2331 HRESULT VarR8FromUI232(USHORT uiIn, double* pdblOut)
2333 TRACE( ole, "( %d, %p ), stub\n", uiIn, pdblOut );
2335 *pdblOut = (double) uiIn;
2337 return S_OK;
2340 /******************************************************************************
2341 * VarR8FromUI432 [OLEAUT32.219]
2343 HRESULT VarR8FromUI432(ULONG ulIn, double* pdblOut)
2345 TRACE( ole, "( %ld, %p ), stub\n", ulIn, pdblOut );
2347 *pdblOut = (double) ulIn;
2349 return S_OK;
2352 /******************************************************************************
2353 * VarR8FromStr32 [OLEAUT32.84]
2355 HRESULT VarR8FromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, double* pdblOut)
2357 double dValue = 0.0;
2358 LPSTR pNewString = NULL;
2360 TRACE( ole, "( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, pdblOut );
2362 /* Check if we have a valid argument
2364 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
2365 RemoveCharacterFromString( pNewString, "," );
2366 if( IsValidRealString( pNewString ) == FALSE )
2368 return DISP_E_TYPEMISMATCH;
2371 /* Convert the valid string to a floating point number.
2373 dValue = atof( pNewString );
2375 /* We don't need the string anymore so free it.
2377 HeapFree( GetProcessHeap(), 0, pNewString );
2379 *pdblOut = dValue;
2381 return S_OK;
2384 /******************************************************************************
2385 * VarDateFromUI132 [OLEAUT32.]
2387 HRESULT VarDateFromUI132(BYTE bIn, DATE* pdateOut)
2389 TRACE( ole, "( %d, %p ), stub\n", bIn, pdateOut );
2391 *pdateOut = (DATE) bIn;
2393 return S_OK;
2396 /******************************************************************************
2397 * VarDateFromI232 [OLEAUT32.222]
2399 HRESULT VarDateFromI232(short sIn, DATE* pdateOut)
2401 TRACE( ole, "( %d, %p ), stub\n", sIn, pdateOut );
2403 *pdateOut = (DATE) sIn;
2405 return S_OK;
2408 /******************************************************************************
2409 * VarDateFromI432 [OLEAUT32.90]
2411 HRESULT VarDateFromI432(LONG lIn, DATE* pdateOut)
2413 TRACE( ole, "( %ld, %p ), stub\n", lIn, pdateOut );
2415 if( lIn < DATE_MIN || lIn > DATE_MAX )
2417 return DISP_E_OVERFLOW;
2420 *pdateOut = (DATE) lIn;
2422 return S_OK;
2425 /******************************************************************************
2426 * VarDateFromR432 [OLEAUT32.91]
2428 HRESULT VarDateFromR432(FLOAT fltIn, DATE* pdateOut)
2430 unsigned long test = 0;
2432 TRACE( ole, "( %f, %p ), stub\n", fltIn, pdateOut );
2434 test = (unsigned long) fltIn;
2435 if( test < DATE_MIN || test > DATE_MAX )
2437 return DISP_E_OVERFLOW;
2440 *pdateOut = (DATE) fltIn;
2442 return S_OK;
2445 /******************************************************************************
2446 * VarDateFromR832 [OLEAUT32.92]
2448 HRESULT VarDateFromR832(double dblIn, DATE* pdateOut)
2450 unsigned long test = 0;
2452 TRACE( ole, "( %f, %p ), stub\n", dblIn, pdateOut );
2454 test = (unsigned long) dblIn;
2455 if( test < DATE_MIN || test > DATE_MAX )
2457 return DISP_E_OVERFLOW;
2460 *pdateOut = (DATE) dblIn;
2462 return S_OK;
2465 /******************************************************************************
2466 * VarDateFromStr32 [OLEAUT32.94]
2467 * The string representing the date is composed of two parts, a date and time.
2469 * The format of the time is has follows:
2470 * hh[:mm][:ss][AM|PM]
2471 * Whitespace can be inserted anywhere between these tokens. A whitespace consists
2472 * of space and/or tab characters, which are ignored.
2474 * The formats for the date part are has follows:
2475 * mm/[dd/][yy]yy
2476 * [dd/]mm/[yy]yy
2477 * [yy]yy/mm/dd
2478 * January dd[,] [yy]yy
2479 * dd January [yy]yy
2480 * [yy]yy January dd
2481 * Whitespace can be inserted anywhere between these tokens.
2483 * The formats for the date and time string are has follows.
2484 * date[whitespace][time]
2485 * [time][whitespace]date
2487 * These are the only characters allowed in a string representing a date and time:
2488 * [A-Z] [a-z] [0-9] ':' '-' '/' ',' ' ' '\t'
2490 HRESULT VarDateFromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, DATE* pdateOut)
2492 HRESULT ret = S_OK;
2494 FIXME( ole, "( %p, %lx, %lx, %p ), stub\n", strIn, lcid, dwFlags, pdateOut );
2496 return ret;
2499 /******************************************************************************
2500 * VarDateFromI132 [OLEAUT32.221]
2502 HRESULT VarDateFromI132(CHAR cIn, DATE* pdateOut)
2504 TRACE( ole, "( %c, %p ), stub\n", cIn, pdateOut );
2506 *pdateOut = (DATE) cIn;
2508 return S_OK;
2511 /******************************************************************************
2512 * VarDateFromUI232 [OLEAUT32.222]
2514 HRESULT VarDateFromUI232(USHORT uiIn, DATE* pdateOut)
2516 TRACE( ole, "( %d, %p ), stub\n", uiIn, pdateOut );
2518 if( uiIn > DATE_MAX )
2520 return DISP_E_OVERFLOW;
2523 *pdateOut = (DATE) uiIn;
2525 return S_OK;
2528 /******************************************************************************
2529 * VarDateFromUI432 [OLEAUT32.223]
2531 HRESULT VarDateFromUI432(ULONG ulIn, DATE* pdateOut)
2533 TRACE( ole, "( %ld, %p ), stub\n", ulIn, pdateOut );
2535 if( ulIn < DATE_MIN || ulIn > DATE_MAX )
2537 return DISP_E_OVERFLOW;
2540 *pdateOut = (DATE) ulIn;
2542 return S_OK;
2545 /******************************************************************************
2546 * VarDateFromBool32 [OLEAUT32.96]
2548 HRESULT VarDateFromBool32(VARIANT_BOOL boolIn, DATE* pdateOut)
2550 TRACE( ole, "( %d, %p ), stub\n", boolIn, pdateOut );
2552 *pdateOut = (DATE) boolIn;
2554 return S_OK;
2558 /******************************************************************************
2559 * VarBstrFromUI132 [OLEAUT32.108]
2561 HRESULT VarBstrFromUI132(BYTE bVal, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
2563 TRACE( ole, "( %d, %ld, %ld, %p ), stub\n", bVal, lcid, dwFlags, pbstrOut );
2564 sprintf( pBuffer, "%d", bVal );
2566 *pbstrOut = StringDupAtoBstr( pBuffer );
2568 return S_OK;
2571 /******************************************************************************
2572 * VarBstrFromI232 [OLEAUT32.109]
2574 HRESULT VarBstrFromI232(short iVal, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
2576 TRACE( ole, "( %d, %ld, %ld, %p ), stub\n", iVal, lcid, dwFlags, pbstrOut );
2577 sprintf( pBuffer, "%d", iVal );
2578 *pbstrOut = StringDupAtoBstr( pBuffer );
2580 return S_OK;
2583 /******************************************************************************
2584 * VarBstrFromI432 [OLEAUT32.110]
2586 HRESULT VarBstrFromI432(LONG lIn, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
2588 TRACE( ole, "( %ld, %ld, %ld, %p ), stub\n", lIn, lcid, dwFlags, pbstrOut );
2590 sprintf( pBuffer, "%ld", lIn );
2591 *pbstrOut = StringDupAtoBstr( pBuffer );
2593 return S_OK;
2596 /******************************************************************************
2597 * VarBstrFromR432 [OLEAUT32.111]
2599 HRESULT VarBstrFromR432(FLOAT fltIn, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
2601 TRACE( ole, "( %f, %ld, %ld, %p ), stub\n", fltIn, lcid, dwFlags, pbstrOut );
2603 sprintf( pBuffer, "%.7g", fltIn );
2604 *pbstrOut = StringDupAtoBstr( pBuffer );
2606 return S_OK;
2609 /******************************************************************************
2610 * VarBstrFromR832 [OLEAUT32.112]
2612 HRESULT VarBstrFromR832(double dblIn, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
2614 TRACE( ole, "( %f, %ld, %ld, %p ), stub\n", dblIn, lcid, dwFlags, pbstrOut );
2616 sprintf( pBuffer, "%.15g", dblIn );
2617 *pbstrOut = StringDupAtoBstr( pBuffer );
2619 return S_OK;
2622 /******************************************************************************
2623 * VarBstrFromDate32 [OLEAUT32.114]
2625 * The date is implemented using an 8 byte floating-point number.
2626 * Days are represented by whole numbers increments starting with 0.00 has
2627 * being December 30 1899, midnight.
2628 * The hours are expressed as the fractional part of the number.
2629 * December 30 1899 at midnight = 0.00
2630 * January 1 1900 at midnight = 2.00
2631 * January 4 1900 at 6 AM = 5.25
2632 * January 4 1900 at noon = 5.50
2633 * December 29 1899 at midnight = -1.00
2634 * December 18 1899 at midnight = -12.00
2635 * December 18 1899 at 6AM = -12.25
2636 * December 18 1899 at 6PM = -12.75
2637 * December 19 1899 at midnight = -11.00
2638 * The tm structure is as follows:
2639 * struct tm {
2640 * int tm_sec; seconds after the minute - [0,59]
2641 * int tm_min; minutes after the hour - [0,59]
2642 * int tm_hour; hours since midnight - [0,23]
2643 * int tm_mday; day of the month - [1,31]
2644 * int tm_mon; months since January - [0,11]
2645 * int tm_year; years since 1900
2646 * int tm_wday; days since Sunday - [0,6]
2647 * int tm_yday; days since January 1 - [0,365]
2648 * int tm_isdst; daylight savings time flag
2649 * };
2651 HRESULT VarBstrFromDate32(DATE dateIn, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
2653 /* If the date is not after the 1900 return an error because
2654 * the tm structure does not allow such dates.
2656 if( dateIn >= 1.0 )
2658 double decimalPart = 0.0;
2659 double wholePart = 0.0;
2660 struct tm TM = {0,0,0,0,0,0,0,0,0};
2662 wholePart = (double) (long) dateIn;
2663 decimalPart = fmod( dateIn, wholePart );
2665 if( !(lcid & VAR_TIMEVALUEONLY) )
2667 int nDay = 0;
2668 int leapYear = 0;
2669 /* find in what year the day in the "wholePart" falls into.
2671 TM.tm_year = (int) ( wholePart / 365.25 );
2672 /* determine if this is a leap year.
2674 if( ( TM.tm_year % 4 ) == 0 )
2675 leapYear = 1;
2676 /* find what day of that year does the "wholePart" corresponds to.
2677 * the day is [1-366]
2679 nDay = (int) ( wholePart - ( TM.tm_year * 365.25 ) );
2680 TM.tm_yday = nDay - 1;
2681 /* find which mount this day corresponds to.
2683 if( nDay <= 31 )
2685 TM.tm_mday = nDay;
2686 TM.tm_mon = 0;
2688 else if( nDay <= ( 59 + leapYear ) )
2690 TM.tm_mday = nDay - 31;
2691 TM.tm_mon = 1;
2693 else if( nDay <= ( 90 + leapYear ) )
2695 TM.tm_mday = nDay - ( 59 + leapYear );
2696 TM.tm_mon = 2;
2698 else if( nDay <= ( 120 + leapYear ) )
2700 TM.tm_mday = nDay - ( 90 + leapYear );
2701 TM.tm_mon = 3;
2703 else if( nDay <= ( 151 + leapYear ) )
2705 TM.tm_mday = nDay - ( 120 + leapYear );
2706 TM.tm_mon = 4;
2708 else if( nDay <= ( 181 + leapYear ) )
2710 TM.tm_mday = nDay - ( 151 + leapYear );
2711 TM.tm_mon = 5;
2713 else if( nDay <= ( 212 + leapYear ) )
2715 TM.tm_mday = nDay - ( 181 + leapYear );
2716 TM.tm_mon = 6;
2718 else if( nDay <= ( 243 + leapYear ) )
2720 TM.tm_mday = nDay - ( 212 + leapYear );
2721 TM.tm_mon = 7;
2723 else if( nDay <= ( 273 + leapYear ) )
2725 TM.tm_mday = nDay - ( 243 + leapYear );
2726 TM.tm_mon = 8;
2728 else if( nDay <= ( 304 + leapYear ) )
2730 TM.tm_mday = nDay - ( 273 + leapYear );
2731 TM.tm_mon = 9;
2733 else if( nDay <= ( 334 + leapYear ) )
2735 TM.tm_mday = nDay - ( 304 + leapYear );
2736 TM.tm_mon = 10;
2738 else if( nDay <= ( 365 + leapYear ) )
2740 TM.tm_mday = nDay - ( 334 + leapYear );
2741 TM.tm_mon = 11;
2744 if( !(lcid & VAR_DATEVALUEONLY) )
2746 /* find the number of seconds in this day.
2747 * fractional part times, hours, minutes, seconds.
2749 TM.tm_hour = (int) ( decimalPart * 24 );
2750 TM.tm_min = (int) ( ( ( decimalPart * 24 ) - TM.tm_hour ) * 60 );
2751 TM.tm_sec = (int) ( ( ( decimalPart * 24 * 60 ) - ( TM.tm_hour * 60 ) - TM.tm_min ) * 60 );
2754 if( lcid & VAR_DATEVALUEONLY )
2755 strftime( pBuffer, BUFFER_MAX, "%x", &TM );
2756 else if( lcid & VAR_TIMEVALUEONLY )
2757 strftime( pBuffer, BUFFER_MAX, "%X", &TM );
2758 else
2759 strftime( pBuffer, 100, "%x %X", &TM );
2761 *pbstrOut = StringDupAtoBstr( pBuffer );
2763 else
2765 FIXME( ole, "( %f, %ld, %ld, %p ), stub\n", dateIn, lcid, dwFlags, pbstrOut );
2766 return E_INVALIDARG;
2769 return S_OK;
2772 /******************************************************************************
2773 * VarBstrFromBool32 [OLEAUT32.116]
2775 HRESULT VarBstrFromBool32(VARIANT_BOOL boolIn, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
2777 TRACE( ole, "( %d, %ld, %ld, %p ), stub\n", boolIn, lcid, dwFlags, pbstrOut );
2779 if( boolIn == VARIANT_FALSE )
2781 sprintf( pBuffer, "False" );
2783 else
2785 sprintf( pBuffer, "True" );
2788 *pbstrOut = StringDupAtoBstr( pBuffer );
2790 return S_OK;
2793 /******************************************************************************
2794 * VarBstrFromI132 [OLEAUT32.229]
2796 HRESULT VarBstrFromI132(CHAR cIn, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
2798 TRACE( ole, "( %c, %ld, %ld, %p ), stub\n", cIn, lcid, dwFlags, pbstrOut );
2799 sprintf( pBuffer, "%d", cIn );
2800 *pbstrOut = StringDupAtoBstr( pBuffer );
2802 return S_OK;
2805 /******************************************************************************
2806 * VarBstrFromUI232 [OLEAUT32.230]
2808 HRESULT VarBstrFromUI232(USHORT uiIn, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
2810 TRACE( ole, "( %d, %ld, %ld, %p ), stub\n", uiIn, lcid, dwFlags, pbstrOut );
2811 sprintf( pBuffer, "%d", uiIn );
2812 *pbstrOut = StringDupAtoBstr( pBuffer );
2814 return S_OK;
2817 /******************************************************************************
2818 * VarBstrFromUI432 [OLEAUT32.231]
2820 HRESULT VarBstrFromUI432(ULONG ulIn, LCID lcid, ULONG dwFlags, BSTR32* pbstrOut)
2822 TRACE( ole, "( %ld, %ld, %ld, %p ), stub\n", ulIn, lcid, dwFlags, pbstrOut );
2823 sprintf( pBuffer, "%ld", ulIn );
2824 *pbstrOut = StringDupAtoBstr( pBuffer );
2826 return S_OK;
2829 /******************************************************************************
2830 * VarBoolFromUI132 [OLEAUT32.118]
2832 HRESULT VarBoolFromUI132(BYTE bIn, VARIANT_BOOL* pboolOut)
2834 TRACE( ole, "( %d, %p ), stub\n", bIn, pboolOut );
2836 if( bIn == 0 )
2838 *pboolOut = VARIANT_FALSE;
2840 else
2842 *pboolOut = VARIANT_TRUE;
2845 return S_OK;
2848 /******************************************************************************
2849 * VarBoolFromI232 [OLEAUT32.119]
2851 HRESULT VarBoolFromI232(short sIn, VARIANT_BOOL* pboolOut)
2853 TRACE( ole, "( %d, %p ), stub\n", sIn, pboolOut );
2855 if( sIn == 0 )
2857 *pboolOut = VARIANT_FALSE;
2859 else
2861 *pboolOut = VARIANT_TRUE;
2864 return S_OK;
2867 /******************************************************************************
2868 * VarBoolFromI432 [OLEAUT32.120]
2870 HRESULT VarBoolFromI432(LONG lIn, VARIANT_BOOL* pboolOut)
2872 TRACE( ole, "( %ld, %p ), stub\n", lIn, pboolOut );
2874 if( lIn == 0 )
2876 *pboolOut = VARIANT_FALSE;
2878 else
2880 *pboolOut = VARIANT_TRUE;
2883 return S_OK;
2886 /******************************************************************************
2887 * VarBoolFromR432 [OLEAUT32.121]
2889 HRESULT VarBoolFromR432(FLOAT fltIn, VARIANT_BOOL* pboolOut)
2891 TRACE( ole, "( %f, %p ), stub\n", fltIn, pboolOut );
2893 if( fltIn == 0.0 )
2895 *pboolOut = VARIANT_FALSE;
2897 else
2899 *pboolOut = VARIANT_TRUE;
2902 return S_OK;
2905 /******************************************************************************
2906 * VarBoolFromR832 [OLEAUT32.122]
2908 HRESULT VarBoolFromR832(double dblIn, VARIANT_BOOL* pboolOut)
2910 TRACE( ole, "( %f, %p ), stub\n", dblIn, pboolOut );
2912 if( dblIn == 0.0 )
2914 *pboolOut = VARIANT_FALSE;
2916 else
2918 *pboolOut = VARIANT_TRUE;
2921 return S_OK;
2924 /******************************************************************************
2925 * VarBoolFromDate32 [OLEAUT32.123]
2927 HRESULT VarBoolFromDate32(DATE dateIn, VARIANT_BOOL* pboolOut)
2929 TRACE( ole, "( %f, %p ), stub\n", dateIn, pboolOut );
2931 if( dateIn == 0.0 )
2933 *pboolOut = VARIANT_FALSE;
2935 else
2937 *pboolOut = VARIANT_TRUE;
2940 return S_OK;
2943 /******************************************************************************
2944 * VarBoolFromStr32 [OLEAUT32.125]
2946 HRESULT VarBoolFromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, VARIANT_BOOL* pboolOut)
2948 HRESULT ret = S_OK;
2949 char* pNewString = NULL;
2951 TRACE( ole, "( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, pboolOut );
2953 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
2955 if( pNewString == NULL || strlen( pNewString ) == 0 )
2957 ret = DISP_E_TYPEMISMATCH;
2960 if( ret == S_OK )
2962 if( strncasecmp( pNewString, "True", strlen( pNewString ) ) == 0 )
2964 *pboolOut = VARIANT_TRUE;
2966 else if( strncasecmp( pNewString, "False", strlen( pNewString ) ) == 0 )
2968 *pboolOut = VARIANT_FALSE;
2970 else
2972 /* Try converting the string to a floating point number.
2974 double dValue = 0.0;
2975 HRESULT res = VarR8FromStr32( strIn, lcid, dwFlags, &dValue );
2976 if( res != S_OK )
2978 ret = DISP_E_TYPEMISMATCH;
2980 else if( dValue == 0.0 )
2982 *pboolOut = VARIANT_FALSE;
2984 else
2986 *pboolOut = VARIANT_TRUE;
2991 HeapFree( GetProcessHeap(), 0, pNewString );
2993 return ret;
2996 /******************************************************************************
2997 * VarBoolFromI132 [OLEAUT32.233]
2999 HRESULT VarBoolFromI132(CHAR cIn, VARIANT_BOOL* pboolOut)
3001 TRACE( ole, "( %c, %p ), stub\n", cIn, pboolOut );
3003 if( cIn == 0 )
3005 *pboolOut = VARIANT_FALSE;
3007 else
3009 *pboolOut = VARIANT_TRUE;
3012 return S_OK;
3015 /******************************************************************************
3016 * VarBoolFromUI232 [OLEAUT32.234]
3018 HRESULT VarBoolFromUI232(USHORT uiIn, VARIANT_BOOL* pboolOut)
3020 TRACE( ole, "( %d, %p ), stub\n", uiIn, pboolOut );
3022 if( uiIn == 0 )
3024 *pboolOut = VARIANT_FALSE;
3026 else
3028 *pboolOut = VARIANT_TRUE;
3031 return S_OK;
3034 /******************************************************************************
3035 * VarBoolFromUI432 [OLEAUT32.235]
3037 HRESULT VarBoolFromUI432(ULONG ulIn, VARIANT_BOOL* pboolOut)
3039 TRACE( ole, "( %ld, %p ), stub\n", ulIn, pboolOut );
3041 if( ulIn == 0 )
3043 *pboolOut = VARIANT_FALSE;
3045 else
3047 *pboolOut = VARIANT_TRUE;
3050 return S_OK;
3053 /******************************************************************************
3054 * VarI1FromUI132 [OLEAUT32.244]
3056 HRESULT VarI1FromUI132(BYTE bIn, CHAR* pcOut)
3058 TRACE( ole, "( %d, %p ), stub\n", bIn, pcOut );
3060 /* Check range of value.
3062 if( bIn > CHAR_MAX )
3064 return DISP_E_OVERFLOW;
3067 *pcOut = (CHAR) bIn;
3069 return S_OK;
3072 /******************************************************************************
3073 * VarI1FromI232 [OLEAUT32.245]
3075 HRESULT VarI1FromI232(short uiIn, CHAR* pcOut)
3077 TRACE( ole, "( %d, %p ), stub\n", uiIn, pcOut );
3079 if( uiIn > CHAR_MAX )
3081 return DISP_E_OVERFLOW;
3084 *pcOut = (CHAR) uiIn;
3086 return S_OK;
3089 /******************************************************************************
3090 * VarI1FromI432 [OLEAUT32.246]
3092 HRESULT VarI1FromI432(LONG lIn, CHAR* pcOut)
3094 TRACE( ole, "( %ld, %p ), stub\n", lIn, pcOut );
3096 if( lIn < CHAR_MIN || lIn > CHAR_MAX )
3098 return DISP_E_OVERFLOW;
3101 *pcOut = (CHAR) lIn;
3103 return S_OK;
3106 /******************************************************************************
3107 * VarI1FromR432 [OLEAUT32.247]
3109 HRESULT VarI1FromR432(FLOAT fltIn, CHAR* pcOut)
3111 TRACE( ole, "( %f, %p ), stub\n", fltIn, pcOut );
3113 fltIn = round( fltIn );
3114 if( fltIn < CHAR_MIN || fltIn > CHAR_MAX )
3116 return DISP_E_OVERFLOW;
3119 *pcOut = (CHAR) fltIn;
3121 return S_OK;
3124 /******************************************************************************
3125 * VarI1FromR832 [OLEAUT32.248]
3127 HRESULT VarI1FromR832(double dblIn, CHAR* pcOut)
3129 TRACE( ole, "( %f, %p ), stub\n", dblIn, pcOut );
3131 dblIn = round( dblIn );
3132 if( dblIn < CHAR_MIN || dblIn > CHAR_MAX )
3134 return DISP_E_OVERFLOW;
3137 *pcOut = (CHAR) dblIn;
3139 return S_OK;
3142 /******************************************************************************
3143 * VarI1FromDate32 [OLEAUT32.249]
3145 HRESULT VarI1FromDate32(DATE dateIn, CHAR* pcOut)
3147 TRACE( ole, "( %f, %p ), stub\n", dateIn, pcOut );
3149 dateIn = round( dateIn );
3150 if( dateIn < CHAR_MIN || dateIn > CHAR_MAX )
3152 return DISP_E_OVERFLOW;
3155 *pcOut = (CHAR) dateIn;
3157 return S_OK;
3160 /******************************************************************************
3161 * VarI1FromStr32 [OLEAUT32.251]
3163 HRESULT VarI1FromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, CHAR* pcOut)
3165 double dValue = 0.0;
3166 LPSTR pNewString = NULL;
3168 TRACE( ole, "( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, pcOut );
3170 /* Check if we have a valid argument
3172 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
3173 RemoveCharacterFromString( pNewString, "," );
3174 if( IsValidRealString( pNewString ) == FALSE )
3176 return DISP_E_TYPEMISMATCH;
3179 /* Convert the valid string to a floating point number.
3181 dValue = atof( pNewString );
3183 /* We don't need the string anymore so free it.
3185 HeapFree( GetProcessHeap(), 0, pNewString );
3187 /* Check range of value.
3189 dValue = round( dValue );
3190 if( dValue < CHAR_MIN || dValue > CHAR_MAX )
3192 return DISP_E_OVERFLOW;
3195 *pcOut = (CHAR) dValue;
3197 return S_OK;
3200 /******************************************************************************
3201 * VarI1FromBool32 [OLEAUT32.253]
3203 HRESULT VarI1FromBool32(VARIANT_BOOL boolIn, CHAR* pcOut)
3205 TRACE( ole, "( %d, %p ), stub\n", boolIn, pcOut );
3207 *pcOut = (CHAR) boolIn;
3209 return S_OK;
3212 /******************************************************************************
3213 * VarI1FromUI232 [OLEAUT32.254]
3215 HRESULT VarI1FromUI232(USHORT uiIn, CHAR* pcOut)
3217 TRACE( ole, "( %d, %p ), stub\n", uiIn, pcOut );
3219 if( uiIn > CHAR_MAX )
3221 return DISP_E_OVERFLOW;
3224 *pcOut = (CHAR) uiIn;
3226 return S_OK;
3229 /******************************************************************************
3230 * VarI1FromUI432 [OLEAUT32.255]
3232 HRESULT VarI1FromUI432(ULONG ulIn, CHAR* pcOut)
3234 TRACE( ole, "( %ld, %p ), stub\n", ulIn, pcOut );
3236 if( ulIn > CHAR_MAX )
3238 return DISP_E_OVERFLOW;
3241 *pcOut = (CHAR) ulIn;
3243 return S_OK;
3246 /******************************************************************************
3247 * VarUI2FromUI132 [OLEAUT32.257]
3249 HRESULT VarUI2FromUI132(BYTE bIn, USHORT* puiOut)
3251 TRACE( ole, "( %d, %p ), stub\n", bIn, puiOut );
3253 *puiOut = (USHORT) bIn;
3255 return S_OK;
3258 /******************************************************************************
3259 * VarUI2FromI232 [OLEAUT32.258]
3261 HRESULT VarUI2FromI232(short uiIn, USHORT* puiOut)
3263 TRACE( ole, "( %d, %p ), stub\n", uiIn, puiOut );
3265 if( uiIn < UI2_MIN )
3267 return DISP_E_OVERFLOW;
3270 *puiOut = (USHORT) uiIn;
3272 return S_OK;
3275 /******************************************************************************
3276 * VarUI2FromI432 [OLEAUT32.259]
3278 HRESULT VarUI2FromI432(LONG lIn, USHORT* puiOut)
3280 TRACE( ole, "( %ld, %p ), stub\n", lIn, puiOut );
3282 if( lIn < UI2_MIN || lIn > UI2_MAX )
3284 return DISP_E_OVERFLOW;
3287 *puiOut = (USHORT) lIn;
3289 return S_OK;
3292 /******************************************************************************
3293 * VarUI2FromR432 [OLEAUT32.260]
3295 HRESULT VarUI2FromR432(FLOAT fltIn, USHORT* puiOut)
3297 TRACE( ole, "( %f, %p ), stub\n", fltIn, puiOut );
3299 fltIn = round( fltIn );
3300 if( fltIn < UI2_MIN || fltIn > UI2_MAX )
3302 return DISP_E_OVERFLOW;
3305 *puiOut = (USHORT) fltIn;
3307 return S_OK;
3310 /******************************************************************************
3311 * VarUI2FromR832 [OLEAUT32.261]
3313 HRESULT VarUI2FromR832(double dblIn, USHORT* puiOut)
3315 TRACE( ole, "( %f, %p ), stub\n", dblIn, puiOut );
3317 dblIn = round( dblIn );
3318 if( dblIn < UI2_MIN || dblIn > UI2_MAX )
3320 return DISP_E_OVERFLOW;
3323 *puiOut = (USHORT) dblIn;
3325 return S_OK;
3328 /******************************************************************************
3329 * VarUI2FromDate32 [OLEAUT32.262]
3331 HRESULT VarUI2FromDate32(DATE dateIn, USHORT* puiOut)
3333 TRACE( ole, "( %f, %p ), stub\n", dateIn, puiOut );
3335 dateIn = round( dateIn );
3336 if( dateIn < UI2_MIN || dateIn > UI2_MAX )
3338 return DISP_E_OVERFLOW;
3341 *puiOut = (USHORT) dateIn;
3343 return S_OK;
3346 /******************************************************************************
3347 * VarUI2FromStr32 [OLEAUT32.264]
3349 HRESULT VarUI2FromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, USHORT* puiOut)
3351 double dValue = 0.0;
3352 LPSTR pNewString = NULL;
3354 TRACE( ole, "( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, puiOut );
3356 /* Check if we have a valid argument
3358 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
3359 RemoveCharacterFromString( pNewString, "," );
3360 if( IsValidRealString( pNewString ) == FALSE )
3362 return DISP_E_TYPEMISMATCH;
3365 /* Convert the valid string to a floating point number.
3367 dValue = atof( pNewString );
3369 /* We don't need the string anymore so free it.
3371 HeapFree( GetProcessHeap(), 0, pNewString );
3373 /* Check range of value.
3375 dValue = round( dValue );
3376 if( dValue < UI2_MIN || dValue > UI2_MAX )
3378 return DISP_E_OVERFLOW;
3381 *puiOut = (USHORT) dValue;
3383 return S_OK;
3386 /******************************************************************************
3387 * VarUI2FromBool32 [OLEAUT32.266]
3389 HRESULT VarUI2FromBool32(VARIANT_BOOL boolIn, USHORT* puiOut)
3391 TRACE( ole, "( %d, %p ), stub\n", boolIn, puiOut );
3393 *puiOut = (USHORT) boolIn;
3395 return S_OK;
3398 /******************************************************************************
3399 * VarUI2FromI132 [OLEAUT32.267]
3401 HRESULT VarUI2FromI132(CHAR cIn, USHORT* puiOut)
3403 TRACE( ole, "( %c, %p ), stub\n", cIn, puiOut );
3405 *puiOut = (USHORT) cIn;
3407 return S_OK;
3410 /******************************************************************************
3411 * VarUI2FromUI432 [OLEAUT32.268]
3413 HRESULT VarUI2FromUI432(ULONG ulIn, USHORT* puiOut)
3415 TRACE( ole, "( %ld, %p ), stub\n", ulIn, puiOut );
3417 if( ulIn < UI2_MIN || ulIn > UI2_MAX )
3419 return DISP_E_OVERFLOW;
3422 *puiOut = (USHORT) ulIn;
3424 return S_OK;
3427 /******************************************************************************
3428 * VarUI4FromStr32 [OLEAUT32.277]
3430 HRESULT VarUI4FromStr32(OLECHAR32* strIn, LCID lcid, ULONG dwFlags, ULONG* pulOut)
3432 double dValue = 0.0;
3433 LPSTR pNewString = NULL;
3435 TRACE( ole, "( %p, %ld, %ld, %p ), stub\n", strIn, lcid, dwFlags, pulOut );
3437 /* Check if we have a valid argument
3439 pNewString = HEAP_strdupWtoA( GetProcessHeap(), 0, strIn );
3440 RemoveCharacterFromString( pNewString, "," );
3441 if( IsValidRealString( pNewString ) == FALSE )
3443 return DISP_E_TYPEMISMATCH;
3446 /* Convert the valid string to a floating point number.
3448 dValue = atof( pNewString );
3450 /* We don't need the string anymore so free it.
3452 HeapFree( GetProcessHeap(), 0, pNewString );
3454 /* Check range of value.
3456 dValue = round( dValue );
3457 if( dValue < UI4_MIN || dValue > UI4_MAX )
3459 return DISP_E_OVERFLOW;
3462 *pulOut = (ULONG) dValue;
3464 return S_OK;
3467 /******************************************************************************
3468 * VarUI4FromUI132 [OLEAUT32.270]
3470 HRESULT VarUI4FromUI132(BYTE bIn, ULONG* pulOut)
3472 TRACE( ole, "( %d, %p ), stub\n", bIn, pulOut );
3474 *pulOut = (USHORT) bIn;
3476 return S_OK;
3479 /******************************************************************************
3480 * VarUI4FromI232 [OLEAUT32.271]
3482 HRESULT VarUI4FromI232(short uiIn, ULONG* pulOut)
3484 TRACE( ole, "( %d, %p ), stub\n", uiIn, pulOut );
3486 if( uiIn < UI4_MIN )
3488 return DISP_E_OVERFLOW;
3491 *pulOut = (ULONG) uiIn;
3493 return S_OK;
3496 /******************************************************************************
3497 * VarUI4FromI432 [OLEAUT32.272]
3499 HRESULT VarUI4FromI432(LONG lIn, ULONG* pulOut)
3501 TRACE( ole, "( %ld, %p ), stub\n", lIn, pulOut );
3503 if( lIn < UI4_MIN )
3505 return DISP_E_OVERFLOW;
3508 *pulOut = (ULONG) lIn;
3510 return S_OK;
3513 /******************************************************************************
3514 * VarUI4FromR432 [OLEAUT32.273]
3516 HRESULT VarUI4FromR432(FLOAT fltIn, ULONG* pulOut)
3518 fltIn = round( fltIn );
3519 if( fltIn < UI4_MIN || fltIn > UI4_MAX )
3521 return DISP_E_OVERFLOW;
3524 *pulOut = (ULONG) fltIn;
3526 return S_OK;
3529 /******************************************************************************
3530 * VarUI4FromR832 [OLEAUT32.274]
3532 HRESULT VarUI4FromR832(double dblIn, ULONG* pulOut)
3534 TRACE( ole, "( %f, %p ), stub\n", dblIn, pulOut );
3536 dblIn = round( dblIn );
3537 if( dblIn < UI4_MIN || dblIn > UI4_MAX )
3539 return DISP_E_OVERFLOW;
3542 *pulOut = (ULONG) dblIn;
3544 return S_OK;
3547 /******************************************************************************
3548 * VarUI4FromDate32 [OLEAUT32.275]
3550 HRESULT VarUI4FromDate32(DATE dateIn, ULONG* pulOut)
3552 TRACE( ole, "( %f, %p ), stub\n", dateIn, pulOut );
3554 dateIn = round( dateIn );
3555 if( dateIn < UI4_MIN || dateIn > UI4_MAX )
3557 return DISP_E_OVERFLOW;
3560 *pulOut = (ULONG) dateIn;
3562 return S_OK;
3565 /******************************************************************************
3566 * VarUI4FromBool32 [OLEAUT32.279]
3568 HRESULT VarUI4FromBool32(VARIANT_BOOL boolIn, ULONG* pulOut)
3570 TRACE( ole, "( %d, %p ), stub\n", boolIn, pulOut );
3572 *pulOut = (ULONG) boolIn;
3574 return S_OK;
3577 /******************************************************************************
3578 * VarUI4FromI132 [OLEAUT32.280]
3580 HRESULT VarUI4FromI132(CHAR cIn, ULONG* pulOut)
3582 TRACE( ole, "( %c, %p ), stub\n", cIn, pulOut );
3584 *pulOut = (ULONG) cIn;
3586 return S_OK;
3589 /******************************************************************************
3590 * VarUI4FromUI232 [OLEAUT32.281]
3592 HRESULT VarUI4FromUI232(USHORT uiIn, ULONG* pulOut)
3594 TRACE( ole, "( %d, %p ), stub\n", uiIn, pulOut );
3596 *pulOut = (ULONG) uiIn;
3598 return S_OK;