4 * Copyright 1998 Jean-Claude Cote
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.
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
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
)
71 switch( parg
->vt
& VT_TYPEMASK
)
86 size
= sizeof(unsigned short);
89 size
= sizeof(unsigned int);
92 size
= sizeof(unsigned long);
98 size
= sizeof(double);
104 size
= sizeof(VARIANT_BOOL
);
107 size
= sizeof(void*);
114 FIXME(ole
,"Add size information for type vt=%d\n", parg
->vt
& VT_TYPEMASK
);
120 /******************************************************************************
121 * StringDupAtoBstr [INTERNAL]
124 static BSTR32
StringDupAtoBstr( char* strIn
)
127 OLECHAR32
* pNewString
= NULL
;
128 pNewString
= HEAP_strdupAtoW( GetProcessHeap(), 0, strIn
);
129 bstr
= SysAllocString32( pNewString
);
130 HeapFree( GetProcessHeap(), 0, pNewString
);
134 /******************************************************************************
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
;
147 /* Save the sign of the number
149 nSign
= d
>= 0.0 ? 1 : -1;
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.
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
);
185 /* the decimals are exactly 1/2 so round according to
186 * the bEvenNumber flag.
190 roundedValue
= floor( d
);
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
217 pNewString
= strdup( str
);
219 strToken
= strtok( pNewString
, strOfCharToRemove
);
220 while( strToken
!= NULL
) {
221 strcat( str
, strToken
);
222 strToken
= strtok( NULL
, strOfCharToRemove
);
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
;
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
) {
276 strToken
= strtok( NULL
, " " );
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' )
307 if( bWhiteSpaceProcessed
||
308 bFirstSignProcessed
||
309 bFirstDigitsProcessed
||
310 bDecimalPointProcessed
||
311 bSecondDigitsProcessed
||
312 bExponentProcessed
||
313 bSecondSignProcessed
||
314 bThirdDigitsProcessed
)
316 bValidRealString
= FALSE
;
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
||
346 bValidRealString
= FALSE
;
348 bFirstSignProcessed
= TRUE
;
349 bWhiteSpaceProcessed
= TRUE
;
350 bFirstDigitsProcessed
= TRUE
;
351 bDecimalPointProcessed
= TRUE
;
352 bSecondDigitsProcessed
= TRUE
;
353 bSecondSignProcessed
= TRUE
;
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.
412 /* If DecimalPoint...
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
;
434 if( bExponentProcessed
||
435 bSecondSignProcessed
||
436 bThirdDigitsProcessed
||
439 bValidRealString
= FALSE
;
441 bFirstSignProcessed
= TRUE
;
442 bWhiteSpaceProcessed
= TRUE
;
443 bFirstDigitsProcessed
= TRUE
;
444 bDecimalPointProcessed
= TRUE
;
445 bSecondDigitsProcessed
= TRUE
;
446 bExponentProcessed
= TRUE
;
449 bValidRealString
= FALSE
;
452 /* Process next character.
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 /******************************************************************************
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
)
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.
490 res
= VariantClear32( pd
);
493 res
= VariantClear32( pd
);
503 res
= VariantCopy32( pd
, ps
);
506 res
= VarI1FromI232( ps
->u
.iVal
, &(pd
->u
.cVal
) );
510 res
= VarI1FromI432( ps
->u
.lVal
, &(pd
->u
.cVal
) );
513 res
= VarI1FromUI132( ps
->u
.bVal
, &(pd
->u
.cVal
) );
516 res
= VarI1FromUI232( ps
->u
.uiVal
, &(pd
->u
.cVal
) );
520 res
= VarI1FromUI432( ps
->u
.ulVal
, &(pd
->u
.cVal
) );
523 res
= VarI1FromR432( ps
->u
.fltVal
, &(pd
->u
.cVal
) );
526 res
= VarI1FromR832( ps
->u
.dblVal
, &(pd
->u
.cVal
) );
529 res
= VarI1FromDate32( ps
->u
.date
, &(pd
->u
.cVal
) );
532 res
= VarI1FromBool32( ps
->u
.boolVal
, &(pd
->u
.cVal
) );
535 res
= VarI1FromStr32( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.cVal
) );
538 /*res = VarI1FromCY32( ps->u.cyVal, &(pd->u.cVal) );*/
540 /*res = VarI1FromDisp32( ps->u.pdispVal, lcid, &(pd->u.cVal) );*/
542 /*res = VarI1From32( ps->u.lVal, &(pd->u.cVal) );*/
544 /*res = VarI1FromDec32( ps->u.decVal, &(pd->u.cVal) );*/
546 res
= DISP_E_TYPEMISMATCH
;
547 FIXME(ole
,"Coercion from %d to %d\n", vtFrom
, vt
);
556 res
= VarI2FromI132( ps
->u
.cVal
, &(pd
->u
.iVal
) );
559 res
= VariantCopy32( pd
, ps
);
563 res
= VarI2FromI432( ps
->u
.lVal
, &(pd
->u
.iVal
) );
566 res
= VarI2FromUI132( ps
->u
.bVal
, &(pd
->u
.iVal
) );
569 res
= VarI2FromUI232( ps
->u
.uiVal
, &(pd
->u
.iVal
) );
573 res
= VarI2FromUI432( ps
->u
.ulVal
, &(pd
->u
.iVal
) );
576 res
= VarI2FromR432( ps
->u
.fltVal
, &(pd
->u
.iVal
) );
579 res
= VarI2FromR832( ps
->u
.dblVal
, &(pd
->u
.iVal
) );
582 res
= VarI2FromDate32( ps
->u
.date
, &(pd
->u
.iVal
) );
585 res
= VarI2FromBool32( ps
->u
.boolVal
, &(pd
->u
.iVal
) );
588 res
= VarI2FromStr32( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.iVal
) );
591 /*res = VarI2FromCY32( ps->u.cyVal, &(pd->u.iVal) );*/
593 /*res = VarI2FromDisp32( ps->u.pdispVal, lcid, &(pd->u.iVal) );*/
595 /*res = VarI2From32( ps->u.lVal, &(pd->u.iVal) );*/
597 /*res = VarI2FromDec32( ps->u.deiVal, &(pd->u.iVal) );*/
599 res
= DISP_E_TYPEMISMATCH
;
600 FIXME(ole
,"Coercion from %d to %d\n", vtFrom
, vt
);
610 res
= VarI4FromI132( ps
->u
.cVal
, &(pd
->u
.lVal
) );
613 res
= VarI4FromI232( ps
->u
.iVal
, &(pd
->u
.lVal
) );
617 res
= VariantCopy32( pd
, ps
);
620 res
= VarI4FromUI132( ps
->u
.bVal
, &(pd
->u
.lVal
) );
623 res
= VarI4FromUI232( ps
->u
.uiVal
, &(pd
->u
.lVal
) );
627 res
= VarI4FromUI432( ps
->u
.ulVal
, &(pd
->u
.lVal
) );
630 res
= VarI4FromR432( ps
->u
.fltVal
, &(pd
->u
.lVal
) );
633 res
= VarI4FromR832( ps
->u
.dblVal
, &(pd
->u
.lVal
) );
636 res
= VarI4FromDate32( ps
->u
.date
, &(pd
->u
.lVal
) );
639 res
= VarI4FromBool32( ps
->u
.boolVal
, &(pd
->u
.lVal
) );
642 res
= VarI4FromStr32( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.lVal
) );
645 /*res = VarI4FromCY32( ps->u.cyVal, &(pd->u.lVal) );*/
647 /*res = VarI4FromDisp32( ps->u.pdispVal, lcid, &(pd->u.lVal) );*/
649 /*res = VarI4From32( ps->u.lVal, &(pd->u.lVal) );*/
651 /*res = VarI4FromDec32( ps->u.deiVal, &(pd->u.lVal) );*/
653 res
= DISP_E_TYPEMISMATCH
;
654 FIXME(ole
,"Coercion from %d to %d\n", vtFrom
, vt
);
663 res
= VarUI1FromI132( ps
->u
.cVal
, &(pd
->u
.bVal
) );
666 res
= VarUI1FromI232( ps
->u
.iVal
, &(pd
->u
.bVal
) );
670 res
= VarUI1FromI432( ps
->u
.lVal
, &(pd
->u
.bVal
) );
673 res
= VariantCopy32( pd
, ps
);
676 res
= VarUI1FromUI232( ps
->u
.uiVal
, &(pd
->u
.bVal
) );
680 res
= VarUI1FromUI432( ps
->u
.ulVal
, &(pd
->u
.bVal
) );
683 res
= VarUI1FromR432( ps
->u
.fltVal
, &(pd
->u
.bVal
) );
686 res
= VarUI1FromR832( ps
->u
.dblVal
, &(pd
->u
.bVal
) );
689 res
= VarUI1FromDate32( ps
->u
.date
, &(pd
->u
.bVal
) );
692 res
= VarUI1FromBool32( ps
->u
.boolVal
, &(pd
->u
.bVal
) );
695 res
= VarUI1FromStr32( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.bVal
) );
698 /*res = VarUI1FromCY32( ps->u.cyVal, &(pd->u.bVal) );*/
700 /*res = VarUI1FromDisp32( ps->u.pdispVal, lcid, &(pd->u.bVal) );*/
702 /*res = VarUI1From32( ps->u.lVal, &(pd->u.bVal) );*/
704 /*res = VarUI1FromDec32( ps->u.deiVal, &(pd->u.bVal) );*/
706 res
= DISP_E_TYPEMISMATCH
;
707 FIXME(ole
,"Coercion from %d to %d\n", vtFrom
, vt
);
716 res
= VarUI2FromI132( ps
->u
.cVal
, &(pd
->u
.uiVal
) );
719 res
= VarUI2FromI232( ps
->u
.iVal
, &(pd
->u
.uiVal
) );
723 res
= VarUI2FromI432( ps
->u
.lVal
, &(pd
->u
.uiVal
) );
726 res
= VarUI2FromUI132( ps
->u
.bVal
, &(pd
->u
.uiVal
) );
729 res
= VariantCopy32( pd
, ps
);
733 res
= VarUI2FromUI432( ps
->u
.ulVal
, &(pd
->u
.uiVal
) );
736 res
= VarUI2FromR432( ps
->u
.fltVal
, &(pd
->u
.uiVal
) );
739 res
= VarUI2FromR832( ps
->u
.dblVal
, &(pd
->u
.uiVal
) );
742 res
= VarUI2FromDate32( ps
->u
.date
, &(pd
->u
.uiVal
) );
745 res
= VarUI2FromBool32( ps
->u
.boolVal
, &(pd
->u
.uiVal
) );
748 res
= VarUI2FromStr32( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.uiVal
) );
751 /*res = VarUI2FromCY32( ps->u.cyVal, &(pd->u.uiVal) );*/
753 /*res = VarUI2FromDisp32( ps->u.pdispVal, lcid, &(pd->u.uiVal) );*/
755 /*res = VarUI2From32( ps->u.lVal, &(pd->u.uiVal) );*/
757 /*res = VarUI2FromDec32( ps->u.deiVal, &(pd->u.uiVal) );*/
759 res
= DISP_E_TYPEMISMATCH
;
760 FIXME(ole
,"Coercion from %d to %d\n", vtFrom
, vt
);
770 res
= VarUI4FromI132( ps
->u
.cVal
, &(pd
->u
.ulVal
) );
773 res
= VarUI4FromI232( ps
->u
.iVal
, &(pd
->u
.ulVal
) );
777 res
= VarUI4FromI432( ps
->u
.lVal
, &(pd
->u
.ulVal
) );
780 res
= VarUI4FromUI132( ps
->u
.bVal
, &(pd
->u
.ulVal
) );
783 res
= VarUI4FromUI232( ps
->u
.uiVal
, &(pd
->u
.ulVal
) );
786 res
= VariantCopy32( pd
, ps
);
789 res
= VarUI4FromR432( ps
->u
.fltVal
, &(pd
->u
.ulVal
) );
792 res
= VarUI4FromR832( ps
->u
.dblVal
, &(pd
->u
.ulVal
) );
795 res
= VarUI4FromDate32( ps
->u
.date
, &(pd
->u
.ulVal
) );
798 res
= VarUI4FromBool32( ps
->u
.boolVal
, &(pd
->u
.ulVal
) );
801 res
= VarUI4FromStr32( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.ulVal
) );
804 /*res = VarUI4FromCY32( ps->u.cyVal, &(pd->u.ulVal) );*/
806 /*res = VarUI4FromDisp32( ps->u.pdispVal, lcid, &(pd->u.ulVal) );*/
808 /*res = VarUI4From32( ps->u.lVal, &(pd->u.ulVal) );*/
810 /*res = VarUI4FromDec32( ps->u.deiVal, &(pd->u.ulVal) );*/
812 res
= DISP_E_TYPEMISMATCH
;
813 FIXME(ole
,"Coercion from %d to %d\n", vtFrom
, vt
);
822 res
= VarR4FromI132( ps
->u
.cVal
, &(pd
->u
.fltVal
) );
825 res
= VarR4FromI232( ps
->u
.iVal
, &(pd
->u
.fltVal
) );
829 res
= VarR4FromI432( ps
->u
.lVal
, &(pd
->u
.fltVal
) );
832 res
= VarR4FromUI132( ps
->u
.bVal
, &(pd
->u
.fltVal
) );
835 res
= VarR4FromUI232( ps
->u
.uiVal
, &(pd
->u
.fltVal
) );
839 res
= VarR4FromUI432( ps
->u
.ulVal
, &(pd
->u
.fltVal
) );
842 res
= VariantCopy32( pd
, ps
);
845 res
= VarR4FromR832( ps
->u
.dblVal
, &(pd
->u
.fltVal
) );
848 res
= VarR4FromDate32( ps
->u
.date
, &(pd
->u
.fltVal
) );
851 res
= VarR4FromBool32( ps
->u
.boolVal
, &(pd
->u
.fltVal
) );
854 res
= VarR4FromStr32( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.fltVal
) );
857 /*res = VarR4FromCY32( ps->u.cyVal, &(pd->u.fltVal) );*/
859 /*res = VarR4FromDisp32( ps->u.pdispVal, lcid, &(pd->u.fltVal) );*/
861 /*res = VarR4From32( ps->u.lVal, &(pd->u.fltVal) );*/
863 /*res = VarR4FromDec32( ps->u.deiVal, &(pd->u.fltVal) );*/
865 res
= DISP_E_TYPEMISMATCH
;
866 FIXME(ole
,"Coercion from %d to %d\n", vtFrom
, vt
);
875 res
= VarR8FromI132( ps
->u
.cVal
, &(pd
->u
.dblVal
) );
878 res
= VarR8FromI232( ps
->u
.iVal
, &(pd
->u
.dblVal
) );
882 res
= VarR8FromI432( ps
->u
.lVal
, &(pd
->u
.dblVal
) );
885 res
= VarR8FromUI132( ps
->u
.bVal
, &(pd
->u
.dblVal
) );
888 res
= VarR8FromUI232( ps
->u
.uiVal
, &(pd
->u
.dblVal
) );
892 res
= VarR8FromUI432( ps
->u
.ulVal
, &(pd
->u
.dblVal
) );
895 res
= VarR8FromR432( ps
->u
.fltVal
, &(pd
->u
.dblVal
) );
898 res
= VariantCopy32( pd
, ps
);
901 res
= VarR8FromDate32( ps
->u
.date
, &(pd
->u
.dblVal
) );
904 res
= VarR8FromBool32( ps
->u
.boolVal
, &(pd
->u
.dblVal
) );
907 res
= VarR8FromStr32( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.dblVal
) );
910 /*res = VarR8FromCY32( ps->u.cyVal, &(pd->u.dblVal) );*/
912 /*res = VarR8FromDisp32( ps->u.pdispVal, lcid, &(pd->u.dblVal) );*/
914 /*res = VarR8From32( ps->u.lVal, &(pd->u.dblVal) );*/
916 /*res = VarR8FromDec32( ps->u.deiVal, &(pd->u.dblVal) );*/
918 res
= DISP_E_TYPEMISMATCH
;
919 FIXME(ole
,"Coercion from %d to %d\n", vtFrom
, vt
);
928 res
= VarDateFromI132( ps
->u
.cVal
, &(pd
->u
.date
) );
931 res
= VarDateFromI232( ps
->u
.iVal
, &(pd
->u
.date
) );
934 res
= VarDateFromInt32( ps
->u
.intVal
, &(pd
->u
.date
) );
937 res
= VarDateFromI432( ps
->u
.lVal
, &(pd
->u
.date
) );
940 res
= VarDateFromUI132( ps
->u
.bVal
, &(pd
->u
.date
) );
943 res
= VarDateFromUI232( ps
->u
.uiVal
, &(pd
->u
.date
) );
946 res
= VarDateFromUint32( ps
->u
.uintVal
, &(pd
->u
.date
) );
949 res
= VarDateFromUI432( ps
->u
.ulVal
, &(pd
->u
.date
) );
952 res
= VarDateFromR432( ps
->u
.fltVal
, &(pd
->u
.date
) );
955 res
= VarDateFromR832( ps
->u
.dblVal
, &(pd
->u
.date
) );
958 res
= VariantCopy32( pd
, ps
);
961 res
= VarDateFromBool32( ps
->u
.boolVal
, &(pd
->u
.date
) );
964 res
= VarDateFromStr32( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.date
) );
967 /*res = VarDateFromCY32( ps->u.cyVal, &(pd->u.date) );*/
969 /*res = VarDateFromDisp32( ps->u.pdispVal, lcid, &(pd->u.date) );*/
971 /*res = VarDateFrom32( ps->u.lVal, &(pd->u.date) );*/
973 /*res = VarDateFromDec32( ps->u.deiVal, &(pd->u.date) );*/
975 res
= DISP_E_TYPEMISMATCH
;
976 FIXME(ole
,"Coercion from %d to %d\n", vtFrom
, vt
);
985 res
= VarBoolFromI132( ps
->u
.cVal
, &(pd
->u
.boolVal
) );
988 res
= VarBoolFromI232( ps
->u
.iVal
, &(pd
->u
.boolVal
) );
991 res
= VarBoolFromInt32( ps
->u
.intVal
, &(pd
->u
.boolVal
) );
994 res
= VarBoolFromI432( ps
->u
.lVal
, &(pd
->u
.boolVal
) );
997 res
= VarBoolFromUI132( ps
->u
.bVal
, &(pd
->u
.boolVal
) );
1000 res
= VarBoolFromUI232( ps
->u
.uiVal
, &(pd
->u
.boolVal
) );
1003 res
= VarBoolFromUint32( ps
->u
.uintVal
, &(pd
->u
.boolVal
) );
1006 res
= VarBoolFromUI432( ps
->u
.ulVal
, &(pd
->u
.boolVal
) );
1009 res
= VarBoolFromR432( ps
->u
.fltVal
, &(pd
->u
.boolVal
) );
1012 res
= VarBoolFromR832( ps
->u
.dblVal
, &(pd
->u
.boolVal
) );
1015 res
= VarBoolFromDate32( ps
->u
.date
, &(pd
->u
.boolVal
) );
1018 res
= VariantCopy32( pd
, ps
);
1021 res
= VarBoolFromStr32( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.boolVal
) );
1024 /*res = VarBoolFromCY32( ps->u.cyVal, &(pd->u.boolVal) );*/
1025 case( VT_DISPATCH
):
1026 /*res = VarBoolFromDisp32( ps->u.pdispVal, lcid, &(pd->u.boolVal) );*/
1028 /*res = VarBoolFrom32( ps->u.lVal, &(pd->u.boolVal) );*/
1030 /*res = VarBoolFromDec32( ps->u.deiVal, &(pd->u.boolVal) );*/
1032 res
= DISP_E_TYPEMISMATCH
;
1033 FIXME(ole
,"Coercion from %d to %d\n", vtFrom
, vt
);
1042 res
= VarBstrFromI132( ps
->u
.cVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1045 res
= VarBstrFromI232( ps
->u
.iVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1048 res
= VarBstrFromInt32( ps
->u
.intVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1051 res
= VarBstrFromI432( ps
->u
.lVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1054 res
= VarBstrFromUI132( ps
->u
.bVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1057 res
= VarBstrFromUI232( ps
->u
.uiVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1060 res
= VarBstrFromUint32( ps
->u
.uintVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1063 res
= VarBstrFromUI432( ps
->u
.ulVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1066 res
= VarBstrFromR432( ps
->u
.fltVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1069 res
= VarBstrFromR832( ps
->u
.dblVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1072 res
= VarBstrFromDate32( ps
->u
.date
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1075 res
= VarBstrFromBool32( ps
->u
.boolVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1078 res
= VariantCopy32( pd
, ps
);
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) );*/
1085 /*res = VarBstrFrom32( ps->u.lVal, lcid, dwFlags, &(pd->u.bstrVal) );*/
1087 /*res = VarBstrFromDec32( ps->u.deiVal, lcid, dwFlags, &(pd->u.bstrVal) );*/
1089 res
= DISP_E_TYPEMISMATCH
;
1090 FIXME(ole
,"Coercion from %d to %d\n", vtFrom
, vt
);
1096 res
= DISP_E_TYPEMISMATCH
;
1097 FIXME(ole
,"Coercion from %d to %d\n", vtFrom
, vt
);
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
;
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
)
1133 /* check if we have a valid argument.
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
)
1150 res
= ValidateVtRange( vt
);
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
)
1166 /* check if we have a valid argument.
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
;
1183 res
= ValidateVtRange( vt
);
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;
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
)
1222 TRACE(ole
,"(%p),stub\n",pvarg
);
1224 res
= ValidateVariantType( pvarg
->vt
);
1227 if( !( pvarg
->vt
& VT_BYREF
) )
1229 switch( pvarg
->vt
& VT_TYPEMASK
)
1232 SysFreeString32( pvarg
->u
.bstrVal
);
1234 case( VT_DISPATCH
):
1240 case( VT_SAFEARRAY
):
1247 /* Set the fields to empty.
1249 pvarg
->wReserved1
= 0;
1250 pvarg
->wReserved2
= 0;
1251 pvarg
->wReserved3
= 0;
1252 pvarg
->vt
= VT_EMPTY
;
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
)
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
1272 if( pvargDest
!= pvargSrc
&& res
== S_OK
)
1274 res
= VariantClear32( pvargDest
);
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
;
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
)
1298 pvargDest
->u
.bstrVal
= SysAllocString32( pvargSrc
->u
.bstrVal
);
1300 case( VT_DISPATCH
):
1306 case( VT_SAFEARRAY
):
1309 pvargDest
->u
= pvargSrc
->u
;
1312 pvargDest
->vt
= pvargSrc
->vt
;
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
)
1330 TRACE(ole
,"(%p, %p),stub\n", pvargDest
, pvargSrc
);
1332 res
= ValidateVariantType( pvargSrc
->vt
);
1336 if( pvargSrc
->vt
& VT_BYREF
)
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
);
1351 res
= VariantClear32( pvargDest
);
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
)
1362 pvargDest
->u
.bstrVal
= SysAllocString32( *(pvargSrc
->u
.pbstrVal
) );
1364 case( VT_DISPATCH
):
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
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.
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
);
1398 case( VT_SAFEARRAY
):
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
1409 memcpy( &pvargDest
->u
, pvargSrc
->u
.byref
, SizeOfVariantData( pvargSrc
) );
1412 pvargDest
->vt
= pvargSrc
->vt
& VT_TYPEMASK
;
1415 /* this should not fail.
1417 VariantClear32( &varg
);
1421 res
= VariantCopy32( pvargDest
, pvargSrc
);
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
)
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.
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
);
1468 /* free up the destination variant.
1470 res
= VariantClear32( pvargDest
);
1475 if( pvargSrc
->vt
& VT_BYREF
)
1477 /* Convert the source variant to a "byvalue" variant.
1480 VariantInit32( &Variant
);
1481 res
= VariantCopyInd32( &Variant
, pvargSrc
);
1484 res
= Coerce( pvargDest
, lcid
, wFlags
, &Variant
, vt
);
1485 /* this should not fail.
1487 VariantClear32( &Variant
);
1493 /* Use the current "byvalue" source variant.
1495 res
= Coerce( pvargDest
, lcid
, wFlags
, pvargSrc
, vt
);
1498 /* this should not fail.
1500 VariantClear32( &varg
);
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
;
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
;
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
;
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
;
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
;
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
;
1619 /******************************************************************************
1620 * VarUI1FromI132 [OLEAUT32.237]
1622 HRESULT
VarUI1FromI132(CHAR cIn
, BYTE
* pbOut
)
1624 TRACE( ole
, "( %c, %p ), stub\n", cIn
, pbOut
);
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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.
1836 return DISP_E_OVERFLOW
;
1839 *psOut
= (short) uiIn
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
);
2384 /******************************************************************************
2385 * VarDateFromUI132 [OLEAUT32.]
2387 HRESULT
VarDateFromUI132(BYTE bIn
, DATE
* pdateOut
)
2389 TRACE( ole
, "( %d, %p ), stub\n", bIn
, pdateOut
);
2391 *pdateOut
= (DATE
) bIn
;
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
;
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
;
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
;
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
;
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:
2478 * January dd[,] [yy]yy
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
)
2494 FIXME( ole
, "( %p, %lx, %lx, %p ), stub\n", strIn
, lcid
, dwFlags
, pdateOut
);
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
;
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
;
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
;
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
;
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
);
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
);
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
);
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
);
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
);
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:
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
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.
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
) )
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 )
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.
2688 else if( nDay
<= ( 59 + leapYear
) )
2690 TM
.tm_mday
= nDay
- 31;
2693 else if( nDay
<= ( 90 + leapYear
) )
2695 TM
.tm_mday
= nDay
- ( 59 + leapYear
);
2698 else if( nDay
<= ( 120 + leapYear
) )
2700 TM
.tm_mday
= nDay
- ( 90 + leapYear
);
2703 else if( nDay
<= ( 151 + leapYear
) )
2705 TM
.tm_mday
= nDay
- ( 120 + leapYear
);
2708 else if( nDay
<= ( 181 + leapYear
) )
2710 TM
.tm_mday
= nDay
- ( 151 + leapYear
);
2713 else if( nDay
<= ( 212 + leapYear
) )
2715 TM
.tm_mday
= nDay
- ( 181 + leapYear
);
2718 else if( nDay
<= ( 243 + leapYear
) )
2720 TM
.tm_mday
= nDay
- ( 212 + leapYear
);
2723 else if( nDay
<= ( 273 + leapYear
) )
2725 TM
.tm_mday
= nDay
- ( 243 + leapYear
);
2728 else if( nDay
<= ( 304 + leapYear
) )
2730 TM
.tm_mday
= nDay
- ( 273 + leapYear
);
2733 else if( nDay
<= ( 334 + leapYear
) )
2735 TM
.tm_mday
= nDay
- ( 304 + leapYear
);
2738 else if( nDay
<= ( 365 + leapYear
) )
2740 TM
.tm_mday
= nDay
- ( 334 + leapYear
);
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
);
2759 strftime( pBuffer
, 100, "%x %X", &TM
);
2761 *pbstrOut
= StringDupAtoBstr( pBuffer
);
2765 FIXME( ole
, "( %f, %ld, %ld, %p ), stub\n", dateIn
, lcid
, dwFlags
, pbstrOut
);
2766 return E_INVALIDARG
;
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" );
2785 sprintf( pBuffer
, "True" );
2788 *pbstrOut
= StringDupAtoBstr( pBuffer
);
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
);
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
);
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
);
2829 /******************************************************************************
2830 * VarBoolFromUI132 [OLEAUT32.118]
2832 HRESULT
VarBoolFromUI132(BYTE bIn
, VARIANT_BOOL
* pboolOut
)
2834 TRACE( ole
, "( %d, %p ), stub\n", bIn
, pboolOut
);
2838 *pboolOut
= VARIANT_FALSE
;
2842 *pboolOut
= VARIANT_TRUE
;
2848 /******************************************************************************
2849 * VarBoolFromI232 [OLEAUT32.119]
2851 HRESULT
VarBoolFromI232(short sIn
, VARIANT_BOOL
* pboolOut
)
2853 TRACE( ole
, "( %d, %p ), stub\n", sIn
, pboolOut
);
2857 *pboolOut
= VARIANT_FALSE
;
2861 *pboolOut
= VARIANT_TRUE
;
2867 /******************************************************************************
2868 * VarBoolFromI432 [OLEAUT32.120]
2870 HRESULT
VarBoolFromI432(LONG lIn
, VARIANT_BOOL
* pboolOut
)
2872 TRACE( ole
, "( %ld, %p ), stub\n", lIn
, pboolOut
);
2876 *pboolOut
= VARIANT_FALSE
;
2880 *pboolOut
= VARIANT_TRUE
;
2886 /******************************************************************************
2887 * VarBoolFromR432 [OLEAUT32.121]
2889 HRESULT
VarBoolFromR432(FLOAT fltIn
, VARIANT_BOOL
* pboolOut
)
2891 TRACE( ole
, "( %f, %p ), stub\n", fltIn
, pboolOut
);
2895 *pboolOut
= VARIANT_FALSE
;
2899 *pboolOut
= VARIANT_TRUE
;
2905 /******************************************************************************
2906 * VarBoolFromR832 [OLEAUT32.122]
2908 HRESULT
VarBoolFromR832(double dblIn
, VARIANT_BOOL
* pboolOut
)
2910 TRACE( ole
, "( %f, %p ), stub\n", dblIn
, pboolOut
);
2914 *pboolOut
= VARIANT_FALSE
;
2918 *pboolOut
= VARIANT_TRUE
;
2924 /******************************************************************************
2925 * VarBoolFromDate32 [OLEAUT32.123]
2927 HRESULT
VarBoolFromDate32(DATE dateIn
, VARIANT_BOOL
* pboolOut
)
2929 TRACE( ole
, "( %f, %p ), stub\n", dateIn
, pboolOut
);
2933 *pboolOut
= VARIANT_FALSE
;
2937 *pboolOut
= VARIANT_TRUE
;
2943 /******************************************************************************
2944 * VarBoolFromStr32 [OLEAUT32.125]
2946 HRESULT
VarBoolFromStr32(OLECHAR32
* strIn
, LCID lcid
, ULONG dwFlags
, VARIANT_BOOL
* pboolOut
)
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
;
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
;
2972 /* Try converting the string to a floating point number.
2974 double dValue
= 0.0;
2975 HRESULT res
= VarR8FromStr32( strIn
, lcid
, dwFlags
, &dValue
);
2978 ret
= DISP_E_TYPEMISMATCH
;
2980 else if( dValue
== 0.0 )
2982 *pboolOut
= VARIANT_FALSE
;
2986 *pboolOut
= VARIANT_TRUE
;
2991 HeapFree( GetProcessHeap(), 0, pNewString
);
2996 /******************************************************************************
2997 * VarBoolFromI132 [OLEAUT32.233]
2999 HRESULT
VarBoolFromI132(CHAR cIn
, VARIANT_BOOL
* pboolOut
)
3001 TRACE( ole
, "( %c, %p ), stub\n", cIn
, pboolOut
);
3005 *pboolOut
= VARIANT_FALSE
;
3009 *pboolOut
= VARIANT_TRUE
;
3015 /******************************************************************************
3016 * VarBoolFromUI232 [OLEAUT32.234]
3018 HRESULT
VarBoolFromUI232(USHORT uiIn
, VARIANT_BOOL
* pboolOut
)
3020 TRACE( ole
, "( %d, %p ), stub\n", uiIn
, pboolOut
);
3024 *pboolOut
= VARIANT_FALSE
;
3028 *pboolOut
= VARIANT_TRUE
;
3034 /******************************************************************************
3035 * VarBoolFromUI432 [OLEAUT32.235]
3037 HRESULT
VarBoolFromUI432(ULONG ulIn
, VARIANT_BOOL
* pboolOut
)
3039 TRACE( ole
, "( %ld, %p ), stub\n", ulIn
, pboolOut
);
3043 *pboolOut
= VARIANT_FALSE
;
3047 *pboolOut
= VARIANT_TRUE
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
3496 /******************************************************************************
3497 * VarUI4FromI432 [OLEAUT32.272]
3499 HRESULT
VarUI4FromI432(LONG lIn
, ULONG
* pulOut
)
3501 TRACE( ole
, "( %ld, %p ), stub\n", lIn
, pulOut
);
3505 return DISP_E_OVERFLOW
;
3508 *pulOut
= (ULONG
) lIn
;
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
;
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
;
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
;
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
;
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
;
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
;