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 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 is not complete.
19 * - The date manipulations do not support date prior to 1900.
20 * - The parsing does not accept has many formats has the Windows implementation.
38 #include "debugtools.h"
42 DEFAULT_DEBUG_CHANNEL(ole
);
46 # define FLT_MAX MAXFLOAT
48 # error "Can't find #define for MAXFLOAT/FLT_MAX"
54 static const char CHAR_MAX
= 127;
55 static const char CHAR_MIN
= -128;
56 static const BYTE UI1_MAX
= 255;
57 static const BYTE UI1_MIN
= 0;
58 static const unsigned short UI2_MAX
= 65535;
59 static const unsigned short UI2_MIN
= 0;
60 static const short I2_MAX
= 32767;
61 static const short I2_MIN
= -32768;
62 static const unsigned long UI4_MAX
= 4294967295U;
63 static const unsigned long UI4_MIN
= 0;
64 static const long I4_MAX
= 2147483647;
65 static const long I4_MIN
= -(2147483648U);
66 static const DATE DATE_MIN
= -657434;
67 static const DATE DATE_MAX
= 2958465;
70 /* This mask is used to set a flag in wReserved1 of
71 * the VARIANTARG structure. The flag indicates if
72 * the API function is using an inner variant or not.
74 #define PROCESSING_INNER_VARIANT 0x0001
76 /* General use buffer.
78 #define BUFFER_MAX 1024
79 static char pBuffer
[BUFFER_MAX
];
82 * Note a leap year is one that is a multiple of 4
83 * but not of a 100. Except if it is a multiple of
84 * 400 then it is a leap year.
86 /* According to postgeSQL date parsing functions there is
87 * a leap year when this expression is true.
88 * (((y % 4) == 0) && (((y % 100) != 0) || ((y % 400) == 0)))
89 * So according to this there is 365.2515 days in one year.
90 * One + every four years: 1/4 -> 365.25
91 * One - every 100 years: 1/100 -> 365.001
92 * One + every 400 years: 1/400 -> 365.0025
94 static const double DAYS_IN_ONE_YEAR
= 365.2515;
98 /******************************************************************************
99 * DateTimeStringToTm [INTERNAL]
101 * Converts a string representation of a date and/or time to a tm structure.
103 * Note this function uses the postgresql date parsing functions found
104 * in the parsedt.c file.
106 * Returns TRUE if successfull.
108 * Note: This function does not parse the day of the week,
109 * daylight savings time. It will only fill the followin fields in
110 * the tm struct, tm_sec, tm_min, tm_hour, tm_year, tm_day, tm_mon.
112 ******************************************************************************/
113 static BOOL
DateTimeStringToTm( OLECHAR
* strIn
, LCID lcid
, struct tm
* pTm
)
120 char *field
[MAXDATEFIELDS
];
121 int ftype
[MAXDATEFIELDS
];
122 char lowstr
[MAXDATELEN
+ 1];
123 char* strDateTime
= NULL
;
125 /* Convert the string to ASCII since this is the only format
126 * postgesql can handle.
128 strDateTime
= HEAP_strdupWtoA( GetProcessHeap(), 0, strIn
);
130 if( strDateTime
!= NULL
)
132 /* Make sure we don't go over the maximum length
133 * accepted by postgesql.
135 if( strlen( strDateTime
) <= MAXDATELEN
)
137 if( ParseDateTime( strDateTime
, lowstr
, field
, ftype
, MAXDATEFIELDS
, &nf
) == 0 )
139 if( lcid
& VAR_DATEVALUEONLY
)
141 /* Get the date information.
142 * It returns 0 if date information was
143 * present and 1 if only time information was present.
144 * -1 if an error occures.
146 if( DecodeDateTime(field
, ftype
, nf
, &dtype
, pTm
, &fsec
, &tzp
) == 0 )
148 /* Eliminate the time information since we
149 * were asked to get date information only.
157 if( lcid
& VAR_TIMEVALUEONLY
)
159 /* Get time information only.
161 if( DecodeTimeOnly(field
, ftype
, nf
, &dtype
, pTm
, &fsec
) == 0 )
168 /* Get both date and time information.
169 * It returns 0 if date information was
170 * present and 1 if only time information was present.
171 * -1 if an error occures.
173 if( DecodeDateTime(field
, ftype
, nf
, &dtype
, pTm
, &fsec
, &tzp
) != -1 )
180 HeapFree( GetProcessHeap(), 0, strDateTime
);
191 /******************************************************************************
192 * TmToDATE [INTERNAL]
194 * The date is implemented using an 8 byte floating-point number.
195 * Days are represented by whole numbers increments starting with 0.00 has
196 * being December 30 1899, midnight.
197 * The hours are expressed as the fractional part of the number.
198 * December 30 1899 at midnight = 0.00
199 * January 1 1900 at midnight = 2.00
200 * January 4 1900 at 6 AM = 5.25
201 * January 4 1900 at noon = 5.50
202 * December 29 1899 at midnight = -1.00
203 * December 18 1899 at midnight = -12.00
204 * December 18 1899 at 6AM = -12.25
205 * December 18 1899 at 6PM = -12.75
206 * December 19 1899 at midnight = -11.00
207 * The tm structure is as follows:
209 * int tm_sec; seconds after the minute - [0,59]
210 * int tm_min; minutes after the hour - [0,59]
211 * int tm_hour; hours since midnight - [0,23]
212 * int tm_mday; day of the month - [1,31]
213 * int tm_mon; months since January - [0,11]
215 * int tm_wday; days since Sunday - [0,6]
216 * int tm_yday; days since January 1 - [0,365]
217 * int tm_isdst; daylight savings time flag
220 * Note: This function does not use the tm_wday, tm_yday, tm_wday,
221 * and tm_isdst fields of the tm structure. And only converts years
224 * Returns TRUE if successfull.
226 static BOOL
TmToDATE( struct tm
* pTm
, DATE
*pDateOut
)
228 if( (pTm
->tm_year
- 1900) >= 0 )
232 /* Start at 1. This is the way DATE is defined.
233 * January 1, 1900 at Midnight is 1.00.
234 * January 1, 1900 at 6AM is 1.25.
239 /* Add the number of days corresponding to
242 *pDateOut
+= (pTm
->tm_year
- 1900) * 365;
244 /* Add the leap days in the previous years between now and 1900.
245 * Note a leap year is one that is a multiple of 4
246 * but not of a 100. Except if it is a multiple of
247 * 400 then it is a leap year.
249 *pDateOut
+= ( (pTm
->tm_year
- 1) / 4 ) - ( 1900 / 4 );
250 *pDateOut
-= ( (pTm
->tm_year
- 1) / 100 ) - ( 1900 / 100 );
251 *pDateOut
+= ( (pTm
->tm_year
- 1) / 400 ) - ( 1900 / 400 );
253 /* Set the leap year flag if the
254 * current year specified by tm_year is a
255 * leap year. This will be used to add a day
258 if( isleap( pTm
->tm_year
) )
261 /* Add the number of days corresponding to
264 switch( pTm
->tm_mon
)
270 *pDateOut
+= ( 59 + leapYear
);
273 *pDateOut
+= ( 90 + leapYear
);
276 *pDateOut
+= ( 120 + leapYear
);
279 *pDateOut
+= ( 151 + leapYear
);
282 *pDateOut
+= ( 181 + leapYear
);
285 *pDateOut
+= ( 212 + leapYear
);
288 *pDateOut
+= ( 243 + leapYear
);
291 *pDateOut
+= ( 273 + leapYear
);
294 *pDateOut
+= ( 304 + leapYear
);
297 *pDateOut
+= ( 334 + leapYear
);
300 /* Add the number of days in this month.
302 *pDateOut
+= pTm
->tm_mday
;
304 /* Add the number of seconds, minutes, and hours
305 * to the DATE. Note these are the fracionnal part
306 * of the DATE so seconds / number of seconds in a day.
308 *pDateOut
+= pTm
->tm_hour
/ 24.0;
309 *pDateOut
+= pTm
->tm_min
/ 1440.0;
310 *pDateOut
+= pTm
->tm_sec
/ 86400.0;
316 /******************************************************************************
317 * DateToTm [INTERNAL]
319 * This function converst a windows DATE to a tm structure.
321 * It does not fill all the fields of the tm structure.
322 * Here is a list of the fields that are filled:
323 * tm_sec, tm_min, tm_hour, tm_year, tm_day, tm_mon.
325 * Note this function does not support dates before the January 1, 1900
326 * or ( dateIn < 2.0 ).
328 * Returns TRUE if successfull.
330 static BOOL
DateToTm( DATE dateIn
, LCID lcid
, struct tm
* pTm
)
332 /* Do not process dates smaller than January 1, 1900.
333 * Which corresponds to 2.0 in the windows DATE format.
337 double decimalPart
= 0.0;
338 double wholePart
= 0.0;
340 memset(pTm
,0,sizeof(*pTm
));
342 /* Because of the nature of DATE format witch
343 * associates 2.0 to January 1, 1900. We will
344 * remove 1.0 from the whole part of the DATE
345 * so that in the following code 1.0
346 * will correspond to January 1, 1900.
347 * This simplyfies the processing of the DATE value.
351 wholePart
= (double) floor( dateIn
);
352 decimalPart
= fmod( dateIn
, wholePart
);
354 if( !(lcid
& VAR_TIMEVALUEONLY
) )
358 double yearsSince1900
= 0;
359 /* Start at 1900, this where the DATE time 0.0 starts.
362 /* find in what year the day in the "wholePart" falls into.
363 * add the value to the year field.
365 yearsSince1900
= floor( (wholePart
/ DAYS_IN_ONE_YEAR
) + 0.001 );
366 pTm
->tm_year
+= yearsSince1900
;
367 /* determine if this is a leap year.
369 if( isleap( pTm
->tm_year
) )
375 /* find what day of that year does the "wholePart" corresponds to.
376 * Note: nDay is in [1-366] format
378 nDay
= (int) ( wholePart
- floor( yearsSince1900
* DAYS_IN_ONE_YEAR
) );
379 /* Set the tm_yday value.
380 * Note: The day is must be converted from [1-366] to [0-365]
382 /*pTm->tm_yday = nDay - 1;*/
383 /* find which mount this day corresponds to.
390 else if( nDay
<= ( 59 + leapYear
) )
392 pTm
->tm_mday
= nDay
- 31;
395 else if( nDay
<= ( 90 + leapYear
) )
397 pTm
->tm_mday
= nDay
- ( 59 + leapYear
);
400 else if( nDay
<= ( 120 + leapYear
) )
402 pTm
->tm_mday
= nDay
- ( 90 + leapYear
);
405 else if( nDay
<= ( 151 + leapYear
) )
407 pTm
->tm_mday
= nDay
- ( 120 + leapYear
);
410 else if( nDay
<= ( 181 + leapYear
) )
412 pTm
->tm_mday
= nDay
- ( 151 + leapYear
);
415 else if( nDay
<= ( 212 + leapYear
) )
417 pTm
->tm_mday
= nDay
- ( 181 + leapYear
);
420 else if( nDay
<= ( 243 + leapYear
) )
422 pTm
->tm_mday
= nDay
- ( 212 + leapYear
);
425 else if( nDay
<= ( 273 + leapYear
) )
427 pTm
->tm_mday
= nDay
- ( 243 + leapYear
);
430 else if( nDay
<= ( 304 + leapYear
) )
432 pTm
->tm_mday
= nDay
- ( 273 + leapYear
);
435 else if( nDay
<= ( 334 + leapYear
) )
437 pTm
->tm_mday
= nDay
- ( 304 + leapYear
);
440 else if( nDay
<= ( 365 + leapYear
) )
442 pTm
->tm_mday
= nDay
- ( 334 + leapYear
);
446 if( !(lcid
& VAR_DATEVALUEONLY
) )
448 /* find the number of seconds in this day.
449 * fractional part times, hours, minutes, seconds.
451 pTm
->tm_hour
= (int) ( decimalPart
* 24 );
452 pTm
->tm_min
= (int) ( ( ( decimalPart
* 24 ) - pTm
->tm_hour
) * 60 );
453 pTm
->tm_sec
= (int) ( ( ( decimalPart
* 24 * 60 ) - ( pTm
->tm_hour
* 60 ) - pTm
->tm_min
) * 60 );
462 /******************************************************************************
463 * SizeOfVariantData [INTERNAL]
465 * This function finds the size of the data referenced by a Variant based
466 * the type "vt" of the Variant.
468 static int SizeOfVariantData( VARIANT
* parg
)
471 switch( parg
->vt
& VT_TYPEMASK
)
474 size
= sizeof(short);
486 size
= sizeof(unsigned short);
489 size
= sizeof(unsigned int);
492 size
= sizeof(unsigned long);
495 size
= sizeof(float);
498 size
= sizeof(double);
504 size
= sizeof(VARIANT_BOOL
);
507 size
= sizeof(void*);
514 FIXME("Add size information for type vt=%d\n", parg
->vt
& VT_TYPEMASK
);
520 /******************************************************************************
521 * StringDupAtoBstr [INTERNAL]
524 static BSTR
StringDupAtoBstr( char* strIn
)
527 OLECHAR
* pNewString
= NULL
;
528 pNewString
= HEAP_strdupAtoW( GetProcessHeap(), 0, strIn
);
529 bstr
= SysAllocString( pNewString
);
530 HeapFree( GetProcessHeap(), 0, pNewString
);
534 /******************************************************************************
537 * Round the double value to the nearest integer value.
539 static double round( double d
)
541 double decimals
= 0.0, integerValue
= 0.0, roundedValue
= 0.0;
542 BOOL bEvenNumber
= FALSE
;
545 /* Save the sign of the number
547 nSign
= (d
>= 0.0) ? 1 : -1;
550 /* Remove the decimals.
552 integerValue
= floor( d
);
554 /* Set the Even flag. This is used to round the number when
555 * the decimals are exactly 1/2. If the integer part is
556 * odd the number is rounded up. If the integer part
557 * is even the number is rounded down. Using this method
558 * numbers are rounded up|down half the time.
560 bEvenNumber
= (((short)fmod(integerValue
, 2)) == 0) ? TRUE
: FALSE
;
562 /* Remove the integral part of the number.
564 decimals
= d
- integerValue
;
566 /* Note: Ceil returns the smallest integer that is greater that x.
567 * and floor returns the largest integer that is less than or equal to x.
571 /* If the decimal part is greater than 1/2
573 roundedValue
= ceil( d
);
575 else if( decimals
< 0.5 )
577 /* If the decimal part is smaller than 1/2
579 roundedValue
= floor( d
);
583 /* the decimals are exactly 1/2 so round according to
584 * the bEvenNumber flag.
588 roundedValue
= floor( d
);
592 roundedValue
= ceil( d
);
596 return roundedValue
* nSign
;
599 /******************************************************************************
600 * RemoveCharacterFromString [INTERNAL]
602 * Removes any of the characters in "strOfCharToRemove" from the "str" argument.
604 static void RemoveCharacterFromString( LPSTR str
, LPSTR strOfCharToRemove
)
606 LPSTR pNewString
= NULL
;
607 LPSTR strToken
= NULL
;
610 /* Check if we have a valid argument
614 pNewString
= strdup( str
);
616 strToken
= strtok( pNewString
, strOfCharToRemove
);
617 while( strToken
!= NULL
) {
618 strcat( str
, strToken
);
619 strToken
= strtok( NULL
, strOfCharToRemove
);
626 /******************************************************************************
627 * GetValidRealString [INTERNAL]
629 * Checks if the string is of proper format to be converted to a real value.
631 static BOOL
IsValidRealString( LPSTR strRealString
)
633 /* Real values that have a decimal point are required to either have
634 * digits before or after the decimal point. We will assume that
635 * we do not have any digits at either position. If we do encounter
636 * some we will disable this flag.
638 BOOL bDigitsRequired
= TRUE
;
639 /* Processed fields in the string representation of the real number.
641 BOOL bWhiteSpaceProcessed
= FALSE
;
642 BOOL bFirstSignProcessed
= FALSE
;
643 BOOL bFirstDigitsProcessed
= FALSE
;
644 BOOL bDecimalPointProcessed
= FALSE
;
645 BOOL bSecondDigitsProcessed
= FALSE
;
646 BOOL bExponentProcessed
= FALSE
;
647 BOOL bSecondSignProcessed
= FALSE
;
648 BOOL bThirdDigitsProcessed
= FALSE
;
649 /* Assume string parameter "strRealString" is valid and try to disprove it.
651 BOOL bValidRealString
= TRUE
;
653 /* Used to count the number of tokens in the "strRealString".
655 LPSTR strToken
= NULL
;
659 /* Check if we have a valid argument
661 if( strRealString
== NULL
)
663 bValidRealString
= FALSE
;
666 if( bValidRealString
== TRUE
)
668 /* Make sure we only have ONE token in the string.
670 strToken
= strtok( strRealString
, " " );
671 while( strToken
!= NULL
) {
673 strToken
= strtok( NULL
, " " );
678 bValidRealString
= FALSE
;
683 /* Make sure this token contains only valid characters.
684 * The string argument to atof has the following form:
685 * [whitespace] [sign] [digits] [.digits] [ {d | D | e | E }[sign]digits]
686 * Whitespace consists of space and|or <TAB> characters, which are ignored.
687 * Sign is either plus '+' or minus '-'.
688 * Digits are one or more decimal digits.
689 * Note: If no digits appear before the decimal point, at least one must
690 * appear after the decimal point.
691 * The decimal digits may be followed by an exponent.
692 * An Exponent consists of an introductory letter ( D, d, E, or e) and
693 * an optionally signed decimal integer.
695 pChar
= strRealString
;
696 while( bValidRealString
== TRUE
&& *pChar
!= '\0' )
704 if( bWhiteSpaceProcessed
||
705 bFirstSignProcessed
||
706 bFirstDigitsProcessed
||
707 bDecimalPointProcessed
||
708 bSecondDigitsProcessed
||
709 bExponentProcessed
||
710 bSecondSignProcessed
||
711 bThirdDigitsProcessed
)
713 bValidRealString
= FALSE
;
720 if( bFirstSignProcessed
== FALSE
)
722 if( bFirstDigitsProcessed
||
723 bDecimalPointProcessed
||
724 bSecondDigitsProcessed
||
725 bExponentProcessed
||
726 bSecondSignProcessed
||
727 bThirdDigitsProcessed
)
729 bValidRealString
= FALSE
;
731 bWhiteSpaceProcessed
= TRUE
;
732 bFirstSignProcessed
= TRUE
;
734 else if( bSecondSignProcessed
== FALSE
)
736 /* Note: The exponent must be present in
737 * order to accept the second sign...
739 if( bExponentProcessed
== FALSE
||
740 bThirdDigitsProcessed
||
743 bValidRealString
= FALSE
;
745 bFirstSignProcessed
= TRUE
;
746 bWhiteSpaceProcessed
= TRUE
;
747 bFirstDigitsProcessed
= TRUE
;
748 bDecimalPointProcessed
= TRUE
;
749 bSecondDigitsProcessed
= TRUE
;
750 bSecondSignProcessed
= TRUE
;
766 if( bFirstDigitsProcessed
== FALSE
)
768 if( bDecimalPointProcessed
||
769 bSecondDigitsProcessed
||
770 bExponentProcessed
||
771 bSecondSignProcessed
||
772 bThirdDigitsProcessed
)
774 bValidRealString
= FALSE
;
776 bFirstSignProcessed
= TRUE
;
777 bWhiteSpaceProcessed
= TRUE
;
778 /* We have found some digits before the decimal point
779 * so disable the "Digits required" flag.
781 bDigitsRequired
= FALSE
;
783 else if( bSecondDigitsProcessed
== FALSE
)
785 if( bExponentProcessed
||
786 bSecondSignProcessed
||
787 bThirdDigitsProcessed
)
789 bValidRealString
= FALSE
;
791 bFirstSignProcessed
= TRUE
;
792 bWhiteSpaceProcessed
= TRUE
;
793 bFirstDigitsProcessed
= TRUE
;
794 bDecimalPointProcessed
= TRUE
;
795 /* We have found some digits after the decimal point
796 * so disable the "Digits required" flag.
798 bDigitsRequired
= FALSE
;
800 else if( bThirdDigitsProcessed
== FALSE
)
802 /* Getting here means everything else should be processed.
803 * If we get anything else than a decimal following this
804 * digit it will be flagged by the other cases, so
805 * we do not really need to do anything in here.
809 /* If DecimalPoint...
812 if( bDecimalPointProcessed
||
813 bSecondDigitsProcessed
||
814 bExponentProcessed
||
815 bSecondSignProcessed
||
816 bThirdDigitsProcessed
)
818 bValidRealString
= FALSE
;
820 bFirstSignProcessed
= TRUE
;
821 bWhiteSpaceProcessed
= TRUE
;
822 bFirstDigitsProcessed
= TRUE
;
823 bDecimalPointProcessed
= TRUE
;
831 if( bExponentProcessed
||
832 bSecondSignProcessed
||
833 bThirdDigitsProcessed
||
836 bValidRealString
= FALSE
;
838 bFirstSignProcessed
= TRUE
;
839 bWhiteSpaceProcessed
= TRUE
;
840 bFirstDigitsProcessed
= TRUE
;
841 bDecimalPointProcessed
= TRUE
;
842 bSecondDigitsProcessed
= TRUE
;
843 bExponentProcessed
= TRUE
;
846 bValidRealString
= FALSE
;
849 /* Process next character.
854 /* If the required digits were not present we have an invalid
855 * string representation of a real number.
857 if( bDigitsRequired
== TRUE
)
859 bValidRealString
= FALSE
;
862 return bValidRealString
;
866 /******************************************************************************
869 * This function dispatches execution to the proper conversion API
870 * to do the necessary coercion.
872 static HRESULT
Coerce( VARIANTARG
* pd
, LCID lcid
, ULONG dwFlags
, VARIANTARG
* ps
, VARTYPE vt
)
875 unsigned short vtFrom
= 0;
876 vtFrom
= ps
->vt
& VT_TYPEMASK
;
878 /* Note: Since "long" and "int" values both have 4 bytes and are
879 * both signed integers "int" will be treated as "long" in the
881 * The same goes for their unsigned versions.
884 /* Trivial Case: If the coercion is from two types that are
885 * identical then we can blindly copy from one argument to another.*/
888 return VariantCopy(pd
,ps
);
891 /* Cases requiring thought*/
896 res
= VariantClear( pd
);
899 res
= VariantClear( pd
);
909 res
= VariantCopy( pd
, ps
);
912 res
= VarI1FromI2( ps
->u
.iVal
, &(pd
->u
.cVal
) );
916 res
= VarI1FromI4( ps
->u
.lVal
, &(pd
->u
.cVal
) );
919 res
= VarI1FromUI1( ps
->u
.bVal
, &(pd
->u
.cVal
) );
922 res
= VarI1FromUI2( ps
->u
.uiVal
, &(pd
->u
.cVal
) );
926 res
= VarI1FromUI4( ps
->u
.ulVal
, &(pd
->u
.cVal
) );
929 res
= VarI1FromR4( ps
->u
.fltVal
, &(pd
->u
.cVal
) );
932 res
= VarI1FromR8( ps
->u
.dblVal
, &(pd
->u
.cVal
) );
935 res
= VarI1FromDate( ps
->u
.date
, &(pd
->u
.cVal
) );
938 res
= VarI1FromBool( ps
->u
.boolVal
, &(pd
->u
.cVal
) );
941 res
= VarI1FromStr( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.cVal
) );
944 res
= VarI1FromCy( ps
->u
.cyVal
, &(pd
->u
.cVal
) );
946 /*res = VarI1FromDisp32( ps->u.pdispVal, lcid, &(pd->u.cVal) );*/
948 /*res = VarI1From32( ps->u.lVal, &(pd->u.cVal) );*/
950 /*res = VarI1FromDec32( ps->u.decVal, &(pd->u.cVal) );*/
952 res
= DISP_E_TYPEMISMATCH
;
953 FIXME("Coercion from %d to %d\n", vtFrom
, vt
);
962 res
= VarI2FromI1( ps
->u
.cVal
, &(pd
->u
.iVal
) );
965 res
= VariantCopy( pd
, ps
);
969 res
= VarI2FromI4( ps
->u
.lVal
, &(pd
->u
.iVal
) );
972 res
= VarI2FromUI1( ps
->u
.bVal
, &(pd
->u
.iVal
) );
975 res
= VarI2FromUI2( ps
->u
.uiVal
, &(pd
->u
.iVal
) );
979 res
= VarI2FromUI4( ps
->u
.ulVal
, &(pd
->u
.iVal
) );
982 res
= VarI2FromR4( ps
->u
.fltVal
, &(pd
->u
.iVal
) );
985 res
= VarI2FromR8( ps
->u
.dblVal
, &(pd
->u
.iVal
) );
988 res
= VarI2FromDate( ps
->u
.date
, &(pd
->u
.iVal
) );
991 res
= VarI2FromBool( ps
->u
.boolVal
, &(pd
->u
.iVal
) );
994 res
= VarI2FromStr( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.iVal
) );
997 res
= VarI2FromCy( ps
->u
.cyVal
, &(pd
->u
.iVal
) );
999 /*res = VarI2FromDisp32( ps->u.pdispVal, lcid, &(pd->u.iVal) );*/
1001 /*res = VarI2From32( ps->u.lVal, &(pd->u.iVal) );*/
1003 /*res = VarI2FromDec32( ps->u.deiVal, &(pd->u.iVal) );*/
1005 res
= DISP_E_TYPEMISMATCH
;
1006 FIXME("Coercion from %d to %d\n", vtFrom
, vt
);
1016 res
= VarI4FromI1( ps
->u
.cVal
, &(pd
->u
.lVal
) );
1019 res
= VarI4FromI2( ps
->u
.iVal
, &(pd
->u
.lVal
) );
1023 res
= VariantCopy( pd
, ps
);
1026 res
= VarI4FromUI1( ps
->u
.bVal
, &(pd
->u
.lVal
) );
1029 res
= VarI4FromUI2( ps
->u
.uiVal
, &(pd
->u
.lVal
) );
1033 res
= VarI4FromUI4( ps
->u
.ulVal
, &(pd
->u
.lVal
) );
1036 res
= VarI4FromR4( ps
->u
.fltVal
, &(pd
->u
.lVal
) );
1039 res
= VarI4FromR8( ps
->u
.dblVal
, &(pd
->u
.lVal
) );
1042 res
= VarI4FromDate( ps
->u
.date
, &(pd
->u
.lVal
) );
1045 res
= VarI4FromBool( ps
->u
.boolVal
, &(pd
->u
.lVal
) );
1048 res
= VarI4FromStr( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.lVal
) );
1051 res
= VarI4FromCy( ps
->u
.cyVal
, &(pd
->u
.lVal
) );
1052 case( VT_DISPATCH
):
1053 /*res = VarI4FromDisp32( ps->u.pdispVal, lcid, &(pd->u.lVal) );*/
1055 /*res = VarI4From32( ps->u.lVal, &(pd->u.lVal) );*/
1057 /*res = VarI4FromDec32( ps->u.deiVal, &(pd->u.lVal) );*/
1059 res
= DISP_E_TYPEMISMATCH
;
1060 FIXME("Coercion from %d to %d\n", vtFrom
, vt
);
1069 res
= VarUI1FromI1( ps
->u
.cVal
, &(pd
->u
.bVal
) );
1072 res
= VarUI1FromI2( ps
->u
.iVal
, &(pd
->u
.bVal
) );
1076 res
= VarUI1FromI4( ps
->u
.lVal
, &(pd
->u
.bVal
) );
1079 res
= VariantCopy( pd
, ps
);
1082 res
= VarUI1FromUI2( ps
->u
.uiVal
, &(pd
->u
.bVal
) );
1086 res
= VarUI1FromUI4( ps
->u
.ulVal
, &(pd
->u
.bVal
) );
1089 res
= VarUI1FromR4( ps
->u
.fltVal
, &(pd
->u
.bVal
) );
1092 res
= VarUI1FromR8( ps
->u
.dblVal
, &(pd
->u
.bVal
) );
1095 res
= VarUI1FromDate( ps
->u
.date
, &(pd
->u
.bVal
) );
1098 res
= VarUI1FromBool( ps
->u
.boolVal
, &(pd
->u
.bVal
) );
1101 res
= VarUI1FromStr( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.bVal
) );
1104 res
= VarUI1FromCy( ps
->u
.cyVal
, &(pd
->u
.bVal
) );
1105 case( VT_DISPATCH
):
1106 /*res = VarUI1FromDisp32( ps->u.pdispVal, lcid, &(pd->u.bVal) );*/
1108 /*res = VarUI1From32( ps->u.lVal, &(pd->u.bVal) );*/
1110 /*res = VarUI1FromDec32( ps->u.deiVal, &(pd->u.bVal) );*/
1112 res
= DISP_E_TYPEMISMATCH
;
1113 FIXME("Coercion from %d to %d\n", vtFrom
, vt
);
1122 res
= VarUI2FromI1( ps
->u
.cVal
, &(pd
->u
.uiVal
) );
1125 res
= VarUI2FromI2( ps
->u
.iVal
, &(pd
->u
.uiVal
) );
1129 res
= VarUI2FromI4( ps
->u
.lVal
, &(pd
->u
.uiVal
) );
1132 res
= VarUI2FromUI1( ps
->u
.bVal
, &(pd
->u
.uiVal
) );
1135 res
= VariantCopy( pd
, ps
);
1139 res
= VarUI2FromUI4( ps
->u
.ulVal
, &(pd
->u
.uiVal
) );
1142 res
= VarUI2FromR4( ps
->u
.fltVal
, &(pd
->u
.uiVal
) );
1145 res
= VarUI2FromR8( ps
->u
.dblVal
, &(pd
->u
.uiVal
) );
1148 res
= VarUI2FromDate( ps
->u
.date
, &(pd
->u
.uiVal
) );
1151 res
= VarUI2FromBool( ps
->u
.boolVal
, &(pd
->u
.uiVal
) );
1154 res
= VarUI2FromStr( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.uiVal
) );
1157 res
= VarUI2FromCy( ps
->u
.cyVal
, &(pd
->u
.uiVal
) );
1158 case( VT_DISPATCH
):
1159 /*res = VarUI2FromDisp32( ps->u.pdispVal, lcid, &(pd->u.uiVal) );*/
1161 /*res = VarUI2From32( ps->u.lVal, &(pd->u.uiVal) );*/
1163 /*res = VarUI2FromDec32( ps->u.deiVal, &(pd->u.uiVal) );*/
1165 res
= DISP_E_TYPEMISMATCH
;
1166 FIXME("Coercion from %d to %d\n", vtFrom
, vt
);
1176 res
= VarUI4FromI1( ps
->u
.cVal
, &(pd
->u
.ulVal
) );
1179 res
= VarUI4FromI2( ps
->u
.iVal
, &(pd
->u
.ulVal
) );
1183 res
= VarUI4FromI4( ps
->u
.lVal
, &(pd
->u
.ulVal
) );
1186 res
= VarUI4FromUI1( ps
->u
.bVal
, &(pd
->u
.ulVal
) );
1189 res
= VarUI4FromUI2( ps
->u
.uiVal
, &(pd
->u
.ulVal
) );
1192 res
= VariantCopy( pd
, ps
);
1195 res
= VarUI4FromR4( ps
->u
.fltVal
, &(pd
->u
.ulVal
) );
1198 res
= VarUI4FromR8( ps
->u
.dblVal
, &(pd
->u
.ulVal
) );
1201 res
= VarUI4FromDate( ps
->u
.date
, &(pd
->u
.ulVal
) );
1204 res
= VarUI4FromBool( ps
->u
.boolVal
, &(pd
->u
.ulVal
) );
1207 res
= VarUI4FromStr( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.ulVal
) );
1210 res
= VarUI4FromCy( ps
->u
.cyVal
, &(pd
->u
.ulVal
) );
1211 case( VT_DISPATCH
):
1212 /*res = VarUI4FromDisp32( ps->u.pdispVal, lcid, &(pd->u.ulVal) );*/
1214 /*res = VarUI4From32( ps->u.lVal, &(pd->u.ulVal) );*/
1216 /*res = VarUI4FromDec32( ps->u.deiVal, &(pd->u.ulVal) );*/
1218 res
= DISP_E_TYPEMISMATCH
;
1219 FIXME("Coercion from %d to %d\n", vtFrom
, vt
);
1228 res
= VarR4FromI1( ps
->u
.cVal
, &(pd
->u
.fltVal
) );
1231 res
= VarR4FromI2( ps
->u
.iVal
, &(pd
->u
.fltVal
) );
1235 res
= VarR4FromI4( ps
->u
.lVal
, &(pd
->u
.fltVal
) );
1238 res
= VarR4FromUI1( ps
->u
.bVal
, &(pd
->u
.fltVal
) );
1241 res
= VarR4FromUI2( ps
->u
.uiVal
, &(pd
->u
.fltVal
) );
1245 res
= VarR4FromUI4( ps
->u
.ulVal
, &(pd
->u
.fltVal
) );
1248 res
= VariantCopy( pd
, ps
);
1251 res
= VarR4FromR8( ps
->u
.dblVal
, &(pd
->u
.fltVal
) );
1254 res
= VarR4FromDate( ps
->u
.date
, &(pd
->u
.fltVal
) );
1257 res
= VarR4FromBool( ps
->u
.boolVal
, &(pd
->u
.fltVal
) );
1260 res
= VarR4FromStr( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.fltVal
) );
1263 res
= VarR4FromCy( ps
->u
.cyVal
, &(pd
->u
.fltVal
) );
1264 case( VT_DISPATCH
):
1265 /*res = VarR4FromDisp32( ps->u.pdispVal, lcid, &(pd->u.fltVal) );*/
1267 /*res = VarR4From32( ps->u.lVal, &(pd->u.fltVal) );*/
1269 /*res = VarR4FromDec32( ps->u.deiVal, &(pd->u.fltVal) );*/
1271 res
= DISP_E_TYPEMISMATCH
;
1272 FIXME("Coercion from %d to %d\n", vtFrom
, vt
);
1281 res
= VarR8FromI1( ps
->u
.cVal
, &(pd
->u
.dblVal
) );
1284 res
= VarR8FromI2( ps
->u
.iVal
, &(pd
->u
.dblVal
) );
1288 res
= VarR8FromI4( ps
->u
.lVal
, &(pd
->u
.dblVal
) );
1291 res
= VarR8FromUI1( ps
->u
.bVal
, &(pd
->u
.dblVal
) );
1294 res
= VarR8FromUI2( ps
->u
.uiVal
, &(pd
->u
.dblVal
) );
1298 res
= VarR8FromUI4( ps
->u
.ulVal
, &(pd
->u
.dblVal
) );
1301 res
= VarR8FromR4( ps
->u
.fltVal
, &(pd
->u
.dblVal
) );
1304 res
= VariantCopy( pd
, ps
);
1307 res
= VarR8FromDate( ps
->u
.date
, &(pd
->u
.dblVal
) );
1310 res
= VarR8FromBool( ps
->u
.boolVal
, &(pd
->u
.dblVal
) );
1313 res
= VarR8FromStr( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.dblVal
) );
1316 res
= VarR8FromCy( ps
->u
.cyVal
, &(pd
->u
.dblVal
) );
1317 case( VT_DISPATCH
):
1318 /*res = VarR8FromDisp32( ps->u.pdispVal, lcid, &(pd->u.dblVal) );*/
1320 /*res = VarR8From32( ps->u.lVal, &(pd->u.dblVal) );*/
1322 /*res = VarR8FromDec32( ps->u.deiVal, &(pd->u.dblVal) );*/
1324 res
= DISP_E_TYPEMISMATCH
;
1325 FIXME("Coercion from %d to %d\n", vtFrom
, vt
);
1334 res
= VarDateFromI1( ps
->u
.cVal
, &(pd
->u
.date
) );
1337 res
= VarDateFromI2( ps
->u
.iVal
, &(pd
->u
.date
) );
1340 res
= VarDateFromInt( ps
->u
.intVal
, &(pd
->u
.date
) );
1343 res
= VarDateFromI4( ps
->u
.lVal
, &(pd
->u
.date
) );
1346 res
= VarDateFromUI1( ps
->u
.bVal
, &(pd
->u
.date
) );
1349 res
= VarDateFromUI2( ps
->u
.uiVal
, &(pd
->u
.date
) );
1352 res
= VarDateFromUint( ps
->u
.uintVal
, &(pd
->u
.date
) );
1355 res
= VarDateFromUI4( ps
->u
.ulVal
, &(pd
->u
.date
) );
1358 res
= VarDateFromR4( ps
->u
.fltVal
, &(pd
->u
.date
) );
1361 res
= VarDateFromR8( ps
->u
.dblVal
, &(pd
->u
.date
) );
1364 res
= VariantCopy( pd
, ps
);
1367 res
= VarDateFromBool( ps
->u
.boolVal
, &(pd
->u
.date
) );
1370 res
= VarDateFromStr( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.date
) );
1373 res
= VarDateFromCy( ps
->u
.cyVal
, &(pd
->u
.date
) );
1374 case( VT_DISPATCH
):
1375 /*res = VarDateFromDisp32( ps->u.pdispVal, lcid, &(pd->u.date) );*/
1377 /*res = VarDateFrom32( ps->u.lVal, &(pd->u.date) );*/
1379 /*res = VarDateFromDec32( ps->u.deiVal, &(pd->u.date) );*/
1381 res
= DISP_E_TYPEMISMATCH
;
1382 FIXME("Coercion from %d to %d\n", vtFrom
, vt
);
1391 res
= VarBoolFromI1( ps
->u
.cVal
, &(pd
->u
.boolVal
) );
1394 res
= VarBoolFromI2( ps
->u
.iVal
, &(pd
->u
.boolVal
) );
1397 res
= VarBoolFromInt( ps
->u
.intVal
, &(pd
->u
.boolVal
) );
1400 res
= VarBoolFromI4( ps
->u
.lVal
, &(pd
->u
.boolVal
) );
1403 res
= VarBoolFromUI1( ps
->u
.bVal
, &(pd
->u
.boolVal
) );
1406 res
= VarBoolFromUI2( ps
->u
.uiVal
, &(pd
->u
.boolVal
) );
1409 res
= VarBoolFromUint( ps
->u
.uintVal
, &(pd
->u
.boolVal
) );
1412 res
= VarBoolFromUI4( ps
->u
.ulVal
, &(pd
->u
.boolVal
) );
1415 res
= VarBoolFromR4( ps
->u
.fltVal
, &(pd
->u
.boolVal
) );
1418 res
= VarBoolFromR8( ps
->u
.dblVal
, &(pd
->u
.boolVal
) );
1421 res
= VarBoolFromDate( ps
->u
.date
, &(pd
->u
.boolVal
) );
1424 res
= VariantCopy( pd
, ps
);
1427 res
= VarBoolFromStr( ps
->u
.bstrVal
, lcid
, dwFlags
, &(pd
->u
.boolVal
) );
1430 res
= VarBoolFromCy( ps
->u
.cyVal
, &(pd
->u
.boolVal
) );
1431 case( VT_DISPATCH
):
1432 /*res = VarBoolFromDisp32( ps->u.pdispVal, lcid, &(pd->u.boolVal) );*/
1434 /*res = VarBoolFrom32( ps->u.lVal, &(pd->u.boolVal) );*/
1436 /*res = VarBoolFromDec32( ps->u.deiVal, &(pd->u.boolVal) );*/
1438 res
= DISP_E_TYPEMISMATCH
;
1439 FIXME("Coercion from %d to %d\n", vtFrom
, vt
);
1448 res
= VarBstrFromI1( ps
->u
.cVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1451 res
= VarBstrFromI2( ps
->u
.iVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1454 res
= VarBstrFromInt( ps
->u
.intVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1457 res
= VarBstrFromI4( ps
->u
.lVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1460 res
= VarBstrFromUI1( ps
->u
.bVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1463 res
= VarBstrFromUI2( ps
->u
.uiVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1466 res
= VarBstrFromUint( ps
->u
.uintVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1469 res
= VarBstrFromUI4( ps
->u
.ulVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1472 res
= VarBstrFromR4( ps
->u
.fltVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1475 res
= VarBstrFromR8( ps
->u
.dblVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1478 res
= VarBstrFromDate( ps
->u
.date
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1481 res
= VarBstrFromBool( ps
->u
.boolVal
, lcid
, dwFlags
, &(pd
->u
.bstrVal
) );
1484 res
= VariantCopy( pd
, ps
);
1487 /*res = VarBstrFromCy32( ps->u.cyVal, lcid, dwFlags, &(pd->u.bstrVal) );*/
1488 case( VT_DISPATCH
):
1489 /*res = VarBstrFromDisp32( ps->u.pdispVal, lcid, lcid, dwFlags, &(pd->u.bstrVal) );*/
1491 /*res = VarBstrFrom32( ps->u.lVal, lcid, dwFlags, &(pd->u.bstrVal) );*/
1493 /*res = VarBstrFromDec32( ps->u.deiVal, lcid, dwFlags, &(pd->u.bstrVal) );*/
1495 res
= DISP_E_TYPEMISMATCH
;
1496 FIXME("Coercion from %d to %d\n", vtFrom
, vt
);
1505 res
= VarCyFromI1( ps
->u
.cVal
, &(pd
->u
.cyVal
) );
1508 res
= VarCyFromI2( ps
->u
.iVal
, &(pd
->u
.cyVal
) );
1511 res
= VarCyFromInt( ps
->u
.intVal
, &(pd
->u
.cyVal
) );
1514 res
= VarCyFromI4( ps
->u
.lVal
, &(pd
->u
.cyVal
) );
1517 res
= VarCyFromUI1( ps
->u
.bVal
, &(pd
->u
.cyVal
) );
1520 res
= VarCyFromUI2( ps
->u
.uiVal
, &(pd
->u
.cyVal
) );
1523 res
= VarCyFromUint( ps
->u
.uintVal
, &(pd
->u
.cyVal
) );
1526 res
= VarCyFromUI4( ps
->u
.ulVal
, &(pd
->u
.cyVal
) );
1529 res
= VarCyFromR4( ps
->u
.fltVal
, &(pd
->u
.cyVal
) );
1532 res
= VarCyFromR8( ps
->u
.dblVal
, &(pd
->u
.cyVal
) );
1535 res
= VarCyFromDate( ps
->u
.date
, &(pd
->u
.cyVal
) );
1538 res
= VarCyFromBool( ps
->u
.date
, &(pd
->u
.cyVal
) );
1541 res
= VariantCopy( pd
, ps
);
1544 /*res = VarCyFromStr32( ps->u.bstrVal, lcid, dwFlags, &(pd->u.cyVal) );*/
1545 case( VT_DISPATCH
):
1546 /*res = VarCyFromDisp32( ps->u.pdispVal, lcid, &(pd->u.boolVal) );*/
1548 /*res = VarCyFrom32( ps->u.lVal, &(pd->u.boolVal) );*/
1550 /*res = VarCyFromDec32( ps->u.deiVal, &(pd->u.boolVal) );*/
1552 res
= DISP_E_TYPEMISMATCH
;
1553 FIXME("Coercion from %d to %d\n", vtFrom
, vt
);
1559 res
= DISP_E_TYPEMISMATCH
;
1560 FIXME("Coercion from %d to %d\n", vtFrom
, vt
);
1567 /******************************************************************************
1568 * ValidateVtRange [INTERNAL]
1570 * Used internally by the hi-level Variant API to determine
1571 * if the vartypes are valid.
1573 static HRESULT WINAPI
ValidateVtRange( VARTYPE vt
)
1575 /* if by value we must make sure it is in the
1576 * range of the valid types.
1578 if( ( vt
& VT_TYPEMASK
) > VT_MAXVALIDTYPE
)
1580 return DISP_E_BADVARTYPE
;
1586 /******************************************************************************
1587 * ValidateVartype [INTERNAL]
1589 * Used internally by the hi-level Variant API to determine
1590 * if the vartypes are valid.
1592 static HRESULT WINAPI
ValidateVariantType( VARTYPE vt
)
1596 /* check if we have a valid argument.
1600 /* if by reference check that the type is in
1601 * the valid range and that it is not of empty or null type
1603 if( ( vt
& VT_TYPEMASK
) == VT_EMPTY
||
1604 ( vt
& VT_TYPEMASK
) == VT_NULL
||
1605 ( vt
& VT_TYPEMASK
) > VT_MAXVALIDTYPE
)
1613 res
= ValidateVtRange( vt
);
1619 /******************************************************************************
1620 * ValidateVt [INTERNAL]
1622 * Used internally by the hi-level Variant API to determine
1623 * if the vartypes are valid.
1625 static HRESULT WINAPI
ValidateVt( VARTYPE vt
)
1629 /* check if we have a valid argument.
1633 /* if by reference check that the type is in
1634 * the valid range and that it is not of empty or null type
1636 if( ( vt
& VT_TYPEMASK
) == VT_EMPTY
||
1637 ( vt
& VT_TYPEMASK
) == VT_NULL
||
1638 ( vt
& VT_TYPEMASK
) > VT_MAXVALIDTYPE
)
1640 res
= DISP_E_BADVARTYPE
;
1646 res
= ValidateVtRange( vt
);
1656 /******************************************************************************
1657 * VariantInit32 [OLEAUT32.8]
1659 * Initializes the Variant. Unlike VariantClear it does not interpret the current
1660 * contents of the Variant.
1662 void WINAPI
VariantInit(VARIANTARG
* pvarg
)
1664 TRACE("(%p),stub\n",pvarg
);
1666 memset(pvarg
, 0, sizeof (VARIANTARG
));
1667 pvarg
->vt
= VT_EMPTY
;
1672 /******************************************************************************
1673 * VariantClear32 [OLEAUT32.9]
1675 * This function clears the VARIANT by setting the vt field to VT_EMPTY. It also
1676 * sets the wReservedX field to 0. The current contents of the VARIANT are
1677 * freed. If the vt is VT_BSTR the string is freed. If VT_DISPATCH the object is
1678 * released. If VT_ARRAY the array is freed.
1680 HRESULT WINAPI
VariantClear(VARIANTARG
* pvarg
)
1683 TRACE("(%p)\n",pvarg
);
1685 res
= ValidateVariantType( pvarg
->vt
);
1688 if( !( pvarg
->vt
& VT_BYREF
) )
1691 * The VT_ARRAY flag is a special case of a safe array.
1693 if ( (pvarg
->vt
& VT_ARRAY
) != 0)
1695 SafeArrayDestroy(pvarg
->u
.parray
);
1699 switch( pvarg
->vt
& VT_TYPEMASK
)
1702 SysFreeString( pvarg
->u
.bstrVal
);
1704 case( VT_DISPATCH
):
1705 if(pvarg
->u
.pdispVal
!=NULL
)
1706 ICOM_CALL(Release
,pvarg
->u
.pdispVal
);
1709 VariantClear(pvarg
->u
.pvarVal
);
1712 if(pvarg
->u
.punkVal
!=NULL
)
1713 ICOM_CALL(Release
,pvarg
->u
.punkVal
);
1715 case( VT_SAFEARRAY
):
1716 SafeArrayDestroy(pvarg
->u
.parray
);
1725 * Empty all the fields and mark the type as empty.
1727 memset(pvarg
, 0, sizeof (VARIANTARG
));
1728 pvarg
->vt
= VT_EMPTY
;
1734 /******************************************************************************
1735 * VariantCopy32 [OLEAUT32.10]
1737 * Frees up the designation variant and makes a copy of the source.
1739 HRESULT WINAPI
VariantCopy(VARIANTARG
* pvargDest
, VARIANTARG
* pvargSrc
)
1743 TRACE("(%p, %p)\n", pvargDest
, pvargSrc
);
1745 res
= ValidateVariantType( pvargSrc
->vt
);
1747 /* If the pointer are to the same variant we don't need
1750 if( pvargDest
!= pvargSrc
&& res
== S_OK
)
1752 res
= VariantClear( pvargDest
);
1756 if( pvargSrc
->vt
& VT_BYREF
)
1758 /* In the case of byreference we only need
1759 * to copy the pointer.
1761 pvargDest
->u
= pvargSrc
->u
;
1762 pvargDest
->vt
= pvargSrc
->vt
;
1767 * The VT_ARRAY flag is another way to designate a safe array.
1769 if (pvargSrc
->vt
& VT_ARRAY
)
1771 SafeArrayCopy(pvargSrc
->u
.parray
, &pvargDest
->u
.parray
);
1775 /* In the case of by value we need to
1776 * copy the actuall value. In the case of
1777 * VT_BSTR a copy of the string is made,
1778 * if VT_DISPATCH or VT_IUNKNOWN AddReff is
1779 * called to increment the object's reference count.
1781 switch( pvargSrc
->vt
& VT_TYPEMASK
)
1784 pvargDest
->u
.bstrVal
= SysAllocString( pvargSrc
->u
.bstrVal
);
1786 case( VT_DISPATCH
):
1787 pvargDest
->u
.pdispVal
= pvargSrc
->u
.pdispVal
;
1788 if (pvargDest
->u
.pdispVal
!=NULL
)
1789 ICOM_CALL(AddRef
,pvargDest
->u
.pdispVal
);
1792 VariantCopy(pvargDest
->u
.pvarVal
,pvargSrc
->u
.pvarVal
);
1795 pvargDest
->u
.punkVal
= pvargSrc
->u
.punkVal
;
1796 if (pvargDest
->u
.pdispVal
!=NULL
)
1797 ICOM_CALL(AddRef
,pvargDest
->u
.punkVal
);
1799 case( VT_SAFEARRAY
):
1800 SafeArrayCopy(pvargSrc
->u
.parray
, &pvargDest
->u
.parray
);
1803 pvargDest
->u
= pvargSrc
->u
;
1808 pvargDest
->vt
= pvargSrc
->vt
;
1817 /******************************************************************************
1818 * VariantCopyInd32 [OLEAUT32.11]
1820 * Frees up the destination variant and makes a copy of the source. If
1821 * the source is of type VT_BYREF it performs the necessary indirections.
1823 HRESULT WINAPI
VariantCopyInd(VARIANT
* pvargDest
, VARIANTARG
* pvargSrc
)
1827 TRACE("(%p, %p)\n", pvargDest
, pvargSrc
);
1829 res
= ValidateVariantType( pvargSrc
->vt
);
1834 if( pvargSrc
->vt
& VT_BYREF
)
1837 VariantInit( &varg
);
1839 /* handle the in place copy.
1841 if( pvargDest
== pvargSrc
)
1843 /* we will use a copy of the source instead.
1845 res
= VariantCopy( &varg
, pvargSrc
);
1851 res
= VariantClear( pvargDest
);
1856 * The VT_ARRAY flag is another way to designate a safearray variant.
1858 if ( pvargSrc
->vt
& VT_ARRAY
)
1860 SafeArrayCopy(*pvargSrc
->u
.pparray
, &pvargDest
->u
.parray
);
1864 /* In the case of by reference we need
1865 * to copy the date pointed to by the variant.
1868 /* Get the variant type.
1870 switch( pvargSrc
->vt
& VT_TYPEMASK
)
1873 pvargDest
->u
.bstrVal
= SysAllocString( *(pvargSrc
->u
.pbstrVal
) );
1875 case( VT_DISPATCH
):
1879 /* Prevent from cycling. According to tests on
1880 * VariantCopyInd in Windows and the documentation
1881 * this API dereferences the inner Variants to only one depth.
1882 * If the inner Variant itself contains an
1883 * other inner variant the E_INVALIDARG error is
1886 if( pvargSrc
->wReserved1
& PROCESSING_INNER_VARIANT
)
1888 /* If we get here we are attempting to deference
1889 * an inner variant that that is itself contained
1890 * in an inner variant so report E_INVALIDARG error.
1896 /* Set the processing inner variant flag.
1897 * We will set this flag in the inner variant
1898 * that will be passed to the VariantCopyInd function.
1900 (pvargSrc
->u
.pvarVal
)->wReserved1
|= PROCESSING_INNER_VARIANT
;
1902 /* Dereference the inner variant.
1904 res
= VariantCopyInd( pvargDest
, pvargSrc
->u
.pvarVal
);
1910 case( VT_SAFEARRAY
):
1911 SafeArrayCopy(*pvargSrc
->u
.pparray
, &pvargDest
->u
.parray
);
1914 /* This is a by reference Variant which means that the union
1915 * part of the Variant contains a pointer to some data of
1916 * type "pvargSrc->vt & VT_TYPEMASK".
1917 * We will deference this data in a generic fashion using
1918 * the void pointer "Variant.u.byref".
1919 * We will copy this data into the union of the destination
1922 memcpy( &pvargDest
->u
, pvargSrc
->u
.byref
, SizeOfVariantData( pvargSrc
) );
1927 pvargDest
->vt
= pvargSrc
->vt
& VT_TYPEMASK
;
1931 /* this should not fail.
1933 VariantClear( &varg
);
1937 res
= VariantCopy( pvargDest
, pvargSrc
);
1943 /******************************************************************************
1944 * VariantChangeType32 [OLEAUT32.12]
1946 HRESULT WINAPI
VariantChangeType(VARIANTARG
* pvargDest
, VARIANTARG
* pvargSrc
,
1947 USHORT wFlags
, VARTYPE vt
)
1949 return VariantChangeTypeEx( pvargDest
, pvargSrc
, 0, wFlags
, vt
);
1952 /******************************************************************************
1953 * VariantChangeTypeEx32 [OLEAUT32.147]
1955 HRESULT WINAPI
VariantChangeTypeEx(VARIANTARG
* pvargDest
, VARIANTARG
* pvargSrc
,
1956 LCID lcid
, USHORT wFlags
, VARTYPE vt
)
1960 VariantInit( &varg
);
1962 TRACE("(%p, %p, %ld, %u, %u),stub\n", pvargDest
, pvargSrc
, lcid
, wFlags
, vt
);
1964 /* validate our source argument.
1966 res
= ValidateVariantType( pvargSrc
->vt
);
1968 /* validate the vartype.
1972 res
= ValidateVt( vt
);
1975 /* if we are doing an in-place conversion make a copy of the source.
1977 if( res
== S_OK
&& pvargDest
== pvargSrc
)
1979 res
= VariantCopy( &varg
, pvargSrc
);
1985 /* free up the destination variant.
1987 res
= VariantClear( pvargDest
);
1992 if( pvargSrc
->vt
& VT_BYREF
)
1994 /* Convert the source variant to a "byvalue" variant.
1997 VariantInit( &Variant
);
1998 res
= VariantCopyInd( &Variant
, pvargSrc
);
2001 res
= Coerce( pvargDest
, lcid
, wFlags
, &Variant
, vt
);
2002 /* this should not fail.
2004 VariantClear( &Variant
);
2010 /* Use the current "byvalue" source variant.
2012 res
= Coerce( pvargDest
, lcid
, wFlags
, pvargSrc
, vt
);
2015 /* this should not fail.
2017 VariantClear( &varg
);
2019 /* set the type of the destination
2030 /******************************************************************************
2031 * VarUI1FromI232 [OLEAUT32.130]
2033 HRESULT WINAPI
VarUI1FromI2(short sIn
, BYTE
* pbOut
)
2035 TRACE("( %d, %p ), stub\n", sIn
, pbOut
);
2037 /* Check range of value.
2039 if( sIn
< UI1_MIN
|| sIn
> UI1_MAX
)
2041 return DISP_E_OVERFLOW
;
2044 *pbOut
= (BYTE
) sIn
;
2049 /******************************************************************************
2050 * VarUI1FromI432 [OLEAUT32.131]
2052 HRESULT WINAPI
VarUI1FromI4(LONG lIn
, BYTE
* pbOut
)
2054 TRACE("( %ld, %p ), stub\n", lIn
, pbOut
);
2056 /* Check range of value.
2058 if( lIn
< UI1_MIN
|| lIn
> UI1_MAX
)
2060 return DISP_E_OVERFLOW
;
2063 *pbOut
= (BYTE
) lIn
;
2069 /******************************************************************************
2070 * VarUI1FromR432 [OLEAUT32.132]
2072 HRESULT WINAPI
VarUI1FromR4(FLOAT fltIn
, BYTE
* pbOut
)
2074 TRACE("( %f, %p ), stub\n", fltIn
, pbOut
);
2076 /* Check range of value.
2078 fltIn
= round( fltIn
);
2079 if( fltIn
< UI1_MIN
|| fltIn
> UI1_MAX
)
2081 return DISP_E_OVERFLOW
;
2084 *pbOut
= (BYTE
) fltIn
;
2089 /******************************************************************************
2090 * VarUI1FromR832 [OLEAUT32.133]
2092 HRESULT WINAPI
VarUI1FromR8(double dblIn
, BYTE
* pbOut
)
2094 TRACE("( %f, %p ), stub\n", dblIn
, pbOut
);
2096 /* Check range of value.
2098 dblIn
= round( dblIn
);
2099 if( dblIn
< UI1_MIN
|| dblIn
> UI1_MAX
)
2101 return DISP_E_OVERFLOW
;
2104 *pbOut
= (BYTE
) dblIn
;
2109 /******************************************************************************
2110 * VarUI1FromDate32 [OLEAUT32.135]
2112 HRESULT WINAPI
VarUI1FromDate(DATE dateIn
, BYTE
* pbOut
)
2114 TRACE("( %f, %p ), stub\n", dateIn
, pbOut
);
2116 /* Check range of value.
2118 dateIn
= round( dateIn
);
2119 if( dateIn
< UI1_MIN
|| dateIn
> UI1_MAX
)
2121 return DISP_E_OVERFLOW
;
2124 *pbOut
= (BYTE
) dateIn
;
2129 /******************************************************************************
2130 * VarUI1FromBool32 [OLEAUT32.138]
2132 HRESULT WINAPI
VarUI1FromBool(VARIANT_BOOL boolIn
, BYTE
* pbOut
)
2134 TRACE("( %d, %p ), stub\n", boolIn
, pbOut
);
2136 *pbOut
= (BYTE
) boolIn
;
2141 /******************************************************************************
2142 * VarUI1FromI132 [OLEAUT32.237]
2144 HRESULT WINAPI
VarUI1FromI1(CHAR cIn
, BYTE
* pbOut
)
2146 TRACE("( %c, %p ), stub\n", cIn
, pbOut
);
2153 /******************************************************************************
2154 * VarUI1FromUI232 [OLEAUT32.238]
2156 HRESULT WINAPI
VarUI1FromUI2(USHORT uiIn
, BYTE
* pbOut
)
2158 TRACE("( %d, %p ), stub\n", uiIn
, pbOut
);
2160 /* Check range of value.
2162 if( uiIn
> UI1_MAX
)
2164 return DISP_E_OVERFLOW
;
2167 *pbOut
= (BYTE
) uiIn
;
2172 /******************************************************************************
2173 * VarUI1FromUI432 [OLEAUT32.239]
2175 HRESULT WINAPI
VarUI1FromUI4(ULONG ulIn
, BYTE
* pbOut
)
2177 TRACE("( %ld, %p ), stub\n", ulIn
, pbOut
);
2179 /* Check range of value.
2181 if( ulIn
> UI1_MAX
)
2183 return DISP_E_OVERFLOW
;
2186 *pbOut
= (BYTE
) ulIn
;
2192 /******************************************************************************
2193 * VarUI1FromStr32 [OLEAUT32.54]
2195 HRESULT WINAPI
VarUI1FromStr(OLECHAR
* strIn
, LCID lcid
, ULONG dwFlags
, BYTE
* pbOut
)
2197 double dValue
= 0.0;
2198 LPSTR pNewString
= NULL
;
2200 TRACE("( %p, 0x%08lx, 0x%08lx, %p ), stub\n", strIn
, lcid
, dwFlags
, pbOut
);
2202 /* Check if we have a valid argument
2204 pNewString
= HEAP_strdupWtoA( GetProcessHeap(), 0, strIn
);
2205 RemoveCharacterFromString( pNewString
, "," );
2206 if( IsValidRealString( pNewString
) == FALSE
)
2208 return DISP_E_TYPEMISMATCH
;
2211 /* Convert the valid string to a floating point number.
2213 dValue
= atof( pNewString
);
2215 /* We don't need the string anymore so free it.
2217 HeapFree( GetProcessHeap(), 0 , pNewString
);
2219 /* Check range of value.
2221 dValue
= round( dValue
);
2222 if( dValue
< UI1_MIN
|| dValue
> UI1_MAX
)
2224 return DISP_E_OVERFLOW
;
2227 *pbOut
= (BYTE
) dValue
;
2232 /**********************************************************************
2233 * VarUI1FromCy32 [OLEAUT32.134]
2234 * Convert currency to unsigned char
2236 HRESULT WINAPI
VarUI1FromCy(CY cyIn
, BYTE
* pbOut
) {
2237 double t
= round((((double)cyIn
.s
.Hi
* 4294967296.0) + (double)cyIn
.s
.Lo
) / 10000);
2239 if (t
> UI1_MAX
|| t
< UI1_MIN
) return DISP_E_OVERFLOW
;
2245 /******************************************************************************
2246 * VarI2FromUI132 [OLEAUT32.48]
2248 HRESULT WINAPI
VarI2FromUI1(BYTE bIn
, short* psOut
)
2250 TRACE("( 0x%08x, %p ), stub\n", bIn
, psOut
);
2252 *psOut
= (short) bIn
;
2257 /******************************************************************************
2258 * VarI2FromI432 [OLEAUT32.49]
2260 HRESULT WINAPI
VarI2FromI4(LONG lIn
, short* psOut
)
2262 TRACE("( %lx, %p ), stub\n", lIn
, psOut
);
2264 /* Check range of value.
2266 if( lIn
< I2_MIN
|| lIn
> I2_MAX
)
2268 return DISP_E_OVERFLOW
;
2271 *psOut
= (short) lIn
;
2276 /******************************************************************************
2277 * VarI2FromR432 [OLEAUT32.50]
2279 HRESULT WINAPI
VarI2FromR4(FLOAT fltIn
, short* psOut
)
2281 TRACE("( %f, %p ), stub\n", fltIn
, psOut
);
2283 /* Check range of value.
2285 fltIn
= round( fltIn
);
2286 if( fltIn
< I2_MIN
|| fltIn
> I2_MAX
)
2288 return DISP_E_OVERFLOW
;
2291 *psOut
= (short) fltIn
;
2296 /******************************************************************************
2297 * VarI2FromR832 [OLEAUT32.51]
2299 HRESULT WINAPI
VarI2FromR8(double dblIn
, short* psOut
)
2301 TRACE("( %f, %p ), stub\n", dblIn
, psOut
);
2303 /* Check range of value.
2305 dblIn
= round( dblIn
);
2306 if( dblIn
< I2_MIN
|| dblIn
> I2_MAX
)
2308 return DISP_E_OVERFLOW
;
2311 *psOut
= (short) dblIn
;
2316 /******************************************************************************
2317 * VarI2FromDate32 [OLEAUT32.53]
2319 HRESULT WINAPI
VarI2FromDate(DATE dateIn
, short* psOut
)
2321 TRACE("( %f, %p ), stub\n", dateIn
, psOut
);
2323 /* Check range of value.
2325 dateIn
= round( dateIn
);
2326 if( dateIn
< I2_MIN
|| dateIn
> I2_MAX
)
2328 return DISP_E_OVERFLOW
;
2331 *psOut
= (short) dateIn
;
2336 /******************************************************************************
2337 * VarI2FromBool32 [OLEAUT32.56]
2339 HRESULT WINAPI
VarI2FromBool(VARIANT_BOOL boolIn
, short* psOut
)
2341 TRACE("( %d, %p ), stub\n", boolIn
, psOut
);
2343 *psOut
= (short) boolIn
;
2348 /******************************************************************************
2349 * VarI2FromI132 [OLEAUT32.48]
2351 HRESULT WINAPI
VarI2FromI1(CHAR cIn
, short* psOut
)
2353 TRACE("( %c, %p ), stub\n", cIn
, psOut
);
2355 *psOut
= (short) cIn
;
2360 /******************************************************************************
2361 * VarI2FromUI232 [OLEAUT32.206]
2363 HRESULT WINAPI
VarI2FromUI2(USHORT uiIn
, short* psOut
)
2365 TRACE("( %d, %p ), stub\n", uiIn
, psOut
);
2367 /* Check range of value.
2371 return DISP_E_OVERFLOW
;
2374 *psOut
= (short) uiIn
;
2379 /******************************************************************************
2380 * VarI2FromUI432 [OLEAUT32.49]
2382 HRESULT WINAPI
VarI2FromUI4(ULONG ulIn
, short* psOut
)
2384 TRACE("( %lx, %p ), stub\n", ulIn
, psOut
);
2386 /* Check range of value.
2388 if( ulIn
< I2_MIN
|| ulIn
> I2_MAX
)
2390 return DISP_E_OVERFLOW
;
2393 *psOut
= (short) ulIn
;
2398 /******************************************************************************
2399 * VarI2FromStr32 [OLEAUT32.54]
2401 HRESULT WINAPI
VarI2FromStr(OLECHAR
* strIn
, LCID lcid
, ULONG dwFlags
, short* psOut
)
2403 double dValue
= 0.0;
2404 LPSTR pNewString
= NULL
;
2406 TRACE("( %p, 0x%08lx, 0x%08lx, %p ), stub\n", strIn
, lcid
, dwFlags
, psOut
);
2408 /* Check if we have a valid argument
2410 pNewString
= HEAP_strdupWtoA( GetProcessHeap(), 0, strIn
);
2411 RemoveCharacterFromString( pNewString
, "," );
2412 if( IsValidRealString( pNewString
) == FALSE
)
2414 return DISP_E_TYPEMISMATCH
;
2417 /* Convert the valid string to a floating point number.
2419 dValue
= atof( pNewString
);
2421 /* We don't need the string anymore so free it.
2423 HeapFree( GetProcessHeap(), 0, pNewString
);
2425 /* Check range of value.
2427 dValue
= round( dValue
);
2428 if( dValue
< I2_MIN
|| dValue
> I2_MAX
)
2430 return DISP_E_OVERFLOW
;
2433 *psOut
= (short) dValue
;
2438 /**********************************************************************
2439 * VarI2FromCy32 [OLEAUT32.52]
2440 * Convert currency to signed short
2442 HRESULT WINAPI
VarI2FromCy(CY cyIn
, short* psOut
) {
2443 double t
= round((((double)cyIn
.s
.Hi
* 4294967296.0) + (double)cyIn
.s
.Lo
) / 10000);
2445 if (t
> I2_MAX
|| t
< I2_MIN
) return DISP_E_OVERFLOW
;
2451 /******************************************************************************
2452 * VarI4FromUI132 [OLEAUT32.58]
2454 HRESULT WINAPI
VarI4FromUI1(BYTE bIn
, LONG
* plOut
)
2456 TRACE("( %X, %p ), stub\n", bIn
, plOut
);
2458 *plOut
= (LONG
) bIn
;
2464 /******************************************************************************
2465 * VarI4FromR432 [OLEAUT32.60]
2467 HRESULT WINAPI
VarI4FromR4(FLOAT fltIn
, LONG
* plOut
)
2469 TRACE("( %f, %p ), stub\n", fltIn
, plOut
);
2471 /* Check range of value.
2473 fltIn
= round( fltIn
);
2474 if( fltIn
< I4_MIN
|| fltIn
> I4_MAX
)
2476 return DISP_E_OVERFLOW
;
2479 *plOut
= (LONG
) fltIn
;
2484 /******************************************************************************
2485 * VarI4FromR832 [OLEAUT32.61]
2487 HRESULT WINAPI
VarI4FromR8(double dblIn
, LONG
* plOut
)
2489 TRACE("( %f, %p ), stub\n", dblIn
, plOut
);
2491 /* Check range of value.
2493 dblIn
= round( dblIn
);
2494 if( dblIn
< I4_MIN
|| dblIn
> I4_MAX
)
2496 return DISP_E_OVERFLOW
;
2499 *plOut
= (LONG
) dblIn
;
2504 /******************************************************************************
2505 * VarI4FromDate32 [OLEAUT32.63]
2507 HRESULT WINAPI
VarI4FromDate(DATE dateIn
, LONG
* plOut
)
2509 TRACE("( %f, %p ), stub\n", dateIn
, plOut
);
2511 /* Check range of value.
2513 dateIn
= round( dateIn
);
2514 if( dateIn
< I4_MIN
|| dateIn
> I4_MAX
)
2516 return DISP_E_OVERFLOW
;
2519 *plOut
= (LONG
) dateIn
;
2524 /******************************************************************************
2525 * VarI4FromBool32 [OLEAUT32.66]
2527 HRESULT WINAPI
VarI4FromBool(VARIANT_BOOL boolIn
, LONG
* plOut
)
2529 TRACE("( %d, %p ), stub\n", boolIn
, plOut
);
2531 *plOut
= (LONG
) boolIn
;
2536 /******************************************************************************
2537 * VarI4FromI132 [OLEAUT32.209]
2539 HRESULT WINAPI
VarI4FromI1(CHAR cIn
, LONG
* plOut
)
2541 TRACE("( %c, %p ), stub\n", cIn
, plOut
);
2543 *plOut
= (LONG
) cIn
;
2548 /******************************************************************************
2549 * VarI4FromUI232 [OLEAUT32.210]
2551 HRESULT WINAPI
VarI4FromUI2(USHORT uiIn
, LONG
* plOut
)
2553 TRACE("( %d, %p ), stub\n", uiIn
, plOut
);
2555 *plOut
= (LONG
) uiIn
;
2560 /******************************************************************************
2561 * VarI4FromUI432 [OLEAUT32.211]
2563 HRESULT WINAPI
VarI4FromUI4(ULONG ulIn
, LONG
* plOut
)
2565 TRACE("( %lx, %p ), stub\n", ulIn
, plOut
);
2567 /* Check range of value.
2569 if( ulIn
< I4_MIN
|| ulIn
> I4_MAX
)
2571 return DISP_E_OVERFLOW
;
2574 *plOut
= (LONG
) ulIn
;
2579 /******************************************************************************
2580 * VarI4FromI232 [OLEAUT32.59]
2582 HRESULT WINAPI
VarI4FromI2(short sIn
, LONG
* plOut
)
2584 TRACE("( %d, %p ), stub\n", sIn
, plOut
);
2586 *plOut
= (LONG
) sIn
;
2591 /******************************************************************************
2592 * VarI4FromStr32 [OLEAUT32.64]
2594 HRESULT WINAPI
VarI4FromStr(OLECHAR
* strIn
, LCID lcid
, ULONG dwFlags
, LONG
* plOut
)
2596 double dValue
= 0.0;
2597 LPSTR pNewString
= NULL
;
2599 TRACE("( %p, 0x%08lx, 0x%08lx, %p ), stub\n", strIn
, lcid
, dwFlags
, plOut
);
2601 /* Check if we have a valid argument
2603 pNewString
= HEAP_strdupWtoA( GetProcessHeap(), 0, strIn
);
2604 RemoveCharacterFromString( pNewString
, "," );
2605 if( IsValidRealString( pNewString
) == FALSE
)
2607 return DISP_E_TYPEMISMATCH
;
2610 /* Convert the valid string to a floating point number.
2612 dValue
= atof( pNewString
);
2614 /* We don't need the string anymore so free it.
2616 HeapFree( GetProcessHeap(), 0, pNewString
);
2618 /* Check range of value.
2620 dValue
= round( dValue
);
2621 if( dValue
< I4_MIN
|| dValue
> I4_MAX
)
2623 return DISP_E_OVERFLOW
;
2626 *plOut
= (LONG
) dValue
;
2631 /**********************************************************************
2632 * VarI4FromCy32 [OLEAUT32.62]
2633 * Convert currency to signed long
2635 HRESULT WINAPI
VarI4FromCy(CY cyIn
, LONG
* plOut
) {
2636 double t
= round((((double)cyIn
.s
.Hi
* 4294967296.0) + (double)cyIn
.s
.Lo
) / 10000);
2638 if (t
> I4_MAX
|| t
< I4_MIN
) return DISP_E_OVERFLOW
;
2644 /******************************************************************************
2645 * VarR4FromUI132 [OLEAUT32.68]
2647 HRESULT WINAPI
VarR4FromUI1(BYTE bIn
, FLOAT
* pfltOut
)
2649 TRACE("( %X, %p ), stub\n", bIn
, pfltOut
);
2651 *pfltOut
= (FLOAT
) bIn
;
2656 /******************************************************************************
2657 * VarR4FromI232 [OLEAUT32.69]
2659 HRESULT WINAPI
VarR4FromI2(short sIn
, FLOAT
* pfltOut
)
2661 TRACE("( %d, %p ), stub\n", sIn
, pfltOut
);
2663 *pfltOut
= (FLOAT
) sIn
;
2668 /******************************************************************************
2669 * VarR4FromI432 [OLEAUT32.70]
2671 HRESULT WINAPI
VarR4FromI4(LONG lIn
, FLOAT
* pfltOut
)
2673 TRACE("( %lx, %p ), stub\n", lIn
, pfltOut
);
2675 *pfltOut
= (FLOAT
) lIn
;
2680 /******************************************************************************
2681 * VarR4FromR832 [OLEAUT32.71]
2683 HRESULT WINAPI
VarR4FromR8(double dblIn
, FLOAT
* pfltOut
)
2685 TRACE("( %f, %p ), stub\n", dblIn
, pfltOut
);
2687 /* Check range of value.
2689 if( dblIn
< -(FLT_MAX
) || dblIn
> FLT_MAX
)
2691 return DISP_E_OVERFLOW
;
2694 *pfltOut
= (FLOAT
) dblIn
;
2699 /******************************************************************************
2700 * VarR4FromDate32 [OLEAUT32.73]
2702 HRESULT WINAPI
VarR4FromDate(DATE dateIn
, FLOAT
* pfltOut
)
2704 TRACE("( %f, %p ), stub\n", dateIn
, pfltOut
);
2706 /* Check range of value.
2708 if( dateIn
< -(FLT_MAX
) || dateIn
> FLT_MAX
)
2710 return DISP_E_OVERFLOW
;
2713 *pfltOut
= (FLOAT
) dateIn
;
2718 /******************************************************************************
2719 * VarR4FromBool32 [OLEAUT32.76]
2721 HRESULT WINAPI
VarR4FromBool(VARIANT_BOOL boolIn
, FLOAT
* pfltOut
)
2723 TRACE("( %d, %p ), stub\n", boolIn
, pfltOut
);
2725 *pfltOut
= (FLOAT
) boolIn
;
2730 /******************************************************************************
2731 * VarR4FromI132 [OLEAUT32.213]
2733 HRESULT WINAPI
VarR4FromI1(CHAR cIn
, FLOAT
* pfltOut
)
2735 TRACE("( %c, %p ), stub\n", cIn
, pfltOut
);
2737 *pfltOut
= (FLOAT
) cIn
;
2742 /******************************************************************************
2743 * VarR4FromUI232 [OLEAUT32.214]
2745 HRESULT WINAPI
VarR4FromUI2(USHORT uiIn
, FLOAT
* pfltOut
)
2747 TRACE("( %d, %p ), stub\n", uiIn
, pfltOut
);
2749 *pfltOut
= (FLOAT
) uiIn
;
2754 /******************************************************************************
2755 * VarR4FromUI432 [OLEAUT32.215]
2757 HRESULT WINAPI
VarR4FromUI4(ULONG ulIn
, FLOAT
* pfltOut
)
2759 TRACE("( %ld, %p ), stub\n", ulIn
, pfltOut
);
2761 *pfltOut
= (FLOAT
) ulIn
;
2766 /******************************************************************************
2767 * VarR4FromStr32 [OLEAUT32.74]
2769 HRESULT WINAPI
VarR4FromStr(OLECHAR
* strIn
, LCID lcid
, ULONG dwFlags
, FLOAT
* pfltOut
)
2771 double dValue
= 0.0;
2772 LPSTR pNewString
= NULL
;
2774 TRACE("( %p, %ld, %ld, %p ), stub\n", strIn
, lcid
, dwFlags
, pfltOut
);
2776 /* Check if we have a valid argument
2778 pNewString
= HEAP_strdupWtoA( GetProcessHeap(), 0, strIn
);
2779 RemoveCharacterFromString( pNewString
, "," );
2780 if( IsValidRealString( pNewString
) == FALSE
)
2782 return DISP_E_TYPEMISMATCH
;
2785 /* Convert the valid string to a floating point number.
2787 dValue
= atof( pNewString
);
2789 /* We don't need the string anymore so free it.
2791 HeapFree( GetProcessHeap(), 0, pNewString
);
2793 /* Check range of value.
2795 if( dValue
< -(FLT_MAX
) || dValue
> FLT_MAX
)
2797 return DISP_E_OVERFLOW
;
2800 *pfltOut
= (FLOAT
) dValue
;
2805 /**********************************************************************
2806 * VarR4FromCy32 [OLEAUT32.72]
2807 * Convert currency to float
2809 HRESULT WINAPI
VarR4FromCy(CY cyIn
, FLOAT
* pfltOut
) {
2810 *pfltOut
= (FLOAT
)((((double)cyIn
.s
.Hi
* 4294967296.0) + (double)cyIn
.s
.Lo
) / 10000);
2815 /******************************************************************************
2816 * VarR8FromUI132 [OLEAUT32.68]
2818 HRESULT WINAPI
VarR8FromUI1(BYTE bIn
, double* pdblOut
)
2820 TRACE("( %d, %p ), stub\n", bIn
, pdblOut
);
2822 *pdblOut
= (double) bIn
;
2827 /******************************************************************************
2828 * VarR8FromI232 [OLEAUT32.69]
2830 HRESULT WINAPI
VarR8FromI2(short sIn
, double* pdblOut
)
2832 TRACE("( %d, %p ), stub\n", sIn
, pdblOut
);
2834 *pdblOut
= (double) sIn
;
2839 /******************************************************************************
2840 * VarR8FromI432 [OLEAUT32.70]
2842 HRESULT WINAPI
VarR8FromI4(LONG lIn
, double* pdblOut
)
2844 TRACE("( %ld, %p ), stub\n", lIn
, pdblOut
);
2846 *pdblOut
= (double) lIn
;
2851 /******************************************************************************
2852 * VarR8FromR432 [OLEAUT32.81]
2854 HRESULT WINAPI
VarR8FromR4(FLOAT fltIn
, double* pdblOut
)
2856 TRACE("( %f, %p ), stub\n", fltIn
, pdblOut
);
2858 *pdblOut
= (double) fltIn
;
2863 /******************************************************************************
2864 * VarR8FromDate32 [OLEAUT32.83]
2866 HRESULT WINAPI
VarR8FromDate(DATE dateIn
, double* pdblOut
)
2868 TRACE("( %f, %p ), stub\n", dateIn
, pdblOut
);
2870 *pdblOut
= (double) dateIn
;
2875 /******************************************************************************
2876 * VarR8FromBool32 [OLEAUT32.86]
2878 HRESULT WINAPI
VarR8FromBool(VARIANT_BOOL boolIn
, double* pdblOut
)
2880 TRACE("( %d, %p ), stub\n", boolIn
, pdblOut
);
2882 *pdblOut
= (double) boolIn
;
2887 /******************************************************************************
2888 * VarR8FromI132 [OLEAUT32.217]
2890 HRESULT WINAPI
VarR8FromI1(CHAR cIn
, double* pdblOut
)
2892 TRACE("( %c, %p ), stub\n", cIn
, pdblOut
);
2894 *pdblOut
= (double) cIn
;
2899 /******************************************************************************
2900 * VarR8FromUI232 [OLEAUT32.218]
2902 HRESULT WINAPI
VarR8FromUI2(USHORT uiIn
, double* pdblOut
)
2904 TRACE("( %d, %p ), stub\n", uiIn
, pdblOut
);
2906 *pdblOut
= (double) uiIn
;
2911 /******************************************************************************
2912 * VarR8FromUI432 [OLEAUT32.219]
2914 HRESULT WINAPI
VarR8FromUI4(ULONG ulIn
, double* pdblOut
)
2916 TRACE("( %ld, %p ), stub\n", ulIn
, pdblOut
);
2918 *pdblOut
= (double) ulIn
;
2923 /******************************************************************************
2924 * VarR8FromStr32 [OLEAUT32.84]
2926 HRESULT WINAPI
VarR8FromStr(OLECHAR
* strIn
, LCID lcid
, ULONG dwFlags
, double* pdblOut
)
2928 double dValue
= 0.0;
2929 LPSTR pNewString
= NULL
;
2931 TRACE("( %p, %ld, %ld, %p ), stub\n", strIn
, lcid
, dwFlags
, pdblOut
);
2933 /* Check if we have a valid argument
2935 pNewString
= HEAP_strdupWtoA( GetProcessHeap(), 0, strIn
);
2936 RemoveCharacterFromString( pNewString
, "," );
2937 if( IsValidRealString( pNewString
) == FALSE
)
2939 return DISP_E_TYPEMISMATCH
;
2942 /* Convert the valid string to a floating point number.
2944 dValue
= atof( pNewString
);
2946 /* We don't need the string anymore so free it.
2948 HeapFree( GetProcessHeap(), 0, pNewString
);
2955 /**********************************************************************
2956 * VarR8FromCy32 [OLEAUT32.82]
2957 * Convert currency to double
2959 HRESULT WINAPI
VarR8FromCy(CY cyIn
, double* pdblOut
) {
2960 *pdblOut
= (double)((((double)cyIn
.s
.Hi
* 4294967296.0) + (double)cyIn
.s
.Lo
) / 10000);
2965 /******************************************************************************
2966 * VarDateFromUI132 [OLEAUT32.]
2968 HRESULT WINAPI
VarDateFromUI1(BYTE bIn
, DATE
* pdateOut
)
2970 TRACE("( %d, %p ), stub\n", bIn
, pdateOut
);
2972 *pdateOut
= (DATE
) bIn
;
2977 /******************************************************************************
2978 * VarDateFromI232 [OLEAUT32.222]
2980 HRESULT WINAPI
VarDateFromI2(short sIn
, DATE
* pdateOut
)
2982 TRACE("( %d, %p ), stub\n", sIn
, pdateOut
);
2984 *pdateOut
= (DATE
) sIn
;
2989 /******************************************************************************
2990 * VarDateFromI432 [OLEAUT32.90]
2992 HRESULT WINAPI
VarDateFromI4(LONG lIn
, DATE
* pdateOut
)
2994 TRACE("( %ld, %p ), stub\n", lIn
, pdateOut
);
2996 if( lIn
< DATE_MIN
|| lIn
> DATE_MAX
)
2998 return DISP_E_OVERFLOW
;
3001 *pdateOut
= (DATE
) lIn
;
3006 /******************************************************************************
3007 * VarDateFromR432 [OLEAUT32.91]
3009 HRESULT WINAPI
VarDateFromR4(FLOAT fltIn
, DATE
* pdateOut
)
3011 TRACE("( %f, %p ), stub\n", fltIn
, pdateOut
);
3013 if( ceil(fltIn
) < DATE_MIN
|| floor(fltIn
) > DATE_MAX
)
3015 return DISP_E_OVERFLOW
;
3018 *pdateOut
= (DATE
) fltIn
;
3023 /******************************************************************************
3024 * VarDateFromR832 [OLEAUT32.92]
3026 HRESULT WINAPI
VarDateFromR8(double dblIn
, DATE
* pdateOut
)
3028 TRACE("( %f, %p ), stub\n", dblIn
, pdateOut
);
3030 if( ceil(dblIn
) < DATE_MIN
|| floor(dblIn
) > DATE_MAX
)
3032 return DISP_E_OVERFLOW
;
3035 *pdateOut
= (DATE
) dblIn
;
3040 /******************************************************************************
3041 * VarDateFromStr32 [OLEAUT32.94]
3042 * The string representing the date is composed of two parts, a date and time.
3044 * The format of the time is has follows:
3045 * hh[:mm][:ss][AM|PM]
3046 * Whitespace can be inserted anywhere between these tokens. A whitespace consists
3047 * of space and/or tab characters, which are ignored.
3049 * The formats for the date part are has follows:
3053 * January dd[,] [yy]yy
3056 * Whitespace can be inserted anywhere between these tokens.
3058 * The formats for the date and time string are has follows.
3059 * date[whitespace][time]
3060 * [time][whitespace]date
3062 * These are the only characters allowed in a string representing a date and time:
3063 * [A-Z] [a-z] [0-9] ':' '-' '/' ',' ' ' '\t'
3065 HRESULT WINAPI
VarDateFromStr(OLECHAR
* strIn
, LCID lcid
, ULONG dwFlags
, DATE
* pdateOut
)
3068 struct tm TM
= { 0,0,0,0,0,0,0,0,0 };
3070 TRACE("( %p, %lx, %lx, %p ), stub\n", strIn
, lcid
, dwFlags
, pdateOut
);
3072 if( DateTimeStringToTm( strIn
, lcid
, &TM
) )
3074 if( TmToDATE( &TM
, pdateOut
) == FALSE
)
3081 ret
= DISP_E_TYPEMISMATCH
;
3088 /******************************************************************************
3089 * VarDateFromI132 [OLEAUT32.221]
3091 HRESULT WINAPI
VarDateFromI1(CHAR cIn
, DATE
* pdateOut
)
3093 TRACE("( %c, %p ), stub\n", cIn
, pdateOut
);
3095 *pdateOut
= (DATE
) cIn
;
3100 /******************************************************************************
3101 * VarDateFromUI232 [OLEAUT32.222]
3103 HRESULT WINAPI
VarDateFromUI2(USHORT uiIn
, DATE
* pdateOut
)
3105 TRACE("( %d, %p ), stub\n", uiIn
, pdateOut
);
3107 if( uiIn
> DATE_MAX
)
3109 return DISP_E_OVERFLOW
;
3112 *pdateOut
= (DATE
) uiIn
;
3117 /******************************************************************************
3118 * VarDateFromUI432 [OLEAUT32.223]
3120 HRESULT WINAPI
VarDateFromUI4(ULONG ulIn
, DATE
* pdateOut
)
3122 TRACE("( %ld, %p ), stub\n", ulIn
, pdateOut
);
3124 if( ulIn
< DATE_MIN
|| ulIn
> DATE_MAX
)
3126 return DISP_E_OVERFLOW
;
3129 *pdateOut
= (DATE
) ulIn
;
3134 /******************************************************************************
3135 * VarDateFromBool32 [OLEAUT32.96]
3137 HRESULT WINAPI
VarDateFromBool(VARIANT_BOOL boolIn
, DATE
* pdateOut
)
3139 TRACE("( %d, %p ), stub\n", boolIn
, pdateOut
);
3141 *pdateOut
= (DATE
) boolIn
;
3146 /**********************************************************************
3147 * VarDateFromCy32 [OLEAUT32.93]
3148 * Convert currency to date
3150 HRESULT WINAPI
VarDateFromCy(CY cyIn
, DATE
* pdateOut
) {
3151 *pdateOut
= (DATE
)((((double)cyIn
.s
.Hi
* 4294967296.0) + (double)cyIn
.s
.Lo
) / 10000);
3153 if (*pdateOut
> DATE_MAX
|| *pdateOut
< DATE_MIN
) return DISP_E_TYPEMISMATCH
;
3157 /******************************************************************************
3158 * VarBstrFromUI132 [OLEAUT32.108]
3160 HRESULT WINAPI
VarBstrFromUI1(BYTE bVal
, LCID lcid
, ULONG dwFlags
, BSTR
* pbstrOut
)
3162 TRACE("( %d, %ld, %ld, %p ), stub\n", bVal
, lcid
, dwFlags
, pbstrOut
);
3163 sprintf( pBuffer
, "%d", bVal
);
3165 *pbstrOut
= StringDupAtoBstr( pBuffer
);
3170 /******************************************************************************
3171 * VarBstrFromI232 [OLEAUT32.109]
3173 HRESULT WINAPI
VarBstrFromI2(short iVal
, LCID lcid
, ULONG dwFlags
, BSTR
* pbstrOut
)
3175 TRACE("( %d, %ld, %ld, %p ), stub\n", iVal
, lcid
, dwFlags
, pbstrOut
);
3176 sprintf( pBuffer
, "%d", iVal
);
3177 *pbstrOut
= StringDupAtoBstr( pBuffer
);
3182 /******************************************************************************
3183 * VarBstrFromI432 [OLEAUT32.110]
3185 HRESULT WINAPI
VarBstrFromI4(LONG lIn
, LCID lcid
, ULONG dwFlags
, BSTR
* pbstrOut
)
3187 TRACE("( %ld, %ld, %ld, %p ), stub\n", lIn
, lcid
, dwFlags
, pbstrOut
);
3189 sprintf( pBuffer
, "%ld", lIn
);
3190 *pbstrOut
= StringDupAtoBstr( pBuffer
);
3195 /******************************************************************************
3196 * VarBstrFromR432 [OLEAUT32.111]
3198 HRESULT WINAPI
VarBstrFromR4(FLOAT fltIn
, LCID lcid
, ULONG dwFlags
, BSTR
* pbstrOut
)
3200 TRACE("( %f, %ld, %ld, %p ), stub\n", fltIn
, lcid
, dwFlags
, pbstrOut
);
3202 sprintf( pBuffer
, "%.7g", fltIn
);
3203 *pbstrOut
= StringDupAtoBstr( pBuffer
);
3208 /******************************************************************************
3209 * VarBstrFromR832 [OLEAUT32.112]
3211 HRESULT WINAPI
VarBstrFromR8(double dblIn
, LCID lcid
, ULONG dwFlags
, BSTR
* pbstrOut
)
3213 TRACE("( %f, %ld, %ld, %p ), stub\n", dblIn
, lcid
, dwFlags
, pbstrOut
);
3215 sprintf( pBuffer
, "%.15g", dblIn
);
3216 *pbstrOut
= StringDupAtoBstr( pBuffer
);
3221 /******************************************************************************
3222 * VarBstrFromCy [OLEAUT32.113]
3224 HRESULT WINAPI
VarBstrFromCy(CY cyIn
, LCID lcid
, ULONG dwFlags
, BSTR
*pbstrOut
) {
3230 /******************************************************************************
3231 * VarBstrFromDate32 [OLEAUT32.114]
3233 * The date is implemented using an 8 byte floating-point number.
3234 * Days are represented by whole numbers increments starting with 0.00 has
3235 * being December 30 1899, midnight.
3236 * The hours are expressed as the fractional part of the number.
3237 * December 30 1899 at midnight = 0.00
3238 * January 1 1900 at midnight = 2.00
3239 * January 4 1900 at 6 AM = 5.25
3240 * January 4 1900 at noon = 5.50
3241 * December 29 1899 at midnight = -1.00
3242 * December 18 1899 at midnight = -12.00
3243 * December 18 1899 at 6AM = -12.25
3244 * December 18 1899 at 6PM = -12.75
3245 * December 19 1899 at midnight = -11.00
3246 * The tm structure is as follows:
3248 * int tm_sec; seconds after the minute - [0,59]
3249 * int tm_min; minutes after the hour - [0,59]
3250 * int tm_hour; hours since midnight - [0,23]
3251 * int tm_mday; day of the month - [1,31]
3252 * int tm_mon; months since January - [0,11]
3253 * int tm_year; years
3254 * int tm_wday; days since Sunday - [0,6]
3255 * int tm_yday; days since January 1 - [0,365]
3256 * int tm_isdst; daylight savings time flag
3259 HRESULT WINAPI
VarBstrFromDate(DATE dateIn
, LCID lcid
, ULONG dwFlags
, BSTR
* pbstrOut
)
3261 struct tm TM
= {0,0,0,0,0,0,0,0,0};
3263 TRACE("( %f, %ld, %ld, %p ), stub\n", dateIn
, lcid
, dwFlags
, pbstrOut
);
3265 if( DateToTm( dateIn
, lcid
, &TM
) == FALSE
)
3267 return E_INVALIDARG
;
3270 if( dwFlags
& VAR_DATEVALUEONLY
)
3271 strftime( pBuffer
, BUFFER_MAX
, "%x", &TM
);
3272 else if( dwFlags
& VAR_TIMEVALUEONLY
)
3273 strftime( pBuffer
, BUFFER_MAX
, "%X", &TM
);
3275 strftime( pBuffer
, BUFFER_MAX
, "%x %X", &TM
);
3277 *pbstrOut
= StringDupAtoBstr( pBuffer
);
3282 /******************************************************************************
3283 * VarBstrFromBool32 [OLEAUT32.116]
3285 HRESULT WINAPI
VarBstrFromBool(VARIANT_BOOL boolIn
, LCID lcid
, ULONG dwFlags
, BSTR
* pbstrOut
)
3287 TRACE("( %d, %ld, %ld, %p ), stub\n", boolIn
, lcid
, dwFlags
, pbstrOut
);
3289 if( boolIn
== VARIANT_FALSE
)
3291 sprintf( pBuffer
, "False" );
3295 sprintf( pBuffer
, "True" );
3298 *pbstrOut
= StringDupAtoBstr( pBuffer
);
3303 /******************************************************************************
3304 * VarBstrFromI132 [OLEAUT32.229]
3306 HRESULT WINAPI
VarBstrFromI1(CHAR cIn
, LCID lcid
, ULONG dwFlags
, BSTR
* pbstrOut
)
3308 TRACE("( %c, %ld, %ld, %p ), stub\n", cIn
, lcid
, dwFlags
, pbstrOut
);
3309 sprintf( pBuffer
, "%d", cIn
);
3310 *pbstrOut
= StringDupAtoBstr( pBuffer
);
3315 /******************************************************************************
3316 * VarBstrFromUI232 [OLEAUT32.230]
3318 HRESULT WINAPI
VarBstrFromUI2(USHORT uiIn
, LCID lcid
, ULONG dwFlags
, BSTR
* pbstrOut
)
3320 TRACE("( %d, %ld, %ld, %p ), stub\n", uiIn
, lcid
, dwFlags
, pbstrOut
);
3321 sprintf( pBuffer
, "%d", uiIn
);
3322 *pbstrOut
= StringDupAtoBstr( pBuffer
);
3327 /******************************************************************************
3328 * VarBstrFromUI432 [OLEAUT32.231]
3330 HRESULT WINAPI
VarBstrFromUI4(ULONG ulIn
, LCID lcid
, ULONG dwFlags
, BSTR
* pbstrOut
)
3332 TRACE("( %ld, %ld, %ld, %p ), stub\n", ulIn
, lcid
, dwFlags
, pbstrOut
);
3333 sprintf( pBuffer
, "%ld", ulIn
);
3334 *pbstrOut
= StringDupAtoBstr( pBuffer
);
3339 /******************************************************************************
3340 * VarBoolFromUI132 [OLEAUT32.118]
3342 HRESULT WINAPI
VarBoolFromUI1(BYTE bIn
, VARIANT_BOOL
* pboolOut
)
3344 TRACE("( %d, %p ), stub\n", bIn
, pboolOut
);
3348 *pboolOut
= VARIANT_FALSE
;
3352 *pboolOut
= VARIANT_TRUE
;
3358 /******************************************************************************
3359 * VarBoolFromI232 [OLEAUT32.119]
3361 HRESULT WINAPI
VarBoolFromI2(short sIn
, VARIANT_BOOL
* pboolOut
)
3363 TRACE("( %d, %p ), stub\n", sIn
, pboolOut
);
3367 *pboolOut
= VARIANT_FALSE
;
3371 *pboolOut
= VARIANT_TRUE
;
3377 /******************************************************************************
3378 * VarBoolFromI432 [OLEAUT32.120]
3380 HRESULT WINAPI
VarBoolFromI4(LONG lIn
, VARIANT_BOOL
* pboolOut
)
3382 TRACE("( %ld, %p ), stub\n", lIn
, pboolOut
);
3386 *pboolOut
= VARIANT_FALSE
;
3390 *pboolOut
= VARIANT_TRUE
;
3396 /******************************************************************************
3397 * VarBoolFromR432 [OLEAUT32.121]
3399 HRESULT WINAPI
VarBoolFromR4(FLOAT fltIn
, VARIANT_BOOL
* pboolOut
)
3401 TRACE("( %f, %p ), stub\n", fltIn
, pboolOut
);
3405 *pboolOut
= VARIANT_FALSE
;
3409 *pboolOut
= VARIANT_TRUE
;
3415 /******************************************************************************
3416 * VarBoolFromR832 [OLEAUT32.122]
3418 HRESULT WINAPI
VarBoolFromR8(double dblIn
, VARIANT_BOOL
* pboolOut
)
3420 TRACE("( %f, %p ), stub\n", dblIn
, pboolOut
);
3424 *pboolOut
= VARIANT_FALSE
;
3428 *pboolOut
= VARIANT_TRUE
;
3434 /******************************************************************************
3435 * VarBoolFromDate32 [OLEAUT32.123]
3437 HRESULT WINAPI
VarBoolFromDate(DATE dateIn
, VARIANT_BOOL
* pboolOut
)
3439 TRACE("( %f, %p ), stub\n", dateIn
, pboolOut
);
3443 *pboolOut
= VARIANT_FALSE
;
3447 *pboolOut
= VARIANT_TRUE
;
3453 /******************************************************************************
3454 * VarBoolFromStr32 [OLEAUT32.125]
3456 HRESULT WINAPI
VarBoolFromStr(OLECHAR
* strIn
, LCID lcid
, ULONG dwFlags
, VARIANT_BOOL
* pboolOut
)
3459 char* pNewString
= NULL
;
3461 TRACE("( %p, %ld, %ld, %p ), stub\n", strIn
, lcid
, dwFlags
, pboolOut
);
3463 pNewString
= HEAP_strdupWtoA( GetProcessHeap(), 0, strIn
);
3465 if( pNewString
== NULL
|| strlen( pNewString
) == 0 )
3467 ret
= DISP_E_TYPEMISMATCH
;
3472 if( strncasecmp( pNewString
, "True", strlen( pNewString
) ) == 0 )
3474 *pboolOut
= VARIANT_TRUE
;
3476 else if( strncasecmp( pNewString
, "False", strlen( pNewString
) ) == 0 )
3478 *pboolOut
= VARIANT_FALSE
;
3482 /* Try converting the string to a floating point number.
3484 double dValue
= 0.0;
3485 HRESULT res
= VarR8FromStr( strIn
, lcid
, dwFlags
, &dValue
);
3488 ret
= DISP_E_TYPEMISMATCH
;
3490 else if( dValue
== 0.0 )
3492 *pboolOut
= VARIANT_FALSE
;
3496 *pboolOut
= VARIANT_TRUE
;
3501 HeapFree( GetProcessHeap(), 0, pNewString
);
3506 /******************************************************************************
3507 * VarBoolFromI132 [OLEAUT32.233]
3509 HRESULT WINAPI
VarBoolFromI1(CHAR cIn
, VARIANT_BOOL
* pboolOut
)
3511 TRACE("( %c, %p ), stub\n", cIn
, pboolOut
);
3515 *pboolOut
= VARIANT_FALSE
;
3519 *pboolOut
= VARIANT_TRUE
;
3525 /******************************************************************************
3526 * VarBoolFromUI232 [OLEAUT32.234]
3528 HRESULT WINAPI
VarBoolFromUI2(USHORT uiIn
, VARIANT_BOOL
* pboolOut
)
3530 TRACE("( %d, %p ), stub\n", uiIn
, pboolOut
);
3534 *pboolOut
= VARIANT_FALSE
;
3538 *pboolOut
= VARIANT_TRUE
;
3544 /******************************************************************************
3545 * VarBoolFromUI432 [OLEAUT32.235]
3547 HRESULT WINAPI
VarBoolFromUI4(ULONG ulIn
, VARIANT_BOOL
* pboolOut
)
3549 TRACE("( %ld, %p ), stub\n", ulIn
, pboolOut
);
3553 *pboolOut
= VARIANT_FALSE
;
3557 *pboolOut
= VARIANT_TRUE
;
3563 /**********************************************************************
3564 * VarBoolFromCy32 [OLEAUT32.124]
3565 * Convert currency to boolean
3567 HRESULT WINAPI
VarBoolFromCy(CY cyIn
, VARIANT_BOOL
* pboolOut
) {
3568 if (cyIn
.s
.Hi
|| cyIn
.s
.Lo
) *pboolOut
= -1;
3574 /******************************************************************************
3575 * VarI1FromUI132 [OLEAUT32.244]
3577 HRESULT WINAPI
VarI1FromUI1(BYTE bIn
, CHAR
* pcOut
)
3579 TRACE("( %d, %p ), stub\n", bIn
, pcOut
);
3581 /* Check range of value.
3583 if( bIn
> CHAR_MAX
)
3585 return DISP_E_OVERFLOW
;
3588 *pcOut
= (CHAR
) bIn
;
3593 /******************************************************************************
3594 * VarI1FromI232 [OLEAUT32.245]
3596 HRESULT WINAPI
VarI1FromI2(short uiIn
, CHAR
* pcOut
)
3598 TRACE("( %d, %p ), stub\n", uiIn
, pcOut
);
3600 if( uiIn
> CHAR_MAX
)
3602 return DISP_E_OVERFLOW
;
3605 *pcOut
= (CHAR
) uiIn
;
3610 /******************************************************************************
3611 * VarI1FromI432 [OLEAUT32.246]
3613 HRESULT WINAPI
VarI1FromI4(LONG lIn
, CHAR
* pcOut
)
3615 TRACE("( %ld, %p ), stub\n", lIn
, pcOut
);
3617 if( lIn
< CHAR_MIN
|| lIn
> CHAR_MAX
)
3619 return DISP_E_OVERFLOW
;
3622 *pcOut
= (CHAR
) lIn
;
3627 /******************************************************************************
3628 * VarI1FromR432 [OLEAUT32.247]
3630 HRESULT WINAPI
VarI1FromR4(FLOAT fltIn
, CHAR
* pcOut
)
3632 TRACE("( %f, %p ), stub\n", fltIn
, pcOut
);
3634 fltIn
= round( fltIn
);
3635 if( fltIn
< CHAR_MIN
|| fltIn
> CHAR_MAX
)
3637 return DISP_E_OVERFLOW
;
3640 *pcOut
= (CHAR
) fltIn
;
3645 /******************************************************************************
3646 * VarI1FromR832 [OLEAUT32.248]
3648 HRESULT WINAPI
VarI1FromR8(double dblIn
, CHAR
* pcOut
)
3650 TRACE("( %f, %p ), stub\n", dblIn
, pcOut
);
3652 dblIn
= round( dblIn
);
3653 if( dblIn
< CHAR_MIN
|| dblIn
> CHAR_MAX
)
3655 return DISP_E_OVERFLOW
;
3658 *pcOut
= (CHAR
) dblIn
;
3663 /******************************************************************************
3664 * VarI1FromDate32 [OLEAUT32.249]
3666 HRESULT WINAPI
VarI1FromDate(DATE dateIn
, CHAR
* pcOut
)
3668 TRACE("( %f, %p ), stub\n", dateIn
, pcOut
);
3670 dateIn
= round( dateIn
);
3671 if( dateIn
< CHAR_MIN
|| dateIn
> CHAR_MAX
)
3673 return DISP_E_OVERFLOW
;
3676 *pcOut
= (CHAR
) dateIn
;
3681 /******************************************************************************
3682 * VarI1FromStr32 [OLEAUT32.251]
3684 HRESULT WINAPI
VarI1FromStr(OLECHAR
* strIn
, LCID lcid
, ULONG dwFlags
, CHAR
* pcOut
)
3686 double dValue
= 0.0;
3687 LPSTR pNewString
= NULL
;
3689 TRACE("( %p, %ld, %ld, %p ), stub\n", strIn
, lcid
, dwFlags
, pcOut
);
3691 /* Check if we have a valid argument
3693 pNewString
= HEAP_strdupWtoA( GetProcessHeap(), 0, strIn
);
3694 RemoveCharacterFromString( pNewString
, "," );
3695 if( IsValidRealString( pNewString
) == FALSE
)
3697 return DISP_E_TYPEMISMATCH
;
3700 /* Convert the valid string to a floating point number.
3702 dValue
= atof( pNewString
);
3704 /* We don't need the string anymore so free it.
3706 HeapFree( GetProcessHeap(), 0, pNewString
);
3708 /* Check range of value.
3710 dValue
= round( dValue
);
3711 if( dValue
< CHAR_MIN
|| dValue
> CHAR_MAX
)
3713 return DISP_E_OVERFLOW
;
3716 *pcOut
= (CHAR
) dValue
;
3721 /******************************************************************************
3722 * VarI1FromBool32 [OLEAUT32.253]
3724 HRESULT WINAPI
VarI1FromBool(VARIANT_BOOL boolIn
, CHAR
* pcOut
)
3726 TRACE("( %d, %p ), stub\n", boolIn
, pcOut
);
3728 *pcOut
= (CHAR
) boolIn
;
3733 /******************************************************************************
3734 * VarI1FromUI232 [OLEAUT32.254]
3736 HRESULT WINAPI
VarI1FromUI2(USHORT uiIn
, CHAR
* pcOut
)
3738 TRACE("( %d, %p ), stub\n", uiIn
, pcOut
);
3740 if( uiIn
> CHAR_MAX
)
3742 return DISP_E_OVERFLOW
;
3745 *pcOut
= (CHAR
) uiIn
;
3750 /******************************************************************************
3751 * VarI1FromUI432 [OLEAUT32.255]
3753 HRESULT WINAPI
VarI1FromUI4(ULONG ulIn
, CHAR
* pcOut
)
3755 TRACE("( %ld, %p ), stub\n", ulIn
, pcOut
);
3757 if( ulIn
> CHAR_MAX
)
3759 return DISP_E_OVERFLOW
;
3762 *pcOut
= (CHAR
) ulIn
;
3767 /**********************************************************************
3768 * VarI1FromCy32 [OLEAUT32.250]
3769 * Convert currency to signed char
3771 HRESULT WINAPI
VarI1FromCy(CY cyIn
, CHAR
* pcOut
) {
3772 double t
= round((((double)cyIn
.s
.Hi
* 4294967296.0) + (double)cyIn
.s
.Lo
) / 10000);
3774 if (t
> CHAR_MAX
|| t
< CHAR_MIN
) return DISP_E_OVERFLOW
;
3780 /******************************************************************************
3781 * VarUI2FromUI132 [OLEAUT32.257]
3783 HRESULT WINAPI
VarUI2FromUI1(BYTE bIn
, USHORT
* puiOut
)
3785 TRACE("( %d, %p ), stub\n", bIn
, puiOut
);
3787 *puiOut
= (USHORT
) bIn
;
3792 /******************************************************************************
3793 * VarUI2FromI232 [OLEAUT32.258]
3795 HRESULT WINAPI
VarUI2FromI2(short uiIn
, USHORT
* puiOut
)
3797 TRACE("( %d, %p ), stub\n", uiIn
, puiOut
);
3799 if( uiIn
< UI2_MIN
)
3801 return DISP_E_OVERFLOW
;
3804 *puiOut
= (USHORT
) uiIn
;
3809 /******************************************************************************
3810 * VarUI2FromI432 [OLEAUT32.259]
3812 HRESULT WINAPI
VarUI2FromI4(LONG lIn
, USHORT
* puiOut
)
3814 TRACE("( %ld, %p ), stub\n", lIn
, puiOut
);
3816 if( lIn
< UI2_MIN
|| lIn
> UI2_MAX
)
3818 return DISP_E_OVERFLOW
;
3821 *puiOut
= (USHORT
) lIn
;
3826 /******************************************************************************
3827 * VarUI2FromR432 [OLEAUT32.260]
3829 HRESULT WINAPI
VarUI2FromR4(FLOAT fltIn
, USHORT
* puiOut
)
3831 TRACE("( %f, %p ), stub\n", fltIn
, puiOut
);
3833 fltIn
= round( fltIn
);
3834 if( fltIn
< UI2_MIN
|| fltIn
> UI2_MAX
)
3836 return DISP_E_OVERFLOW
;
3839 *puiOut
= (USHORT
) fltIn
;
3844 /******************************************************************************
3845 * VarUI2FromR832 [OLEAUT32.261]
3847 HRESULT WINAPI
VarUI2FromR8(double dblIn
, USHORT
* puiOut
)
3849 TRACE("( %f, %p ), stub\n", dblIn
, puiOut
);
3851 dblIn
= round( dblIn
);
3852 if( dblIn
< UI2_MIN
|| dblIn
> UI2_MAX
)
3854 return DISP_E_OVERFLOW
;
3857 *puiOut
= (USHORT
) dblIn
;
3862 /******************************************************************************
3863 * VarUI2FromDate32 [OLEAUT32.262]
3865 HRESULT WINAPI
VarUI2FromDate(DATE dateIn
, USHORT
* puiOut
)
3867 TRACE("( %f, %p ), stub\n", dateIn
, puiOut
);
3869 dateIn
= round( dateIn
);
3870 if( dateIn
< UI2_MIN
|| dateIn
> UI2_MAX
)
3872 return DISP_E_OVERFLOW
;
3875 *puiOut
= (USHORT
) dateIn
;
3880 /******************************************************************************
3881 * VarUI2FromStr32 [OLEAUT32.264]
3883 HRESULT WINAPI
VarUI2FromStr(OLECHAR
* strIn
, LCID lcid
, ULONG dwFlags
, USHORT
* puiOut
)
3885 double dValue
= 0.0;
3886 LPSTR pNewString
= NULL
;
3888 TRACE("( %p, %ld, %ld, %p ), stub\n", strIn
, lcid
, dwFlags
, puiOut
);
3890 /* Check if we have a valid argument
3892 pNewString
= HEAP_strdupWtoA( GetProcessHeap(), 0, strIn
);
3893 RemoveCharacterFromString( pNewString
, "," );
3894 if( IsValidRealString( pNewString
) == FALSE
)
3896 return DISP_E_TYPEMISMATCH
;
3899 /* Convert the valid string to a floating point number.
3901 dValue
= atof( pNewString
);
3903 /* We don't need the string anymore so free it.
3905 HeapFree( GetProcessHeap(), 0, pNewString
);
3907 /* Check range of value.
3909 dValue
= round( dValue
);
3910 if( dValue
< UI2_MIN
|| dValue
> UI2_MAX
)
3912 return DISP_E_OVERFLOW
;
3915 *puiOut
= (USHORT
) dValue
;
3920 /******************************************************************************
3921 * VarUI2FromBool32 [OLEAUT32.266]
3923 HRESULT WINAPI
VarUI2FromBool(VARIANT_BOOL boolIn
, USHORT
* puiOut
)
3925 TRACE("( %d, %p ), stub\n", boolIn
, puiOut
);
3927 *puiOut
= (USHORT
) boolIn
;
3932 /******************************************************************************
3933 * VarUI2FromI132 [OLEAUT32.267]
3935 HRESULT WINAPI
VarUI2FromI1(CHAR cIn
, USHORT
* puiOut
)
3937 TRACE("( %c, %p ), stub\n", cIn
, puiOut
);
3939 *puiOut
= (USHORT
) cIn
;
3944 /******************************************************************************
3945 * VarUI2FromUI432 [OLEAUT32.268]
3947 HRESULT WINAPI
VarUI2FromUI4(ULONG ulIn
, USHORT
* puiOut
)
3949 TRACE("( %ld, %p ), stub\n", ulIn
, puiOut
);
3951 if( ulIn
< UI2_MIN
|| ulIn
> UI2_MAX
)
3953 return DISP_E_OVERFLOW
;
3956 *puiOut
= (USHORT
) ulIn
;
3961 /******************************************************************************
3962 * VarUI4FromStr32 [OLEAUT32.277]
3964 HRESULT WINAPI
VarUI4FromStr(OLECHAR
* strIn
, LCID lcid
, ULONG dwFlags
, ULONG
* pulOut
)
3966 double dValue
= 0.0;
3967 LPSTR pNewString
= NULL
;
3969 TRACE("( %p, %ld, %ld, %p ), stub\n", strIn
, lcid
, dwFlags
, pulOut
);
3971 /* Check if we have a valid argument
3973 pNewString
= HEAP_strdupWtoA( GetProcessHeap(), 0, strIn
);
3974 RemoveCharacterFromString( pNewString
, "," );
3975 if( IsValidRealString( pNewString
) == FALSE
)
3977 return DISP_E_TYPEMISMATCH
;
3980 /* Convert the valid string to a floating point number.
3982 dValue
= atof( pNewString
);
3984 /* We don't need the string anymore so free it.
3986 HeapFree( GetProcessHeap(), 0, pNewString
);
3988 /* Check range of value.
3990 dValue
= round( dValue
);
3991 if( dValue
< UI4_MIN
|| dValue
> UI4_MAX
)
3993 return DISP_E_OVERFLOW
;
3996 *pulOut
= (ULONG
) dValue
;
4001 /**********************************************************************
4002 * VarUI2FromCy32 [OLEAUT32.263]
4003 * Convert currency to unsigned short
4005 HRESULT WINAPI
VarUI2FromCy(CY cyIn
, USHORT
* pusOut
) {
4006 double t
= round((((double)cyIn
.s
.Hi
* 4294967296.0) + (double)cyIn
.s
.Lo
) / 10000);
4008 if (t
> UI2_MAX
|| t
< UI2_MIN
) return DISP_E_OVERFLOW
;
4010 *pusOut
= (USHORT
)t
;
4015 /******************************************************************************
4016 * VarUI4FromUI132 [OLEAUT32.270]
4018 HRESULT WINAPI
VarUI4FromUI1(BYTE bIn
, ULONG
* pulOut
)
4020 TRACE("( %d, %p ), stub\n", bIn
, pulOut
);
4022 *pulOut
= (USHORT
) bIn
;
4027 /******************************************************************************
4028 * VarUI4FromI232 [OLEAUT32.271]
4030 HRESULT WINAPI
VarUI4FromI2(short uiIn
, ULONG
* pulOut
)
4032 TRACE("( %d, %p ), stub\n", uiIn
, pulOut
);
4034 if( uiIn
< UI4_MIN
)
4036 return DISP_E_OVERFLOW
;
4039 *pulOut
= (ULONG
) uiIn
;
4044 /******************************************************************************
4045 * VarUI4FromI432 [OLEAUT32.272]
4047 HRESULT WINAPI
VarUI4FromI4(LONG lIn
, ULONG
* pulOut
)
4049 TRACE("( %ld, %p ), stub\n", lIn
, pulOut
);
4053 return DISP_E_OVERFLOW
;
4056 *pulOut
= (ULONG
) lIn
;
4061 /******************************************************************************
4062 * VarUI4FromR432 [OLEAUT32.273]
4064 HRESULT WINAPI
VarUI4FromR4(FLOAT fltIn
, ULONG
* pulOut
)
4066 fltIn
= round( fltIn
);
4067 if( fltIn
< UI4_MIN
|| fltIn
> UI4_MAX
)
4069 return DISP_E_OVERFLOW
;
4072 *pulOut
= (ULONG
) fltIn
;
4077 /******************************************************************************
4078 * VarUI4FromR832 [OLEAUT32.274]
4080 HRESULT WINAPI
VarUI4FromR8(double dblIn
, ULONG
* pulOut
)
4082 TRACE("( %f, %p ), stub\n", dblIn
, pulOut
);
4084 dblIn
= round( dblIn
);
4085 if( dblIn
< UI4_MIN
|| dblIn
> UI4_MAX
)
4087 return DISP_E_OVERFLOW
;
4090 *pulOut
= (ULONG
) dblIn
;
4095 /******************************************************************************
4096 * VarUI4FromDate32 [OLEAUT32.275]
4098 HRESULT WINAPI
VarUI4FromDate(DATE dateIn
, ULONG
* pulOut
)
4100 TRACE("( %f, %p ), stub\n", dateIn
, pulOut
);
4102 dateIn
= round( dateIn
);
4103 if( dateIn
< UI4_MIN
|| dateIn
> UI4_MAX
)
4105 return DISP_E_OVERFLOW
;
4108 *pulOut
= (ULONG
) dateIn
;
4113 /******************************************************************************
4114 * VarUI4FromBool32 [OLEAUT32.279]
4116 HRESULT WINAPI
VarUI4FromBool(VARIANT_BOOL boolIn
, ULONG
* pulOut
)
4118 TRACE("( %d, %p ), stub\n", boolIn
, pulOut
);
4120 *pulOut
= (ULONG
) boolIn
;
4125 /******************************************************************************
4126 * VarUI4FromI132 [OLEAUT32.280]
4128 HRESULT WINAPI
VarUI4FromI1(CHAR cIn
, ULONG
* pulOut
)
4130 TRACE("( %c, %p ), stub\n", cIn
, pulOut
);
4132 *pulOut
= (ULONG
) cIn
;
4137 /******************************************************************************
4138 * VarUI4FromUI232 [OLEAUT32.281]
4140 HRESULT WINAPI
VarUI4FromUI2(USHORT uiIn
, ULONG
* pulOut
)
4142 TRACE("( %d, %p ), stub\n", uiIn
, pulOut
);
4144 *pulOut
= (ULONG
) uiIn
;
4149 /**********************************************************************
4150 * VarUI4FromCy32 [OLEAUT32.276]
4151 * Convert currency to unsigned long
4153 HRESULT WINAPI
VarUI4FromCy(CY cyIn
, ULONG
* pulOut
) {
4154 double t
= round((((double)cyIn
.s
.Hi
* 4294967296.0) + (double)cyIn
.s
.Lo
) / 10000);
4156 if (t
> UI4_MAX
|| t
< UI4_MIN
) return DISP_E_OVERFLOW
;
4163 /**********************************************************************
4164 * VarCyFromUI132 [OLEAUT32.98]
4165 * Convert unsigned char to currency
4167 HRESULT WINAPI
VarCyFromUI1(BYTE bIn
, CY
* pcyOut
) {
4169 pcyOut
->s
.Lo
= ((ULONG
)bIn
) * 10000;
4174 /**********************************************************************
4175 * VarCyFromI232 [OLEAUT32.99]
4176 * Convert signed short to currency
4178 HRESULT WINAPI
VarCyFromI2(short sIn
, CY
* pcyOut
) {
4179 if (sIn
< 0) pcyOut
->s
.Hi
= -1;
4180 else pcyOut
->s
.Hi
= 0;
4181 pcyOut
->s
.Lo
= ((ULONG
)sIn
) * 10000;
4186 /**********************************************************************
4187 * VarCyFromI432 [OLEAUT32.100]
4188 * Convert signed long to currency
4190 HRESULT WINAPI
VarCyFromI4(LONG lIn
, CY
* pcyOut
) {
4191 double t
= (double)lIn
* (double)10000;
4192 pcyOut
->s
.Hi
= (LONG
)(t
/ (double)4294967296.0);
4193 pcyOut
->s
.Lo
= (ULONG
)fmod(t
, (double)4294967296.0);
4194 if (lIn
< 0) pcyOut
->s
.Hi
--;
4199 /**********************************************************************
4200 * VarCyFromR432 [OLEAUT32.101]
4201 * Convert float to currency
4203 HRESULT WINAPI
VarCyFromR4(FLOAT fltIn
, CY
* pcyOut
) {
4204 double t
= round((double)fltIn
* (double)10000);
4205 pcyOut
->s
.Hi
= (LONG
)(t
/ (double)4294967296.0);
4206 pcyOut
->s
.Lo
= (ULONG
)fmod(t
, (double)4294967296.0);
4207 if (fltIn
< 0) pcyOut
->s
.Hi
--;
4212 /**********************************************************************
4213 * VarCyFromR832 [OLEAUT32.102]
4214 * Convert double to currency
4216 HRESULT WINAPI
VarCyFromR8(double dblIn
, CY
* pcyOut
) {
4217 double t
= round(dblIn
* (double)10000);
4218 pcyOut
->s
.Hi
= (LONG
)(t
/ (double)4294967296.0);
4219 pcyOut
->s
.Lo
= (ULONG
)fmod(t
, (double)4294967296.0);
4220 if (dblIn
< 0) pcyOut
->s
.Hi
--;
4225 /**********************************************************************
4226 * VarCyFromDate32 [OLEAUT32.103]
4227 * Convert date to currency
4229 HRESULT WINAPI
VarCyFromDate(DATE dateIn
, CY
* pcyOut
) {
4230 double t
= round((double)dateIn
* (double)10000);
4231 pcyOut
->s
.Hi
= (LONG
)(t
/ (double)4294967296.0);
4232 pcyOut
->s
.Lo
= (ULONG
)fmod(t
, (double)4294967296.0);
4233 if (dateIn
< 0) pcyOut
->s
.Hi
--;
4238 /**********************************************************************
4239 * VarCyFromDate32 [OLEAUT32.104]
4241 HRESULT WINAPI
VarCyFromStr(OLECHAR
*strIn
, LCID lcid
, ULONG dwFlags
, CY
*pcyOut
) {
4247 /**********************************************************************
4248 * VarCyFromBool32 [OLEAUT32.106]
4249 * Convert boolean to currency
4251 HRESULT WINAPI
VarCyFromBool(VARIANT_BOOL boolIn
, CY
* pcyOut
) {
4252 if (boolIn
< 0) pcyOut
->s
.Hi
= -1;
4253 else pcyOut
->s
.Hi
= 0;
4254 pcyOut
->s
.Lo
= (ULONG
)boolIn
* (ULONG
)10000;
4259 /**********************************************************************
4260 * VarCyFromI132 [OLEAUT32.225]
4261 * Convert signed char to currency
4263 HRESULT WINAPI
VarCyFromI1(CHAR cIn
, CY
* pcyOut
) {
4264 if (cIn
< 0) pcyOut
->s
.Hi
= -1;
4265 else pcyOut
->s
.Hi
= 0;
4266 pcyOut
->s
.Lo
= (ULONG
)cIn
* (ULONG
)10000;
4271 /**********************************************************************
4272 * VarCyFromUI232 [OLEAUT32.226]
4273 * Convert unsigned short to currency
4275 HRESULT WINAPI
VarCyFromUI2(USHORT usIn
, CY
* pcyOut
) {
4277 pcyOut
->s
.Lo
= (ULONG
)usIn
* (ULONG
)10000;
4282 /**********************************************************************
4283 * VarCyFromUI432 [OLEAUT32.227]
4284 * Convert unsigned long to currency
4286 HRESULT WINAPI
VarCyFromUI4(ULONG ulIn
, CY
* pcyOut
) {
4287 double t
= (double)ulIn
* (double)10000;
4288 pcyOut
->s
.Hi
= (LONG
)(t
/ (double)4294967296.0);
4289 pcyOut
->s
.Lo
= (ULONG
)fmod(t
, (double)4294967296.0);
4295 /**********************************************************************
4296 * DosDateTimeToVariantTime [OLEAUT32.14]
4297 * Convert dos representation of time to the date and time representation
4298 * stored in a variant.
4300 INT WINAPI
DosDateTimeToVariantTime(USHORT wDosDate
, USHORT wDosTime
,
4305 TRACE("( 0x%x, 0x%x, 0x%p ), stub\n", wDosDate
, wDosTime
, pvtime
);
4307 t
.tm_sec
= (wDosTime
& 0x001f) * 2;
4308 t
.tm_min
= (wDosTime
& 0x07e0) >> 5;
4309 t
.tm_hour
= (wDosTime
& 0xf800) >> 11;
4311 t
.tm_mday
= (wDosDate
& 0x001f);
4312 t
.tm_mon
= (wDosDate
& 0x01e0) >> 5;
4313 t
.tm_year
= ((wDosDate
& 0xfe00) >> 9) + 1980;
4315 return TmToDATE( &t
, pvtime
);