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
35 static const char CHAR_MAX
= 127;
36 static const char CHAR_MIN
= -128;
37 static const BYTE UI1_MAX
= 255;
38 static const BYTE UI1_MIN
= 0;
39 static const unsigned short UI2_MAX
= 65535;
40 static const unsigned short UI2_MIN
= 0;
41 static const short I2_MAX
= 32767;
42 static const short I2_MIN
= -32768;
43 static const unsigned long UI4_MAX
= 4294967295;
44 static const unsigned long UI4_MIN
= 0;
45 static const long I4_MAX
= 2147483647;
46 static const long I4_MIN
= -2147483648;
47 static const DATE DATE_MIN
= -657434;
48 static const DATE DATE_MAX
= 2958465;
51 /* This mask is used to set a flag in wReserved1 of
52 * the VARIANTARG structure. The flag indicates if
53 * the API function is using an inner variant or not.
55 #define PROCESSING_INNER_VARIANT 0x0001
57 /* General use buffer.
59 #define BUFFER_MAX 1024
60 static char pBuffer
[BUFFER_MAX
];
64 /******************************************************************************
65 * SizeOfVariantData [INTERNAL]
67 * This function finds the size of the data referenced by a Variant based
68 * the type "vt" of the Variant.
70 static int SizeOfVariantData( VARIANT
* parg
)
73 switch( parg
->vt
& VT_TYPEMASK
)
88 size
= sizeof(unsigned short);
91 size
= sizeof(unsigned int);
94 size
= sizeof(unsigned long);
100 size
= sizeof(double);
106 size
= sizeof(VARIANT_BOOL
);
109 size
= sizeof(void*);
116 FIXME(ole
,"Add size information for type vt=%d\n", parg
->vt
& VT_TYPEMASK
);
122 /******************************************************************************
123 * StringDupAtoBstr [INTERNAL]
126 static BSTR32
StringDupAtoBstr( char* strIn
)
129 OLECHAR32
* pNewString
= NULL
;
130 pNewString
= HEAP_strdupAtoW( GetProcessHeap(), 0, strIn
);
131 bstr
= SysAllocString32( pNewString
);
132 HeapFree( GetProcessHeap(), 0, pNewString
);
136 /******************************************************************************
139 * Round the double value to the nearest integer value.
141 static double round( double d
)
143 double decimals
= 0.0, integerValue
= 0.0, 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
= floor( 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
= (((short)fmod(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
;
201 /******************************************************************************
202 * RemoveCharacterFromString [INTERNAL]
204 * Removes any of the characters in "strOfCharToRemove" from the "str" argument.
206 static void RemoveCharacterFromString( LPSTR str
, LPSTR strOfCharToRemove
)
208 LPSTR pNewString
= NULL
;
209 LPSTR strToken
= NULL
;
212 /* Check if we have a valid argument
216 pNewString
= strdup( str
);
218 strToken
= strtok( pNewString
, strOfCharToRemove
);
219 while( strToken
!= NULL
) {
220 strcat( str
, strToken
);
221 strToken
= strtok( NULL
, strOfCharToRemove
);
228 /******************************************************************************
229 * GetValidRealString [INTERNAL]
231 * Checks if the string is of proper format to be converted to a real value.
233 static BOOL32
IsValidRealString( LPSTR strRealString
)
235 /* Real values that have a decimal point are required to either have
236 * digits before or after the decimal point. We will assume that
237 * we do not have any digits at either position. If we do encounter
238 * some we will disable this flag.
240 BOOL32 bDigitsRequired
= TRUE
;
241 /* Processed fields in the string representation of the real number.
243 BOOL32 bWhiteSpaceProcessed
= FALSE
;
244 BOOL32 bFirstSignProcessed
= FALSE
;
245 BOOL32 bFirstDigitsProcessed
= FALSE
;
246 BOOL32 bDecimalPointProcessed
= FALSE
;
247 BOOL32 bSecondDigitsProcessed
= FALSE
;
248 BOOL32 bExponentProcessed
= FALSE
;
249 BOOL32 bSecondSignProcessed
= FALSE
;
250 BOOL32 bThirdDigitsProcessed
= FALSE
;
251 /* Assume string parameter "strRealString" is valid and try to disprove it.
253 BOOL32 bValidRealString
= TRUE
;
255 /* Used to count the number of tokens in the "strRealString".
257 LPSTR strToken
= NULL
;
261 /* Check if we have a valid argument
263 if( strRealString
== NULL
)
265 bValidRealString
= FALSE
;
268 if( bValidRealString
== TRUE
)
270 /* Make sure we only have ONE token in the string.
272 strToken
= strtok( strRealString
, " " );
273 while( strToken
!= NULL
) {
275 strToken
= strtok( NULL
, " " );
280 bValidRealString
= FALSE
;
285 /* Make sure this token contains only valid characters.
286 * The string argument to atof has the following form:
287 * [whitespace] [sign] [digits] [.digits] [ {d | D | e | E }[sign]digits]
288 * Whitespace consists of space and|or <TAB> characters, which are ignored.
289 * Sign is either plus '+' or minus '-'.
290 * Digits are one or more decimal digits.
291 * Note: If no digits appear before the decimal point, at least one must
292 * appear after the decimal point.
293 * The decimal digits may be followed by an exponent.
294 * An Exponent consists of an introductory letter ( D, d, E, or e) and
295 * an optionally signed decimal integer.
297 pChar
= strRealString
;
298 while( bValidRealString
== TRUE
&& *pChar
!= '\0' )
306 if( bWhiteSpaceProcessed
||
307 bFirstSignProcessed
||
308 bFirstDigitsProcessed
||
309 bDecimalPointProcessed
||
310 bSecondDigitsProcessed
||
311 bExponentProcessed
||
312 bSecondSignProcessed
||
313 bThirdDigitsProcessed
)
315 bValidRealString
= FALSE
;
322 if( bFirstSignProcessed
== FALSE
)
324 if( bFirstDigitsProcessed
||
325 bDecimalPointProcessed
||
326 bSecondDigitsProcessed
||
327 bExponentProcessed
||
328 bSecondSignProcessed
||
329 bThirdDigitsProcessed
)
331 bValidRealString
= FALSE
;
333 bWhiteSpaceProcessed
= TRUE
;
334 bFirstSignProcessed
= TRUE
;
336 else if( bSecondSignProcessed
== FALSE
)
338 /* Note: The exponent must be present in
339 * order to accept the second sign...
341 if( bExponentProcessed
== FALSE
||
342 bThirdDigitsProcessed
||
345 bValidRealString
= FALSE
;
347 bFirstSignProcessed
= TRUE
;
348 bWhiteSpaceProcessed
= TRUE
;
349 bFirstDigitsProcessed
= TRUE
;
350 bDecimalPointProcessed
= TRUE
;
351 bSecondDigitsProcessed
= TRUE
;
352 bSecondSignProcessed
= TRUE
;
368 if( bFirstDigitsProcessed
== FALSE
)
370 if( bDecimalPointProcessed
||
371 bSecondDigitsProcessed
||
372 bExponentProcessed
||
373 bSecondSignProcessed
||
374 bThirdDigitsProcessed
)
376 bValidRealString
= FALSE
;
378 bFirstSignProcessed
= TRUE
;
379 bWhiteSpaceProcessed
= TRUE
;
380 /* We have found some digits before the decimal point
381 * so disable the "Digits required" flag.
383 bDigitsRequired
= FALSE
;
385 else if( bSecondDigitsProcessed
== FALSE
)
387 if( bExponentProcessed
||
388 bSecondSignProcessed
||
389 bThirdDigitsProcessed
)
391 bValidRealString
= FALSE
;
393 bFirstSignProcessed
= TRUE
;
394 bWhiteSpaceProcessed
= TRUE
;
395 bFirstDigitsProcessed
= TRUE
;
396 bDecimalPointProcessed
= TRUE
;
397 /* We have found some digits after the decimal point
398 * so disable the "Digits required" flag.
400 bDigitsRequired
= FALSE
;
402 else if( bThirdDigitsProcessed
== FALSE
)
404 /* Getting here means everything else should be processed.
405 * If we get anything else than a decimal following this
406 * digit it will be flagged by the other cases, so
407 * we do not really need to do anything in here.
411 /* If DecimalPoint...
414 if( bDecimalPointProcessed
||
415 bSecondDigitsProcessed
||
416 bExponentProcessed
||
417 bSecondSignProcessed
||
418 bThirdDigitsProcessed
)
420 bValidRealString
= FALSE
;
422 bFirstSignProcessed
= TRUE
;
423 bWhiteSpaceProcessed
= TRUE
;
424 bFirstDigitsProcessed
= TRUE
;
425 bDecimalPointProcessed
= TRUE
;
433 if( bExponentProcessed
||
434 bSecondSignProcessed
||
435 bThirdDigitsProcessed
||
438 bValidRealString
= FALSE
;
440 bFirstSignProcessed
= TRUE
;
441 bWhiteSpaceProcessed
= TRUE
;
442 bFirstDigitsProcessed
= TRUE
;
443 bDecimalPointProcessed
= TRUE
;
444 bSecondDigitsProcessed
= TRUE
;
445 bExponentProcessed
= TRUE
;
448 bValidRealString
= FALSE
;
451 /* Process next character.
456 /* If the required digits were not present we have an invalid
457 * string representation of a real number.
459 if( bDigitsRequired
== TRUE
)
461 bValidRealString
= FALSE
;
464 return bValidRealString
;
468 /******************************************************************************
471 * This function dispatches execution to the proper conversion API
472 * to do the necessary coercion.
474 static HRESULT
Coerce( VARIANTARG
* pd
, LCID lcid
, ULONG dwFlags
, VARIANTARG
* ps
, VARTYPE vt
)
477 unsigned short vtFrom
= 0;
478 vtFrom
= ps
->vt
& VT_TYPEMASK
;
480 /* Note: Since "long" and "int" values both have 4 bytes and are both signed integers
481 * "int" will be treated as "long" in the following code.
482 * The same goes for there unsigned versions.
489 res
= VariantClear32( pd
);
492 res
= VariantClear32( pd
);
502 res
= VariantCopy32( pd
, ps
);
505 res
= VarI1FromI232( ps
->u
.iVal
, &(pd
->u
.cVal
) );
509 res
= VarI1FromI432( ps
->u
.lVal
, &(pd
->u
.cVal
) );
512 res
= VarI1FromUI132( ps
->u
.bVal
, &(pd
->u
.cVal
) );
515 res
= VarI1FromUI232( ps
->u
.uiVal
, &(pd
->u
.cVal
) );
519 res
= VarI1FromUI432( ps
->u
.ulVal
, &(pd
->u
.cVal
) );
522 res
= VarI1FromR432( ps
->u
.fltVal
, &(pd
->u
.cVal
) );
525 res
= VarI1FromR832( ps
->u
.dblVal
, &(pd
->u
.cVal
) );
528 res
= VarI1FromDate32( ps
->u
.date
, &(pd
->u
.cVal
) );
531 res
= VarI1FromBool32( ps
->u
.boolVal
, &(pd
->u
.cVal
) );
534 res
= VarI1FromStr32( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.cVal
) );
537 res
= VarI1FromCy32( ps
->u
.cyVal
, &(pd
->u
.cVal
) );
539 /*res = VarI1FromDisp32( ps->u.pdispVal, lcid, &(pd->u.cVal) );*/
541 /*res = VarI1From32( ps->u.lVal, &(pd->u.cVal) );*/
543 /*res = VarI1FromDec32( ps->u.decVal, &(pd->u.cVal) );*/
545 res
= DISP_E_TYPEMISMATCH
;
546 FIXME(ole
,"Coercion from %d to %d\n", vtFrom
, vt
);
555 res
= VarI2FromI132( ps
->u
.cVal
, &(pd
->u
.iVal
) );
558 res
= VariantCopy32( pd
, ps
);
562 res
= VarI2FromI432( ps
->u
.lVal
, &(pd
->u
.iVal
) );
565 res
= VarI2FromUI132( ps
->u
.bVal
, &(pd
->u
.iVal
) );
568 res
= VarI2FromUI232( ps
->u
.uiVal
, &(pd
->u
.iVal
) );
572 res
= VarI2FromUI432( ps
->u
.ulVal
, &(pd
->u
.iVal
) );
575 res
= VarI2FromR432( ps
->u
.fltVal
, &(pd
->u
.iVal
) );
578 res
= VarI2FromR832( ps
->u
.dblVal
, &(pd
->u
.iVal
) );
581 res
= VarI2FromDate32( ps
->u
.date
, &(pd
->u
.iVal
) );
584 res
= VarI2FromBool32( ps
->u
.boolVal
, &(pd
->u
.iVal
) );
587 res
= VarI2FromStr32( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.iVal
) );
590 res
= VarI2FromCy32( ps
->u
.cyVal
, &(pd
->u
.iVal
) );
592 /*res = VarI2FromDisp32( ps->u.pdispVal, lcid, &(pd->u.iVal) );*/
594 /*res = VarI2From32( ps->u.lVal, &(pd->u.iVal) );*/
596 /*res = VarI2FromDec32( ps->u.deiVal, &(pd->u.iVal) );*/
598 res
= DISP_E_TYPEMISMATCH
;
599 FIXME(ole
,"Coercion from %d to %d\n", vtFrom
, vt
);
609 res
= VarI4FromI132( ps
->u
.cVal
, &(pd
->u
.lVal
) );
612 res
= VarI4FromI232( ps
->u
.iVal
, &(pd
->u
.lVal
) );
616 res
= VariantCopy32( pd
, ps
);
619 res
= VarI4FromUI132( ps
->u
.bVal
, &(pd
->u
.lVal
) );
622 res
= VarI4FromUI232( ps
->u
.uiVal
, &(pd
->u
.lVal
) );
626 res
= VarI4FromUI432( ps
->u
.ulVal
, &(pd
->u
.lVal
) );
629 res
= VarI4FromR432( ps
->u
.fltVal
, &(pd
->u
.lVal
) );
632 res
= VarI4FromR832( ps
->u
.dblVal
, &(pd
->u
.lVal
) );
635 res
= VarI4FromDate32( ps
->u
.date
, &(pd
->u
.lVal
) );
638 res
= VarI4FromBool32( ps
->u
.boolVal
, &(pd
->u
.lVal
) );
641 res
= VarI4FromStr32( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.lVal
) );
644 res
= VarI4FromCy32( ps
->u
.cyVal
, &(pd
->u
.lVal
) );
646 /*res = VarI4FromDisp32( ps->u.pdispVal, lcid, &(pd->u.lVal) );*/
648 /*res = VarI4From32( ps->u.lVal, &(pd->u.lVal) );*/
650 /*res = VarI4FromDec32( ps->u.deiVal, &(pd->u.lVal) );*/
652 res
= DISP_E_TYPEMISMATCH
;
653 FIXME(ole
,"Coercion from %d to %d\n", vtFrom
, vt
);
662 res
= VarUI1FromI132( ps
->u
.cVal
, &(pd
->u
.bVal
) );
665 res
= VarUI1FromI232( ps
->u
.iVal
, &(pd
->u
.bVal
) );
669 res
= VarUI1FromI432( ps
->u
.lVal
, &(pd
->u
.bVal
) );
672 res
= VariantCopy32( pd
, ps
);
675 res
= VarUI1FromUI232( ps
->u
.uiVal
, &(pd
->u
.bVal
) );
679 res
= VarUI1FromUI432( ps
->u
.ulVal
, &(pd
->u
.bVal
) );
682 res
= VarUI1FromR432( ps
->u
.fltVal
, &(pd
->u
.bVal
) );
685 res
= VarUI1FromR832( ps
->u
.dblVal
, &(pd
->u
.bVal
) );
688 res
= VarUI1FromDate32( ps
->u
.date
, &(pd
->u
.bVal
) );
691 res
= VarUI1FromBool32( ps
->u
.boolVal
, &(pd
->u
.bVal
) );
694 res
= VarUI1FromStr32( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.bVal
) );
697 res
= VarUI1FromCy32( ps
->u
.cyVal
, &(pd
->u
.bVal
) );
699 /*res = VarUI1FromDisp32( ps->u.pdispVal, lcid, &(pd->u.bVal) );*/
701 /*res = VarUI1From32( ps->u.lVal, &(pd->u.bVal) );*/
703 /*res = VarUI1FromDec32( ps->u.deiVal, &(pd->u.bVal) );*/
705 res
= DISP_E_TYPEMISMATCH
;
706 FIXME(ole
,"Coercion from %d to %d\n", vtFrom
, vt
);
715 res
= VarUI2FromI132( ps
->u
.cVal
, &(pd
->u
.uiVal
) );
718 res
= VarUI2FromI232( ps
->u
.iVal
, &(pd
->u
.uiVal
) );
722 res
= VarUI2FromI432( ps
->u
.lVal
, &(pd
->u
.uiVal
) );
725 res
= VarUI2FromUI132( ps
->u
.bVal
, &(pd
->u
.uiVal
) );
728 res
= VariantCopy32( pd
, ps
);
732 res
= VarUI2FromUI432( ps
->u
.ulVal
, &(pd
->u
.uiVal
) );
735 res
= VarUI2FromR432( ps
->u
.fltVal
, &(pd
->u
.uiVal
) );
738 res
= VarUI2FromR832( ps
->u
.dblVal
, &(pd
->u
.uiVal
) );
741 res
= VarUI2FromDate32( ps
->u
.date
, &(pd
->u
.uiVal
) );
744 res
= VarUI2FromBool32( ps
->u
.boolVal
, &(pd
->u
.uiVal
) );
747 res
= VarUI2FromStr32( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.uiVal
) );
750 res
= VarUI2FromCy32( ps
->u
.cyVal
, &(pd
->u
.uiVal
) );
752 /*res = VarUI2FromDisp32( ps->u.pdispVal, lcid, &(pd->u.uiVal) );*/
754 /*res = VarUI2From32( ps->u.lVal, &(pd->u.uiVal) );*/
756 /*res = VarUI2FromDec32( ps->u.deiVal, &(pd->u.uiVal) );*/
758 res
= DISP_E_TYPEMISMATCH
;
759 FIXME(ole
,"Coercion from %d to %d\n", vtFrom
, vt
);
769 res
= VarUI4FromI132( ps
->u
.cVal
, &(pd
->u
.ulVal
) );
772 res
= VarUI4FromI232( ps
->u
.iVal
, &(pd
->u
.ulVal
) );
776 res
= VarUI4FromI432( ps
->u
.lVal
, &(pd
->u
.ulVal
) );
779 res
= VarUI4FromUI132( ps
->u
.bVal
, &(pd
->u
.ulVal
) );
782 res
= VarUI4FromUI232( ps
->u
.uiVal
, &(pd
->u
.ulVal
) );
785 res
= VariantCopy32( pd
, ps
);
788 res
= VarUI4FromR432( ps
->u
.fltVal
, &(pd
->u
.ulVal
) );
791 res
= VarUI4FromR832( ps
->u
.dblVal
, &(pd
->u
.ulVal
) );
794 res
= VarUI4FromDate32( ps
->u
.date
, &(pd
->u
.ulVal
) );
797 res
= VarUI4FromBool32( ps
->u
.boolVal
, &(pd
->u
.ulVal
) );
800 res
= VarUI4FromStr32( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.ulVal
) );
803 res
= VarUI4FromCy32( ps
->u
.cyVal
, &(pd
->u
.ulVal
) );
805 /*res = VarUI4FromDisp32( ps->u.pdispVal, lcid, &(pd->u.ulVal) );*/
807 /*res = VarUI4From32( ps->u.lVal, &(pd->u.ulVal) );*/
809 /*res = VarUI4FromDec32( ps->u.deiVal, &(pd->u.ulVal) );*/
811 res
= DISP_E_TYPEMISMATCH
;
812 FIXME(ole
,"Coercion from %d to %d\n", vtFrom
, vt
);
821 res
= VarR4FromI132( ps
->u
.cVal
, &(pd
->u
.fltVal
) );
824 res
= VarR4FromI232( ps
->u
.iVal
, &(pd
->u
.fltVal
) );
828 res
= VarR4FromI432( ps
->u
.lVal
, &(pd
->u
.fltVal
) );
831 res
= VarR4FromUI132( ps
->u
.bVal
, &(pd
->u
.fltVal
) );
834 res
= VarR4FromUI232( ps
->u
.uiVal
, &(pd
->u
.fltVal
) );
838 res
= VarR4FromUI432( ps
->u
.ulVal
, &(pd
->u
.fltVal
) );
841 res
= VariantCopy32( pd
, ps
);
844 res
= VarR4FromR832( ps
->u
.dblVal
, &(pd
->u
.fltVal
) );
847 res
= VarR4FromDate32( ps
->u
.date
, &(pd
->u
.fltVal
) );
850 res
= VarR4FromBool32( ps
->u
.boolVal
, &(pd
->u
.fltVal
) );
853 res
= VarR4FromStr32( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.fltVal
) );
856 res
= VarR4FromCy32( ps
->u
.cyVal
, &(pd
->u
.fltVal
) );
858 /*res = VarR4FromDisp32( ps->u.pdispVal, lcid, &(pd->u.fltVal) );*/
860 /*res = VarR4From32( ps->u.lVal, &(pd->u.fltVal) );*/
862 /*res = VarR4FromDec32( ps->u.deiVal, &(pd->u.fltVal) );*/
864 res
= DISP_E_TYPEMISMATCH
;
865 FIXME(ole
,"Coercion from %d to %d\n", vtFrom
, vt
);
874 res
= VarR8FromI132( ps
->u
.cVal
, &(pd
->u
.dblVal
) );
877 res
= VarR8FromI232( ps
->u
.iVal
, &(pd
->u
.dblVal
) );
881 res
= VarR8FromI432( ps
->u
.lVal
, &(pd
->u
.dblVal
) );
884 res
= VarR8FromUI132( ps
->u
.bVal
, &(pd
->u
.dblVal
) );
887 res
= VarR8FromUI232( ps
->u
.uiVal
, &(pd
->u
.dblVal
) );
891 res
= VarR8FromUI432( ps
->u
.ulVal
, &(pd
->u
.dblVal
) );
894 res
= VarR8FromR432( ps
->u
.fltVal
, &(pd
->u
.dblVal
) );
897 res
= VariantCopy32( pd
, ps
);
900 res
= VarR8FromDate32( ps
->u
.date
, &(pd
->u
.dblVal
) );
903 res
= VarR8FromBool32( ps
->u
.boolVal
, &(pd
->u
.dblVal
) );
906 res
= VarR8FromStr32( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.dblVal
) );
909 res
= VarR8FromCy32( ps
->u
.cyVal
, &(pd
->u
.dblVal
) );
911 /*res = VarR8FromDisp32( ps->u.pdispVal, lcid, &(pd->u.dblVal) );*/
913 /*res = VarR8From32( ps->u.lVal, &(pd->u.dblVal) );*/
915 /*res = VarR8FromDec32( ps->u.deiVal, &(pd->u.dblVal) );*/
917 res
= DISP_E_TYPEMISMATCH
;
918 FIXME(ole
,"Coercion from %d to %d\n", vtFrom
, vt
);
927 res
= VarDateFromI132( ps
->u
.cVal
, &(pd
->u
.date
) );
930 res
= VarDateFromI232( ps
->u
.iVal
, &(pd
->u
.date
) );
933 res
= VarDateFromInt32( ps
->u
.intVal
, &(pd
->u
.date
) );
936 res
= VarDateFromI432( ps
->u
.lVal
, &(pd
->u
.date
) );
939 res
= VarDateFromUI132( ps
->u
.bVal
, &(pd
->u
.date
) );
942 res
= VarDateFromUI232( ps
->u
.uiVal
, &(pd
->u
.date
) );
945 res
= VarDateFromUint32( ps
->u
.uintVal
, &(pd
->u
.date
) );
948 res
= VarDateFromUI432( ps
->u
.ulVal
, &(pd
->u
.date
) );
951 res
= VarDateFromR432( ps
->u
.fltVal
, &(pd
->u
.date
) );
954 res
= VarDateFromR832( ps
->u
.dblVal
, &(pd
->u
.date
) );
957 res
= VariantCopy32( pd
, ps
);
960 res
= VarDateFromBool32( ps
->u
.boolVal
, &(pd
->u
.date
) );
963 res
= VarDateFromStr32( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.date
) );
966 res
= VarDateFromCy32( ps
->u
.cyVal
, &(pd
->u
.date
) );
968 /*res = VarDateFromDisp32( ps->u.pdispVal, lcid, &(pd->u.date) );*/
970 /*res = VarDateFrom32( ps->u.lVal, &(pd->u.date) );*/
972 /*res = VarDateFromDec32( ps->u.deiVal, &(pd->u.date) );*/
974 res
= DISP_E_TYPEMISMATCH
;
975 FIXME(ole
,"Coercion from %d to %d\n", vtFrom
, vt
);
984 res
= VarBoolFromI132( ps
->u
.cVal
, &(pd
->u
.boolVal
) );
987 res
= VarBoolFromI232( ps
->u
.iVal
, &(pd
->u
.boolVal
) );
990 res
= VarBoolFromInt32( ps
->u
.intVal
, &(pd
->u
.boolVal
) );
993 res
= VarBoolFromI432( ps
->u
.lVal
, &(pd
->u
.boolVal
) );
996 res
= VarBoolFromUI132( ps
->u
.bVal
, &(pd
->u
.boolVal
) );
999 res
= VarBoolFromUI232( ps
->u
.uiVal
, &(pd
->u
.boolVal
) );
1002 res
= VarBoolFromUint32( ps
->u
.uintVal
, &(pd
->u
.boolVal
) );
1005 res
= VarBoolFromUI432( ps
->u
.ulVal
, &(pd
->u
.boolVal
) );
1008 res
= VarBoolFromR432( ps
->u
.fltVal
, &(pd
->u
.boolVal
) );
1011 res
= VarBoolFromR832( ps
->u
.dblVal
, &(pd
->u
.boolVal
) );
1014 res
= VarBoolFromDate32( ps
->u
.date
, &(pd
->u
.boolVal
) );
1017 res
= VariantCopy32( pd
, ps
);
1020 res
= VarBoolFromStr32( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.boolVal
) );
1023 res
= VarBoolFromCy32( ps
->u
.cyVal
, &(pd
->u
.boolVal
) );
1024 case( VT_DISPATCH
):
1025 /*res = VarBoolFromDisp32( ps->u.pdispVal, lcid, &(pd->u.boolVal) );*/
1027 /*res = VarBoolFrom32( ps->u.lVal, &(pd->u.boolVal) );*/
1029 /*res = VarBoolFromDec32( ps->u.deiVal, &(pd->u.boolVal) );*/
1031 res
= DISP_E_TYPEMISMATCH
;
1032 FIXME(ole
,"Coercion from %d to %d\n", vtFrom
, vt
);
1041 res
= VarBstrFromI132( ps
->u
.cVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1044 res
= VarBstrFromI232( ps
->u
.iVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1047 res
= VarBstrFromInt32( ps
->u
.intVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1050 res
= VarBstrFromI432( ps
->u
.lVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1053 res
= VarBstrFromUI132( ps
->u
.bVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1056 res
= VarBstrFromUI232( ps
->u
.uiVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1059 res
= VarBstrFromUint32( ps
->u
.uintVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1062 res
= VarBstrFromUI432( ps
->u
.ulVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1065 res
= VarBstrFromR432( ps
->u
.fltVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1068 res
= VarBstrFromR832( ps
->u
.dblVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1071 res
= VarBstrFromDate32( ps
->u
.date
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1074 res
= VarBstrFromBool32( ps
->u
.boolVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1077 res
= VariantCopy32( pd
, ps
);
1080 /*res = VarBstrFromCy32( ps->u.cyVal, lcid, dwFlags, &(pd->u.bstrVal) );*/
1081 case( VT_DISPATCH
):
1082 /*res = VarBstrFromDisp32( ps->u.pdispVal, lcid, lcid, dwFlags, &(pd->u.bstrVal) );*/
1084 /*res = VarBstrFrom32( ps->u.lVal, lcid, dwFlags, &(pd->u.bstrVal) );*/
1086 /*res = VarBstrFromDec32( ps->u.deiVal, lcid, dwFlags, &(pd->u.bstrVal) );*/
1088 res
= DISP_E_TYPEMISMATCH
;
1089 FIXME(ole
,"Coercion from %d to %d\n", vtFrom
, vt
);
1098 res
= VarCyFromI132( ps
->u
.cVal
, &(pd
->u
.cyVal
) );
1101 res
= VarCyFromI232( ps
->u
.iVal
, &(pd
->u
.cyVal
) );
1104 res
= VarCyFromInt32( ps
->u
.intVal
, &(pd
->u
.cyVal
) );
1107 res
= VarCyFromI432( ps
->u
.lVal
, &(pd
->u
.cyVal
) );
1110 res
= VarCyFromUI132( ps
->u
.bVal
, &(pd
->u
.cyVal
) );
1113 res
= VarCyFromUI232( ps
->u
.uiVal
, &(pd
->u
.cyVal
) );
1116 res
= VarCyFromUint32( ps
->u
.uintVal
, &(pd
->u
.cyVal
) );
1119 res
= VarCyFromUI432( ps
->u
.ulVal
, &(pd
->u
.cyVal
) );
1122 res
= VarCyFromR432( ps
->u
.fltVal
, &(pd
->u
.cyVal
) );
1125 res
= VarCyFromR832( ps
->u
.dblVal
, &(pd
->u
.cyVal
) );
1128 res
= VarCyFromDate32( ps
->u
.date
, &(pd
->u
.cyVal
) );
1131 res
= VarCyFromBool32( ps
->u
.date
, &(pd
->u
.cyVal
) );
1134 res
= VariantCopy32( pd
, ps
);
1137 /*res = VarCyFromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.cyVal) );*/
1138 case( VT_DISPATCH
):
1139 /*res = VarCyFromDisp32( ps->u.pdispVal, lcid, &(pd->u.boolVal) );*/
1141 /*res = VarCyFrom32( ps->u.lVal, &(pd->u.boolVal) );*/
1143 /*res = VarCyFromDec32( ps->u.deiVal, &(pd->u.boolVal) );*/
1145 res
= DISP_E_TYPEMISMATCH
;
1146 FIXME(ole
,"Coercion from %d to %d\n", vtFrom
, vt
);
1152 res
= DISP_E_TYPEMISMATCH
;
1153 FIXME(ole
,"Coercion from %d to %d\n", vtFrom
, vt
);
1160 /******************************************************************************
1161 * ValidateVtRange [INTERNAL]
1163 * Used internally by the hi-level Variant API to determine
1164 * if the vartypes are valid.
1166 static HRESULT WINAPI
ValidateVtRange( VARTYPE vt
)
1168 /* if by value we must make sure it is in the
1169 * range of the valid types.
1171 if( ( vt
& VT_TYPEMASK
) > VT_MAXVALIDTYPE
)
1173 return DISP_E_BADVARTYPE
;
1179 /******************************************************************************
1180 * ValidateVartype [INTERNAL]
1182 * Used internally by the hi-level Variant API to determine
1183 * if the vartypes are valid.
1185 static HRESULT WINAPI
ValidateVariantType( VARTYPE vt
)
1189 /* check if we have a valid argument.
1193 /* if by reference check that the type is in
1194 * the valid range and that it is not of empty or null type
1196 if( ( vt
& VT_TYPEMASK
) == VT_EMPTY
||
1197 ( vt
& VT_TYPEMASK
) == VT_NULL
||
1198 ( vt
& VT_TYPEMASK
) > VT_MAXVALIDTYPE
)
1206 res
= ValidateVtRange( vt
);
1212 /******************************************************************************
1213 * ValidateVt [INTERNAL]
1215 * Used internally by the hi-level Variant API to determine
1216 * if the vartypes are valid.
1218 static HRESULT WINAPI
ValidateVt( VARTYPE vt
)
1222 /* check if we have a valid argument.
1226 /* if by reference check that the type is in
1227 * the valid range and that it is not of empty or null type
1229 if( ( vt
& VT_TYPEMASK
) == VT_EMPTY
||
1230 ( vt
& VT_TYPEMASK
) == VT_NULL
||
1231 ( vt
& VT_TYPEMASK
) > VT_MAXVALIDTYPE
)
1233 res
= DISP_E_BADVARTYPE
;
1239 res
= ValidateVtRange( vt
);
1249 /******************************************************************************
1250 * VariantInit32 [OLEAUT32.8]
1252 * Initializes the Variant. Unlike VariantClear it does not interpret the current
1253 * contents of the Variant.
1255 void WINAPI
VariantInit32(VARIANTARG
* pvarg
)
1257 TRACE(ole
,"(%p),stub\n",pvarg
);
1259 pvarg
->vt
= VT_EMPTY
;
1260 pvarg
->wReserved1
= 0;
1261 pvarg
->wReserved2
= 0;
1262 pvarg
->wReserved3
= 0;
1267 /******************************************************************************
1268 * VariantClear32 [OLEAUT32.9]
1270 * This function clears the VARIANT by setting the vt field to VT_EMPTY. It also
1271 * sets the wReservedX field to 0. The current contents of the VARIANT are
1272 * freed. If the vt is VT_BSTR the string is freed. If VT_DISPATCH the object is
1273 * released. If VT_ARRAY the array is freed.
1275 HRESULT WINAPI
VariantClear32(VARIANTARG
* pvarg
)
1278 TRACE(ole
,"(%p),stub\n",pvarg
);
1280 res
= ValidateVariantType( pvarg
->vt
);
1283 if( !( pvarg
->vt
& VT_BYREF
) )
1285 switch( pvarg
->vt
& VT_TYPEMASK
)
1288 SysFreeString32( pvarg
->u
.bstrVal
);
1290 case( VT_DISPATCH
):
1296 case( VT_SAFEARRAY
):
1303 /* Set the fields to empty.
1305 pvarg
->wReserved1
= 0;
1306 pvarg
->wReserved2
= 0;
1307 pvarg
->wReserved3
= 0;
1308 pvarg
->vt
= VT_EMPTY
;
1314 /******************************************************************************
1315 * VariantCopy32 [OLEAUT32.10]
1317 * Frees up the designation variant and makes a copy of the source.
1319 HRESULT WINAPI
VariantCopy32(VARIANTARG
* pvargDest
, VARIANTARG
* pvargSrc
)
1322 TRACE(ole
,"(%p, %p),stub\n", pvargDest
, pvargSrc
);
1324 res
= ValidateVariantType( pvargSrc
->vt
);
1325 /* If the pointer are to the same variant we don't need
1328 if( pvargDest
!= pvargSrc
&& res
== S_OK
)
1330 res
= VariantClear32( pvargDest
);
1334 if( pvargSrc
->vt
& VT_BYREF
)
1336 /* In the case of byreference we only need
1337 * to copy the pointer.
1339 pvargDest
->u
= pvargSrc
->u
;
1340 pvargDest
->vt
= pvargSrc
->vt
;
1344 /* In the case of by value we need to
1345 * copy the actuall value. In the case of
1346 * VT_BSTR a copy of the string is made,
1347 * if VT_ARRAY the entire array is copied
1348 * if VT_DISPATCH or VT_IUNKNOWN AddReff is
1349 * called to increment the object's reference count.
1351 switch( pvargSrc
->vt
& VT_TYPEMASK
)
1354 pvargDest
->u
.bstrVal
= SysAllocString32( pvargSrc
->u
.bstrVal
);
1356 case( VT_DISPATCH
):
1362 case( VT_SAFEARRAY
):
1365 pvargDest
->u
= pvargSrc
->u
;
1368 pvargDest
->vt
= pvargSrc
->vt
;
1377 /******************************************************************************
1378 * VariantCopyInd32 [OLEAUT32.11]
1380 * Frees up the destination variant and makes a copy of the source. If
1381 * the source is of type VT_BYREF it performs the necessary indirections.
1383 HRESULT WINAPI
VariantCopyInd32(VARIANT
* pvargDest
, VARIANTARG
* pvargSrc
)
1386 TRACE(ole
,"(%p, %p),stub\n", pvargDest
, pvargSrc
);
1388 res
= ValidateVariantType( pvargSrc
->vt
);
1392 if( pvargSrc
->vt
& VT_BYREF
)
1395 VariantInit32( &varg
);
1396 /* handle the in place copy.
1398 if( pvargDest
== pvargSrc
)
1400 /* we will use a copy of the source instead.
1402 res
= VariantCopy32( &varg
, pvargSrc
);
1407 res
= VariantClear32( pvargDest
);
1410 /* In the case of by reference we need
1411 * to copy the date pointed to by the variant.
1413 /* Get the variant type.
1415 switch( pvargSrc
->vt
& VT_TYPEMASK
)
1418 pvargDest
->u
.bstrVal
= SysAllocString32( *(pvargSrc
->u
.pbstrVal
) );
1420 case( VT_DISPATCH
):
1424 /* Prevent from cycling. According to tests on
1425 * VariantCopyInd in Windows and the documentation
1426 * this API dereferences the inner Variants to only one depth.
1427 * If the inner Variant itself contains an
1428 * other inner variant the E_INVALIDARG error is
1431 if( pvargSrc
->wReserved1
& PROCESSING_INNER_VARIANT
)
1433 /* If we get here we are attempting to deference
1434 * an inner variant that that is itself contained
1435 * in an inner variant so report E_INVALIDARG error.
1441 /* Set the processing inner variant flag.
1442 * We will set this flag in the inner variant
1443 * that will be passed to the VariantCopyInd function.
1445 (pvargSrc
->u
.pvarVal
)->wReserved1
|= PROCESSING_INNER_VARIANT
;
1446 /* Dereference the inner variant.
1448 res
= VariantCopyInd32( pvargDest
, pvargSrc
->u
.pvarVal
);
1454 case( VT_SAFEARRAY
):
1457 /* This is a by reference Variant which means that the union
1458 * part of the Variant contains a pointer to some data of
1459 * type "pvargSrc->vt & VT_TYPEMASK".
1460 * We will deference this data in a generic fashion using
1461 * the void pointer "Variant.u.byref".
1462 * We will copy this data into the union of the destination
1465 memcpy( &pvargDest
->u
, pvargSrc
->u
.byref
, SizeOfVariantData( pvargSrc
) );
1468 pvargDest
->vt
= pvargSrc
->vt
& VT_TYPEMASK
;
1471 /* this should not fail.
1473 VariantClear32( &varg
);
1477 res
= VariantCopy32( pvargDest
, pvargSrc
);
1482 /******************************************************************************
1483 * VariantChangeType32 [OLEAUT32.12]
1485 HRESULT WINAPI
VariantChangeType32(VARIANTARG
* pvargDest
, VARIANTARG
* pvargSrc
,
1486 USHORT wFlags
, VARTYPE vt
)
1488 return VariantChangeTypeEx32( pvargDest
, pvargSrc
, 0, wFlags
, vt
);
1491 /******************************************************************************
1492 * VariantChangeTypeEx32 [OLEAUT32.147]
1494 HRESULT WINAPI
VariantChangeTypeEx32(VARIANTARG
* pvargDest
, VARIANTARG
* pvargSrc
,
1495 LCID lcid
, USHORT wFlags
, VARTYPE vt
)
1499 VariantInit32( &varg
);
1501 TRACE(ole
,"(%p, %p, %ld, %u, %u),stub\n", pvargDest
, pvargSrc
, lcid
, wFlags
, vt
);
1503 /* validate our source argument.
1505 res
= ValidateVariantType( pvargSrc
->vt
);
1507 /* validate the vartype.
1511 res
= ValidateVt( vt
);
1514 /* if we are doing an in-place conversion make a copy of the source.
1516 if( res
== S_OK
&& pvargDest
== pvargSrc
)
1518 res
= VariantCopy32( &varg
, pvargSrc
);
1524 /* free up the destination variant.
1526 res
= VariantClear32( pvargDest
);
1531 if( pvargSrc
->vt
& VT_BYREF
)
1533 /* Convert the source variant to a "byvalue" variant.
1536 VariantInit32( &Variant
);
1537 res
= VariantCopyInd32( &Variant
, pvargSrc
);
1540 res
= Coerce( pvargDest
, lcid
, wFlags
, &Variant
, vt
);
1541 /* this should not fail.
1543 VariantClear32( &Variant
);
1549 /* Use the current "byvalue" source variant.
1551 res
= Coerce( pvargDest
, lcid
, wFlags
, pvargSrc
, vt
);
1554 /* this should not fail.
1556 VariantClear32( &varg
);
1564 /******************************************************************************
1565 * VarUI1FromI232 [OLEAUT32.130]
1567 HRESULT WINAPI
VarUI1FromI232(short sIn
, BYTE
* pbOut
)
1569 TRACE( ole
, "( %d, %p ), stub\n", sIn
, pbOut
);
1571 /* Check range of value.
1573 if( sIn
< UI1_MIN
|| sIn
> UI1_MAX
)
1575 return DISP_E_OVERFLOW
;
1578 *pbOut
= (BYTE
) sIn
;
1583 /******************************************************************************
1584 * VarUI1FromI432 [OLEAUT32.131]
1586 HRESULT WINAPI
VarUI1FromI432(LONG lIn
, BYTE
* pbOut
)
1588 TRACE( ole
, "( %ld, %p ), stub\n", lIn
, pbOut
);
1590 /* Check range of value.
1592 if( lIn
< UI1_MIN
|| lIn
> UI1_MAX
)
1594 return DISP_E_OVERFLOW
;
1597 *pbOut
= (BYTE
) lIn
;
1603 /******************************************************************************
1604 * VarUI1FromR432 [OLEAUT32.132]
1606 HRESULT WINAPI
VarUI1FromR432(FLOAT fltIn
, BYTE
* pbOut
)
1608 TRACE( ole
, "( %f, %p ), stub\n", fltIn
, pbOut
);
1610 /* Check range of value.
1612 fltIn
= round( fltIn
);
1613 if( fltIn
< UI1_MIN
|| fltIn
> UI1_MAX
)
1615 return DISP_E_OVERFLOW
;
1618 *pbOut
= (BYTE
) fltIn
;
1623 /******************************************************************************
1624 * VarUI1FromR832 [OLEAUT32.133]
1626 HRESULT WINAPI
VarUI1FromR832(double dblIn
, BYTE
* pbOut
)
1628 TRACE( ole
, "( %f, %p ), stub\n", dblIn
, pbOut
);
1630 /* Check range of value.
1632 dblIn
= round( dblIn
);
1633 if( dblIn
< UI1_MIN
|| dblIn
> UI1_MAX
)
1635 return DISP_E_OVERFLOW
;
1638 *pbOut
= (BYTE
) dblIn
;
1643 /******************************************************************************
1644 * VarUI1FromDate32 [OLEAUT32.135]
1646 HRESULT WINAPI
VarUI1FromDate32(DATE dateIn
, BYTE
* pbOut
)
1648 TRACE( ole
, "( %f, %p ), stub\n", dateIn
, pbOut
);
1650 /* Check range of value.
1652 dateIn
= round( dateIn
);
1653 if( dateIn
< UI1_MIN
|| dateIn
> UI1_MAX
)
1655 return DISP_E_OVERFLOW
;
1658 *pbOut
= (BYTE
) dateIn
;
1663 /******************************************************************************
1664 * VarUI1FromBool32 [OLEAUT32.138]
1666 HRESULT WINAPI
VarUI1FromBool32(VARIANT_BOOL boolIn
, BYTE
* pbOut
)
1668 TRACE( ole
, "( %d, %p ), stub\n", boolIn
, pbOut
);
1670 *pbOut
= (BYTE
) boolIn
;
1675 /******************************************************************************
1676 * VarUI1FromI132 [OLEAUT32.237]
1678 HRESULT WINAPI
VarUI1FromI132(CHAR cIn
, BYTE
* pbOut
)
1680 TRACE( ole
, "( %c, %p ), stub\n", cIn
, pbOut
);
1687 /******************************************************************************
1688 * VarUI1FromUI232 [OLEAUT32.238]
1690 HRESULT WINAPI
VarUI1FromUI232(USHORT uiIn
, BYTE
* pbOut
)
1692 TRACE( ole
, "( %d, %p ), stub\n", uiIn
, pbOut
);
1694 /* Check range of value.
1696 if( uiIn
> UI1_MAX
)
1698 return DISP_E_OVERFLOW
;
1701 *pbOut
= (BYTE
) uiIn
;
1706 /******************************************************************************
1707 * VarUI1FromUI432 [OLEAUT32.239]
1709 HRESULT WINAPI
VarUI1FromUI432(ULONG ulIn
, BYTE
* pbOut
)
1711 TRACE( ole
, "( %ld, %p ), stub\n", ulIn
, pbOut
);
1713 /* Check range of value.
1715 if( ulIn
> UI1_MAX
)
1717 return DISP_E_OVERFLOW
;
1720 *pbOut
= (BYTE
) ulIn
;
1726 /******************************************************************************
1727 * VarUI1FromStr32 [OLEAUT32.54]
1729 HRESULT WINAPI
VarUI1FromStr32(OLECHAR32
* strIn
, LCID lcid
, ULONG dwFlags
, BYTE
* pbOut
)
1731 double dValue
= 0.0;
1732 LPSTR pNewString
= NULL
;
1734 TRACE( ole
, "( %p, 0x%08lx, 0x%08lx, %p ), stub\n", strIn
, lcid
, dwFlags
, pbOut
);
1736 /* Check if we have a valid argument
1738 pNewString
= HEAP_strdupWtoA( GetProcessHeap(), 0, strIn
);
1739 RemoveCharacterFromString( pNewString
, "," );
1740 if( IsValidRealString( pNewString
) == FALSE
)
1742 return DISP_E_TYPEMISMATCH
;
1745 /* Convert the valid string to a floating point number.
1747 dValue
= atof( pNewString
);
1749 /* We don't need the string anymore so free it.
1751 HeapFree( GetProcessHeap(), 0 , pNewString
);
1753 /* Check range of value.
1755 dValue
= round( dValue
);
1756 if( dValue
< UI1_MIN
|| dValue
> UI1_MAX
)
1758 return DISP_E_OVERFLOW
;
1761 *pbOut
= (BYTE
) dValue
;
1766 /**********************************************************************
1767 * VarUI1FromCy32 [OLEAUT32.134]
1768 * Convert currency to unsigned char
1770 HRESULT WINAPI
VarUI1FromCy32(CY cyIn
, BYTE
* pbOut
) {
1771 double t
= round((((double)cyIn
.u
.Hi
* 4294967296) + (double)cyIn
.u
.Lo
) / 10000);
1773 if (t
> UI1_MAX
|| t
< UI1_MIN
) return DISP_E_OVERFLOW
;
1779 /******************************************************************************
1780 * VarI2FromUI132 [OLEAUT32.48]
1782 HRESULT WINAPI
VarI2FromUI132(BYTE bIn
, short* psOut
)
1784 TRACE( ole
, "( 0x%08x, %p ), stub\n", bIn
, psOut
);
1786 *psOut
= (short) bIn
;
1791 /******************************************************************************
1792 * VarI2FromI432 [OLEAUT32.49]
1794 HRESULT WINAPI
VarI2FromI432(LONG lIn
, short* psOut
)
1796 TRACE( ole
, "( %lx, %p ), stub\n", lIn
, psOut
);
1798 /* Check range of value.
1800 if( lIn
< I2_MIN
|| lIn
> I2_MAX
)
1802 return DISP_E_OVERFLOW
;
1805 *psOut
= (short) lIn
;
1810 /******************************************************************************
1811 * VarI2FromR432 [OLEAUT32.50]
1813 HRESULT WINAPI
VarI2FromR432(FLOAT fltIn
, short* psOut
)
1815 TRACE( ole
, "( %f, %p ), stub\n", fltIn
, psOut
);
1817 /* Check range of value.
1819 fltIn
= round( fltIn
);
1820 if( fltIn
< I2_MIN
|| fltIn
> I2_MAX
)
1822 return DISP_E_OVERFLOW
;
1825 *psOut
= (short) fltIn
;
1830 /******************************************************************************
1831 * VarI2FromR832 [OLEAUT32.51]
1833 HRESULT WINAPI
VarI2FromR832(double dblIn
, short* psOut
)
1835 TRACE( ole
, "( %f, %p ), stub\n", dblIn
, psOut
);
1837 /* Check range of value.
1839 dblIn
= round( dblIn
);
1840 if( dblIn
< I2_MIN
|| dblIn
> I2_MAX
)
1842 return DISP_E_OVERFLOW
;
1845 *psOut
= (short) dblIn
;
1850 /******************************************************************************
1851 * VarI2FromDate32 [OLEAUT32.53]
1853 HRESULT WINAPI
VarI2FromDate32(DATE dateIn
, short* psOut
)
1855 TRACE( ole
, "( %f, %p ), stub\n", dateIn
, psOut
);
1857 /* Check range of value.
1859 dateIn
= round( dateIn
);
1860 if( dateIn
< I2_MIN
|| dateIn
> I2_MAX
)
1862 return DISP_E_OVERFLOW
;
1865 *psOut
= (short) dateIn
;
1870 /******************************************************************************
1871 * VarI2FromBool32 [OLEAUT32.56]
1873 HRESULT WINAPI
VarI2FromBool32(VARIANT_BOOL boolIn
, short* psOut
)
1875 TRACE( ole
, "( %d, %p ), stub\n", boolIn
, psOut
);
1877 *psOut
= (short) boolIn
;
1882 /******************************************************************************
1883 * VarI2FromI132 [OLEAUT32.48]
1885 HRESULT WINAPI
VarI2FromI132(CHAR cIn
, short* psOut
)
1887 TRACE( ole
, "( %c, %p ), stub\n", cIn
, psOut
);
1889 *psOut
= (short) cIn
;
1894 /******************************************************************************
1895 * VarI2FromUI232 [OLEAUT32.206]
1897 HRESULT WINAPI
VarI2FromUI232(USHORT uiIn
, short* psOut
)
1899 TRACE( ole
, "( %d, %p ), stub\n", uiIn
, psOut
);
1901 /* Check range of value.
1905 return DISP_E_OVERFLOW
;
1908 *psOut
= (short) uiIn
;
1913 /******************************************************************************
1914 * VarI2FromUI432 [OLEAUT32.49]
1916 HRESULT WINAPI
VarI2FromUI432(ULONG ulIn
, short* psOut
)
1918 TRACE( ole
, "( %lx, %p ), stub\n", ulIn
, psOut
);
1920 /* Check range of value.
1922 if( ulIn
< I2_MIN
|| ulIn
> I2_MAX
)
1924 return DISP_E_OVERFLOW
;
1927 *psOut
= (short) ulIn
;
1932 /******************************************************************************
1933 * VarI2FromStr32 [OLEAUT32.54]
1935 HRESULT WINAPI
VarI2FromStr32(OLECHAR32
* strIn
, LCID lcid
, ULONG dwFlags
, short* psOut
)
1937 double dValue
= 0.0;
1938 LPSTR pNewString
= NULL
;
1940 TRACE( ole
, "( %p, 0x%08lx, 0x%08lx, %p ), stub\n", strIn
, lcid
, dwFlags
, psOut
);
1942 /* Check if we have a valid argument
1944 pNewString
= HEAP_strdupWtoA( GetProcessHeap(), 0, strIn
);
1945 RemoveCharacterFromString( pNewString
, "," );
1946 if( IsValidRealString( pNewString
) == FALSE
)
1948 return DISP_E_TYPEMISMATCH
;
1951 /* Convert the valid string to a floating point number.
1953 dValue
= atof( pNewString
);
1955 /* We don't need the string anymore so free it.
1957 HeapFree( GetProcessHeap(), 0, pNewString
);
1959 /* Check range of value.
1961 dValue
= round( dValue
);
1962 if( dValue
< I2_MIN
|| dValue
> I2_MAX
)
1964 return DISP_E_OVERFLOW
;
1967 *psOut
= (short) dValue
;
1972 /**********************************************************************
1973 * VarI2FromCy32 [OLEAUT32.52]
1974 * Convert currency to signed short
1976 HRESULT WINAPI
VarI2FromCy32(CY cyIn
, short* psOut
) {
1977 double t
= round((((double)cyIn
.u
.Hi
* 4294967296) + (double)cyIn
.u
.Lo
) / 10000);
1979 if (t
> I2_MAX
|| t
< I2_MIN
) return DISP_E_OVERFLOW
;
1985 /******************************************************************************
1986 * VarI4FromUI132 [OLEAUT32.58]
1988 HRESULT WINAPI
VarI4FromUI132(BYTE bIn
, LONG
* plOut
)
1990 TRACE( ole
, "( %X, %p ), stub\n", bIn
, plOut
);
1992 *plOut
= (LONG
) bIn
;
1998 /******************************************************************************
1999 * VarI4FromR432 [OLEAUT32.60]
2001 HRESULT WINAPI
VarI4FromR432(FLOAT fltIn
, LONG
* plOut
)
2003 TRACE( ole
, "( %f, %p ), stub\n", fltIn
, plOut
);
2005 /* Check range of value.
2007 fltIn
= round( fltIn
);
2008 if( fltIn
< I4_MIN
|| fltIn
> I4_MAX
)
2010 return DISP_E_OVERFLOW
;
2013 *plOut
= (LONG
) fltIn
;
2018 /******************************************************************************
2019 * VarI4FromR832 [OLEAUT32.61]
2021 HRESULT WINAPI
VarI4FromR832(double dblIn
, LONG
* plOut
)
2023 TRACE( ole
, "( %f, %p ), stub\n", dblIn
, plOut
);
2025 /* Check range of value.
2027 dblIn
= round( dblIn
);
2028 if( dblIn
< I4_MIN
|| dblIn
> I4_MAX
)
2030 return DISP_E_OVERFLOW
;
2033 *plOut
= (LONG
) dblIn
;
2038 /******************************************************************************
2039 * VarI4FromDate32 [OLEAUT32.63]
2041 HRESULT WINAPI
VarI4FromDate32(DATE dateIn
, LONG
* plOut
)
2043 TRACE( ole
, "( %f, %p ), stub\n", dateIn
, plOut
);
2045 /* Check range of value.
2047 dateIn
= round( dateIn
);
2048 if( dateIn
< I4_MIN
|| dateIn
> I4_MAX
)
2050 return DISP_E_OVERFLOW
;
2053 *plOut
= (LONG
) dateIn
;
2058 /******************************************************************************
2059 * VarI4FromBool32 [OLEAUT32.66]
2061 HRESULT WINAPI
VarI4FromBool32(VARIANT_BOOL boolIn
, LONG
* plOut
)
2063 TRACE( ole
, "( %d, %p ), stub\n", boolIn
, plOut
);
2065 *plOut
= (LONG
) boolIn
;
2070 /******************************************************************************
2071 * VarI4FromI132 [OLEAUT32.209]
2073 HRESULT WINAPI
VarI4FromI132(CHAR cIn
, LONG
* plOut
)
2075 TRACE( ole
, "( %c, %p ), stub\n", cIn
, plOut
);
2077 *plOut
= (LONG
) cIn
;
2082 /******************************************************************************
2083 * VarI4FromUI232 [OLEAUT32.210]
2085 HRESULT WINAPI
VarI4FromUI232(USHORT uiIn
, LONG
* plOut
)
2087 TRACE( ole
, "( %d, %p ), stub\n", uiIn
, plOut
);
2089 *plOut
= (LONG
) uiIn
;
2094 /******************************************************************************
2095 * VarI4FromUI432 [OLEAUT32.211]
2097 HRESULT WINAPI
VarI4FromUI432(ULONG ulIn
, LONG
* plOut
)
2099 TRACE( ole
, "( %lx, %p ), stub\n", ulIn
, plOut
);
2101 /* Check range of value.
2103 if( ulIn
< I4_MIN
|| ulIn
> I4_MAX
)
2105 return DISP_E_OVERFLOW
;
2108 *plOut
= (LONG
) ulIn
;
2113 /******************************************************************************
2114 * VarI4FromI232 [OLEAUT32.59]
2116 HRESULT WINAPI
VarI4FromI232(short sIn
, LONG
* plOut
)
2118 TRACE( ole
, "( %d, %p ), stub\n", sIn
, plOut
);
2120 *plOut
= (LONG
) sIn
;
2125 /******************************************************************************
2126 * VarI4FromStr32 [OLEAUT32.64]
2128 HRESULT WINAPI
VarI4FromStr32(OLECHAR32
* strIn
, LCID lcid
, ULONG dwFlags
, LONG
* plOut
)
2130 double dValue
= 0.0;
2131 LPSTR pNewString
= NULL
;
2133 TRACE( ole
, "( %p, 0x%08lx, 0x%08lx, %p ), stub\n", strIn
, lcid
, dwFlags
, plOut
);
2135 /* Check if we have a valid argument
2137 pNewString
= HEAP_strdupWtoA( GetProcessHeap(), 0, strIn
);
2138 RemoveCharacterFromString( pNewString
, "," );
2139 if( IsValidRealString( pNewString
) == FALSE
)
2141 return DISP_E_TYPEMISMATCH
;
2144 /* Convert the valid string to a floating point number.
2146 dValue
= atof( pNewString
);
2148 /* We don't need the string anymore so free it.
2150 HeapFree( GetProcessHeap(), 0, pNewString
);
2152 /* Check range of value.
2154 dValue
= round( dValue
);
2155 if( dValue
< I4_MIN
|| dValue
> I4_MAX
)
2157 return DISP_E_OVERFLOW
;
2160 *plOut
= (LONG
) dValue
;
2165 /**********************************************************************
2166 * VarI4FromCy32 [OLEAUT32.62]
2167 * Convert currency to signed long
2169 HRESULT WINAPI
VarI4FromCy32(CY cyIn
, LONG
* plOut
) {
2170 double t
= round((((double)cyIn
.u
.Hi
* 4294967296) + (double)cyIn
.u
.Lo
) / 10000);
2172 if (t
> I4_MAX
|| t
< I4_MIN
) return DISP_E_OVERFLOW
;
2178 /******************************************************************************
2179 * VarR4FromUI132 [OLEAUT32.68]
2181 HRESULT WINAPI
VarR4FromUI132(BYTE bIn
, FLOAT
* pfltOut
)
2183 TRACE( ole
, "( %X, %p ), stub\n", bIn
, pfltOut
);
2185 *pfltOut
= (FLOAT
) bIn
;
2190 /******************************************************************************
2191 * VarR4FromI232 [OLEAUT32.69]
2193 HRESULT WINAPI
VarR4FromI232(short sIn
, FLOAT
* pfltOut
)
2195 TRACE( ole
, "( %d, %p ), stub\n", sIn
, pfltOut
);
2197 *pfltOut
= (FLOAT
) sIn
;
2202 /******************************************************************************
2203 * VarR4FromI432 [OLEAUT32.70]
2205 HRESULT WINAPI
VarR4FromI432(LONG lIn
, FLOAT
* pfltOut
)
2207 TRACE( ole
, "( %lx, %p ), stub\n", lIn
, pfltOut
);
2209 *pfltOut
= (FLOAT
) lIn
;
2214 /******************************************************************************
2215 * VarR4FromR832 [OLEAUT32.71]
2217 HRESULT WINAPI
VarR4FromR832(double dblIn
, FLOAT
* pfltOut
)
2219 TRACE( ole
, "( %f, %p ), stub\n", dblIn
, pfltOut
);
2221 /* Check range of value.
2223 if( dblIn
< -(FLT_MAX
) || dblIn
> FLT_MAX
)
2225 return DISP_E_OVERFLOW
;
2228 *pfltOut
= (FLOAT
) dblIn
;
2233 /******************************************************************************
2234 * VarR4FromDate32 [OLEAUT32.73]
2236 HRESULT WINAPI
VarR4FromDate32(DATE dateIn
, FLOAT
* pfltOut
)
2238 TRACE( ole
, "( %f, %p ), stub\n", dateIn
, pfltOut
);
2240 /* Check range of value.
2242 if( dateIn
< -(FLT_MAX
) || dateIn
> FLT_MAX
)
2244 return DISP_E_OVERFLOW
;
2247 *pfltOut
= (FLOAT
) dateIn
;
2252 /******************************************************************************
2253 * VarR4FromBool32 [OLEAUT32.76]
2255 HRESULT WINAPI
VarR4FromBool32(VARIANT_BOOL boolIn
, FLOAT
* pfltOut
)
2257 TRACE( ole
, "( %d, %p ), stub\n", boolIn
, pfltOut
);
2259 *pfltOut
= (FLOAT
) boolIn
;
2264 /******************************************************************************
2265 * VarR4FromI132 [OLEAUT32.213]
2267 HRESULT WINAPI
VarR4FromI132(CHAR cIn
, FLOAT
* pfltOut
)
2269 TRACE( ole
, "( %c, %p ), stub\n", cIn
, pfltOut
);
2271 *pfltOut
= (FLOAT
) cIn
;
2276 /******************************************************************************
2277 * VarR4FromUI232 [OLEAUT32.214]
2279 HRESULT WINAPI
VarR4FromUI232(USHORT uiIn
, FLOAT
* pfltOut
)
2281 TRACE( ole
, "( %d, %p ), stub\n", uiIn
, pfltOut
);
2283 *pfltOut
= (FLOAT
) uiIn
;
2288 /******************************************************************************
2289 * VarR4FromUI432 [OLEAUT32.215]
2291 HRESULT WINAPI
VarR4FromUI432(ULONG ulIn
, FLOAT
* pfltOut
)
2293 TRACE( ole
, "( %ld, %p ), stub\n", ulIn
, pfltOut
);
2295 *pfltOut
= (FLOAT
) ulIn
;
2300 /******************************************************************************
2301 * VarR4FromStr32 [OLEAUT32.74]
2303 HRESULT WINAPI
VarR4FromStr32(OLECHAR32
* strIn
, LCID lcid
, ULONG dwFlags
, FLOAT
* pfltOut
)
2305 double dValue
= 0.0;
2306 LPSTR pNewString
= NULL
;
2308 TRACE( ole
, "( %p, %ld, %ld, %p ), stub\n", strIn
, lcid
, dwFlags
, pfltOut
);
2310 /* Check if we have a valid argument
2312 pNewString
= HEAP_strdupWtoA( GetProcessHeap(), 0, strIn
);
2313 RemoveCharacterFromString( pNewString
, "," );
2314 if( IsValidRealString( pNewString
) == FALSE
)
2316 return DISP_E_TYPEMISMATCH
;
2319 /* Convert the valid string to a floating point number.
2321 dValue
= atof( pNewString
);
2323 /* We don't need the string anymore so free it.
2325 HeapFree( GetProcessHeap(), 0, pNewString
);
2327 /* Check range of value.
2329 if( dValue
< -(FLT_MAX
) || dValue
> FLT_MAX
)
2331 return DISP_E_OVERFLOW
;
2334 *pfltOut
= (FLOAT
) dValue
;
2339 /**********************************************************************
2340 * VarR4FromCy32 [OLEAUT32.72]
2341 * Convert currency to float
2343 HRESULT WINAPI
VarR4FromCy32(CY cyIn
, FLOAT
* pfltOut
) {
2344 *pfltOut
= (FLOAT
)((((double)cyIn
.u
.Hi
* 4294967296) + (double)cyIn
.u
.Lo
) / 10000);
2349 /******************************************************************************
2350 * VarR8FromUI132 [OLEAUT32.68]
2352 HRESULT WINAPI
VarR8FromUI132(BYTE bIn
, double* pdblOut
)
2354 TRACE( ole
, "( %d, %p ), stub\n", bIn
, pdblOut
);
2356 *pdblOut
= (double) bIn
;
2361 /******************************************************************************
2362 * VarR8FromI232 [OLEAUT32.69]
2364 HRESULT WINAPI
VarR8FromI232(short sIn
, double* pdblOut
)
2366 TRACE( ole
, "( %d, %p ), stub\n", sIn
, pdblOut
);
2368 *pdblOut
= (double) sIn
;
2373 /******************************************************************************
2374 * VarR8FromI432 [OLEAUT32.70]
2376 HRESULT WINAPI
VarR8FromI432(LONG lIn
, double* pdblOut
)
2378 TRACE( ole
, "( %ld, %p ), stub\n", lIn
, pdblOut
);
2380 *pdblOut
= (double) lIn
;
2385 /******************************************************************************
2386 * VarR8FromR432 [OLEAUT32.81]
2388 HRESULT WINAPI
VarR8FromR432(FLOAT fltIn
, double* pdblOut
)
2390 TRACE( ole
, "( %f, %p ), stub\n", fltIn
, pdblOut
);
2392 *pdblOut
= (double) fltIn
;
2397 /******************************************************************************
2398 * VarR8FromDate32 [OLEAUT32.83]
2400 HRESULT WINAPI
VarR8FromDate32(DATE dateIn
, double* pdblOut
)
2402 TRACE( ole
, "( %f, %p ), stub\n", dateIn
, pdblOut
);
2404 *pdblOut
= (double) dateIn
;
2409 /******************************************************************************
2410 * VarR8FromBool32 [OLEAUT32.86]
2412 HRESULT WINAPI
VarR8FromBool32(VARIANT_BOOL boolIn
, double* pdblOut
)
2414 TRACE( ole
, "( %d, %p ), stub\n", boolIn
, pdblOut
);
2416 *pdblOut
= (double) boolIn
;
2421 /******************************************************************************
2422 * VarR8FromI132 [OLEAUT32.217]
2424 HRESULT WINAPI
VarR8FromI132(CHAR cIn
, double* pdblOut
)
2426 TRACE( ole
, "( %c, %p ), stub\n", cIn
, pdblOut
);
2428 *pdblOut
= (double) cIn
;
2433 /******************************************************************************
2434 * VarR8FromUI232 [OLEAUT32.218]
2436 HRESULT WINAPI
VarR8FromUI232(USHORT uiIn
, double* pdblOut
)
2438 TRACE( ole
, "( %d, %p ), stub\n", uiIn
, pdblOut
);
2440 *pdblOut
= (double) uiIn
;
2445 /******************************************************************************
2446 * VarR8FromUI432 [OLEAUT32.219]
2448 HRESULT WINAPI
VarR8FromUI432(ULONG ulIn
, double* pdblOut
)
2450 TRACE( ole
, "( %ld, %p ), stub\n", ulIn
, pdblOut
);
2452 *pdblOut
= (double) ulIn
;
2457 /******************************************************************************
2458 * VarR8FromStr32 [OLEAUT32.84]
2460 HRESULT WINAPI
VarR8FromStr32(OLECHAR32
* strIn
, LCID lcid
, ULONG dwFlags
, double* pdblOut
)
2462 double dValue
= 0.0;
2463 LPSTR pNewString
= NULL
;
2465 TRACE( ole
, "( %p, %ld, %ld, %p ), stub\n", strIn
, lcid
, dwFlags
, pdblOut
);
2467 /* Check if we have a valid argument
2469 pNewString
= HEAP_strdupWtoA( GetProcessHeap(), 0, strIn
);
2470 RemoveCharacterFromString( pNewString
, "," );
2471 if( IsValidRealString( pNewString
) == FALSE
)
2473 return DISP_E_TYPEMISMATCH
;
2476 /* Convert the valid string to a floating point number.
2478 dValue
= atof( pNewString
);
2480 /* We don't need the string anymore so free it.
2482 HeapFree( GetProcessHeap(), 0, pNewString
);
2489 /**********************************************************************
2490 * VarR8FromCy32 [OLEAUT32.82]
2491 * Convert currency to double
2493 HRESULT WINAPI
VarR8FromCy32(CY cyIn
, double* pdblOut
) {
2494 *pdblOut
= (double)((((double)cyIn
.u
.Hi
* 4294967296) + (double)cyIn
.u
.Lo
) / 10000);
2499 /******************************************************************************
2500 * VarDateFromUI132 [OLEAUT32.]
2502 HRESULT WINAPI
VarDateFromUI132(BYTE bIn
, DATE
* pdateOut
)
2504 TRACE( ole
, "( %d, %p ), stub\n", bIn
, pdateOut
);
2506 *pdateOut
= (DATE
) bIn
;
2511 /******************************************************************************
2512 * VarDateFromI232 [OLEAUT32.222]
2514 HRESULT WINAPI
VarDateFromI232(short sIn
, DATE
* pdateOut
)
2516 TRACE( ole
, "( %d, %p ), stub\n", sIn
, pdateOut
);
2518 *pdateOut
= (DATE
) sIn
;
2523 /******************************************************************************
2524 * VarDateFromI432 [OLEAUT32.90]
2526 HRESULT WINAPI
VarDateFromI432(LONG lIn
, DATE
* pdateOut
)
2528 TRACE( ole
, "( %ld, %p ), stub\n", lIn
, pdateOut
);
2530 if( lIn
< DATE_MIN
|| lIn
> DATE_MAX
)
2532 return DISP_E_OVERFLOW
;
2535 *pdateOut
= (DATE
) lIn
;
2540 /******************************************************************************
2541 * VarDateFromR432 [OLEAUT32.91]
2543 HRESULT WINAPI
VarDateFromR432(FLOAT fltIn
, DATE
* pdateOut
)
2545 unsigned long test
= 0;
2547 TRACE( ole
, "( %f, %p ), stub\n", fltIn
, pdateOut
);
2549 test
= (unsigned long) fltIn
;
2550 if( test
< DATE_MIN
|| test
> DATE_MAX
)
2552 return DISP_E_OVERFLOW
;
2555 *pdateOut
= (DATE
) fltIn
;
2560 /******************************************************************************
2561 * VarDateFromR832 [OLEAUT32.92]
2563 HRESULT WINAPI
VarDateFromR832(double dblIn
, DATE
* pdateOut
)
2565 unsigned long test
= 0;
2567 TRACE( ole
, "( %f, %p ), stub\n", dblIn
, pdateOut
);
2569 test
= (unsigned long) dblIn
;
2570 if( test
< DATE_MIN
|| test
> DATE_MAX
)
2572 return DISP_E_OVERFLOW
;
2575 *pdateOut
= (DATE
) dblIn
;
2580 /******************************************************************************
2581 * VarDateFromStr32 [OLEAUT32.94]
2582 * The string representing the date is composed of two parts, a date and time.
2584 * The format of the time is has follows:
2585 * hh[:mm][:ss][AM|PM]
2586 * Whitespace can be inserted anywhere between these tokens. A whitespace consists
2587 * of space and/or tab characters, which are ignored.
2589 * The formats for the date part are has follows:
2593 * January dd[,] [yy]yy
2596 * Whitespace can be inserted anywhere between these tokens.
2598 * The formats for the date and time string are has follows.
2599 * date[whitespace][time]
2600 * [time][whitespace]date
2602 * These are the only characters allowed in a string representing a date and time:
2603 * [A-Z] [a-z] [0-9] ':' '-' '/' ',' ' ' '\t'
2605 HRESULT WINAPI
VarDateFromStr32(OLECHAR32
* strIn
, LCID lcid
, ULONG dwFlags
, DATE
* pdateOut
)
2609 FIXME( ole
, "( %p, %lx, %lx, %p ), stub\n", strIn
, lcid
, dwFlags
, pdateOut
);
2614 /******************************************************************************
2615 * VarDateFromI132 [OLEAUT32.221]
2617 HRESULT WINAPI
VarDateFromI132(CHAR cIn
, DATE
* pdateOut
)
2619 TRACE( ole
, "( %c, %p ), stub\n", cIn
, pdateOut
);
2621 *pdateOut
= (DATE
) cIn
;
2626 /******************************************************************************
2627 * VarDateFromUI232 [OLEAUT32.222]
2629 HRESULT WINAPI
VarDateFromUI232(USHORT uiIn
, DATE
* pdateOut
)
2631 TRACE( ole
, "( %d, %p ), stub\n", uiIn
, pdateOut
);
2633 if( uiIn
> DATE_MAX
)
2635 return DISP_E_OVERFLOW
;
2638 *pdateOut
= (DATE
) uiIn
;
2643 /******************************************************************************
2644 * VarDateFromUI432 [OLEAUT32.223]
2646 HRESULT WINAPI
VarDateFromUI432(ULONG ulIn
, DATE
* pdateOut
)
2648 TRACE( ole
, "( %ld, %p ), stub\n", ulIn
, pdateOut
);
2650 if( ulIn
< DATE_MIN
|| ulIn
> DATE_MAX
)
2652 return DISP_E_OVERFLOW
;
2655 *pdateOut
= (DATE
) ulIn
;
2660 /******************************************************************************
2661 * VarDateFromBool32 [OLEAUT32.96]
2663 HRESULT WINAPI
VarDateFromBool32(VARIANT_BOOL boolIn
, DATE
* pdateOut
)
2665 TRACE( ole
, "( %d, %p ), stub\n", boolIn
, pdateOut
);
2667 *pdateOut
= (DATE
) boolIn
;
2672 /**********************************************************************
2673 * VarDateFromCy32 [OLEAUT32.93]
2674 * Convert currency to date
2676 HRESULT WINAPI
VarDateFromCy32(CY cyIn
, DATE
* pdateOut
) {
2677 *pdateOut
= (DATE
)((((double)cyIn
.u
.Hi
* 4294967296) + (double)cyIn
.u
.Lo
) / 10000);
2679 if (*pdateOut
> DATE_MAX
|| *pdateOut
< DATE_MIN
) return DISP_E_TYPEMISMATCH
;
2683 /******************************************************************************
2684 * VarBstrFromUI132 [OLEAUT32.108]
2686 HRESULT WINAPI
VarBstrFromUI132(BYTE bVal
, LCID lcid
, ULONG dwFlags
, BSTR32
* pbstrOut
)
2688 TRACE( ole
, "( %d, %ld, %ld, %p ), stub\n", bVal
, lcid
, dwFlags
, pbstrOut
);
2689 sprintf( pBuffer
, "%d", bVal
);
2691 *pbstrOut
= StringDupAtoBstr( pBuffer
);
2696 /******************************************************************************
2697 * VarBstrFromI232 [OLEAUT32.109]
2699 HRESULT WINAPI
VarBstrFromI232(short iVal
, LCID lcid
, ULONG dwFlags
, BSTR32
* pbstrOut
)
2701 TRACE( ole
, "( %d, %ld, %ld, %p ), stub\n", iVal
, lcid
, dwFlags
, pbstrOut
);
2702 sprintf( pBuffer
, "%d", iVal
);
2703 *pbstrOut
= StringDupAtoBstr( pBuffer
);
2708 /******************************************************************************
2709 * VarBstrFromI432 [OLEAUT32.110]
2711 HRESULT WINAPI
VarBstrFromI432(LONG lIn
, LCID lcid
, ULONG dwFlags
, BSTR32
* pbstrOut
)
2713 TRACE( ole
, "( %ld, %ld, %ld, %p ), stub\n", lIn
, lcid
, dwFlags
, pbstrOut
);
2715 sprintf( pBuffer
, "%ld", lIn
);
2716 *pbstrOut
= StringDupAtoBstr( pBuffer
);
2721 /******************************************************************************
2722 * VarBstrFromR432 [OLEAUT32.111]
2724 HRESULT WINAPI
VarBstrFromR432(FLOAT fltIn
, LCID lcid
, ULONG dwFlags
, BSTR32
* pbstrOut
)
2726 TRACE( ole
, "( %f, %ld, %ld, %p ), stub\n", fltIn
, lcid
, dwFlags
, pbstrOut
);
2728 sprintf( pBuffer
, "%.7g", fltIn
);
2729 *pbstrOut
= StringDupAtoBstr( pBuffer
);
2734 /******************************************************************************
2735 * VarBstrFromR832 [OLEAUT32.112]
2737 HRESULT WINAPI
VarBstrFromR832(double dblIn
, LCID lcid
, ULONG dwFlags
, BSTR32
* pbstrOut
)
2739 TRACE( ole
, "( %f, %ld, %ld, %p ), stub\n", dblIn
, lcid
, dwFlags
, pbstrOut
);
2741 sprintf( pBuffer
, "%.15g", dblIn
);
2742 *pbstrOut
= StringDupAtoBstr( pBuffer
);
2747 /******************************************************************************
2748 * VarBstrFromDate32 [OLEAUT32.114]
2750 * The date is implemented using an 8 byte floating-point number.
2751 * Days are represented by whole numbers increments starting with 0.00 has
2752 * being December 30 1899, midnight.
2753 * The hours are expressed as the fractional part of the number.
2754 * December 30 1899 at midnight = 0.00
2755 * January 1 1900 at midnight = 2.00
2756 * January 4 1900 at 6 AM = 5.25
2757 * January 4 1900 at noon = 5.50
2758 * December 29 1899 at midnight = -1.00
2759 * December 18 1899 at midnight = -12.00
2760 * December 18 1899 at 6AM = -12.25
2761 * December 18 1899 at 6PM = -12.75
2762 * December 19 1899 at midnight = -11.00
2763 * The tm structure is as follows:
2765 * int tm_sec; seconds after the minute - [0,59]
2766 * int tm_min; minutes after the hour - [0,59]
2767 * int tm_hour; hours since midnight - [0,23]
2768 * int tm_mday; day of the month - [1,31]
2769 * int tm_mon; months since January - [0,11]
2770 * int tm_year; years since 1900
2771 * int tm_wday; days since Sunday - [0,6]
2772 * int tm_yday; days since January 1 - [0,365]
2773 * int tm_isdst; daylight savings time flag
2776 HRESULT WINAPI
VarBstrFromDate32(DATE dateIn
, LCID lcid
, ULONG dwFlags
, BSTR32
* pbstrOut
)
2778 /* If the date is not after the 1900 return an error because
2779 * the tm structure does not allow such dates.
2783 double decimalPart
= 0.0;
2784 double wholePart
= 0.0;
2785 struct tm TM
= {0,0,0,0,0,0,0,0,0};
2787 wholePart
= (double) (long) dateIn
;
2788 decimalPart
= fmod( dateIn
, wholePart
);
2790 if( !(lcid
& VAR_TIMEVALUEONLY
) )
2794 /* find in what year the day in the "wholePart" falls into.
2796 TM
.tm_year
= (int) ( wholePart
/ 365.25 );
2797 /* determine if this is a leap year.
2799 if( ( TM
.tm_year
% 4 ) == 0 )
2801 /* find what day of that year does the "wholePart" corresponds to.
2802 * the day is [1-366]
2804 nDay
= (int) ( wholePart
- ( TM
.tm_year
* 365.25 ) );
2805 TM
.tm_yday
= nDay
- 1;
2806 /* find which mount this day corresponds to.
2813 else if( nDay
<= ( 59 + leapYear
) )
2815 TM
.tm_mday
= nDay
- 31;
2818 else if( nDay
<= ( 90 + leapYear
) )
2820 TM
.tm_mday
= nDay
- ( 59 + leapYear
);
2823 else if( nDay
<= ( 120 + leapYear
) )
2825 TM
.tm_mday
= nDay
- ( 90 + leapYear
);
2828 else if( nDay
<= ( 151 + leapYear
) )
2830 TM
.tm_mday
= nDay
- ( 120 + leapYear
);
2833 else if( nDay
<= ( 181 + leapYear
) )
2835 TM
.tm_mday
= nDay
- ( 151 + leapYear
);
2838 else if( nDay
<= ( 212 + leapYear
) )
2840 TM
.tm_mday
= nDay
- ( 181 + leapYear
);
2843 else if( nDay
<= ( 243 + leapYear
) )
2845 TM
.tm_mday
= nDay
- ( 212 + leapYear
);
2848 else if( nDay
<= ( 273 + leapYear
) )
2850 TM
.tm_mday
= nDay
- ( 243 + leapYear
);
2853 else if( nDay
<= ( 304 + leapYear
) )
2855 TM
.tm_mday
= nDay
- ( 273 + leapYear
);
2858 else if( nDay
<= ( 334 + leapYear
) )
2860 TM
.tm_mday
= nDay
- ( 304 + leapYear
);
2863 else if( nDay
<= ( 365 + leapYear
) )
2865 TM
.tm_mday
= nDay
- ( 334 + leapYear
);
2869 if( !(lcid
& VAR_DATEVALUEONLY
) )
2871 /* find the number of seconds in this day.
2872 * fractional part times, hours, minutes, seconds.
2874 TM
.tm_hour
= (int) ( decimalPart
* 24 );
2875 TM
.tm_min
= (int) ( ( ( decimalPart
* 24 ) - TM
.tm_hour
) * 60 );
2876 TM
.tm_sec
= (int) ( ( ( decimalPart
* 24 * 60 ) - ( TM
.tm_hour
* 60 ) - TM
.tm_min
) * 60 );
2879 if( lcid
& VAR_DATEVALUEONLY
)
2880 strftime( pBuffer
, BUFFER_MAX
, "%x", &TM
);
2881 else if( lcid
& VAR_TIMEVALUEONLY
)
2882 strftime( pBuffer
, BUFFER_MAX
, "%X", &TM
);
2884 strftime( pBuffer
, 100, "%x %X", &TM
);
2886 *pbstrOut
= StringDupAtoBstr( pBuffer
);
2890 FIXME( ole
, "( %f, %ld, %ld, %p ), stub\n", dateIn
, lcid
, dwFlags
, pbstrOut
);
2891 return E_INVALIDARG
;
2897 /******************************************************************************
2898 * VarBstrFromBool32 [OLEAUT32.116]
2900 HRESULT WINAPI
VarBstrFromBool32(VARIANT_BOOL boolIn
, LCID lcid
, ULONG dwFlags
, BSTR32
* pbstrOut
)
2902 TRACE( ole
, "( %d, %ld, %ld, %p ), stub\n", boolIn
, lcid
, dwFlags
, pbstrOut
);
2904 if( boolIn
== VARIANT_FALSE
)
2906 sprintf( pBuffer
, "False" );
2910 sprintf( pBuffer
, "True" );
2913 *pbstrOut
= StringDupAtoBstr( pBuffer
);
2918 /******************************************************************************
2919 * VarBstrFromI132 [OLEAUT32.229]
2921 HRESULT WINAPI
VarBstrFromI132(CHAR cIn
, LCID lcid
, ULONG dwFlags
, BSTR32
* pbstrOut
)
2923 TRACE( ole
, "( %c, %ld, %ld, %p ), stub\n", cIn
, lcid
, dwFlags
, pbstrOut
);
2924 sprintf( pBuffer
, "%d", cIn
);
2925 *pbstrOut
= StringDupAtoBstr( pBuffer
);
2930 /******************************************************************************
2931 * VarBstrFromUI232 [OLEAUT32.230]
2933 HRESULT WINAPI
VarBstrFromUI232(USHORT uiIn
, LCID lcid
, ULONG dwFlags
, BSTR32
* pbstrOut
)
2935 TRACE( ole
, "( %d, %ld, %ld, %p ), stub\n", uiIn
, lcid
, dwFlags
, pbstrOut
);
2936 sprintf( pBuffer
, "%d", uiIn
);
2937 *pbstrOut
= StringDupAtoBstr( pBuffer
);
2942 /******************************************************************************
2943 * VarBstrFromUI432 [OLEAUT32.231]
2945 HRESULT WINAPI
VarBstrFromUI432(ULONG ulIn
, LCID lcid
, ULONG dwFlags
, BSTR32
* pbstrOut
)
2947 TRACE( ole
, "( %ld, %ld, %ld, %p ), stub\n", ulIn
, lcid
, dwFlags
, pbstrOut
);
2948 sprintf( pBuffer
, "%ld", ulIn
);
2949 *pbstrOut
= StringDupAtoBstr( pBuffer
);
2954 /******************************************************************************
2955 * VarBoolFromUI132 [OLEAUT32.118]
2957 HRESULT WINAPI
VarBoolFromUI132(BYTE bIn
, VARIANT_BOOL
* pboolOut
)
2959 TRACE( ole
, "( %d, %p ), stub\n", bIn
, pboolOut
);
2963 *pboolOut
= VARIANT_FALSE
;
2967 *pboolOut
= VARIANT_TRUE
;
2973 /******************************************************************************
2974 * VarBoolFromI232 [OLEAUT32.119]
2976 HRESULT WINAPI
VarBoolFromI232(short sIn
, VARIANT_BOOL
* pboolOut
)
2978 TRACE( ole
, "( %d, %p ), stub\n", sIn
, pboolOut
);
2982 *pboolOut
= VARIANT_FALSE
;
2986 *pboolOut
= VARIANT_TRUE
;
2992 /******************************************************************************
2993 * VarBoolFromI432 [OLEAUT32.120]
2995 HRESULT WINAPI
VarBoolFromI432(LONG lIn
, VARIANT_BOOL
* pboolOut
)
2997 TRACE( ole
, "( %ld, %p ), stub\n", lIn
, pboolOut
);
3001 *pboolOut
= VARIANT_FALSE
;
3005 *pboolOut
= VARIANT_TRUE
;
3011 /******************************************************************************
3012 * VarBoolFromR432 [OLEAUT32.121]
3014 HRESULT WINAPI
VarBoolFromR432(FLOAT fltIn
, VARIANT_BOOL
* pboolOut
)
3016 TRACE( ole
, "( %f, %p ), stub\n", fltIn
, pboolOut
);
3020 *pboolOut
= VARIANT_FALSE
;
3024 *pboolOut
= VARIANT_TRUE
;
3030 /******************************************************************************
3031 * VarBoolFromR832 [OLEAUT32.122]
3033 HRESULT WINAPI
VarBoolFromR832(double dblIn
, VARIANT_BOOL
* pboolOut
)
3035 TRACE( ole
, "( %f, %p ), stub\n", dblIn
, pboolOut
);
3039 *pboolOut
= VARIANT_FALSE
;
3043 *pboolOut
= VARIANT_TRUE
;
3049 /******************************************************************************
3050 * VarBoolFromDate32 [OLEAUT32.123]
3052 HRESULT WINAPI
VarBoolFromDate32(DATE dateIn
, VARIANT_BOOL
* pboolOut
)
3054 TRACE( ole
, "( %f, %p ), stub\n", dateIn
, pboolOut
);
3058 *pboolOut
= VARIANT_FALSE
;
3062 *pboolOut
= VARIANT_TRUE
;
3068 /******************************************************************************
3069 * VarBoolFromStr32 [OLEAUT32.125]
3071 HRESULT WINAPI
VarBoolFromStr32(OLECHAR32
* strIn
, LCID lcid
, ULONG dwFlags
, VARIANT_BOOL
* pboolOut
)
3074 char* pNewString
= NULL
;
3076 TRACE( ole
, "( %p, %ld, %ld, %p ), stub\n", strIn
, lcid
, dwFlags
, pboolOut
);
3078 pNewString
= HEAP_strdupWtoA( GetProcessHeap(), 0, strIn
);
3080 if( pNewString
== NULL
|| strlen( pNewString
) == 0 )
3082 ret
= DISP_E_TYPEMISMATCH
;
3087 if( strncasecmp( pNewString
, "True", strlen( pNewString
) ) == 0 )
3089 *pboolOut
= VARIANT_TRUE
;
3091 else if( strncasecmp( pNewString
, "False", strlen( pNewString
) ) == 0 )
3093 *pboolOut
= VARIANT_FALSE
;
3097 /* Try converting the string to a floating point number.
3099 double dValue
= 0.0;
3100 HRESULT res
= VarR8FromStr32( strIn
, lcid
, dwFlags
, &dValue
);
3103 ret
= DISP_E_TYPEMISMATCH
;
3105 else if( dValue
== 0.0 )
3107 *pboolOut
= VARIANT_FALSE
;
3111 *pboolOut
= VARIANT_TRUE
;
3116 HeapFree( GetProcessHeap(), 0, pNewString
);
3121 /******************************************************************************
3122 * VarBoolFromI132 [OLEAUT32.233]
3124 HRESULT WINAPI
VarBoolFromI132(CHAR cIn
, VARIANT_BOOL
* pboolOut
)
3126 TRACE( ole
, "( %c, %p ), stub\n", cIn
, pboolOut
);
3130 *pboolOut
= VARIANT_FALSE
;
3134 *pboolOut
= VARIANT_TRUE
;
3140 /******************************************************************************
3141 * VarBoolFromUI232 [OLEAUT32.234]
3143 HRESULT WINAPI
VarBoolFromUI232(USHORT uiIn
, VARIANT_BOOL
* pboolOut
)
3145 TRACE( ole
, "( %d, %p ), stub\n", uiIn
, pboolOut
);
3149 *pboolOut
= VARIANT_FALSE
;
3153 *pboolOut
= VARIANT_TRUE
;
3159 /******************************************************************************
3160 * VarBoolFromUI432 [OLEAUT32.235]
3162 HRESULT WINAPI
VarBoolFromUI432(ULONG ulIn
, VARIANT_BOOL
* pboolOut
)
3164 TRACE( ole
, "( %ld, %p ), stub\n", ulIn
, pboolOut
);
3168 *pboolOut
= VARIANT_FALSE
;
3172 *pboolOut
= VARIANT_TRUE
;
3178 /**********************************************************************
3179 * VarBoolFromCy32 [OLEAUT32.124]
3180 * Convert currency to boolean
3182 HRESULT WINAPI
VarBoolFromCy32(CY cyIn
, VARIANT_BOOL
* pboolOut
) {
3183 if (cyIn
.u
.Hi
|| cyIn
.u
.Lo
) *pboolOut
= -1;
3189 /******************************************************************************
3190 * VarI1FromUI132 [OLEAUT32.244]
3192 HRESULT WINAPI
VarI1FromUI132(BYTE bIn
, CHAR
* pcOut
)
3194 TRACE( ole
, "( %d, %p ), stub\n", bIn
, pcOut
);
3196 /* Check range of value.
3198 if( bIn
> CHAR_MAX
)
3200 return DISP_E_OVERFLOW
;
3203 *pcOut
= (CHAR
) bIn
;
3208 /******************************************************************************
3209 * VarI1FromI232 [OLEAUT32.245]
3211 HRESULT WINAPI
VarI1FromI232(short uiIn
, CHAR
* pcOut
)
3213 TRACE( ole
, "( %d, %p ), stub\n", uiIn
, pcOut
);
3215 if( uiIn
> CHAR_MAX
)
3217 return DISP_E_OVERFLOW
;
3220 *pcOut
= (CHAR
) uiIn
;
3225 /******************************************************************************
3226 * VarI1FromI432 [OLEAUT32.246]
3228 HRESULT WINAPI
VarI1FromI432(LONG lIn
, CHAR
* pcOut
)
3230 TRACE( ole
, "( %ld, %p ), stub\n", lIn
, pcOut
);
3232 if( lIn
< CHAR_MIN
|| lIn
> CHAR_MAX
)
3234 return DISP_E_OVERFLOW
;
3237 *pcOut
= (CHAR
) lIn
;
3242 /******************************************************************************
3243 * VarI1FromR432 [OLEAUT32.247]
3245 HRESULT WINAPI
VarI1FromR432(FLOAT fltIn
, CHAR
* pcOut
)
3247 TRACE( ole
, "( %f, %p ), stub\n", fltIn
, pcOut
);
3249 fltIn
= round( fltIn
);
3250 if( fltIn
< CHAR_MIN
|| fltIn
> CHAR_MAX
)
3252 return DISP_E_OVERFLOW
;
3255 *pcOut
= (CHAR
) fltIn
;
3260 /******************************************************************************
3261 * VarI1FromR832 [OLEAUT32.248]
3263 HRESULT WINAPI
VarI1FromR832(double dblIn
, CHAR
* pcOut
)
3265 TRACE( ole
, "( %f, %p ), stub\n", dblIn
, pcOut
);
3267 dblIn
= round( dblIn
);
3268 if( dblIn
< CHAR_MIN
|| dblIn
> CHAR_MAX
)
3270 return DISP_E_OVERFLOW
;
3273 *pcOut
= (CHAR
) dblIn
;
3278 /******************************************************************************
3279 * VarI1FromDate32 [OLEAUT32.249]
3281 HRESULT WINAPI
VarI1FromDate32(DATE dateIn
, CHAR
* pcOut
)
3283 TRACE( ole
, "( %f, %p ), stub\n", dateIn
, pcOut
);
3285 dateIn
= round( dateIn
);
3286 if( dateIn
< CHAR_MIN
|| dateIn
> CHAR_MAX
)
3288 return DISP_E_OVERFLOW
;
3291 *pcOut
= (CHAR
) dateIn
;
3296 /******************************************************************************
3297 * VarI1FromStr32 [OLEAUT32.251]
3299 HRESULT WINAPI
VarI1FromStr32(OLECHAR32
* strIn
, LCID lcid
, ULONG dwFlags
, CHAR
* pcOut
)
3301 double dValue
= 0.0;
3302 LPSTR pNewString
= NULL
;
3304 TRACE( ole
, "( %p, %ld, %ld, %p ), stub\n", strIn
, lcid
, dwFlags
, pcOut
);
3306 /* Check if we have a valid argument
3308 pNewString
= HEAP_strdupWtoA( GetProcessHeap(), 0, strIn
);
3309 RemoveCharacterFromString( pNewString
, "," );
3310 if( IsValidRealString( pNewString
) == FALSE
)
3312 return DISP_E_TYPEMISMATCH
;
3315 /* Convert the valid string to a floating point number.
3317 dValue
= atof( pNewString
);
3319 /* We don't need the string anymore so free it.
3321 HeapFree( GetProcessHeap(), 0, pNewString
);
3323 /* Check range of value.
3325 dValue
= round( dValue
);
3326 if( dValue
< CHAR_MIN
|| dValue
> CHAR_MAX
)
3328 return DISP_E_OVERFLOW
;
3331 *pcOut
= (CHAR
) dValue
;
3336 /******************************************************************************
3337 * VarI1FromBool32 [OLEAUT32.253]
3339 HRESULT WINAPI
VarI1FromBool32(VARIANT_BOOL boolIn
, CHAR
* pcOut
)
3341 TRACE( ole
, "( %d, %p ), stub\n", boolIn
, pcOut
);
3343 *pcOut
= (CHAR
) boolIn
;
3348 /******************************************************************************
3349 * VarI1FromUI232 [OLEAUT32.254]
3351 HRESULT WINAPI
VarI1FromUI232(USHORT uiIn
, CHAR
* pcOut
)
3353 TRACE( ole
, "( %d, %p ), stub\n", uiIn
, pcOut
);
3355 if( uiIn
> CHAR_MAX
)
3357 return DISP_E_OVERFLOW
;
3360 *pcOut
= (CHAR
) uiIn
;
3365 /******************************************************************************
3366 * VarI1FromUI432 [OLEAUT32.255]
3368 HRESULT WINAPI
VarI1FromUI432(ULONG ulIn
, CHAR
* pcOut
)
3370 TRACE( ole
, "( %ld, %p ), stub\n", ulIn
, pcOut
);
3372 if( ulIn
> CHAR_MAX
)
3374 return DISP_E_OVERFLOW
;
3377 *pcOut
= (CHAR
) ulIn
;
3382 /**********************************************************************
3383 * VarI1FromCy32 [OLEAUT32.250]
3384 * Convert currency to signed char
3386 HRESULT WINAPI
VarI1FromCy32(CY cyIn
, CHAR
* pcOut
) {
3387 double t
= round((((double)cyIn
.u
.Hi
* 4294967296) + (double)cyIn
.u
.Lo
) / 10000);
3389 if (t
> CHAR_MAX
|| t
< CHAR_MIN
) return DISP_E_OVERFLOW
;
3395 /******************************************************************************
3396 * VarUI2FromUI132 [OLEAUT32.257]
3398 HRESULT WINAPI
VarUI2FromUI132(BYTE bIn
, USHORT
* puiOut
)
3400 TRACE( ole
, "( %d, %p ), stub\n", bIn
, puiOut
);
3402 *puiOut
= (USHORT
) bIn
;
3407 /******************************************************************************
3408 * VarUI2FromI232 [OLEAUT32.258]
3410 HRESULT WINAPI
VarUI2FromI232(short uiIn
, USHORT
* puiOut
)
3412 TRACE( ole
, "( %d, %p ), stub\n", uiIn
, puiOut
);
3414 if( uiIn
< UI2_MIN
)
3416 return DISP_E_OVERFLOW
;
3419 *puiOut
= (USHORT
) uiIn
;
3424 /******************************************************************************
3425 * VarUI2FromI432 [OLEAUT32.259]
3427 HRESULT WINAPI
VarUI2FromI432(LONG lIn
, USHORT
* puiOut
)
3429 TRACE( ole
, "( %ld, %p ), stub\n", lIn
, puiOut
);
3431 if( lIn
< UI2_MIN
|| lIn
> UI2_MAX
)
3433 return DISP_E_OVERFLOW
;
3436 *puiOut
= (USHORT
) lIn
;
3441 /******************************************************************************
3442 * VarUI2FromR432 [OLEAUT32.260]
3444 HRESULT WINAPI
VarUI2FromR432(FLOAT fltIn
, USHORT
* puiOut
)
3446 TRACE( ole
, "( %f, %p ), stub\n", fltIn
, puiOut
);
3448 fltIn
= round( fltIn
);
3449 if( fltIn
< UI2_MIN
|| fltIn
> UI2_MAX
)
3451 return DISP_E_OVERFLOW
;
3454 *puiOut
= (USHORT
) fltIn
;
3459 /******************************************************************************
3460 * VarUI2FromR832 [OLEAUT32.261]
3462 HRESULT WINAPI
VarUI2FromR832(double dblIn
, USHORT
* puiOut
)
3464 TRACE( ole
, "( %f, %p ), stub\n", dblIn
, puiOut
);
3466 dblIn
= round( dblIn
);
3467 if( dblIn
< UI2_MIN
|| dblIn
> UI2_MAX
)
3469 return DISP_E_OVERFLOW
;
3472 *puiOut
= (USHORT
) dblIn
;
3477 /******************************************************************************
3478 * VarUI2FromDate32 [OLEAUT32.262]
3480 HRESULT WINAPI
VarUI2FromDate32(DATE dateIn
, USHORT
* puiOut
)
3482 TRACE( ole
, "( %f, %p ), stub\n", dateIn
, puiOut
);
3484 dateIn
= round( dateIn
);
3485 if( dateIn
< UI2_MIN
|| dateIn
> UI2_MAX
)
3487 return DISP_E_OVERFLOW
;
3490 *puiOut
= (USHORT
) dateIn
;
3495 /******************************************************************************
3496 * VarUI2FromStr32 [OLEAUT32.264]
3498 HRESULT WINAPI
VarUI2FromStr32(OLECHAR32
* strIn
, LCID lcid
, ULONG dwFlags
, USHORT
* puiOut
)
3500 double dValue
= 0.0;
3501 LPSTR pNewString
= NULL
;
3503 TRACE( ole
, "( %p, %ld, %ld, %p ), stub\n", strIn
, lcid
, dwFlags
, puiOut
);
3505 /* Check if we have a valid argument
3507 pNewString
= HEAP_strdupWtoA( GetProcessHeap(), 0, strIn
);
3508 RemoveCharacterFromString( pNewString
, "," );
3509 if( IsValidRealString( pNewString
) == FALSE
)
3511 return DISP_E_TYPEMISMATCH
;
3514 /* Convert the valid string to a floating point number.
3516 dValue
= atof( pNewString
);
3518 /* We don't need the string anymore so free it.
3520 HeapFree( GetProcessHeap(), 0, pNewString
);
3522 /* Check range of value.
3524 dValue
= round( dValue
);
3525 if( dValue
< UI2_MIN
|| dValue
> UI2_MAX
)
3527 return DISP_E_OVERFLOW
;
3530 *puiOut
= (USHORT
) dValue
;
3535 /******************************************************************************
3536 * VarUI2FromBool32 [OLEAUT32.266]
3538 HRESULT WINAPI
VarUI2FromBool32(VARIANT_BOOL boolIn
, USHORT
* puiOut
)
3540 TRACE( ole
, "( %d, %p ), stub\n", boolIn
, puiOut
);
3542 *puiOut
= (USHORT
) boolIn
;
3547 /******************************************************************************
3548 * VarUI2FromI132 [OLEAUT32.267]
3550 HRESULT WINAPI
VarUI2FromI132(CHAR cIn
, USHORT
* puiOut
)
3552 TRACE( ole
, "( %c, %p ), stub\n", cIn
, puiOut
);
3554 *puiOut
= (USHORT
) cIn
;
3559 /******************************************************************************
3560 * VarUI2FromUI432 [OLEAUT32.268]
3562 HRESULT WINAPI
VarUI2FromUI432(ULONG ulIn
, USHORT
* puiOut
)
3564 TRACE( ole
, "( %ld, %p ), stub\n", ulIn
, puiOut
);
3566 if( ulIn
< UI2_MIN
|| ulIn
> UI2_MAX
)
3568 return DISP_E_OVERFLOW
;
3571 *puiOut
= (USHORT
) ulIn
;
3576 /******************************************************************************
3577 * VarUI4FromStr32 [OLEAUT32.277]
3579 HRESULT WINAPI
VarUI4FromStr32(OLECHAR32
* strIn
, LCID lcid
, ULONG dwFlags
, ULONG
* pulOut
)
3581 double dValue
= 0.0;
3582 LPSTR pNewString
= NULL
;
3584 TRACE( ole
, "( %p, %ld, %ld, %p ), stub\n", strIn
, lcid
, dwFlags
, pulOut
);
3586 /* Check if we have a valid argument
3588 pNewString
= HEAP_strdupWtoA( GetProcessHeap(), 0, strIn
);
3589 RemoveCharacterFromString( pNewString
, "," );
3590 if( IsValidRealString( pNewString
) == FALSE
)
3592 return DISP_E_TYPEMISMATCH
;
3595 /* Convert the valid string to a floating point number.
3597 dValue
= atof( pNewString
);
3599 /* We don't need the string anymore so free it.
3601 HeapFree( GetProcessHeap(), 0, pNewString
);
3603 /* Check range of value.
3605 dValue
= round( dValue
);
3606 if( dValue
< UI4_MIN
|| dValue
> UI4_MAX
)
3608 return DISP_E_OVERFLOW
;
3611 *pulOut
= (ULONG
) dValue
;
3616 /**********************************************************************
3617 * VarUI2FromCy32 [OLEAUT32.263]
3618 * Convert currency to unsigned short
3620 HRESULT WINAPI
VarUI2FromCy32(CY cyIn
, USHORT
* pusOut
) {
3621 double t
= round((((double)cyIn
.u
.Hi
* 4294967296) + (double)cyIn
.u
.Lo
) / 10000);
3623 if (t
> UI2_MAX
|| t
< UI2_MIN
) return DISP_E_OVERFLOW
;
3625 *pusOut
= (USHORT
)t
;
3630 /******************************************************************************
3631 * VarUI4FromUI132 [OLEAUT32.270]
3633 HRESULT WINAPI
VarUI4FromUI132(BYTE bIn
, ULONG
* pulOut
)
3635 TRACE( ole
, "( %d, %p ), stub\n", bIn
, pulOut
);
3637 *pulOut
= (USHORT
) bIn
;
3642 /******************************************************************************
3643 * VarUI4FromI232 [OLEAUT32.271]
3645 HRESULT WINAPI
VarUI4FromI232(short uiIn
, ULONG
* pulOut
)
3647 TRACE( ole
, "( %d, %p ), stub\n", uiIn
, pulOut
);
3649 if( uiIn
< UI4_MIN
)
3651 return DISP_E_OVERFLOW
;
3654 *pulOut
= (ULONG
) uiIn
;
3659 /******************************************************************************
3660 * VarUI4FromI432 [OLEAUT32.272]
3662 HRESULT WINAPI
VarUI4FromI432(LONG lIn
, ULONG
* pulOut
)
3664 TRACE( ole
, "( %ld, %p ), stub\n", lIn
, pulOut
);
3668 return DISP_E_OVERFLOW
;
3671 *pulOut
= (ULONG
) lIn
;
3676 /******************************************************************************
3677 * VarUI4FromR432 [OLEAUT32.273]
3679 HRESULT WINAPI
VarUI4FromR432(FLOAT fltIn
, ULONG
* pulOut
)
3681 fltIn
= round( fltIn
);
3682 if( fltIn
< UI4_MIN
|| fltIn
> UI4_MAX
)
3684 return DISP_E_OVERFLOW
;
3687 *pulOut
= (ULONG
) fltIn
;
3692 /******************************************************************************
3693 * VarUI4FromR832 [OLEAUT32.274]
3695 HRESULT WINAPI
VarUI4FromR832(double dblIn
, ULONG
* pulOut
)
3697 TRACE( ole
, "( %f, %p ), stub\n", dblIn
, pulOut
);
3699 dblIn
= round( dblIn
);
3700 if( dblIn
< UI4_MIN
|| dblIn
> UI4_MAX
)
3702 return DISP_E_OVERFLOW
;
3705 *pulOut
= (ULONG
) dblIn
;
3710 /******************************************************************************
3711 * VarUI4FromDate32 [OLEAUT32.275]
3713 HRESULT WINAPI
VarUI4FromDate32(DATE dateIn
, ULONG
* pulOut
)
3715 TRACE( ole
, "( %f, %p ), stub\n", dateIn
, pulOut
);
3717 dateIn
= round( dateIn
);
3718 if( dateIn
< UI4_MIN
|| dateIn
> UI4_MAX
)
3720 return DISP_E_OVERFLOW
;
3723 *pulOut
= (ULONG
) dateIn
;
3728 /******************************************************************************
3729 * VarUI4FromBool32 [OLEAUT32.279]
3731 HRESULT WINAPI
VarUI4FromBool32(VARIANT_BOOL boolIn
, ULONG
* pulOut
)
3733 TRACE( ole
, "( %d, %p ), stub\n", boolIn
, pulOut
);
3735 *pulOut
= (ULONG
) boolIn
;
3740 /******************************************************************************
3741 * VarUI4FromI132 [OLEAUT32.280]
3743 HRESULT WINAPI
VarUI4FromI132(CHAR cIn
, ULONG
* pulOut
)
3745 TRACE( ole
, "( %c, %p ), stub\n", cIn
, pulOut
);
3747 *pulOut
= (ULONG
) cIn
;
3752 /******************************************************************************
3753 * VarUI4FromUI232 [OLEAUT32.281]
3755 HRESULT WINAPI
VarUI4FromUI232(USHORT uiIn
, ULONG
* pulOut
)
3757 TRACE( ole
, "( %d, %p ), stub\n", uiIn
, pulOut
);
3759 *pulOut
= (ULONG
) uiIn
;
3764 /**********************************************************************
3765 * VarUI4FromCy32 [OLEAUT32.276]
3766 * Convert currency to unsigned long
3768 HRESULT WINAPI
VarUI4FromCy32(CY cyIn
, ULONG
* pulOut
) {
3769 double t
= round((((double)cyIn
.u
.Hi
* 4294967296) + (double)cyIn
.u
.Lo
) / 10000);
3771 if (t
> UI4_MAX
|| t
< UI4_MIN
) return DISP_E_OVERFLOW
;
3778 /**********************************************************************
3779 * VarCyFromUI132 [OLEAUT32.98]
3780 * Convert unsigned char to currency
3782 HRESULT WINAPI
VarCyFromUI132(BYTE bIn
, CY
* pcyOut
) {
3784 pcyOut
->u
.Lo
= ((ULONG
)bIn
) * 10000;
3789 /**********************************************************************
3790 * VarCyFromI232 [OLEAUT32.99]
3791 * Convert signed short to currency
3793 HRESULT WINAPI
VarCyFromI232(short sIn
, CY
* pcyOut
) {
3794 if (sIn
< 0) pcyOut
->u
.Hi
= -1;
3795 else pcyOut
->u
.Hi
= 0;
3796 pcyOut
->u
.Lo
= ((ULONG
)sIn
) * 10000;
3801 /**********************************************************************
3802 * VarCyFromI432 [OLEAUT32.100]
3803 * Convert signed long to currency
3805 HRESULT WINAPI
VarCyFromI432(LONG lIn
, CY
* pcyOut
) {
3806 double t
= (double)lIn
* (double)10000;
3807 pcyOut
->u
.Hi
= (LONG
)(t
/ (double)4294967296);
3808 pcyOut
->u
.Lo
= (ULONG
)fmod(t
, (double)4294967296);
3809 if (lIn
< 0) pcyOut
->u
.Hi
--;
3814 /**********************************************************************
3815 * VarCyFromR432 [OLEAUT32.101]
3816 * Convert float to currency
3818 HRESULT WINAPI
VarCyFromR432(FLOAT fltIn
, CY
* pcyOut
) {
3819 double t
= round((double)fltIn
* (double)10000);
3820 pcyOut
->u
.Hi
= (LONG
)(t
/ (double)4294967296);
3821 pcyOut
->u
.Lo
= (ULONG
)fmod(t
, (double)4294967296);
3822 if (fltIn
< 0) pcyOut
->u
.Hi
--;
3827 /**********************************************************************
3828 * VarCyFromR832 [OLEAUT32.102]
3829 * Convert double to currency
3831 HRESULT WINAPI
VarCyFromR832(double dblIn
, CY
* pcyOut
) {
3832 double t
= round(dblIn
* (double)10000);
3833 pcyOut
->u
.Hi
= (LONG
)(t
/ (double)4294967296);
3834 pcyOut
->u
.Lo
= (ULONG
)fmod(t
, (double)4294967296);
3835 if (dblIn
< 0) pcyOut
->u
.Hi
--;
3840 /**********************************************************************
3841 * VarCyFromDate32 [OLEAUT32.103]
3842 * Convert date to currency
3844 HRESULT WINAPI
VarCyFromDate32(DATE dateIn
, CY
* pcyOut
) {
3845 double t
= round((double)dateIn
* (double)10000);
3846 pcyOut
->u
.Hi
= (LONG
)(t
/ (double)4294967296);
3847 pcyOut
->u
.Lo
= (ULONG
)fmod(t
, (double)4294967296);
3848 if (dateIn
< 0) pcyOut
->u
.Hi
--;
3853 /**********************************************************************
3854 * VarCyFromBool32 [OLEAUT32.106]
3855 * Convert boolean to currency
3857 HRESULT WINAPI
VarCyFromBool32(VARIANT_BOOL boolIn
, CY
* pcyOut
) {
3858 if (boolIn
< 0) pcyOut
->u
.Hi
= -1;
3859 else pcyOut
->u
.Hi
= 0;
3860 pcyOut
->u
.Lo
= (ULONG
)boolIn
* (ULONG
)10000;
3865 /**********************************************************************
3866 * VarCyFromI132 [OLEAUT32.225]
3867 * Convert signed char to currency
3869 HRESULT WINAPI
VarCyFromI132(CHAR cIn
, CY
* pcyOut
) {
3870 if (cIn
< 0) pcyOut
->u
.Hi
= -1;
3871 else pcyOut
->u
.Hi
= 0;
3872 pcyOut
->u
.Lo
= (ULONG
)cIn
* (ULONG
)10000;
3877 /**********************************************************************
3878 * VarCyFromUI232 [OLEAUT32.226]
3879 * Convert unsigned short to currency
3881 HRESULT WINAPI
VarCyFromUI232(USHORT usIn
, CY
* pcyOut
) {
3883 pcyOut
->u
.Lo
= (ULONG
)usIn
* (ULONG
)10000;
3888 /**********************************************************************
3889 * VarCyFromUI432 [OLEAUT32.227]
3890 * Convert unsigned long to currency
3892 HRESULT WINAPI
VarCyFromUI432(ULONG ulIn
, CY
* pcyOut
) {
3893 double t
= (double)ulIn
* (double)10000;
3894 pcyOut
->u
.Hi
= (LONG
)(t
/ (double)4294967296);
3895 pcyOut
->u
.Lo
= (ULONG
)fmod(t
, (double)4294967296);