added Linux specific files
This commit is contained in:
parent
7ff6b40fc0
commit
9714d94cd5
2805
source/shared/FormattedPrint.cpp
Normal file
2805
source/shared/FormattedPrint.cpp
Normal file
|
@ -0,0 +1,2805 @@
|
|||
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: FormattedPrint.cpp
|
||||
//
|
||||
//
|
||||
// Contents: Contains functions for handling Windows format strings
|
||||
// and UTF-16 on non-Windows platforms
|
||||
//
|
||||
// Microsoft Drivers 4.0 for PHP for SQL Server
|
||||
// Copyright(c) Microsoft Corporation
|
||||
// All rights reserved.
|
||||
// MIT License
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""),
|
||||
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#include <FormattedPrint.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
#include <iconv.h>
|
||||
#endif
|
||||
|
||||
#include "StringFunctions.h"
|
||||
|
||||
// XPLAT_ODBC_TODO VSTS 819733 - MPlat: Reconcile std c++ usage between platforms
|
||||
#ifdef MPLAT_UNIX
|
||||
// #include <sal_undef.h>
|
||||
#elif defined(MPLAT_WWOWH)
|
||||
# define _ASSERTE assert
|
||||
# include <malloc.h>
|
||||
# undef _M_IX86
|
||||
# undef min
|
||||
# undef max
|
||||
#endif
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#ifdef MPLAT_UNIX
|
||||
#include <sal.h>
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
#define PTR_IS_INT64 1
|
||||
#else
|
||||
#define PTR_IS_INT64 0
|
||||
#endif
|
||||
|
||||
#ifndef _MSC_VER
|
||||
// SQL Server does not have a long double type
|
||||
#define LONGDOUBLE_IS_DOUBLE 1
|
||||
typedef double _LONGDOUBLE;
|
||||
#endif
|
||||
|
||||
// XPLAT_ODBC_TODO VSTS VSTS 718708 Localization
|
||||
#define _SAFECRT_IMPL
|
||||
|
||||
#if !defined(_countof)
|
||||
#define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
|
||||
#endif // _countof
|
||||
|
||||
#ifndef _VALIDATE_RETURN
|
||||
#define _VALIDATE_RETURN( expr, errorcode, retexpr ) \
|
||||
{ \
|
||||
int _Expr_val=!!(expr); \
|
||||
if ( !( _Expr_val ) ) \
|
||||
{ \
|
||||
assert(false); \
|
||||
errno = errorcode; \
|
||||
return ( retexpr ); \
|
||||
} \
|
||||
}
|
||||
#endif /* _VALIDATE_RETURN */
|
||||
|
||||
|
||||
static const char *__nullstring = "(null)"; /* string to print on null ptr */
|
||||
static const wchar_t *__wnullstring = L"(null)";/* string to print on null ptr */
|
||||
|
||||
#define BUFFERSIZE 512
|
||||
#define MAXPRECISION BUFFERSIZE
|
||||
#define _CVTBUFSIZE (309+40) /* # of digits in max. dp value + slop */
|
||||
|
||||
|
||||
/* flag definitions */
|
||||
#define FL_SIGN 0x00001 /* put plus or minus in front */
|
||||
#define FL_SIGNSP 0x00002 /* put space or minus in front */
|
||||
#define FL_LEFT 0x00004 /* left justify */
|
||||
#define FL_LEADZERO 0x00008 /* pad with leading zeros */
|
||||
#define FL_LONG 0x00010 /* long value given */
|
||||
#define FL_SHORT 0x00020 /* short value given */
|
||||
#define FL_SIGNED 0x00040 /* signed data given */
|
||||
#define FL_ALTERNATE 0x00080 /* alternate form requested */
|
||||
#define FL_NEGATIVE 0x00100 /* value is negative */
|
||||
#define FL_FORCEOCTAL 0x00200 /* force leading '0' for octals */
|
||||
#define FL_LONGDOUBLE 0x00400 /* long double value given */
|
||||
#define FL_WIDECHAR 0x00800 /* wide characters */
|
||||
#define FL_LONGLONG 0x01000 /* long long value given */
|
||||
#define FL_I64 0x08000 /* __int64 value given */
|
||||
|
||||
|
||||
/* state definitions */
|
||||
enum STATE {
|
||||
ST_NORMAL, /* normal state; outputting literal chars */
|
||||
ST_PERCENT, /* just read '%' */
|
||||
ST_FLAG, /* just read flag character */
|
||||
ST_WIDTH, /* just read width specifier */
|
||||
ST_DOT, /* just read '.' */
|
||||
ST_PRECIS, /* just read precision specifier */
|
||||
ST_SIZE, /* just read size specifier */
|
||||
ST_TYPE /* just read type specifier */
|
||||
,ST_INVALID /* Invalid format */
|
||||
|
||||
};
|
||||
|
||||
#define NUMSTATES (ST_INVALID + 1)
|
||||
|
||||
/* character type values */
|
||||
enum CHARTYPE {
|
||||
CH_OTHER, /* character with no special meaning */
|
||||
CH_PERCENT, /* '%' */
|
||||
CH_DOT, /* '.' */
|
||||
CH_STAR, /* '*' */
|
||||
CH_ZERO, /* '0' */
|
||||
CH_DIGIT, /* '1'..'9' */
|
||||
CH_FLAG, /* ' ', '+', '-', '#' */
|
||||
CH_SIZE, /* 'h', 'l', 'L', 'N', 'F', 'w' */
|
||||
CH_TYPE /* type specifying character */
|
||||
};
|
||||
|
||||
|
||||
static const unsigned char __lookuptable_s[] = {
|
||||
/* ' ' */ 0x06,
|
||||
/* '!' */ 0x80,
|
||||
/* '"' */ 0x80,
|
||||
/* '#' */ 0x86,
|
||||
/* '$' */ 0x80,
|
||||
/* '%' */ 0x81,
|
||||
/* '&' */ 0x80,
|
||||
/* ''' */ 0x00,
|
||||
/* '(' */ 0x00,
|
||||
/* ')' */ 0x10,
|
||||
/* '*' */ 0x03,
|
||||
/* '+' */ 0x86,
|
||||
/* ',' */ 0x80,
|
||||
/* '-' */ 0x86,
|
||||
/* '.' */ 0x82,
|
||||
/* '/' */ 0x80,
|
||||
/* '0' */ 0x14,
|
||||
/* '1' */ 0x05,
|
||||
/* '2' */ 0x05,
|
||||
/* '3' */ 0x45,
|
||||
/* '4' */ 0x45,
|
||||
/* '5' */ 0x45,
|
||||
/* '6' */ 0x85,
|
||||
/* '7' */ 0x85,
|
||||
/* '8' */ 0x85,
|
||||
/* '9' */ 0x05,
|
||||
/* ':' */ 0x00,
|
||||
/* ';' */ 0x00,
|
||||
/* '<' */ 0x30,
|
||||
/* '=' */ 0x30,
|
||||
/* '>' */ 0x80,
|
||||
/* '?' */ 0x50,
|
||||
/* '@' */ 0x80,
|
||||
#if defined (_SAFECRT_IMPL)
|
||||
/* 'A' */ 0x80, // Disable %A format
|
||||
#else /* defined (_SAFECRT_IMPL) */
|
||||
/* 'A' */ 0x88,
|
||||
#endif /* defined (_SAFECRT_IMPL) */
|
||||
/* 'B' */ 0x00,
|
||||
/* 'C' */ 0x08,
|
||||
/* 'D' */ 0x00,
|
||||
/* 'E' */ 0x28,
|
||||
/* 'F' */ 0x27,
|
||||
/* 'G' */ 0x38,
|
||||
/* 'H' */ 0x50,
|
||||
/* 'I' */ 0x57,
|
||||
/* 'J' */ 0x80,
|
||||
/* 'K' */ 0x00,
|
||||
/* 'L' */ 0x07,
|
||||
/* 'M' */ 0x00,
|
||||
/* 'N' */ 0x37,
|
||||
/* 'O' */ 0x30,
|
||||
/* 'P' */ 0x30,
|
||||
/* 'Q' */ 0x50,
|
||||
/* 'R' */ 0x50,
|
||||
/* 'S' */ 0x88,
|
||||
/* 'T' */ 0x00,
|
||||
/* 'U' */ 0x00,
|
||||
/* 'V' */ 0x00,
|
||||
/* 'W' */ 0x20,
|
||||
/* 'X' */ 0x28,
|
||||
/* 'Y' */ 0x80,
|
||||
/* 'Z' */ 0x88,
|
||||
/* '[' */ 0x80,
|
||||
/* '\' */ 0x80,
|
||||
/* ']' */ 0x00,
|
||||
/* '^' */ 0x00,
|
||||
/* '_' */ 0x00,
|
||||
/* '`' */ 0x60,
|
||||
#if defined (_SAFECRT_IMPL)
|
||||
/* 'a' */ 0x60, // Disable %a format
|
||||
#else /* defined (_SAFECRT_IMPL) */
|
||||
/* 'a' */ 0x68,
|
||||
#endif /* defined (_SAFECRT_IMPL) */
|
||||
/* 'b' */ 0x60,
|
||||
/* 'c' */ 0x68,
|
||||
/* 'd' */ 0x68,
|
||||
/* 'e' */ 0x68,
|
||||
/* 'f' */ 0x08,
|
||||
/* 'g' */ 0x08,
|
||||
/* 'h' */ 0x07,
|
||||
/* 'i' */ 0x78,
|
||||
/* 'j' */ 0x70,
|
||||
/* 'k' */ 0x70,
|
||||
/* 'l' */ 0x77,
|
||||
/* 'm' */ 0x70,
|
||||
/* 'n' */ 0x70,
|
||||
/* 'o' */ 0x08,
|
||||
/* 'p' */ 0x08,
|
||||
/* 'q' */ 0x00,
|
||||
/* 'r' */ 0x00,
|
||||
/* 's' */ 0x08,
|
||||
/* 't' */ 0x00,
|
||||
/* 'u' */ 0x08,
|
||||
/* 'v' */ 0x00,
|
||||
/* 'w' */ 0x07,
|
||||
/* 'x' */ 0x08
|
||||
};
|
||||
|
||||
static inline CHARTYPE GetCharType( WCHAR wch )
|
||||
{
|
||||
return ((wch < (L' ') || wch > (L'x')) ? CH_OTHER : (enum CHARTYPE)(__lookuptable_s[wch - (L' ')] & 0xF));
|
||||
}
|
||||
static inline CHARTYPE GetCharType( char ch )
|
||||
{
|
||||
return ((ch < (' ') || ch > ('x')) ? CH_OTHER : (enum CHARTYPE)(__lookuptable_s[ch - (' ')] & 0xF));
|
||||
}
|
||||
static inline STATE GetState( CHARTYPE type, STATE oldState )
|
||||
{
|
||||
return (enum STATE)(__lookuptable_s[type * NUMSTATES + oldState] >> 4);
|
||||
}
|
||||
|
||||
|
||||
static bool isleadbyte(unsigned char ch)
|
||||
{
|
||||
return (FALSE != IsDBCSLeadByte(ch) );
|
||||
}
|
||||
static bool isleadwchar(WCHAR ch)
|
||||
{
|
||||
return ((ch & 0xFC00) == 0xD800);
|
||||
}
|
||||
static bool _isleadbyte_l(unsigned char ch, _locale_t loc)
|
||||
{
|
||||
// XPLAT_ODBC_TODO VSTS 718708 Localization
|
||||
return ( FALSE != IsDBCSLeadByte(ch) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define _WCTOMB_S mplat_wctomb_s
|
||||
errno_t mplat_wctomb_s(
|
||||
int *pRetValue,
|
||||
char *mbchar,
|
||||
size_t sizeInBytes,
|
||||
WCHAR wchar
|
||||
)
|
||||
{
|
||||
DWORD rc;
|
||||
size_t cch = SystemLocale::FromUtf16( CP_ACP, &wchar, 1, mbchar, sizeInBytes, NULL, &rc );
|
||||
*pRetValue = (int)cch;
|
||||
return (ERROR_SUCCESS == rc ? 0 : -1);
|
||||
}
|
||||
|
||||
#define _MBTOWC mplat_mbtowc
|
||||
int mplat_mbtowc(
|
||||
WCHAR * pwchar,
|
||||
const char * pmb,
|
||||
size_t n
|
||||
)
|
||||
{
|
||||
size_t cch = SystemLocale::NextChar( CP_ACP, pmb ) - pmb;
|
||||
if ( 0 < cch )
|
||||
{
|
||||
size_t cchActual = SystemLocale::ToUtf16( CP_ACP, pmb, cch, pwchar, 1, NULL );
|
||||
assert( cch == cchActual );
|
||||
}
|
||||
return (int)cch;
|
||||
}
|
||||
|
||||
// Floating point print routines
|
||||
void _CFLTCVT( double * dbl, char * buf, int bufSize, char fmt, int precision, int caps, _locale_t loc = NULL )
|
||||
{
|
||||
const size_t local_bufsize = 8;
|
||||
char local_fmt[local_bufsize];
|
||||
|
||||
if ( 0 != caps )
|
||||
{
|
||||
fmt -= ('a') - ('A'); /* convert format char to upper */
|
||||
}
|
||||
int chars_printed = snprintf( local_fmt, local_bufsize, "%%.%d%c", precision-1, fmt );
|
||||
assert( 0 < chars_printed && (size_t)chars_printed < local_bufsize );
|
||||
|
||||
// We want to use the platform version of snprintf so temporarily undef.
|
||||
// Formatting of floating pt values is complex so we didn't implement it here.
|
||||
// Even porting the CRT code would've been difficult. Instead, we can use the
|
||||
// platform's snprintf for just floating pt values. We have to undef to prevent
|
||||
// recursing right back to here.
|
||||
# undef snprintf
|
||||
# if defined(MPLAT_WWOWH)
|
||||
# undef _snprintf
|
||||
# define snprintf _snprintf
|
||||
# endif
|
||||
chars_printed = snprintf( buf, bufSize, local_fmt, *dbl );
|
||||
assert( 0 < chars_printed && chars_printed < bufSize );
|
||||
# if defined(MPLAT_WWOWH)
|
||||
# undef snprintf
|
||||
# define _snprintf mplat_snprintf
|
||||
# endif
|
||||
# define snprintf mplat_snprintf
|
||||
}
|
||||
|
||||
#if !LONGDOUBLE_IS_DOUBLE
|
||||
// SQL Server does not support the long double data type so this should never be called.
|
||||
// It will be compiled out on Linux.
|
||||
void _CLDCVT( _LONGDOUBLE * dbl, char * buf, int bufSize, char fmt, int precision, int caps )
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
#endif
|
||||
|
||||
static enum STATE ProcessSizeA( char sizeCh, char fmt_ch, char next_fmt_ch, int * advance, int * flags )
|
||||
{
|
||||
*advance = 0;
|
||||
switch (sizeCh)
|
||||
{
|
||||
case 'l':
|
||||
/*
|
||||
* In order to handle the ll case, we depart from the
|
||||
* simple deterministic state machine.
|
||||
*/
|
||||
if ( 'l' == fmt_ch )
|
||||
{
|
||||
*advance = 1;
|
||||
*flags |= FL_LONGLONG;
|
||||
}
|
||||
else
|
||||
{
|
||||
*flags |= FL_LONG;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
/*
|
||||
* In order to handle the I, I32, and I64 size modifiers, we
|
||||
* depart from the simple deterministic state machine. The
|
||||
* code below scans for characters following the 'I',
|
||||
* and defaults to 64 bit on WIN64 and 32 bit on WIN32
|
||||
*/
|
||||
#if PTR_IS_INT64
|
||||
*flags |= FL_I64; /* 'I' => __int64 on WIN64 systems */
|
||||
#endif /* PTR_IS_INT64 */
|
||||
if ( '6' == fmt_ch && '4' == next_fmt_ch )
|
||||
{
|
||||
*advance = 2;
|
||||
*flags |= FL_I64; /* I64 => __int64 */
|
||||
}
|
||||
else if ( '3' == fmt_ch && '2' == next_fmt_ch )
|
||||
{
|
||||
*advance = 2;
|
||||
*flags &= ~FL_I64; /* I32 => __int32 */
|
||||
}
|
||||
else if (
|
||||
(fmt_ch == 'd') ||
|
||||
(fmt_ch == 'i') ||
|
||||
(fmt_ch == 'o') ||
|
||||
(fmt_ch == 'u') ||
|
||||
(fmt_ch == 'x') ||
|
||||
(fmt_ch == 'X') )
|
||||
{
|
||||
/*
|
||||
* Nothing further needed. %Id (et al) is
|
||||
* handled just like %d, except that it defaults to 64 bits
|
||||
* on WIN64. Fall through to the next iteration.
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
return ST_NORMAL;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
*flags |= FL_SHORT;
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
*flags |= FL_WIDECHAR;
|
||||
}
|
||||
|
||||
return ST_SIZE;
|
||||
}
|
||||
|
||||
static enum STATE ProcessSizeW( WCHAR sizeCh, WCHAR fmt_ch, WCHAR next_fmt_ch, int * advance, int * flags )
|
||||
{
|
||||
*advance = 0;
|
||||
switch (sizeCh)
|
||||
{
|
||||
case L'l':
|
||||
/*
|
||||
* In order to handle the ll case, we depart from the
|
||||
* simple deterministic state machine.
|
||||
*/
|
||||
if ( L'l' == fmt_ch )
|
||||
{
|
||||
*advance = 1;
|
||||
*flags |= FL_LONGLONG;
|
||||
}
|
||||
else
|
||||
{
|
||||
*flags |= FL_LONG;
|
||||
}
|
||||
break;
|
||||
|
||||
case L'I':
|
||||
/*
|
||||
* In order to handle the I, I32, and I64 size modifiers, we
|
||||
* depart from the simple deterministic state machine. The
|
||||
* code below scans for characters following the 'I',
|
||||
* and defaults to 64 bit on WIN64 and 32 bit on WIN32
|
||||
*/
|
||||
#if PTR_IS_INT64
|
||||
*flags |= FL_I64; /* 'I' => __int64 on WIN64 systems */
|
||||
#endif /* PTR_IS_INT64 */
|
||||
if ( L'6' == fmt_ch && L'4' == next_fmt_ch )
|
||||
{
|
||||
*advance = 2;
|
||||
*flags |= FL_I64; /* I64 => __int64 */
|
||||
}
|
||||
else if ( L'3' == fmt_ch && L'2' == next_fmt_ch )
|
||||
{
|
||||
*advance = 2;
|
||||
*flags &= ~FL_I64; /* I32 => __int32 */
|
||||
}
|
||||
else if (
|
||||
(fmt_ch == L'd') ||
|
||||
(fmt_ch == L'i') ||
|
||||
(fmt_ch == L'o') ||
|
||||
(fmt_ch == L'u') ||
|
||||
(fmt_ch == L'x') ||
|
||||
(fmt_ch == L'X') )
|
||||
{
|
||||
/*
|
||||
* Nothing further needed. %Id (et al) is
|
||||
* handled just like %d, except that it defaults to 64 bits
|
||||
* on WIN64. Fall through to the next iteration.
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
return ST_NORMAL;
|
||||
}
|
||||
break;
|
||||
|
||||
case L'h':
|
||||
*flags |= FL_SHORT;
|
||||
break;
|
||||
|
||||
case L'w':
|
||||
*flags |= FL_WIDECHAR;
|
||||
}
|
||||
|
||||
return ST_SIZE;
|
||||
}
|
||||
|
||||
STATE ProcessSize( WCHAR sizeCh, const WCHAR * format, int * advance, int * flags )
|
||||
{
|
||||
WCHAR formatCh = *format;
|
||||
WCHAR next_formatCh = (L'\0' == formatCh ? L'\0' : *(format+1));
|
||||
return ProcessSizeW( sizeCh, formatCh, next_formatCh, advance, flags );
|
||||
}
|
||||
|
||||
STATE ProcessSize( char sizeCh, const char * format, int * advance, int * flags )
|
||||
{
|
||||
char formatCh = *format;
|
||||
char next_formatCh = ('\0' == formatCh ? '\0' : *(format+1));
|
||||
return ProcessSizeA( sizeCh, formatCh, next_formatCh, advance, flags );
|
||||
}
|
||||
|
||||
// Tools\vc\src\crt\amd64\output.c
|
||||
int FormattedPrintA( IFormattedPrintOutput<char> * output, const char *format, va_list argptr )
|
||||
{
|
||||
int hexadd=0; /* offset to add to number to get 'a'..'f' */
|
||||
char ch; /* character just read */
|
||||
int flags=0; /* flag word -- see #defines above for flag values */
|
||||
enum STATE state; /* current state */
|
||||
enum CHARTYPE chclass; /* class of current character */
|
||||
int radix; /* current conversion radix */
|
||||
int charsout; /* characters currently written so far, -1 = IO error */
|
||||
int fldwidth = 0; /* selected field width -- 0 means default */
|
||||
int precision = 0; /* selected precision -- -1 means default */
|
||||
char prefix[2]; /* numeric prefix -- up to two characters */
|
||||
int prefixlen=0; /* length of prefix -- 0 means no prefix */
|
||||
int capexp=0; /* non-zero = 'E' exponent signifient, zero = 'e' or unused */
|
||||
int no_output=0; /* non-zero = prodcue no output for this specifier */
|
||||
union {
|
||||
char *sz; /* pointer text to be printed, not zero terminated */
|
||||
WCHAR *wz;
|
||||
} text;
|
||||
|
||||
int textlen; /* length of the text in bytes/wchars to be printed.
|
||||
textlen is in multibyte or wide chars if _UNICODE */
|
||||
union {
|
||||
char sz[BUFFERSIZE];
|
||||
} buffer;
|
||||
WCHAR wchar; /* temp wchar_t */
|
||||
int buffersize; /* size of text.sz (used only for the call to _cfltcvt) */
|
||||
int bufferiswide=0; /* non-zero = buffer contains wide chars already */
|
||||
|
||||
#ifndef _SAFECRT_IMPL
|
||||
_LocaleUpdate _loc_update(plocinfo);
|
||||
#endif /* _SAFECRT_IMPL */
|
||||
|
||||
char *heapbuf = NULL; /* non-zero = test.sz using heap buffer to be freed */
|
||||
|
||||
int advance; /* count of how much helper fxns need format ptr incremented */
|
||||
|
||||
_VALIDATE_RETURN( ((output != NULL) && (format != NULL)), EINVAL, -1);
|
||||
|
||||
charsout = 0; /* no characters written yet */
|
||||
textlen = 0; /* no text yet */
|
||||
state = ST_NORMAL; /* starting state */
|
||||
heapbuf = NULL; /* not using heap-allocated buffer */
|
||||
buffersize = 0;
|
||||
|
||||
/* main loop -- loop while format character exist and no I/O errors */
|
||||
while ((ch = *format++) != '\0' && charsout >= 0) {
|
||||
// Find char class and next state
|
||||
chclass = GetCharType( ch );
|
||||
state = GetState( chclass, state );
|
||||
|
||||
/* execute code for each state */
|
||||
switch (state) {
|
||||
|
||||
case ST_INVALID:
|
||||
// "Incorrect format specifier"
|
||||
assert( false );
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
|
||||
case ST_NORMAL:
|
||||
|
||||
NORMAL_STATE:
|
||||
|
||||
/* normal state -- just write character */
|
||||
bufferiswide = 0;
|
||||
#ifdef _SAFECRT_IMPL
|
||||
if (isleadbyte((unsigned char)ch)) {
|
||||
#else /* _SAFECRT_IMPL */
|
||||
if (_isleadbyte_l((unsigned char)ch, _loc_update.GetLocaleT())) {
|
||||
#endif /* _SAFECRT_IMPL */
|
||||
// XPLAT_ODBC_TODO VSTS 718708 Localization
|
||||
// Deal with more than 2 storage units per character
|
||||
output->WRITE_CHAR(ch, &charsout);
|
||||
ch = *format++;
|
||||
/* don't fall off format string */
|
||||
_VALIDATE_RETURN( (ch != '\0'), EINVAL, -1);
|
||||
}
|
||||
output->WRITE_CHAR(ch, &charsout);
|
||||
break;
|
||||
|
||||
case ST_PERCENT:
|
||||
/* set default value of conversion parameters */
|
||||
prefixlen = fldwidth = no_output = capexp = 0;
|
||||
flags = 0;
|
||||
precision = -1;
|
||||
bufferiswide = 0; /* default */
|
||||
break;
|
||||
|
||||
case ST_FLAG:
|
||||
/* set flag based on which flag character */
|
||||
switch (ch) {
|
||||
case ('-'):
|
||||
flags |= FL_LEFT; /* '-' => left justify */
|
||||
break;
|
||||
case ('+'):
|
||||
flags |= FL_SIGN; /* '+' => force sign indicator */
|
||||
break;
|
||||
case (' '):
|
||||
flags |= FL_SIGNSP; /* ' ' => force sign or space */
|
||||
break;
|
||||
case ('#'):
|
||||
flags |= FL_ALTERNATE; /* '#' => alternate form */
|
||||
break;
|
||||
case ('0'):
|
||||
flags |= FL_LEADZERO; /* '0' => pad with leading zeros */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_WIDTH:
|
||||
/* update width value */
|
||||
if (ch == ('*')) {
|
||||
/* get width from arg list */
|
||||
fldwidth = va_arg(argptr, int);
|
||||
if (fldwidth < 0) {
|
||||
/* ANSI says neg fld width means '-' flag and pos width */
|
||||
flags |= FL_LEFT;
|
||||
fldwidth = -fldwidth;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* add digit to current field width */
|
||||
fldwidth = fldwidth * 10 + (ch - ('0'));
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_DOT:
|
||||
/* zero the precision, since dot with no number means 0
|
||||
not default, according to ANSI */
|
||||
precision = 0;
|
||||
break;
|
||||
|
||||
case ST_PRECIS:
|
||||
/* update precison value */
|
||||
if (ch == ('*')) {
|
||||
/* get precision from arg list */
|
||||
precision = va_arg(argptr, int);
|
||||
if (precision < 0)
|
||||
precision = -1; /* neg precision means default */
|
||||
}
|
||||
else {
|
||||
/* add digit to current precision */
|
||||
precision = precision * 10 + (ch - ('0'));
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_SIZE:
|
||||
/* just read a size specifier, set the flags based on it */
|
||||
state = ProcessSize( ch, format, &advance, &flags );
|
||||
format += advance;
|
||||
if ( ST_NORMAL == state )
|
||||
{
|
||||
goto NORMAL_STATE;
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_TYPE:
|
||||
/* we have finally read the actual type character, so we */
|
||||
/* now format and "print" the output. We use a big switch */
|
||||
/* statement that sets 'text' to point to the text that should */
|
||||
/* be printed, and 'textlen' to the length of this text. */
|
||||
/* Common code later on takes care of justifying it and */
|
||||
/* other miscellaneous chores. Note that cases share code, */
|
||||
/* in particular, all integer formatting is done in one place. */
|
||||
/* Look at those funky goto statements! */
|
||||
|
||||
switch (ch) {
|
||||
|
||||
case ('C'): /* ISO wide character */
|
||||
if (!(flags & (FL_SHORT|FL_LONG|FL_WIDECHAR)))
|
||||
flags |= FL_WIDECHAR; /* ISO std. */
|
||||
/* fall into 'c' case */
|
||||
|
||||
case ('c'): {
|
||||
/* print a single character specified by int argument */
|
||||
if (flags & (FL_LONG|FL_WIDECHAR)) {
|
||||
errno_t e = 0;
|
||||
wchar = (WCHAR) va_arg(argptr, int);
|
||||
/* convert to multibyte character */
|
||||
e = _WCTOMB_S(&textlen, buffer.sz, _countof(buffer.sz), wchar);
|
||||
|
||||
/* check that conversion was successful */
|
||||
if (e != 0)
|
||||
no_output = 1;
|
||||
} else {
|
||||
/* format multibyte character */
|
||||
/* this is an extension of ANSI */
|
||||
unsigned short temp;
|
||||
temp = (unsigned short) va_arg(argptr, int);
|
||||
{
|
||||
buffer.sz[0] = (char) temp;
|
||||
textlen = 1;
|
||||
}
|
||||
}
|
||||
text.sz = buffer.sz;
|
||||
}
|
||||
break;
|
||||
|
||||
case ('Z'): {
|
||||
// 'Z' format specifier disabled
|
||||
_VALIDATE_RETURN(0, EINVAL, -1);
|
||||
}
|
||||
break;
|
||||
|
||||
case ('S'): /* ISO wide character string */
|
||||
if (!(flags & (FL_SHORT|FL_LONG|FL_WIDECHAR)))
|
||||
flags |= FL_WIDECHAR;
|
||||
|
||||
case ('s'): {
|
||||
/* print a string -- */
|
||||
/* ANSI rules on how much of string to print: */
|
||||
/* all if precision is default, */
|
||||
/* min(precision, length) if precision given. */
|
||||
/* prints '(null)' if a null string is passed */
|
||||
|
||||
int i;
|
||||
char *p; /* temps */
|
||||
WCHAR *pwch;
|
||||
|
||||
/* At this point it is tempting to use strlen(), but */
|
||||
/* if a precision is specified, we're not allowed to */
|
||||
/* scan past there, because there might be no null */
|
||||
/* at all. Thus, we must do our own scan. */
|
||||
|
||||
i = (precision == -1) ? INT_MAX : precision;
|
||||
text.sz = (char *)va_arg(argptr, void *);
|
||||
|
||||
/* scan for null upto i characters */
|
||||
if (flags & (FL_LONG|FL_WIDECHAR)) {
|
||||
if (text.wz == NULL) /* NULL passed, use special string */
|
||||
text.wz = (WCHAR *)__wnullstring;
|
||||
bufferiswide = 1;
|
||||
pwch = text.wz;
|
||||
while ( i-- && *pwch )
|
||||
++pwch;
|
||||
textlen = (int)(pwch - text.wz);
|
||||
/* textlen now contains length in wide chars */
|
||||
} else {
|
||||
if (text.sz == NULL) /* NULL passed, use special string */
|
||||
text.sz = (char*) __nullstring;
|
||||
p = text.sz;
|
||||
while (i-- && *p)
|
||||
++p;
|
||||
textlen = (int)(p - text.sz); /* length of the string */
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case ('n'): {
|
||||
// We will not support %n
|
||||
_VALIDATE_RETURN(0, EINVAL, -1);
|
||||
}
|
||||
break;
|
||||
|
||||
case ('E'):
|
||||
case ('G'):
|
||||
case ('A'):
|
||||
capexp = 1; /* capitalize exponent */
|
||||
ch += ('a') - ('A'); /* convert format char to lower */
|
||||
/* DROP THROUGH */
|
||||
case ('e'):
|
||||
case ('f'):
|
||||
case ('g'):
|
||||
case ('a'): {
|
||||
/* floating point conversion -- we call cfltcvt routines */
|
||||
/* to do the work for us. */
|
||||
flags |= FL_SIGNED; /* floating point is signed conversion */
|
||||
text.sz = buffer.sz; /* put result in buffer */
|
||||
buffersize = BUFFERSIZE;
|
||||
|
||||
/* compute the precision value */
|
||||
if (precision < 0)
|
||||
precision = 6; /* default precision: 6 */
|
||||
else if (precision == 0 && ch == ('g'))
|
||||
precision = 1; /* ANSI specified */
|
||||
else if (precision > MAXPRECISION)
|
||||
precision = MAXPRECISION;
|
||||
|
||||
if (precision > BUFFERSIZE - _CVTBUFSIZE) {
|
||||
/* conversion will potentially overflow local buffer */
|
||||
/* so we need to use a heap-allocated buffer. */
|
||||
heapbuf = (char *)malloc(_CVTBUFSIZE + precision);
|
||||
if (heapbuf != NULL)
|
||||
{
|
||||
text.sz = heapbuf;
|
||||
buffersize = _CVTBUFSIZE + precision;
|
||||
}
|
||||
else
|
||||
/* malloc failed, cap precision further */
|
||||
precision = BUFFERSIZE - _CVTBUFSIZE;
|
||||
}
|
||||
|
||||
#ifdef _SAFECRT_IMPL
|
||||
/* for safecrt, we pass along the FL_ALTERNATE flag to _safecrt_cfltcvt */
|
||||
if (flags & FL_ALTERNATE)
|
||||
{
|
||||
capexp |= FL_ALTERNATE;
|
||||
}
|
||||
#endif /* _SAFECRT_IMPL */
|
||||
|
||||
#if !LONGDOUBLE_IS_DOUBLE
|
||||
/* do the conversion */
|
||||
if (flags & FL_LONGDOUBLE) {
|
||||
_LONGDOUBLE tmp;
|
||||
tmp=va_arg(argptr, _LONGDOUBLE);
|
||||
/* Note: assumes ch is in ASCII range */
|
||||
_CLDCVT(&tmp, text.sz, buffersize, (char)ch, precision, capexp);
|
||||
} else
|
||||
#endif /* !LONGDOUBLE_IS_DOUBLE */
|
||||
{
|
||||
double tmp;
|
||||
tmp=va_arg(argptr, double);
|
||||
/* Note: assumes ch is in ASCII range */
|
||||
/* In safecrt, we provide a special version of _cfltcvt which internally calls printf (see safecrt_output_s.c) */
|
||||
#ifndef _SAFECRT_IMPL
|
||||
_cfltcvt_l(&tmp, text.sz, buffersize, (char)ch, precision, capexp, _loc_update.GetLocaleT());
|
||||
#else /* _SAFECRT_IMPL */
|
||||
_CFLTCVT(&tmp, text.sz, buffersize, (char)ch, precision, capexp);
|
||||
#endif /* _SAFECRT_IMPL */
|
||||
}
|
||||
|
||||
#ifndef _SAFECRT_IMPL
|
||||
/* For safecrt, this is done already in _safecrt_cfltcvt */
|
||||
|
||||
/* '#' and precision == 0 means force a decimal point */
|
||||
if ((flags & FL_ALTERNATE) && precision == 0)
|
||||
{
|
||||
_forcdecpt_l(text.sz, _loc_update.GetLocaleT());
|
||||
}
|
||||
|
||||
/* 'g' format means crop zero unless '#' given */
|
||||
if (ch == ('g') && !(flags & FL_ALTERNATE))
|
||||
{
|
||||
_cropzeros_l(text.sz, _loc_update.GetLocaleT());
|
||||
}
|
||||
#endif /* _SAFECRT_IMPL */
|
||||
|
||||
/* check if result was negative, save '-' for later */
|
||||
/* and point to positive part (this is for '0' padding) */
|
||||
if (*text.sz == '-') {
|
||||
flags |= FL_NEGATIVE;
|
||||
++text.sz;
|
||||
}
|
||||
|
||||
textlen = (int)strlen(text.sz); /* compute length of text */
|
||||
}
|
||||
break;
|
||||
|
||||
case ('d'):
|
||||
case ('i'):
|
||||
/* signed decimal output */
|
||||
flags |= FL_SIGNED;
|
||||
radix = 10;
|
||||
goto COMMON_INT;
|
||||
|
||||
case ('u'):
|
||||
radix = 10;
|
||||
goto COMMON_INT;
|
||||
|
||||
case ('p'):
|
||||
/* write a pointer -- this is like an integer or long */
|
||||
/* except we force precision to pad with zeros and */
|
||||
/* output in big hex. */
|
||||
|
||||
precision = 2 * sizeof(void *); /* number of hex digits needed */
|
||||
#if PTR_IS_INT64
|
||||
flags |= FL_I64; /* assume we're converting an int64 */
|
||||
#endif /* !PTR_IS_INT */
|
||||
/* DROP THROUGH to hex formatting */
|
||||
|
||||
case ('X'):
|
||||
/* unsigned upper hex output */
|
||||
hexadd = ('A') - ('9') - 1; /* set hexadd for uppercase hex */
|
||||
goto COMMON_HEX;
|
||||
|
||||
case ('x'):
|
||||
/* unsigned lower hex output */
|
||||
hexadd = ('a') - ('9') - 1; /* set hexadd for lowercase hex */
|
||||
/* DROP THROUGH TO COMMON_HEX */
|
||||
|
||||
COMMON_HEX:
|
||||
radix = 16;
|
||||
if (flags & FL_ALTERNATE) {
|
||||
/* alternate form means '0x' prefix */
|
||||
prefix[0] = ('0');
|
||||
prefix[1] = (char)(('x') - ('a') + ('9') + 1 + hexadd); /* 'x' or 'X' */
|
||||
prefixlen = 2;
|
||||
}
|
||||
goto COMMON_INT;
|
||||
|
||||
case ('o'):
|
||||
/* unsigned octal output */
|
||||
radix = 8;
|
||||
if (flags & FL_ALTERNATE) {
|
||||
/* alternate form means force a leading 0 */
|
||||
flags |= FL_FORCEOCTAL;
|
||||
}
|
||||
/* DROP THROUGH to COMMON_INT */
|
||||
|
||||
COMMON_INT: {
|
||||
/* This is the general integer formatting routine. */
|
||||
/* Basically, we get an argument, make it positive */
|
||||
/* if necessary, and convert it according to the */
|
||||
/* correct radix, setting text and textlen */
|
||||
/* appropriately. */
|
||||
|
||||
ULONGLONG number; /* number to convert */
|
||||
int digit; /* ascii value of digit */
|
||||
LONGLONG l; /* temp long value */
|
||||
|
||||
/* 1. read argument into l, sign extend as needed */
|
||||
if (flags & FL_I64)
|
||||
l = va_arg(argptr, LONGLONG);
|
||||
else if (flags & FL_LONGLONG)
|
||||
l = va_arg(argptr, LONGLONG);
|
||||
else
|
||||
|
||||
if (flags & FL_SHORT) {
|
||||
if (flags & FL_SIGNED)
|
||||
l = (short) va_arg(argptr, int); /* sign extend */
|
||||
else
|
||||
l = (unsigned short) va_arg(argptr, int); /* zero-extend*/
|
||||
|
||||
} else
|
||||
{
|
||||
if (flags & FL_SIGNED)
|
||||
l = (int)va_arg(argptr, int); /* sign extend */
|
||||
else
|
||||
l = (unsigned int) va_arg(argptr, int); /* zero-extend*/
|
||||
}
|
||||
|
||||
/* 2. check for negative; copy into number */
|
||||
if ( (flags & FL_SIGNED) && l < 0) {
|
||||
number = -l;
|
||||
flags |= FL_NEGATIVE; /* remember negative sign */
|
||||
} else {
|
||||
number = l;
|
||||
}
|
||||
|
||||
if ( (flags & FL_I64) == 0 && (flags & FL_LONGLONG) == 0 ) {
|
||||
/*
|
||||
* Unless printing a full 64-bit value, insure values
|
||||
* here are not in cananical longword format to prevent
|
||||
* the sign extended upper 32-bits from being printed.
|
||||
*/
|
||||
number &= 0xffffffff;
|
||||
}
|
||||
|
||||
/* 3. check precision value for default; non-default */
|
||||
/* turns off 0 flag, according to ANSI. */
|
||||
if (precision < 0)
|
||||
precision = 1; /* default precision */
|
||||
else {
|
||||
flags &= ~FL_LEADZERO;
|
||||
if (precision > MAXPRECISION)
|
||||
precision = MAXPRECISION;
|
||||
}
|
||||
|
||||
/* 4. Check if data is 0; if so, turn off hex prefix */
|
||||
if (number == 0)
|
||||
prefixlen = 0;
|
||||
|
||||
/* 5. Convert data to ASCII -- note if precision is zero */
|
||||
/* and number is zero, we get no digits at all. */
|
||||
|
||||
text.sz = &buffer.sz[BUFFERSIZE-1]; /* last digit at end of buffer */
|
||||
|
||||
while (precision-- > 0 || number != 0) {
|
||||
digit = (int)(number % radix) + '0';
|
||||
number /= radix; /* reduce number */
|
||||
if (digit > '9') {
|
||||
/* a hex digit, make it a letter */
|
||||
digit += hexadd;
|
||||
}
|
||||
*text.sz-- = (char)digit; /* store the digit */
|
||||
}
|
||||
|
||||
textlen = (int)((char *)&buffer.sz[BUFFERSIZE-1] - text.sz); /* compute length of number */
|
||||
++text.sz; /* text points to first digit now */
|
||||
|
||||
|
||||
/* 6. Force a leading zero if FORCEOCTAL flag set */
|
||||
if ((flags & FL_FORCEOCTAL) && (textlen == 0 || text.sz[0] != '0')) {
|
||||
*--text.sz = '0';
|
||||
++textlen; /* add a zero */
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* At this point, we have done the specific conversion, and */
|
||||
/* 'text' points to text to print; 'textlen' is length. Now we */
|
||||
/* justify it, put on prefixes, leading zeros, and then */
|
||||
/* print it. */
|
||||
|
||||
if (!no_output) {
|
||||
int padding; /* amount of padding, negative means zero */
|
||||
|
||||
if (flags & FL_SIGNED) {
|
||||
if (flags & FL_NEGATIVE) {
|
||||
/* prefix is a '-' */
|
||||
prefix[0] = ('-');
|
||||
prefixlen = 1;
|
||||
}
|
||||
else if (flags & FL_SIGN) {
|
||||
/* prefix is '+' */
|
||||
prefix[0] = ('+');
|
||||
prefixlen = 1;
|
||||
}
|
||||
else if (flags & FL_SIGNSP) {
|
||||
/* prefix is ' ' */
|
||||
prefix[0] = (' ');
|
||||
prefixlen = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate amount of padding -- might be negative, */
|
||||
/* but this will just mean zero */
|
||||
padding = fldwidth - textlen - prefixlen;
|
||||
|
||||
/* put out the padding, prefix, and text, in the correct order */
|
||||
|
||||
if (!(flags & (FL_LEFT | FL_LEADZERO))) {
|
||||
/* pad on left with blanks */
|
||||
output->WRITE_MULTI_CHAR((' '), padding, &charsout);
|
||||
}
|
||||
|
||||
/* write prefix */
|
||||
output->WRITE_STRING(prefix, prefixlen, &charsout);
|
||||
|
||||
if ((flags & FL_LEADZERO) && !(flags & FL_LEFT)) {
|
||||
/* write leading zeros */
|
||||
output->WRITE_MULTI_CHAR(('0'), padding, &charsout);
|
||||
}
|
||||
|
||||
/* write text */
|
||||
if (bufferiswide && (textlen > 0)) {
|
||||
WCHAR *p;
|
||||
int retval, count;
|
||||
errno_t e = 0;
|
||||
char L_buffer[MB_LEN_MAX+1];
|
||||
|
||||
p = text.wz;
|
||||
count = textlen;
|
||||
while (count--) {
|
||||
e = _WCTOMB_S(&retval, L_buffer, _countof(L_buffer), *p++);
|
||||
if (e != 0 || retval == 0) {
|
||||
charsout = -1;
|
||||
break;
|
||||
}
|
||||
output->WRITE_STRING(L_buffer, retval, &charsout);
|
||||
}
|
||||
} else {
|
||||
output->WRITE_STRING(text.sz, textlen, &charsout);
|
||||
}
|
||||
|
||||
if (charsout >= 0 && (flags & FL_LEFT)) {
|
||||
/* pad on right with blanks */
|
||||
output->WRITE_MULTI_CHAR((' '), padding, &charsout);
|
||||
}
|
||||
|
||||
/* we're done! */
|
||||
}
|
||||
if (heapbuf) {
|
||||
free(heapbuf);
|
||||
heapbuf = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* The format string shouldn't be incomplete - i.e. when we are finished
|
||||
with the format string, the last thing we should have encountered
|
||||
should have been a regular char to be output or a type specifier. Else
|
||||
the format string was incomplete */
|
||||
_VALIDATE_RETURN(((state == ST_NORMAL) || (state == ST_TYPE)), EINVAL, -1);
|
||||
|
||||
return charsout; /* return value = number of characters written */
|
||||
}
|
||||
|
||||
// Tools\vc\src\crt\amd64\output.c
|
||||
int FormattedPrintW( IFormattedPrintOutput<WCHAR> * output, const WCHAR *format, va_list argptr )
|
||||
{
|
||||
int hexadd=0; /* offset to add to number to get 'a'..'f' */
|
||||
WCHAR ch; /* character just read */
|
||||
int flags=0; /* flag word -- see #defines above for flag values */
|
||||
enum STATE state; /* current state */
|
||||
enum CHARTYPE chclass; /* class of current character */
|
||||
int radix; /* current conversion radix */
|
||||
int charsout; /* characters currently written so far, -1 = IO error */
|
||||
int fldwidth = 0; /* selected field width -- 0 means default */
|
||||
int precision = 0; /* selected precision -- -1 means default */
|
||||
WCHAR prefix[2]; /* numeric prefix -- up to two characters */
|
||||
int prefixlen=0; /* length of prefix -- 0 means no prefix */
|
||||
int capexp=0; /* non-zero = 'E' exponent signifient, zero = 'e' or unused */
|
||||
int no_output=0; /* non-zero = prodcue no output for this specifier */
|
||||
union {
|
||||
char *sz; /* pointer text to be printed, not zero terminated */
|
||||
WCHAR *wz;
|
||||
} text;
|
||||
|
||||
int textlen; /* length of the text in bytes/wchars to be printed.
|
||||
textlen is in multibyte or wide chars if _UNICODE */
|
||||
union {
|
||||
char sz[BUFFERSIZE];
|
||||
WCHAR wz[BUFFERSIZE];
|
||||
} buffer;
|
||||
WCHAR wchar; /* temp wchar_t */
|
||||
int buffersize; /* size of text.sz (used only for the call to _cfltcvt) */
|
||||
int bufferiswide=0; /* non-zero = buffer contains wide chars already */
|
||||
|
||||
#ifndef _SAFECRT_IMPL
|
||||
_LocaleUpdate _loc_update(plocinfo);
|
||||
#endif /* _SAFECRT_IMPL */
|
||||
|
||||
char *heapbuf = NULL; /* non-zero = test.sz using heap buffer to be freed */
|
||||
|
||||
int advance; /* count of how much helper fxns need format ptr incremented */
|
||||
|
||||
_VALIDATE_RETURN( ((output != NULL) && (format != NULL)), EINVAL, -1);
|
||||
|
||||
charsout = 0; /* no characters written yet */
|
||||
textlen = 0; /* no text yet */
|
||||
state = ST_NORMAL; /* starting state */
|
||||
heapbuf = NULL; /* not using heap-allocated buffer */
|
||||
buffersize = 0;
|
||||
|
||||
/* main loop -- loop while format character exist and no I/O errors */
|
||||
while ((ch = *format++) != L'\0' && charsout >= 0) {
|
||||
// Find char class and next state
|
||||
chclass = GetCharType( ch );
|
||||
state = GetState( chclass, state );
|
||||
|
||||
/* execute code for each state */
|
||||
switch (state) {
|
||||
|
||||
case ST_INVALID:
|
||||
// "Incorrect format specifier"
|
||||
assert( false );
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
|
||||
case ST_NORMAL:
|
||||
|
||||
NORMAL_STATE:
|
||||
|
||||
/* normal state -- just write character */
|
||||
bufferiswide = 1;
|
||||
if (isleadwchar(ch)) {
|
||||
// Deal with more than 2 storage units per character
|
||||
output->WRITE_CHAR(ch, &charsout);
|
||||
ch = *format++;
|
||||
/* don't fall off format string */
|
||||
_VALIDATE_RETURN( (ch != L'\0'), EINVAL, -1);
|
||||
}
|
||||
output->WRITE_CHAR(ch, &charsout);
|
||||
break;
|
||||
|
||||
case ST_PERCENT:
|
||||
/* set default value of conversion parameters */
|
||||
prefixlen = fldwidth = no_output = capexp = 0;
|
||||
flags = 0;
|
||||
precision = -1;
|
||||
bufferiswide = 0; /* default */
|
||||
break;
|
||||
|
||||
case ST_FLAG:
|
||||
/* set flag based on which flag character */
|
||||
switch (ch) {
|
||||
case L'-':
|
||||
flags |= FL_LEFT; /* '-' => left justify */
|
||||
break;
|
||||
case L'+':
|
||||
flags |= FL_SIGN; /* '+' => force sign indicator */
|
||||
break;
|
||||
case L' ':
|
||||
flags |= FL_SIGNSP; /* ' ' => force sign or space */
|
||||
break;
|
||||
case L'#':
|
||||
flags |= FL_ALTERNATE; /* '#' => alternate form */
|
||||
break;
|
||||
case L'0':
|
||||
flags |= FL_LEADZERO; /* '0' => pad with leading zeros */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_WIDTH:
|
||||
/* update width value */
|
||||
if (ch == L'*') {
|
||||
/* get width from arg list */
|
||||
fldwidth = va_arg(argptr, int);
|
||||
if (fldwidth < 0) {
|
||||
/* ANSI says neg fld width means '-' flag and pos width */
|
||||
flags |= FL_LEFT;
|
||||
fldwidth = -fldwidth;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* add digit to current field width */
|
||||
fldwidth = fldwidth * 10 + (ch - L'0');
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_DOT:
|
||||
/* zero the precision, since dot with no number means 0
|
||||
not default, according to ANSI */
|
||||
precision = 0;
|
||||
break;
|
||||
|
||||
case ST_PRECIS:
|
||||
/* update precison value */
|
||||
if (ch == L'*') {
|
||||
/* get precision from arg list */
|
||||
precision = va_arg(argptr, int);
|
||||
if (precision < 0)
|
||||
precision = -1; /* neg precision means default */
|
||||
}
|
||||
else {
|
||||
/* add digit to current precision */
|
||||
precision = precision * 10 + (ch - L'0');
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_SIZE:
|
||||
/* just read a size specifier, set the flags based on it */
|
||||
state = ProcessSize( ch, format, &advance, &flags );
|
||||
format += advance;
|
||||
if ( ST_NORMAL == state )
|
||||
{
|
||||
goto NORMAL_STATE;
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_TYPE:
|
||||
/* we have finally read the actual type character, so we */
|
||||
/* now format and "print" the output. We use a big switch */
|
||||
/* statement that sets 'text' to point to the text that should */
|
||||
/* be printed, and 'textlen' to the length of this text. */
|
||||
/* Common code later on takes care of justifying it and */
|
||||
/* other miscellaneous chores. Note that cases share code, */
|
||||
/* in particular, all integer formatting is done in one place. */
|
||||
/* Look at those funky goto statements! */
|
||||
|
||||
switch (ch) {
|
||||
|
||||
case L'C': /* ISO wide character */
|
||||
if (!(flags & (FL_SHORT|FL_LONG|FL_WIDECHAR)))
|
||||
flags |= FL_SHORT;
|
||||
/* fall into 'c' case */
|
||||
|
||||
case L'c': {
|
||||
/* print a single character specified by int argument */
|
||||
bufferiswide = 1;
|
||||
wchar = (WCHAR) va_arg(argptr, int);
|
||||
if (flags & FL_SHORT) {
|
||||
/* format multibyte character */
|
||||
/* this is an extension of ANSI */
|
||||
char tempchar[2];
|
||||
{
|
||||
tempchar[0] = (char)(wchar & 0x00ff);
|
||||
tempchar[1] = '\0';
|
||||
}
|
||||
|
||||
#ifdef _SAFECRT_IMPL
|
||||
if (_MBTOWC(buffer.wz,tempchar, MB_CUR_MAX) < 0)
|
||||
#else /* _SAFECRT_IMPL */
|
||||
if (_mbtowc_l(buffer.wz,
|
||||
tempchar,
|
||||
_loc_update.GetLocaleT()->locinfo->mb_cur_max,
|
||||
_loc_update.GetLocaleT()) < 0)
|
||||
#endif /* _SAFECRT_IMPL */
|
||||
{
|
||||
/* ignore if conversion was unsuccessful */
|
||||
no_output = 1;
|
||||
}
|
||||
} else {
|
||||
buffer.wz[0] = wchar;
|
||||
}
|
||||
text.wz = buffer.wz;
|
||||
textlen = 1; /* print just a single character */
|
||||
}
|
||||
break;
|
||||
|
||||
case L'Z': {
|
||||
// 'Z' format specifier disabled
|
||||
_VALIDATE_RETURN(0, EINVAL, -1);
|
||||
}
|
||||
break;
|
||||
|
||||
case L'S': /* ISO wide character string */
|
||||
if (!(flags & (FL_SHORT|FL_LONG|FL_WIDECHAR)))
|
||||
flags |= FL_SHORT;
|
||||
|
||||
case L's': {
|
||||
/* print a string -- */
|
||||
/* ANSI rules on how much of string to print: */
|
||||
/* all if precision is default, */
|
||||
/* min(precision, length) if precision given. */
|
||||
/* prints '(null)' if a null string is passed */
|
||||
|
||||
int i;
|
||||
char *p; /* temps */
|
||||
WCHAR *pwch;
|
||||
|
||||
/* At this point it is tempting to use strlen(), but */
|
||||
/* if a precision is specified, we're not allowed to */
|
||||
/* scan past there, because there might be no null */
|
||||
/* at all. Thus, we must do our own scan. */
|
||||
|
||||
i = (precision == -1) ? INT_MAX : precision;
|
||||
text.sz = (char *)va_arg(argptr, void *);
|
||||
|
||||
/* scan for null upto i characters */
|
||||
if (flags & FL_SHORT) {
|
||||
if (text.sz == NULL) /* NULL passed, use special string */
|
||||
text.sz = (char*) __nullstring;
|
||||
p = text.sz;
|
||||
for (textlen=0; textlen<i && *p; textlen++) {
|
||||
#ifdef _SAFECRT_IMPL
|
||||
if (isleadbyte((unsigned char)(*p)))
|
||||
#else /* _SAFECRT_IMPL */
|
||||
if (_isleadbyte_l((unsigned char)(*p), _loc_update.GetLocaleT()))
|
||||
#endif /* _SAFECRT_IMPL */
|
||||
++p;
|
||||
++p;
|
||||
}
|
||||
/* textlen now contains length in multibyte chars */
|
||||
} else {
|
||||
if (text.wz == NULL) /* NULL passed, use special string */
|
||||
text.wz = (WCHAR *)__wnullstring;
|
||||
bufferiswide = 1;
|
||||
pwch = text.wz;
|
||||
while (i-- && *pwch)
|
||||
++pwch;
|
||||
textlen = (int)(pwch - text.wz); /* in wchar_ts */
|
||||
/* textlen now contains length in wide chars */
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case L'n': {
|
||||
// 'n' format specifier disabled
|
||||
_VALIDATE_RETURN(0, EINVAL, -1);
|
||||
}
|
||||
break;
|
||||
|
||||
case L'E':
|
||||
case L'G':
|
||||
case L'A':
|
||||
capexp = 1; /* capitalize exponent */
|
||||
ch += L'a' - L'A'; /* convert format char to lower */
|
||||
/* DROP THROUGH */
|
||||
case L'e':
|
||||
case L'f':
|
||||
case L'g':
|
||||
case L'a': {
|
||||
/* floating point conversion -- we call cfltcvt routines */
|
||||
/* to do the work for us. */
|
||||
flags |= FL_SIGNED; /* floating point is signed conversion */
|
||||
text.sz = buffer.sz; /* put result in buffer */
|
||||
buffersize = BUFFERSIZE;
|
||||
|
||||
/* compute the precision value */
|
||||
if (precision < 0)
|
||||
precision = 6; /* default precision: 6 */
|
||||
else if (precision == 0 && ch == L'g')
|
||||
precision = 1; /* ANSI specified */
|
||||
else if (precision > MAXPRECISION)
|
||||
precision = MAXPRECISION;
|
||||
|
||||
if (precision > BUFFERSIZE - _CVTBUFSIZE) {
|
||||
/* conversion will potentially overflow local buffer */
|
||||
/* so we need to use a heap-allocated buffer. */
|
||||
heapbuf = (char *)malloc(_CVTBUFSIZE + precision);
|
||||
if (heapbuf != NULL)
|
||||
{
|
||||
text.sz = heapbuf;
|
||||
buffersize = _CVTBUFSIZE + precision;
|
||||
}
|
||||
else
|
||||
/* malloc failed, cap precision further */
|
||||
precision = BUFFERSIZE - _CVTBUFSIZE;
|
||||
}
|
||||
|
||||
#ifdef _SAFECRT_IMPL
|
||||
/* for safecrt, we pass along the FL_ALTERNATE flag to _safecrt_cfltcvt */
|
||||
if (flags & FL_ALTERNATE)
|
||||
{
|
||||
capexp |= FL_ALTERNATE;
|
||||
}
|
||||
#endif /* _SAFECRT_IMPL */
|
||||
|
||||
#if !LONGDOUBLE_IS_DOUBLE
|
||||
/* do the conversion */
|
||||
if (flags & FL_LONGDOUBLE) {
|
||||
_LONGDOUBLE tmp;
|
||||
tmp=va_arg(argptr, _LONGDOUBLE);
|
||||
/* Note: assumes ch is in ASCII range */
|
||||
_CLDCVT(&tmp, text.sz, buffersize, (char)ch, precision, capexp);
|
||||
} else
|
||||
#endif /* !LONGDOUBLE_IS_DOUBLE */
|
||||
{
|
||||
double tmp;
|
||||
tmp=va_arg(argptr, double);
|
||||
/* Note: assumes ch is in ASCII range */
|
||||
/* In safecrt, we provide a special version of _cfltcvt which internally calls printf (see safecrt_output_s.c) */
|
||||
#ifndef _SAFECRT_IMPL
|
||||
_cfltcvt_l(&tmp, text.sz, buffersize, (char)ch, precision, capexp, _loc_update.GetLocaleT());
|
||||
#else /* _SAFECRT_IMPL */
|
||||
_CFLTCVT(&tmp, text.sz, buffersize, (char)ch, precision, capexp);
|
||||
#endif /* _SAFECRT_IMPL */
|
||||
}
|
||||
|
||||
#ifndef _SAFECRT_IMPL
|
||||
/* For safecrt, this is done already in _safecrt_cfltcvt */
|
||||
|
||||
/* '#' and precision == 0 means force a decimal point */
|
||||
if ((flags & FL_ALTERNATE) && precision == 0)
|
||||
{
|
||||
_forcdecpt_l(text.sz, _loc_update.GetLocaleT());
|
||||
}
|
||||
|
||||
/* 'g' format means crop zero unless '#' given */
|
||||
if (ch == L'g' && !(flags & FL_ALTERNATE))
|
||||
{
|
||||
_cropzeros_l(text.sz, _loc_update.GetLocaleT());
|
||||
}
|
||||
#endif /* _SAFECRT_IMPL */
|
||||
|
||||
/* check if result was negative, save '-' for later */
|
||||
/* and point to positive part (this is for '0' padding) */
|
||||
if (*text.sz == '-') {
|
||||
flags |= FL_NEGATIVE;
|
||||
++text.sz;
|
||||
}
|
||||
|
||||
textlen = (int)strlen(text.sz); /* compute length of text */
|
||||
}
|
||||
break;
|
||||
|
||||
case L'd':
|
||||
case L'i':
|
||||
/* signed decimal output */
|
||||
flags |= FL_SIGNED;
|
||||
radix = 10;
|
||||
goto COMMON_INT;
|
||||
|
||||
case L'u':
|
||||
radix = 10;
|
||||
goto COMMON_INT;
|
||||
|
||||
case L'p':
|
||||
/* write a pointer -- this is like an integer or long */
|
||||
/* except we force precision to pad with zeros and */
|
||||
/* output in big hex. */
|
||||
|
||||
precision = 2 * sizeof(void *); /* number of hex digits needed */
|
||||
#if PTR_IS_INT64
|
||||
flags |= FL_I64; /* assume we're converting an int64 */
|
||||
#endif /* !PTR_IS_INT */
|
||||
/* DROP THROUGH to hex formatting */
|
||||
|
||||
case L'X':
|
||||
/* unsigned upper hex output */
|
||||
hexadd = L'A' - L'9' - 1; /* set hexadd for uppercase hex */
|
||||
goto COMMON_HEX;
|
||||
|
||||
case L'x':
|
||||
/* unsigned lower hex output */
|
||||
hexadd = L'a' - L'9' - 1; /* set hexadd for lowercase hex */
|
||||
/* DROP THROUGH TO COMMON_HEX */
|
||||
|
||||
COMMON_HEX:
|
||||
radix = 16;
|
||||
if (flags & FL_ALTERNATE) {
|
||||
/* alternate form means '0x' prefix */
|
||||
prefix[0] = L'0';
|
||||
prefix[1] = (WCHAR)(L'x' - L'a' + L'9' + 1 + hexadd); /* 'x' or 'X' */
|
||||
prefixlen = 2;
|
||||
}
|
||||
goto COMMON_INT;
|
||||
|
||||
case L'o':
|
||||
/* unsigned octal output */
|
||||
radix = 8;
|
||||
if (flags & FL_ALTERNATE) {
|
||||
/* alternate form means force a leading 0 */
|
||||
flags |= FL_FORCEOCTAL;
|
||||
}
|
||||
/* DROP THROUGH to COMMON_INT */
|
||||
|
||||
COMMON_INT: {
|
||||
/* This is the general integer formatting routine. */
|
||||
/* Basically, we get an argument, make it positive */
|
||||
/* if necessary, and convert it according to the */
|
||||
/* correct radix, setting text and textlen */
|
||||
/* appropriately. */
|
||||
|
||||
ULONGLONG number; /* number to convert */
|
||||
int digit; /* ascii value of digit */
|
||||
LONGLONG l; /* temp long value */
|
||||
|
||||
/* 1. read argument into l, sign extend as needed */
|
||||
if (flags & FL_I64)
|
||||
l = va_arg(argptr, LONGLONG);
|
||||
else if (flags & FL_LONGLONG)
|
||||
l = va_arg(argptr, LONGLONG);
|
||||
else
|
||||
|
||||
if (flags & FL_SHORT) {
|
||||
if (flags & FL_SIGNED)
|
||||
l = (short) va_arg(argptr, int); /* sign extend */
|
||||
else
|
||||
l = (unsigned short) va_arg(argptr, int); /* zero-extend*/
|
||||
|
||||
} else
|
||||
{
|
||||
if (flags & FL_SIGNED)
|
||||
l = (int)va_arg(argptr, int); /* sign extend */
|
||||
else
|
||||
l = (unsigned int) va_arg(argptr, int); /* zero-extend*/
|
||||
}
|
||||
|
||||
/* 2. check for negative; copy into number */
|
||||
if ( (flags & FL_SIGNED) && l < 0) {
|
||||
number = -l;
|
||||
flags |= FL_NEGATIVE; /* remember negative sign */
|
||||
} else {
|
||||
number = l;
|
||||
}
|
||||
|
||||
if ( (flags & FL_I64) == 0 && (flags & FL_LONGLONG) == 0 ) {
|
||||
/*
|
||||
* Unless printing a full 64-bit value, insure values
|
||||
* here are not in cananical longword format to prevent
|
||||
* the sign extended upper 32-bits from being printed.
|
||||
*/
|
||||
number &= 0xffffffff;
|
||||
}
|
||||
|
||||
/* 3. check precision value for default; non-default */
|
||||
/* turns off 0 flag, according to ANSI. */
|
||||
if (precision < 0)
|
||||
precision = 1; /* default precision */
|
||||
else {
|
||||
flags &= ~FL_LEADZERO;
|
||||
if (precision > MAXPRECISION)
|
||||
precision = MAXPRECISION;
|
||||
}
|
||||
|
||||
/* 4. Check if data is 0; if so, turn off hex prefix */
|
||||
if (number == 0)
|
||||
prefixlen = 0;
|
||||
|
||||
/* 5. Convert data to ASCII -- note if precision is zero */
|
||||
/* and number is zero, we get no digits at all. */
|
||||
|
||||
text.sz = &buffer.sz[BUFFERSIZE-1]; /* last digit at end of buffer */
|
||||
|
||||
while (precision-- > 0 || number != 0) {
|
||||
digit = (int)(number % radix) + '0';
|
||||
number /= radix; /* reduce number */
|
||||
if (digit > '9') {
|
||||
/* a hex digit, make it a letter */
|
||||
digit += hexadd;
|
||||
}
|
||||
*text.sz-- = (char)digit; /* store the digit */
|
||||
}
|
||||
|
||||
textlen = (int)((char *)&buffer.sz[BUFFERSIZE-1] - text.sz); /* compute length of number */
|
||||
++text.sz; /* text points to first digit now */
|
||||
|
||||
|
||||
/* 6. Force a leading zero if FORCEOCTAL flag set */
|
||||
if ((flags & FL_FORCEOCTAL) && (textlen == 0 || text.sz[0] != '0')) {
|
||||
*--text.sz = '0';
|
||||
++textlen; /* add a zero */
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* At this point, we have done the specific conversion, and */
|
||||
/* 'text' points to text to print; 'textlen' is length. Now we */
|
||||
/* justify it, put on prefixes, leading zeros, and then */
|
||||
/* print it. */
|
||||
|
||||
if (!no_output) {
|
||||
int padding; /* amount of padding, negative means zero */
|
||||
|
||||
if (flags & FL_SIGNED) {
|
||||
if (flags & FL_NEGATIVE) {
|
||||
/* prefix is a '-' */
|
||||
prefix[0] = L'-';
|
||||
prefixlen = 1;
|
||||
}
|
||||
else if (flags & FL_SIGN) {
|
||||
/* prefix is '+' */
|
||||
prefix[0] = L'+';
|
||||
prefixlen = 1;
|
||||
}
|
||||
else if (flags & FL_SIGNSP) {
|
||||
/* prefix is ' ' */
|
||||
prefix[0] = L' ';
|
||||
prefixlen = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate amount of padding -- might be negative, */
|
||||
/* but this will just mean zero */
|
||||
padding = fldwidth - textlen - prefixlen;
|
||||
|
||||
/* put out the padding, prefix, and text, in the correct order */
|
||||
|
||||
if (!(flags & (FL_LEFT | FL_LEADZERO))) {
|
||||
/* pad on left with blanks */
|
||||
output->WRITE_MULTI_CHAR(L' ', padding, &charsout);
|
||||
}
|
||||
|
||||
/* write prefix */
|
||||
output->WRITE_STRING(prefix, prefixlen, &charsout);
|
||||
|
||||
if ((flags & FL_LEADZERO) && !(flags & FL_LEFT)) {
|
||||
/* write leading zeros */
|
||||
output->WRITE_MULTI_CHAR(L'0', padding, &charsout);
|
||||
}
|
||||
|
||||
/* write text */
|
||||
if (!bufferiswide && textlen > 0) {
|
||||
char *p;
|
||||
int retval, count;
|
||||
|
||||
p = text.sz;
|
||||
count = textlen;
|
||||
while (count-- > 0) {
|
||||
#ifdef _SAFECRT_IMPL
|
||||
retval = _MBTOWC(&wchar, p, MB_CUR_MAX);
|
||||
#else /* _SAFECRT_IMPL */
|
||||
retval = _mbtowc_l(&wchar,
|
||||
p,
|
||||
_loc_update.GetLocaleT()->locinfo->mb_cur_max,
|
||||
_loc_update.GetLocaleT());
|
||||
#endif /* _SAFECRT_IMPL */
|
||||
if (retval <= 0) {
|
||||
charsout = -1;
|
||||
break;
|
||||
}
|
||||
output->WRITE_CHAR(wchar, &charsout);
|
||||
p += retval;
|
||||
}
|
||||
} else {
|
||||
output->WRITE_STRING(text.wz, textlen, &charsout);
|
||||
}
|
||||
|
||||
if (charsout >= 0 && (flags & FL_LEFT)) {
|
||||
/* pad on right with blanks */
|
||||
output->WRITE_MULTI_CHAR(L' ', padding, &charsout);
|
||||
}
|
||||
|
||||
/* we're done! */
|
||||
}
|
||||
if (heapbuf) {
|
||||
free(heapbuf);
|
||||
heapbuf = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* The format string shouldn't be incomplete - i.e. when we are finished
|
||||
with the format string, the last thing we should have encountered
|
||||
should have been a regular char to be output or a type specifier. Else
|
||||
the format string was incomplete */
|
||||
_VALIDATE_RETURN(((state == ST_NORMAL) || (state == ST_TYPE)), EINVAL, -1);
|
||||
|
||||
return charsout; /* return value = number of characters written */
|
||||
}
|
||||
|
||||
|
||||
// Used for holding the size and value of a variable argument.
|
||||
// Uses INT and LONGLONG to hold all possible values. Each is just a buffer to hold the right number of bits.
|
||||
struct vararg_t
|
||||
{
|
||||
enum ArgType_e
|
||||
{
|
||||
Unknown,
|
||||
Int32,
|
||||
Int64,
|
||||
ShouldBeInt32,
|
||||
ShouldBeInt64
|
||||
};
|
||||
|
||||
vararg_t() : int64Val(0), int32Val(0), argType(vararg_t::Unknown) {}
|
||||
vararg_t( INT val ) : int64Val(0), int32Val(val), argType(vararg_t::Int32) {}
|
||||
vararg_t( LONGLONG ptr ) : int64Val(ptr), int32Val(0), argType(vararg_t::Int64) {}
|
||||
|
||||
ArgType_e Type() const { return argType; }
|
||||
INT Int32Value() const { return int32Val; }
|
||||
LONGLONG Int64Value() const { return int64Val; }
|
||||
void * PtrValue() const
|
||||
{
|
||||
#if PTR_IS_INT64
|
||||
return reinterpret_cast<void *>(int64Val);
|
||||
#else
|
||||
return reinterpret_cast<void *>(int32Val);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SetForInt32()
|
||||
{
|
||||
assert( vararg_t::Unknown == argType );
|
||||
argType = vararg_t::ShouldBeInt32;
|
||||
}
|
||||
void SetForInt64()
|
||||
{
|
||||
assert( vararg_t::Unknown == argType );
|
||||
argType = vararg_t::ShouldBeInt64;
|
||||
}
|
||||
void SetForPtr()
|
||||
{
|
||||
#if PTR_IS_INT64
|
||||
SetForInt64();
|
||||
#else
|
||||
SetForInt32();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Int32Value( INT val )
|
||||
{
|
||||
assert( vararg_t::Unknown == argType || vararg_t::ShouldBeInt32 == argType );
|
||||
assert( 0 == int64Val );
|
||||
argType = vararg_t::Int32;
|
||||
int32Val = val;
|
||||
}
|
||||
void Int64Value( LONGLONG val )
|
||||
{
|
||||
assert( vararg_t::Unknown == argType || vararg_t::ShouldBeInt64 == argType );
|
||||
assert( 0 == int32Val );
|
||||
argType = vararg_t::Int64;
|
||||
int64Val = val;
|
||||
}
|
||||
|
||||
private:
|
||||
LONGLONG int64Val;
|
||||
INT int32Val;
|
||||
ArgType_e argType;
|
||||
};
|
||||
|
||||
// Caches the var arg values in the supplied vector. Types are determined by inspecting the format string.
|
||||
// On error, sets errno and returns false
|
||||
static bool GetFormatMessageArgsA( const char * format, std::vector< vararg_t > * argcache, va_list * Arguments )
|
||||
{
|
||||
if ( NULL == format )
|
||||
{
|
||||
errno = EINVAL;
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *p = format;
|
||||
char fmt_ch;
|
||||
|
||||
while( '\0' != (fmt_ch = *p++) )
|
||||
{
|
||||
if ( '%' != fmt_ch )
|
||||
{
|
||||
// continue to next format spec
|
||||
}
|
||||
else if ( '0' == *p || '\0' == *p )
|
||||
{
|
||||
// %0 or null term means end formatting
|
||||
break;
|
||||
}
|
||||
else if ( *p < '1' || '9' < *p )
|
||||
{
|
||||
// Escaped char, skip and keep going
|
||||
++p;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Integer must be [1..99]
|
||||
size_t argPos = *p++ - '0';
|
||||
if ( '0' <= *p && *p <= '9' )
|
||||
{
|
||||
argPos *= 10;
|
||||
argPos += *p++ - '0';
|
||||
}
|
||||
assert( 0 < argPos && argPos < 100 );
|
||||
|
||||
if ( argcache->size() < argPos )
|
||||
{
|
||||
// Haven't processed this arg, yet
|
||||
argcache->resize( argPos );
|
||||
}
|
||||
|
||||
if ( vararg_t::Unknown == argcache->at(argPos-1).Type() )
|
||||
{
|
||||
if ( '!' != *p )
|
||||
{
|
||||
// Assume %s as per spec
|
||||
argcache->at(argPos-1).SetForPtr();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Step over the initial '!' and process format specification
|
||||
++p;
|
||||
|
||||
char ch;
|
||||
int flags = 0;
|
||||
int advance = 0;
|
||||
enum CHARTYPE chclass;
|
||||
enum STATE state = ST_PERCENT;
|
||||
bool found_terminator = false;
|
||||
while ( !found_terminator && ('\0' != (ch = *p++)) )
|
||||
{
|
||||
chclass = GetCharType( ch );
|
||||
state = GetState( chclass, state );
|
||||
|
||||
switch ( state )
|
||||
{
|
||||
case ST_DOT:
|
||||
case ST_FLAG:
|
||||
break;
|
||||
|
||||
case ST_WIDTH:
|
||||
case ST_PRECIS:
|
||||
if ( '*' == ch )
|
||||
{
|
||||
argcache->at(argPos-1).SetForInt32();
|
||||
++argPos;
|
||||
if ( argcache->size() < argPos )
|
||||
{
|
||||
argcache->resize( argPos );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_SIZE:
|
||||
state = ProcessSize( ch, p, &advance, &flags );
|
||||
p += advance;
|
||||
if ( ST_SIZE != state )
|
||||
{
|
||||
// Size and type flags were inconsistent
|
||||
errno = EINVAL;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_TYPE:
|
||||
// Group into 32-bit and 64-bit sized args
|
||||
assert( vararg_t::Unknown == argcache->at(argPos-1).Type() );
|
||||
switch ( ch )
|
||||
{
|
||||
case 'C': // chars
|
||||
case 'c':
|
||||
argcache->at(argPos-1).SetForInt32();
|
||||
break;
|
||||
|
||||
case 'd': // ints
|
||||
case 'i':
|
||||
case 'u':
|
||||
case 'X':
|
||||
case 'x':
|
||||
case 'o':
|
||||
// INT args
|
||||
if ( (flags & FL_I64) || (flags & FL_LONGLONG) )
|
||||
argcache->at(argPos-1).SetForInt64();
|
||||
else
|
||||
argcache->at(argPos-1).SetForInt32();
|
||||
break;
|
||||
|
||||
case 'S': // strings
|
||||
case 's':
|
||||
case 'p': // pointer
|
||||
argcache->at(argPos-1).SetForPtr();
|
||||
break;
|
||||
|
||||
case 'E': // doubles (not supported as per spec)
|
||||
case 'e':
|
||||
case 'G':
|
||||
case 'g':
|
||||
case 'A':
|
||||
case 'a':
|
||||
case 'f':
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_NORMAL:
|
||||
if ( '!' == ch )
|
||||
{
|
||||
found_terminator = true;
|
||||
break;
|
||||
}
|
||||
// Fall thru to error, missing terminating '!'
|
||||
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !found_terminator )
|
||||
{
|
||||
// End of string before trailing '!' was found
|
||||
errno = EINVAL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( 0 < argcache->size() && NULL == Arguments )
|
||||
{
|
||||
errno = EINVAL;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cache var arg values now that we know the number and sizes
|
||||
for ( std::vector< vararg_t >::iterator arg = argcache->begin(); arg != argcache->end(); ++arg )
|
||||
{
|
||||
if ( vararg_t::Unknown == arg->Type() )
|
||||
{
|
||||
// Arg not referenced in format string so assume ptr sized.
|
||||
// This is a decent assumption since every arg gets ptr-size bytes to ensure alignment
|
||||
// of later arg values. Verified this behavior with both Windows and Linux.
|
||||
arg->SetForPtr();
|
||||
}
|
||||
|
||||
vararg_t::ArgType_e argtype = arg->Type();
|
||||
assert( vararg_t::ShouldBeInt32 == argtype || vararg_t::ShouldBeInt64 == argtype );
|
||||
|
||||
if ( vararg_t::ShouldBeInt32 == argtype )
|
||||
{
|
||||
arg->Int32Value( (INT)va_arg(*Arguments, INT) );
|
||||
}
|
||||
else
|
||||
{
|
||||
arg->Int64Value( (LONGLONG)va_arg(*Arguments, LONGLONG) );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Caches the var arg values in the supplied vector. Types are determined by inspecting the format string.
|
||||
// On error, sets errno and returns false
|
||||
static bool GetFormatMessageArgsW( const WCHAR * format, std::vector< vararg_t > * argcache, va_list * Arguments )
|
||||
{
|
||||
if ( NULL == format )
|
||||
{
|
||||
errno = EINVAL;
|
||||
return false;
|
||||
}
|
||||
|
||||
const WCHAR *p = format;
|
||||
WCHAR fmt_ch;
|
||||
|
||||
while( L'\0' != (fmt_ch = *p++) )
|
||||
{
|
||||
if ( L'%' != fmt_ch )
|
||||
{
|
||||
// continue to next format spec
|
||||
}
|
||||
else if ( L'0' == *p || L'\0' == *p )
|
||||
{
|
||||
// %0 or null term means end formatting
|
||||
break;
|
||||
}
|
||||
else if ( *p < L'1' || L'9' < *p )
|
||||
{
|
||||
// Escaped char, skip and keep going
|
||||
++p;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Integer must be [1..99]
|
||||
size_t argPos = *p++ - L'0';
|
||||
if ( L'0' <= *p && *p <= L'9' )
|
||||
{
|
||||
argPos *= 10;
|
||||
argPos += *p++ - L'0';
|
||||
}
|
||||
assert( 0 < argPos && argPos < 100 );
|
||||
|
||||
if ( argcache->size() < argPos )
|
||||
{
|
||||
// Haven't processed this arg, yet
|
||||
argcache->resize( argPos );
|
||||
}
|
||||
|
||||
if ( vararg_t::Unknown == argcache->at(argPos-1).Type() )
|
||||
{
|
||||
if ( L'!' != *p )
|
||||
{
|
||||
// Assume %s as per spec
|
||||
argcache->at(argPos-1).SetForPtr();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Step over the initial '!' and process format specification
|
||||
++p;
|
||||
|
||||
WCHAR ch;
|
||||
int flags = 0;
|
||||
int advance = 0;
|
||||
enum CHARTYPE chclass;
|
||||
enum STATE state = ST_PERCENT;
|
||||
bool found_terminator = false;
|
||||
while ( !found_terminator && (L'\0' != (ch = *p++)) )
|
||||
{
|
||||
chclass = GetCharType( ch );
|
||||
state = GetState( chclass, state );
|
||||
|
||||
switch ( state )
|
||||
{
|
||||
case ST_DOT:
|
||||
case ST_FLAG:
|
||||
break;
|
||||
|
||||
case ST_WIDTH:
|
||||
case ST_PRECIS:
|
||||
if ( L'*' == ch )
|
||||
{
|
||||
argcache->at(argPos-1).SetForInt32();
|
||||
++argPos;
|
||||
if ( argcache->size() < argPos )
|
||||
{
|
||||
argcache->resize( argPos );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_SIZE:
|
||||
state = ProcessSize( ch, p, &advance, &flags );
|
||||
p += advance;
|
||||
if ( ST_SIZE != state )
|
||||
{
|
||||
// Size and type flags were inconsistent
|
||||
errno = EINVAL;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_TYPE:
|
||||
// Group into 32-bit and 64-bit sized args
|
||||
assert( vararg_t::Unknown == argcache->at(argPos-1).Type() );
|
||||
switch ( ch )
|
||||
{
|
||||
case L'C': // chars
|
||||
case L'c':
|
||||
argcache->at(argPos-1).SetForInt32();
|
||||
break;
|
||||
|
||||
case L'd': // ints
|
||||
case L'i':
|
||||
case L'u':
|
||||
case L'X':
|
||||
case L'x':
|
||||
case L'o':
|
||||
// INT args
|
||||
if ( (flags & FL_I64) || (flags & FL_LONGLONG) )
|
||||
argcache->at(argPos-1).SetForInt64();
|
||||
else
|
||||
argcache->at(argPos-1).SetForInt32();
|
||||
break;
|
||||
|
||||
case L'S': // strings
|
||||
case L's':
|
||||
case L'p': // pointer
|
||||
argcache->at(argPos-1).SetForPtr();
|
||||
break;
|
||||
|
||||
case L'E': // doubles (not supported as per spec)
|
||||
case L'e':
|
||||
case L'G':
|
||||
case L'g':
|
||||
case L'A':
|
||||
case L'a':
|
||||
case L'f':
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_NORMAL:
|
||||
if ( L'!' == ch )
|
||||
{
|
||||
found_terminator = true;
|
||||
break;
|
||||
}
|
||||
// Fall thru to error, missing terminating '!'
|
||||
|
||||
default:
|
||||
errno = EINVAL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !found_terminator )
|
||||
{
|
||||
// End of string before trailing '!' was found
|
||||
errno = EINVAL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( 0 < argcache->size() && NULL == Arguments )
|
||||
{
|
||||
errno = EINVAL;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cache var arg values now that we know the number and sizes
|
||||
for ( std::vector< vararg_t >::iterator arg = argcache->begin(); arg != argcache->end(); ++arg )
|
||||
{
|
||||
if ( vararg_t::Unknown == arg->Type() )
|
||||
{
|
||||
// Arg not referenced in format string so assume ptr sized.
|
||||
// This is a decent assumption since every arg gets ptr-size bytes to ensure alignment
|
||||
// of later arg values. Verified this behavior with both Windows and Linux.
|
||||
arg->SetForPtr();
|
||||
}
|
||||
|
||||
vararg_t::ArgType_e argtype = arg->Type();
|
||||
assert( vararg_t::ShouldBeInt32 == argtype || vararg_t::ShouldBeInt64 == argtype );
|
||||
|
||||
if ( vararg_t::ShouldBeInt32 == argtype )
|
||||
{
|
||||
arg->Int32Value( (INT)va_arg(*Arguments, INT) );
|
||||
}
|
||||
else
|
||||
{
|
||||
arg->Int64Value( (LONGLONG)va_arg(*Arguments, LONGLONG) );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// On success, returns the number of chars written into the buffer excluding null terminator.
|
||||
// On error, sets errno and returns zero.
|
||||
static DWORD FormatMessageToBufferA( const char * format, char * buffer, DWORD bufferWCharSize, const std::vector< vararg_t > & args )
|
||||
{
|
||||
char * msg = buffer;
|
||||
DWORD bufsize = std::min(bufferWCharSize, (DWORD)64000);
|
||||
DWORD msg_pos = 0;
|
||||
const DWORD fmtsize = 32;
|
||||
char fmt[fmtsize];
|
||||
DWORD fmt_pos;
|
||||
char fmt_ch;
|
||||
|
||||
const char * p = format;
|
||||
while( msg_pos < bufsize && '\0' != (fmt_ch = *p++) )
|
||||
{
|
||||
if ( '%' != fmt_ch )
|
||||
{
|
||||
msg[msg_pos++] = fmt_ch;
|
||||
}
|
||||
else if ( '0' == *p || '\0' == *p )
|
||||
{
|
||||
// %0 or null term means end formatting
|
||||
break;
|
||||
}
|
||||
else if ( *p < '1' || '9' < *p )
|
||||
{
|
||||
// Escaped char, print and keep going
|
||||
// Eg. "%n" == '\n'
|
||||
switch ( *p )
|
||||
{
|
||||
case 'a': msg[msg_pos++] = '\a'; break;
|
||||
case 'b': msg[msg_pos++] = '\b'; break;
|
||||
case 'f': msg[msg_pos++] = '\f'; break;
|
||||
case 'n': msg[msg_pos++] = '\n'; break;
|
||||
case 'r': msg[msg_pos++] = '\r'; break;
|
||||
case 't': msg[msg_pos++] = '\t'; break;
|
||||
case 'v': msg[msg_pos++] = '\v'; break;
|
||||
default: msg[msg_pos++] = *p; break;
|
||||
}
|
||||
++p;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Integer must be [1..99]
|
||||
size_t argPos = *p++ - '0';
|
||||
if ( '0' <= *p && *p <= '9' )
|
||||
{
|
||||
argPos *= 10;
|
||||
argPos += *p++ - '0';
|
||||
}
|
||||
assert( 0 < argPos && argPos < 100 );
|
||||
|
||||
fmt_pos = 0;
|
||||
fmt[fmt_pos++] = '%';
|
||||
|
||||
if ( '!' != *p )
|
||||
{
|
||||
// Assume %s as per spec
|
||||
fmt[fmt_pos++] = 's';
|
||||
fmt[fmt_pos] = '\0';
|
||||
int chars_printed = mplat_snprintf_s( &msg[msg_pos], bufsize-msg_pos, bufsize-msg_pos, fmt, args[argPos-1].PtrValue() );
|
||||
if ( chars_printed < 0 )
|
||||
{
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
msg_pos += chars_printed;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Skip over '!' and build format string
|
||||
++p;
|
||||
char ch;
|
||||
int flags = 0;
|
||||
int advance = 0;
|
||||
enum CHARTYPE chclass;
|
||||
enum STATE state = ST_PERCENT;
|
||||
bool found_terminator = false;
|
||||
while ( fmt_pos < fmtsize && !found_terminator && ('\0' != (ch = *p++)) )
|
||||
{
|
||||
chclass = GetCharType( ch );
|
||||
state = GetState( chclass, state );
|
||||
|
||||
switch ( state )
|
||||
{
|
||||
case ST_SIZE:
|
||||
state = ProcessSize( ch, p, &advance, &flags );
|
||||
fmt[fmt_pos++] = ch;
|
||||
while ( fmt_pos < fmtsize && 0 < advance-- )
|
||||
{
|
||||
fmt[fmt_pos++] = *p++;
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_NORMAL:
|
||||
assert( '!' == ch );
|
||||
found_terminator = true;
|
||||
break;
|
||||
|
||||
case ST_INVALID:
|
||||
case ST_PERCENT:
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
|
||||
default:
|
||||
fmt[fmt_pos++] = ch;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( fmtsize <= fmt_pos )
|
||||
{
|
||||
// Should not have a format string longer than 31 chars
|
||||
// It can happen but shouldn't (eg. a bunch of size mods like %llllllllllllllld)
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fmt[fmt_pos] = '\0';
|
||||
|
||||
// Format string might need up to 3 args (eg. %*.*d )
|
||||
// If more than one arg, then the first ones must be 32-bit ints
|
||||
// Hence, first 64-bit arg tells us the last arg we need to send.
|
||||
int chars_printed = 0;
|
||||
if ( vararg_t::Int64 == args[argPos-1].Type() )
|
||||
{
|
||||
chars_printed = mplat_snprintf_s( &msg[msg_pos], bufsize-msg_pos, bufsize-msg_pos, fmt, args[argPos-1].Int64Value() );
|
||||
}
|
||||
else if ( args.size() == argPos )
|
||||
{
|
||||
// No more args so send the one Int
|
||||
chars_printed = mplat_snprintf_s( &msg[msg_pos], bufsize-msg_pos, bufsize-msg_pos, fmt, args[argPos-1].Int32Value() );
|
||||
}
|
||||
else if ( vararg_t::Int64 == args[argPos].Type() )
|
||||
{
|
||||
chars_printed = mplat_snprintf_s( &msg[msg_pos], bufsize-msg_pos, bufsize-msg_pos, fmt, args[argPos-1].Int32Value(), args[argPos].Int64Value() );
|
||||
}
|
||||
else if ( args.size() == (argPos+1) )
|
||||
{
|
||||
// No more args so send the two Ints
|
||||
chars_printed = mplat_snprintf_s( &msg[msg_pos], bufsize-msg_pos, bufsize-msg_pos, fmt, args[argPos-1].Int32Value(), args[argPos-1].Int32Value() );
|
||||
}
|
||||
else if ( vararg_t::Int64 == args[argPos+1].Type() )
|
||||
{
|
||||
chars_printed = mplat_snprintf_s( &msg[msg_pos], bufsize-msg_pos, bufsize-msg_pos, fmt, args[argPos-1].Int32Value(), args[argPos].Int32Value(), args[argPos+1].Int64Value() );
|
||||
}
|
||||
else
|
||||
{
|
||||
chars_printed = mplat_snprintf_s( &msg[msg_pos], bufsize-msg_pos, bufsize-msg_pos, fmt, args[argPos-1].Int32Value(), args[argPos].Int32Value(), args[argPos+1].Int32Value() );
|
||||
}
|
||||
|
||||
if ( chars_printed < 0 )
|
||||
{
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
msg_pos += chars_printed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( bufsize <= msg_pos )
|
||||
{
|
||||
errno = ERANGE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
msg[msg_pos] = '\0';
|
||||
return msg_pos;
|
||||
}
|
||||
|
||||
// On success, returns the number of chars written into the buffer excluding null terminator.
|
||||
// On error, sets errno and returns zero.
|
||||
static DWORD FormatMessageToBufferW( const WCHAR * format, WCHAR * buffer, DWORD bufferWCharSize, const std::vector< vararg_t > & args )
|
||||
{
|
||||
WCHAR * msg = buffer;
|
||||
DWORD bufsize = std::min(bufferWCharSize, (DWORD)64000);
|
||||
DWORD msg_pos = 0;
|
||||
const DWORD fmtsize = 32;
|
||||
WCHAR fmt[fmtsize];
|
||||
DWORD fmt_pos;
|
||||
WCHAR fmt_ch;
|
||||
|
||||
const WCHAR * p = format;
|
||||
while( msg_pos < bufsize && L'\0' != (fmt_ch = *p++) )
|
||||
{
|
||||
if ( L'%' != fmt_ch )
|
||||
{
|
||||
msg[msg_pos++] = fmt_ch;
|
||||
}
|
||||
else if ( L'0' == *p || L'\0' == *p )
|
||||
{
|
||||
// %0 or null term means end formatting
|
||||
break;
|
||||
}
|
||||
else if ( *p < L'1' || L'9' < *p )
|
||||
{
|
||||
// Escaped char, print and keep going
|
||||
// Eg. "%n" == '\n'
|
||||
switch ( *p )
|
||||
{
|
||||
case L'a': msg[msg_pos++] = L'\a'; break;
|
||||
case L'b': msg[msg_pos++] = L'\b'; break;
|
||||
case L'f': msg[msg_pos++] = L'\f'; break;
|
||||
case L'n': msg[msg_pos++] = L'\n'; break;
|
||||
case L'r': msg[msg_pos++] = L'\r'; break;
|
||||
case L't': msg[msg_pos++] = L'\t'; break;
|
||||
case L'v': msg[msg_pos++] = L'\v'; break;
|
||||
default: msg[msg_pos++] = *p; break;
|
||||
}
|
||||
++p;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Integer must be [1..99]
|
||||
size_t argPos = *p++ - L'0';
|
||||
if ( L'0' <= *p && *p <= L'9' )
|
||||
{
|
||||
argPos *= 10;
|
||||
argPos += *p++ - L'0';
|
||||
}
|
||||
assert( 0 < argPos && argPos < 100 );
|
||||
|
||||
fmt_pos = 0;
|
||||
fmt[fmt_pos++] = L'%';
|
||||
|
||||
if ( L'!' != *p )
|
||||
{
|
||||
// Assume %s as per spec
|
||||
fmt[fmt_pos++] = L's';
|
||||
fmt[fmt_pos] = L'\0';
|
||||
int chars_printed = mplat_snwprintf_s( &msg[msg_pos], bufsize-msg_pos, bufsize-msg_pos, fmt, args[argPos-1].PtrValue() );
|
||||
if ( chars_printed < 0 )
|
||||
{
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
msg_pos += chars_printed;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Skip over '!' and build format string
|
||||
++p;
|
||||
WCHAR ch;
|
||||
int flags = 0;
|
||||
int advance = 0;
|
||||
enum CHARTYPE chclass;
|
||||
enum STATE state = ST_PERCENT;
|
||||
bool found_terminator = false;
|
||||
while ( fmt_pos < fmtsize && !found_terminator && (L'\0' != (ch = *p++)) )
|
||||
{
|
||||
chclass = GetCharType( ch );
|
||||
state = GetState( chclass, state );
|
||||
|
||||
switch ( state )
|
||||
{
|
||||
case ST_SIZE:
|
||||
state = ProcessSize( ch, p, &advance, &flags );
|
||||
fmt[fmt_pos++] = ch;
|
||||
while ( fmt_pos < fmtsize && 0 < advance-- )
|
||||
{
|
||||
fmt[fmt_pos++] = *p++;
|
||||
}
|
||||
break;
|
||||
|
||||
case ST_NORMAL:
|
||||
assert( L'!' == ch );
|
||||
found_terminator = true;
|
||||
break;
|
||||
|
||||
case ST_INVALID:
|
||||
case ST_PERCENT:
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
|
||||
default:
|
||||
fmt[fmt_pos++] = ch;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( fmtsize <= fmt_pos )
|
||||
{
|
||||
// Should not have a format string longer than 31 chars
|
||||
// It can happen but shouldn't (eg. a bunch of size mods like %llllllllllllllld)
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
fmt[fmt_pos] = L'\0';
|
||||
|
||||
// Format string might need up to 3 args (eg. %*.*d )
|
||||
// If more than one arg, then the first ones must be 32-bit ints
|
||||
// Hence, first 64-bit arg tells us the last arg we need to send.
|
||||
int chars_printed = 0;
|
||||
if ( vararg_t::Int64 == args[argPos-1].Type() )
|
||||
{
|
||||
chars_printed = mplat_snwprintf_s( &msg[msg_pos], bufsize-msg_pos, bufsize-msg_pos, fmt, args[argPos-1].Int64Value() );
|
||||
}
|
||||
else if ( args.size() == argPos )
|
||||
{
|
||||
// No more args so send the one Int
|
||||
chars_printed = mplat_snwprintf_s( &msg[msg_pos], bufsize-msg_pos, bufsize-msg_pos, fmt, args[argPos-1].Int32Value() );
|
||||
}
|
||||
else if ( vararg_t::Int64 == args[argPos].Type() )
|
||||
{
|
||||
chars_printed = mplat_snwprintf_s( &msg[msg_pos], bufsize-msg_pos, bufsize-msg_pos, fmt, args[argPos-1].Int32Value(), args[argPos].Int64Value() );
|
||||
}
|
||||
else if ( args.size() == (argPos+1) )
|
||||
{
|
||||
// No more args so send the two Ints
|
||||
chars_printed = mplat_snwprintf_s( &msg[msg_pos], bufsize-msg_pos, bufsize-msg_pos, fmt, args[argPos-1].Int32Value(), args[argPos-1].Int32Value() );
|
||||
}
|
||||
else if ( vararg_t::Int64 == args[argPos+1].Type() )
|
||||
{
|
||||
chars_printed = mplat_snwprintf_s( &msg[msg_pos], bufsize-msg_pos, bufsize-msg_pos, fmt, args[argPos-1].Int32Value(), args[argPos].Int32Value(), args[argPos+1].Int64Value() );
|
||||
}
|
||||
else
|
||||
{
|
||||
chars_printed = mplat_snwprintf_s( &msg[msg_pos], bufsize-msg_pos, bufsize-msg_pos, fmt, args[argPos-1].Int32Value(), args[argPos].Int32Value(), args[argPos+1].Int32Value() );
|
||||
}
|
||||
|
||||
if ( chars_printed < 0 )
|
||||
{
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
msg_pos += chars_printed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( bufsize <= msg_pos )
|
||||
{
|
||||
errno = ERANGE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
msg[msg_pos] = L'\0';
|
||||
return msg_pos;
|
||||
}
|
||||
|
||||
|
||||
DWORD FormatMessageA(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPTSTR lpBuffer, DWORD nSize, va_list *Arguments)
|
||||
{
|
||||
DWORD chars_printed = 0;
|
||||
|
||||
// XPLAT_ODBC_TODO VSTS 718708 Localization by handling FORMAT_MESSAGE_FROM_HMODULE and dwLanguageId param
|
||||
if ( dwFlags & FORMAT_MESSAGE_FROM_STRING )
|
||||
{
|
||||
// Format specification allows for reordering of insertions relative to var arg position
|
||||
// This means we need to walk thru the format specification to find the types of the var args in var arg order
|
||||
// We extract the var args in order based on the identified types
|
||||
// Finally, we re-walk the format specfication and perform the insertions
|
||||
|
||||
// First pass thru the format string to determine all args and their types
|
||||
// This first pass also validates the format string and will return an error
|
||||
// if it is invalid. This allows FormatMessageToBuffer to have less error
|
||||
// checking.
|
||||
std::vector< vararg_t > args;
|
||||
// Based on quick scan of RC files, the largest arg count was 7 so reserve 8 slots to reduce allocations
|
||||
args.reserve(8);
|
||||
if ( GetFormatMessageArgsA( reinterpret_cast<const char *>(lpSource), &args, Arguments ) )
|
||||
{
|
||||
if ( dwFlags == (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING) )
|
||||
{
|
||||
*((char**)lpBuffer) = NULL;
|
||||
|
||||
const DWORD max_size = 64000;
|
||||
char local_buf[max_size];
|
||||
chars_printed = FormatMessageToBufferA( reinterpret_cast<const char *>(lpSource), local_buf, max_size, args );
|
||||
if ( 0 < chars_printed )
|
||||
{
|
||||
size_t buf_size = std::min( max_size, std::max(nSize, (chars_printed+1)) );
|
||||
char * return_buf = (char *)LocalAlloc(0, buf_size * sizeof(char));
|
||||
if ( NULL == return_buf )
|
||||
{
|
||||
errno = ENOMEM;
|
||||
}
|
||||
else
|
||||
{
|
||||
mplat_cscpy(return_buf, local_buf);
|
||||
*((char**)lpBuffer) = return_buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( dwFlags == FORMAT_MESSAGE_FROM_STRING )
|
||||
{
|
||||
chars_printed = FormatMessageToBufferA( reinterpret_cast<const char *>(lpSource), lpBuffer, std::min(nSize, (DWORD)64000), args );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( dwFlags & FORMAT_MESSAGE_FROM_SYSTEM )
|
||||
{
|
||||
// Since we don't have the Windows system error messages available use a fixed message
|
||||
// Can not use a message ID for this since this same code is used by driver and tools,
|
||||
// each having their own RLL file. Don't think we should be reserving an ID across all RLLs.
|
||||
const char systemMsg[] = "Error code 0x%X";
|
||||
if ( dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER )
|
||||
{
|
||||
*((char**)lpBuffer) = NULL;
|
||||
|
||||
// Add 9 for up to 8 hex digits plus null term (ignore removal of format specs)
|
||||
const size_t msgsize = (9 + sizeof(systemMsg)/sizeof(systemMsg[0]));
|
||||
char * return_buf = (char *)LocalAlloc(0, msgsize * sizeof(char));
|
||||
if ( NULL == return_buf )
|
||||
{
|
||||
errno = ENOMEM;
|
||||
}
|
||||
else
|
||||
{
|
||||
chars_printed = mplat_snprintf_s( return_buf, msgsize, msgsize, systemMsg, dwMessageId );
|
||||
// Assert that we did our buffer size math right
|
||||
assert( chars_printed < msgsize );
|
||||
if ( 0 < chars_printed )
|
||||
{
|
||||
*((char**)lpBuffer) = return_buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
LocalFree( return_buf );
|
||||
errno = EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
chars_printed = mplat_snprintf_s( lpBuffer, nSize, nSize, systemMsg, dwMessageId );
|
||||
}
|
||||
}
|
||||
|
||||
return chars_printed;
|
||||
}
|
||||
|
||||
|
||||
// FormatMessage implementation details (see MSDN for more info)
|
||||
//
|
||||
// The Windows FormatMessage API is very rich, complex. This is not an exact duplication of that function.
|
||||
// Instead, the most important aspects of this function have been implemented here along with constraints to
|
||||
// match how we use it within SNAC, BCP, and SQLCMD.
|
||||
//
|
||||
// Only these combinations of dwFlags are supported:
|
||||
// FORMAT_MESSAGE_FROM_STRING
|
||||
// Writes formatted message into supplied buffer
|
||||
// FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING
|
||||
// Allocates a buffer, writes formatted message into that buffer, returns buffer in lpBufffer
|
||||
// FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS
|
||||
// Writes fixed, English message into the supplied buffer (do not have Windows resources to get real message)
|
||||
// FORMAT_MESSAGE_FROM_HMODULE
|
||||
// SQLCMD uses this to read strings from the RLL that have not been translated to the current lang
|
||||
//
|
||||
// dwLanguageId is ignored for FORMAT_MESSAGE_FROM_STRING as per spec
|
||||
// For FORMAT_MESSAGE_FROM_SYSTEM, we don't have Windows resources so language is irrelevant
|
||||
DWORD FormatMessageW(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, va_list *Arguments)
|
||||
{
|
||||
DWORD chars_printed = 0;
|
||||
|
||||
// XPLAT_ODBC_TODO VSTS 718708 Localization by handling FORMAT_MESSAGE_FROM_HMODULE and dwLanguageId param
|
||||
if ( dwFlags & FORMAT_MESSAGE_FROM_STRING )
|
||||
{
|
||||
// Format specification allows for reordering of insertions relative to var arg position
|
||||
// This means we need to walk thru the format specification to find the types of the var args in var arg order
|
||||
// We extract the var args in order based on the identified types
|
||||
// Finally, we re-walk the format specfication and perform the insertions
|
||||
|
||||
// First pass thru the format string to determine all args and their types
|
||||
// This first pass also validates the format string and will return an error
|
||||
// if it is invalid. This allows FormatMessageToBuffer to have less error
|
||||
// checking.
|
||||
std::vector< vararg_t > args;
|
||||
// Based on quick scan of RC files, the largest arg count was 7 so reserve 8 slots to reduce allocations
|
||||
args.reserve(8);
|
||||
if ( GetFormatMessageArgsW( reinterpret_cast<const WCHAR *>(lpSource), &args, Arguments ) )
|
||||
{
|
||||
if ( dwFlags == (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING) )
|
||||
{
|
||||
*((WCHAR**)lpBuffer) = NULL;
|
||||
|
||||
const DWORD max_size = 64000;
|
||||
WCHAR local_buf[max_size];
|
||||
chars_printed = FormatMessageToBufferW( reinterpret_cast<const WCHAR *>(lpSource), local_buf, max_size, args );
|
||||
if ( 0 < chars_printed )
|
||||
{
|
||||
size_t buf_size = std::min( max_size, std::max(nSize, (chars_printed+1)) );
|
||||
WCHAR * return_buf = (WCHAR *)LocalAlloc(0, buf_size * sizeof(WCHAR));
|
||||
if ( NULL == return_buf )
|
||||
{
|
||||
errno = ENOMEM;
|
||||
}
|
||||
else
|
||||
{
|
||||
mplat_wcscpy(return_buf, local_buf);
|
||||
*((WCHAR**)lpBuffer) = return_buf;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( dwFlags == FORMAT_MESSAGE_FROM_STRING )
|
||||
{
|
||||
chars_printed = FormatMessageToBufferW( reinterpret_cast<const WCHAR *>(lpSource), lpBuffer, std::min(nSize, (DWORD)64000), args );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( dwFlags & FORMAT_MESSAGE_FROM_SYSTEM )
|
||||
{
|
||||
// Since we don't have the Windows system error messages available use a fixed message
|
||||
// Can not use a message ID for this since this same code is used by driver and tools,
|
||||
// each having their own RLL file. Don't think we should be reserving an ID across all RLLs.
|
||||
const wchar_t systemMsg[] = L"Error code 0x%X";
|
||||
if ( dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER )
|
||||
{
|
||||
*((WCHAR**)lpBuffer) = NULL;
|
||||
|
||||
// Add 9 for up to 8 hex digits plus null term (ignore removal of format specs)
|
||||
const size_t msgsize = (9 + sizeof(systemMsg)/sizeof(systemMsg[0]));
|
||||
WCHAR * return_buf = (WCHAR *)LocalAlloc(0, msgsize * sizeof(WCHAR));
|
||||
if ( NULL == return_buf )
|
||||
{
|
||||
errno = ENOMEM;
|
||||
}
|
||||
else
|
||||
{
|
||||
chars_printed = mplat_snwprintf_s( return_buf, msgsize, msgsize, (WCHAR *)systemMsg, dwMessageId );
|
||||
// Assert that we did our buffer size math right
|
||||
assert( chars_printed < msgsize );
|
||||
if ( 0 < chars_printed )
|
||||
{
|
||||
*((WCHAR**)lpBuffer) = return_buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
LocalFree( return_buf );
|
||||
errno = EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
chars_printed = mplat_snwprintf_s( lpBuffer, nSize, nSize, (WCHAR *)systemMsg, dwMessageId );
|
||||
}
|
||||
}
|
||||
|
||||
return chars_printed;
|
||||
}
|
||||
|
||||
//--------Other definitions from xplat stub sources--------------
|
||||
|
||||
BOOL IsDBCSLeadByte(__inn BYTE TestChar)
|
||||
{
|
||||
// XPLAT_ODBC_TODO: This is to allow BatchParser to function
|
||||
// BatchParser will single step thru utf8 code points
|
||||
// BatchParser needs to become utf8-aware
|
||||
// VSTS 718708 Localization
|
||||
if ( CP_UTF8 == SystemLocale::Singleton().AnsiCP() )
|
||||
return FALSE;
|
||||
// XPLAT_ODBC_TODO
|
||||
|
||||
return IsDBCSLeadByteEx(SystemLocale::Singleton().AnsiCP(), TestChar);
|
||||
}
|
||||
|
||||
BOOL IsDBCSLeadByteEx(
|
||||
__inn UINT CodePage,
|
||||
__inn BYTE TestChar)
|
||||
{
|
||||
if ( 1 == SystemLocale::MaxCharCchSize(CodePage) )
|
||||
return FALSE;
|
||||
|
||||
// Lead byte ranges for code pages, inclusive:
|
||||
// CP932
|
||||
// 0x81-0x9f, 0xe0-0xfc
|
||||
// CP936, CP949, CP950
|
||||
// 0x81-0xfe
|
||||
assert( 932 == CodePage || 936 == CodePage || 949 == CodePage || 950 == CodePage );
|
||||
if ( 932 == CodePage )
|
||||
{
|
||||
if ( TestChar < (unsigned char)0x81
|
||||
|| (unsigned char)0xfc < TestChar
|
||||
|| ((unsigned char)0x9f < TestChar && TestChar < (unsigned char)0xe0) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if ( TestChar < (unsigned char)0x81 || TestChar == (unsigned char)0xff )
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int mplat_vsnwprintf( WCHAR * buffer, size_t count, const WCHAR * format, va_list args )
|
||||
{
|
||||
BufferOutput<WCHAR> output( buffer, count );
|
||||
return FormattedPrintW( &output, format, args );
|
||||
}
|
||||
|
||||
int mplat_snwprintf_s( WCHAR *buffer, size_t bufsize, size_t count, const WCHAR *format, ... )
|
||||
{
|
||||
va_list args;
|
||||
va_start( args, format );
|
||||
int retcode = mplat_vsnwprintf( buffer, std::min(bufsize, count), format, args );
|
||||
va_end( args );
|
||||
return retcode;
|
||||
}
|
||||
|
||||
int mplat_vsnprintf( char * buffer, size_t count, const char * format, va_list args )
|
||||
{
|
||||
BufferOutput<char> output( buffer, count );
|
||||
return FormattedPrintA( &output, format, args );
|
||||
}
|
||||
|
||||
int mplat_snprintf_s( char *buffer, size_t bufsize, size_t count, const char *format, ... )
|
||||
{
|
||||
va_list args;
|
||||
va_start( args, format );
|
||||
int retcode = mplat_vsnprintf( buffer, std::min(bufsize, count), format, args );
|
||||
va_end( args );
|
||||
return retcode;
|
||||
}
|
||||
|
||||
// Tools\vc\src\crt\amd64\wcscat.c
|
||||
WCHAR * mplat_wcscpy( WCHAR * dst, const WCHAR * src )
|
||||
{
|
||||
WCHAR * cp = dst;
|
||||
|
||||
while( (*cp++ = *src++) )
|
||||
; /* Copy src over dst */
|
||||
|
||||
return( dst );
|
||||
}
|
||||
|
||||
char * mplat_cscpy( char * dst, const char * src )
|
||||
{
|
||||
char * cp = dst;
|
||||
|
||||
while( (*cp++ = *src++) )
|
||||
; /* Copy src over dst */
|
||||
|
||||
return( dst );
|
||||
}
|
||||
|
||||
size_t mplat_wcslen( const WCHAR * str )
|
||||
{
|
||||
const WCHAR * eos = str;
|
||||
while( *eos++ )
|
||||
{
|
||||
}
|
||||
return( (size_t)(eos - str- 1) );
|
||||
}
|
||||
|
||||
HLOCAL LocalAlloc(UINT uFlags, SIZE_T uBytes)
|
||||
{
|
||||
assert(uFlags == 0); // For now
|
||||
return malloc(uBytes);
|
||||
}
|
||||
|
||||
HLOCAL LocalFree(HLOCAL hMem)
|
||||
{
|
||||
assert(hMem != NULL);
|
||||
|
||||
free(hMem);
|
||||
return NULL;
|
||||
}
|
231
source/shared/FormattedPrint.h
Normal file
231
source/shared/FormattedPrint.h
Normal file
|
@ -0,0 +1,231 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// File: FormattedPrint.h
|
||||
//
|
||||
// Contents: Contains functions for handling Windows format strings
|
||||
// and UTF-16 on non-Windows platforms
|
||||
//
|
||||
// Microsoft Drivers 4.0 for PHP for SQL Server
|
||||
// Copyright(c) Microsoft Corporation
|
||||
// All rights reserved.
|
||||
// MIT License
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""),
|
||||
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef _FORMATTEDPRINT_H_
|
||||
#define _FORMATTEDPRINT_H_
|
||||
|
||||
#include "winnls.h"
|
||||
#include "localization.hpp"
|
||||
|
||||
inline bool __ascii_iswalpha(WCHAR c) { return( ('A' <= (c) && (c) <= 'Z') || ( 'a' <= (c) && (c) <= 'z') ); }
|
||||
inline WCHAR __ascii_towupper(WCHAR c) { return( (((c) >= L'a') && ((c) <= L'z')) ? (WCHAR)((c) - L'a' + L'A') : (c) ); }
|
||||
inline char __ascii_toupper(char c) { return( (((c) >= 'a') && ((c) <= 'z')) ? ((c) - 'a' + 'A') : (c) ); }
|
||||
|
||||
|
||||
|
||||
|
||||
template< typename T >
|
||||
struct IFormattedPrintOutput
|
||||
{
|
||||
/*
|
||||
Method names are all CAPS to match the original code for formatted print from the Windows CRT.
|
||||
|
||||
pCumulativeOutputCount
|
||||
Used to track running total of output storage units.
|
||||
Note that the count is the memory size in sizeof(TCHAR) and not the display char count.
|
||||
For example, a UTF-8 char+diacritical mark is two chars in memory but only one for display
|
||||
so pCumulativeOutputCount will be incremented by 2 after output.
|
||||
If an error is encountered, then set this to -1.
|
||||
If the value is -1 upon entry of any callback, simply return and don't output anything.
|
||||
*/
|
||||
|
||||
// Writes a single character to the output.
|
||||
virtual void WRITE_CHAR( T ch , int * pCumulativeOutputCount ) = 0;
|
||||
|
||||
// Repeatedly writes a single character to the output. If there isn't enough room, writes to end of buffer.
|
||||
// If repeatCount is <=0, then don't output anything and leave pCumulativeOutputCount as is.
|
||||
virtual void WRITE_MULTI_CHAR( T ch, int repeatCount, int * pCumulativeOutputCount ) = 0;
|
||||
|
||||
// Writes the supplied string to the output. If there isn't enough room, writes to end of buffer.
|
||||
// If count is <=0, then don't output anything and leave pCumulativeOutputCount as is.
|
||||
virtual void WRITE_STRING( const T * pch, int count, int * pCumulativeOutputCount ) = 0;
|
||||
|
||||
// Ensure dtors are virtual
|
||||
virtual ~IFormattedPrintOutput() { }
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
class FormattedOutput : public IFormattedPrintOutput<T>
|
||||
{
|
||||
protected:
|
||||
bool ShouldOutput( const int * pCumulativeOutputCount, int count ) const
|
||||
{
|
||||
assert( NULL != pCumulativeOutputCount );
|
||||
return ( (0 <= *pCumulativeOutputCount) && (0 < count) );
|
||||
}
|
||||
};
|
||||
|
||||
int FormattedPrintA( IFormattedPrintOutput<char> * output, const char *format, va_list argptr );
|
||||
int FormattedPrintW( IFormattedPrintOutput<WCHAR> * output, const WCHAR *format, va_list argptr );
|
||||
|
||||
template< typename T >
|
||||
class BufferOutput : public FormattedOutput<T>
|
||||
{
|
||||
T * m_buffer;
|
||||
size_t m_countRemainingInBuffer;
|
||||
|
||||
bool CanOutput() const
|
||||
{
|
||||
return ( 0 < m_countRemainingInBuffer );
|
||||
}
|
||||
|
||||
// Stop these from being available
|
||||
BufferOutput();
|
||||
BufferOutput( const BufferOutput & );
|
||||
BufferOutput & operator=( const BufferOutput & );
|
||||
|
||||
public:
|
||||
BufferOutput( T * pcb, size_t bufsize )
|
||||
: m_buffer( pcb ),
|
||||
m_countRemainingInBuffer( bufsize )
|
||||
{
|
||||
assert( NULL != m_buffer );
|
||||
if ( m_countRemainingInBuffer < INT_MAX )
|
||||
{
|
||||
memset( m_buffer, 0, m_countRemainingInBuffer * sizeof(T) );
|
||||
}
|
||||
}
|
||||
|
||||
virtual void WRITE_CHAR(T ch, int * pCumulativeOutputCount)
|
||||
{
|
||||
if ( FormattedOutput<T>::ShouldOutput( pCumulativeOutputCount, 1 ) )
|
||||
{
|
||||
if ( CanOutput() )
|
||||
{
|
||||
++(*pCumulativeOutputCount);
|
||||
--m_countRemainingInBuffer;
|
||||
*m_buffer++ = ch;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pCumulativeOutputCount = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void WRITE_MULTI_CHAR(T ch, int repeatCount, int * pCumulativeOutputCount)
|
||||
{
|
||||
if ( FormattedOutput<T>::ShouldOutput( pCumulativeOutputCount, repeatCount ) )
|
||||
{
|
||||
if ( CanOutput() )
|
||||
{
|
||||
while ( 0 != m_countRemainingInBuffer && 0 != repeatCount )
|
||||
{
|
||||
*m_buffer++ = ch;
|
||||
--m_countRemainingInBuffer;
|
||||
--repeatCount;
|
||||
++(*pCumulativeOutputCount);
|
||||
}
|
||||
if ( 0 != repeatCount )
|
||||
{
|
||||
// Not enough room in buffer
|
||||
*pCumulativeOutputCount = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*pCumulativeOutputCount = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void WRITE_STRING(const T * pch, int count, int * pCumulativeOutputCount)
|
||||
{
|
||||
assert( NULL != pch );
|
||||
if ( FormattedOutput<T>::ShouldOutput( pCumulativeOutputCount, count ) )
|
||||
{
|
||||
if ( CanOutput() )
|
||||
{
|
||||
while ( 0 != m_countRemainingInBuffer && 0 != count )
|
||||
{
|
||||
*m_buffer++ = *pch++;
|
||||
--m_countRemainingInBuffer;
|
||||
--count;
|
||||
++(*pCumulativeOutputCount);
|
||||
}
|
||||
if ( 0 != count )
|
||||
{
|
||||
// Not enough room in buffer
|
||||
*pCumulativeOutputCount = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*pCumulativeOutputCount = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template< typename T >
|
||||
class FileOutput : public FormattedOutput<T>
|
||||
{
|
||||
FILE * m_file;
|
||||
|
||||
// Stop these from being available
|
||||
FileOutput();
|
||||
FileOutput( const FileOutput & );
|
||||
FileOutput & operator=( const FileOutput & );
|
||||
|
||||
public:
|
||||
FileOutput( FILE * file )
|
||||
: m_file( file )
|
||||
{
|
||||
assert( NULL != m_file );
|
||||
}
|
||||
|
||||
virtual void WRITE_CHAR(T ch, int * pCumulativeOutputCount)
|
||||
{
|
||||
if ( FormattedOutput<T>::ShouldOutput( pCumulativeOutputCount, 1 ) )
|
||||
{
|
||||
++(*pCumulativeOutputCount);
|
||||
if ( fputc( ch, m_file ) != ch )
|
||||
*pCumulativeOutputCount = -1;
|
||||
}
|
||||
}
|
||||
virtual void WRITE_MULTI_CHAR(T ch, int repeatCount, int * pCumulativeOutputCount)
|
||||
{
|
||||
if ( FormattedOutput<T>::ShouldOutput( pCumulativeOutputCount, repeatCount ) )
|
||||
{
|
||||
*pCumulativeOutputCount += repeatCount;
|
||||
while ( 0 < repeatCount-- )
|
||||
{
|
||||
if ( fputc( ch, m_file ) != ch )
|
||||
{
|
||||
*pCumulativeOutputCount = -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void WRITE_STRING(const T * pch, int count, int * pCumulativeOutputCount)
|
||||
{
|
||||
if ( FormattedOutput<T>::ShouldOutput( pCumulativeOutputCount, count ) )
|
||||
{
|
||||
assert( NULL != pch );
|
||||
*pCumulativeOutputCount += count;
|
||||
if ( (size_t)count != fwrite( pch, sizeof(T), count, m_file ) )
|
||||
*pCumulativeOutputCount = -1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // _FORMATTEDPRINT_H_
|
145
source/shared/StringFunctions.cpp
Normal file
145
source/shared/StringFunctions.cpp
Normal file
|
@ -0,0 +1,145 @@
|
|||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
// File: StringFunctions.cpp
|
||||
//
|
||||
// Contents: Contains functions for handling UTF-16 on non-Windows platforms
|
||||
//
|
||||
// Microsoft Drivers 4.0 for PHP for SQL Server
|
||||
// Copyright(c) Microsoft Corporation
|
||||
// All rights reserved.
|
||||
// MIT License
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""),
|
||||
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#include "StringFunctions.h"
|
||||
|
||||
// Tools\vc\src\crt\amd64\memcpy_s.c
|
||||
int mplat_memcpy_s( void * dest, size_t destSize, const void * src, size_t count )
|
||||
{
|
||||
if ( 0 == count )
|
||||
{
|
||||
// nothing to do
|
||||
return 0;
|
||||
}
|
||||
|
||||
// validation section
|
||||
if ( NULL == dest )
|
||||
{
|
||||
errno = EINVAL;
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if ( src == NULL || destSize < count )
|
||||
{
|
||||
// zeroes the destination buffer
|
||||
memset(dest, 0, destSize*sizeof(char));
|
||||
|
||||
if ( NULL == src )
|
||||
{
|
||||
errno = EINVAL;
|
||||
return EINVAL;
|
||||
}
|
||||
if ( destSize < count )
|
||||
{
|
||||
errno = ERANGE;
|
||||
return ERANGE;
|
||||
}
|
||||
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
memcpy(dest, src, count*sizeof(char));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Tools\vc\src\crt\amd64\strcpy_s.c
|
||||
int mplat_strcpy_s( char * dest, size_t destSize, const char * src )
|
||||
{
|
||||
char * p;
|
||||
size_t available;
|
||||
|
||||
// validation section
|
||||
if ( NULL == dest || 0 == destSize )
|
||||
{
|
||||
errno = EINVAL;
|
||||
return EINVAL;
|
||||
}
|
||||
if ( NULL == src )
|
||||
{
|
||||
*dest = 0;
|
||||
errno = EINVAL;
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
p = dest;
|
||||
available = destSize;
|
||||
while ( (*p++ = *src++) != 0 && --available > 0 )
|
||||
{
|
||||
}
|
||||
|
||||
if ( 0 == available )
|
||||
{
|
||||
*dest = 0;
|
||||
errno = ERANGE;
|
||||
return ERANGE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Tools\vc\src\crt\amd64\strcat_s.c
|
||||
int mplat_strcat_s( char * dest, size_t destSize, const char * src )
|
||||
{
|
||||
char *p;
|
||||
size_t available;
|
||||
|
||||
// validation section
|
||||
if ( NULL == dest || 0 == destSize )
|
||||
{
|
||||
errno = EINVAL;
|
||||
return EINVAL;
|
||||
}
|
||||
if ( NULL == src )
|
||||
{
|
||||
*dest = 0;
|
||||
errno = EINVAL;
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
p = dest;
|
||||
available = destSize;
|
||||
while (available > 0 && *p != 0)
|
||||
{
|
||||
p++;
|
||||
available--;
|
||||
}
|
||||
|
||||
if (available == 0)
|
||||
{
|
||||
*dest = 0;
|
||||
errno = EINVAL;
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
while ((*p++ = *src++) != 0 && --available > 0)
|
||||
{
|
||||
}
|
||||
|
||||
if (available == 0)
|
||||
{
|
||||
*dest = 0;
|
||||
errno = ERANGE;
|
||||
return ERANGE;
|
||||
}
|
||||
*p = 0;
|
||||
return 0;
|
||||
}
|
||||
//
|
||||
// End copy functions
|
||||
//----------------------------------------------------------------------------
|
||||
|
39
source/shared/StringFunctions.h
Normal file
39
source/shared/StringFunctions.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
// File: StringFunctions.h
|
||||
//
|
||||
// Contents: Contains functions for handling UTF-16 on non-Windows platforms
|
||||
//
|
||||
// Microsoft Drivers 4.0 for PHP for SQL Server
|
||||
// Copyright(c) Microsoft Corporation
|
||||
// All rights reserved.
|
||||
// MIT License
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""),
|
||||
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#if !defined(_STRINGFUNCTIONS_H_)
|
||||
#define _STRINGFUNCTIONS_H_
|
||||
|
||||
#include "winnls.h"
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Declare internal versions of string handling functions
|
||||
// Only the functions implemented are declared here
|
||||
|
||||
// Copy
|
||||
int mplat_memcpy_s(void *_S1, size_t _N1, const void *_S2, size_t _N);
|
||||
int mplat_strcat_s( char *strDestination, size_t numberOfElements, const char *strSource );
|
||||
int mplat_strcpy_s(char * _Dst, size_t _SizeInBytes, const char * _Src);
|
||||
|
||||
// Copy
|
||||
#define memcpy_s mplat_memcpy_s
|
||||
#define strcat_s mplat_strcat_s
|
||||
#define strcpy_s mplat_strcpy_s
|
||||
|
||||
#endif // _STRINGFUNCTIONS_H_
|
517
source/shared/globalization.h
Normal file
517
source/shared/globalization.h
Normal file
|
@ -0,0 +1,517 @@
|
|||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
// File: Globalization.h
|
||||
//
|
||||
// Contents: Contains functions for handling Windows format strings
|
||||
// and UTF-16 on non-Windows platforms
|
||||
//
|
||||
// Microsoft Drivers 4.0 for PHP for SQL Server
|
||||
// Copyright(c) Microsoft Corporation
|
||||
// All rights reserved.
|
||||
// MIT License
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""),
|
||||
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#if !defined(_GLOBALIZATION_H_)
|
||||
#define _GLOBALIZATION_H_
|
||||
|
||||
#include "xplat.h"
|
||||
#include "typedefs_for_linux.h"
|
||||
#include <errno.h>
|
||||
|
||||
#if defined(MPLAT_UNIX)
|
||||
#include <iconv.h>
|
||||
|
||||
const iconv_t INVALID_ICONV = (iconv_t)(-1);
|
||||
|
||||
class IConvCache : public SLIST_ENTRY
|
||||
{
|
||||
iconv_t m_iconv;
|
||||
|
||||
// Prevent copying
|
||||
IConvCache( const IConvCache & );
|
||||
IConvCache & operator=( const IConvCache & );
|
||||
|
||||
public:
|
||||
IConvCache( int dstIdx, int srcIdx );
|
||||
~IConvCache();
|
||||
|
||||
iconv_t GetIConv() const
|
||||
{
|
||||
return m_iconv;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
class EncodingConverter
|
||||
{
|
||||
UINT m_dstCodePage;
|
||||
UINT m_srcCodePage;
|
||||
#if defined(MPLAT_UNIX)
|
||||
const IConvCache * m_pCvtCache;
|
||||
|
||||
bool IsValidIConv() const
|
||||
{
|
||||
return (NULL != m_pCvtCache && INVALID_ICONV != m_pCvtCache->GetIConv());
|
||||
}
|
||||
|
||||
template< typename T >
|
||||
struct iconv_buffer
|
||||
{
|
||||
char * m_pBytes;
|
||||
size_t m_nBytesLeft;
|
||||
|
||||
iconv_buffer( char * buffer, size_t cchSize )
|
||||
: m_pBytes(buffer), m_nBytesLeft(sizeof(T)*cchSize) {}
|
||||
~iconv_buffer() {}
|
||||
|
||||
void Reset( char * buffer, size_t cchSize )
|
||||
{
|
||||
m_pBytes = buffer;
|
||||
m_nBytesLeft = cchSize*sizeof(T);
|
||||
}
|
||||
|
||||
void SkipSingleCh()
|
||||
{
|
||||
assert( sizeof(T) <= m_nBytesLeft );
|
||||
m_nBytesLeft -= sizeof(T);
|
||||
m_pBytes += sizeof(T);
|
||||
}
|
||||
void SkipDoubleCh()
|
||||
{
|
||||
SkipSingleCh();
|
||||
// Only skip second half if there's bytes left and it is non-NULL
|
||||
if ( m_nBytesLeft && 0 != *(UNALIGNED T *)m_pBytes )
|
||||
SkipSingleCh();
|
||||
}
|
||||
void SkipUtf8Ch()
|
||||
{
|
||||
assert( 1 == sizeof(T) );
|
||||
const char * pNext = SystemLocale::NextChar( CP_UTF8, m_pBytes, m_nBytesLeft );
|
||||
assert( m_pBytes < pNext && (size_t)(pNext-m_pBytes) <= SystemLocale::MaxCharCchSize(CP_UTF8) );
|
||||
|
||||
UINT toTrim = (UINT)(pNext - m_pBytes);
|
||||
assert( toTrim <= m_nBytesLeft );
|
||||
assert( 0 < toTrim );
|
||||
|
||||
m_nBytesLeft -= toTrim;
|
||||
m_pBytes += toTrim;
|
||||
}
|
||||
|
||||
static char DefaultChar( UINT srcDataCP )
|
||||
{
|
||||
return 0x3f;
|
||||
}
|
||||
static WCHAR DefaultWChar( UINT srcDataCP )
|
||||
{
|
||||
return (CP_UTF8 == srcDataCP ? 0xfffd // Unicode to Unicode, use Unicode default char
|
||||
: (932 == srcDataCP ? 0x30fb // 932 to Unicode has special default char
|
||||
: 0x003f)); // WCP source, use '?'
|
||||
}
|
||||
void AssignDefault( UINT srcDataCP )
|
||||
{
|
||||
assert( sizeof(T) <= m_nBytesLeft );
|
||||
if ( 1 == sizeof(T) )
|
||||
{
|
||||
*m_pBytes = DefaultChar( srcDataCP );
|
||||
--m_nBytesLeft;
|
||||
++m_pBytes;
|
||||
}
|
||||
else
|
||||
{
|
||||
*(UNALIGNED T *)m_pBytes = DefaultWChar( srcDataCP );
|
||||
m_nBytesLeft -= sizeof(T);
|
||||
m_pBytes += sizeof(T);
|
||||
}
|
||||
}
|
||||
bool AssignDefaultUtf8( UINT srcDataCP )
|
||||
{
|
||||
// This is a utf8 buffer so T must be char
|
||||
assert( 1 == sizeof(T) );
|
||||
if ( CP_UTF16 == srcDataCP )
|
||||
{
|
||||
// If source codepage is UTF16 then use Unicode default char
|
||||
// UTF8 default char is 3 bytes long
|
||||
if ( m_nBytesLeft < 3 )
|
||||
return false;
|
||||
|
||||
*m_pBytes++ = (T)0xef;
|
||||
*m_pBytes++ = (T)0xbf;
|
||||
*m_pBytes++ = (T)0xbd;
|
||||
m_nBytesLeft -= 3;
|
||||
}
|
||||
else if ( 932 == srcDataCP )
|
||||
{
|
||||
// If source codepage is 932 then use special default char
|
||||
// UTF8 default char for 932 is 3 bytes long
|
||||
if ( m_nBytesLeft < 3 )
|
||||
return false;
|
||||
|
||||
*m_pBytes++ = (T)0xe3;
|
||||
*m_pBytes++ = (T)0x83;
|
||||
*m_pBytes++ = (T)0xbb;
|
||||
m_nBytesLeft -= 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
*m_pBytes = DefaultChar( srcDataCP );
|
||||
++m_pBytes;
|
||||
--m_nBytesLeft;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Prevent compiler from generating these
|
||||
iconv_buffer();
|
||||
iconv_buffer( const iconv_buffer & other );
|
||||
iconv_buffer & operator=( const iconv_buffer & other );
|
||||
};
|
||||
|
||||
template< class DestType >
|
||||
bool AddDefault( iconv_buffer<DestType> * dest, bool * pHasLoss, DWORD * pErrorCode ) const
|
||||
{
|
||||
if ( NULL != pHasLoss )
|
||||
*pHasLoss = true;
|
||||
|
||||
if ( CP_UTF8 != m_dstCodePage )
|
||||
dest->AssignDefault( m_srcCodePage );
|
||||
else if ( !dest->AssignDefaultUtf8(m_srcCodePage) )
|
||||
{
|
||||
// Not enough room for the default char
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_INSUFFICIENT_BUFFER;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template< class DestType, class SrcType >
|
||||
size_t Convert(
|
||||
iconv_buffer<DestType> & dest,
|
||||
iconv_buffer<SrcType> & src,
|
||||
bool failIfLossy = false, bool * pHasLoss = NULL, DWORD * pErrorCode = NULL ) const
|
||||
{
|
||||
if ( !IsValidIConv() )
|
||||
return 0;
|
||||
|
||||
size_t iconv_ret;
|
||||
size_t cchDest = dest.m_nBytesLeft/sizeof(DestType);
|
||||
|
||||
if ( NULL != pHasLoss )
|
||||
*pHasLoss = false;
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_SUCCESS;
|
||||
|
||||
while ( 0 < dest.m_nBytesLeft && 0 < src.m_nBytesLeft )
|
||||
{
|
||||
// First clear any intermediate state left over from previous conversions
|
||||
iconv_ret = iconv( m_pCvtCache->GetIConv(), NULL, NULL, NULL, NULL );
|
||||
assert( 0 == iconv_ret );
|
||||
|
||||
// Now attempt conversion
|
||||
iconv_ret = iconv( m_pCvtCache->GetIConv(), &src.m_pBytes, &src.m_nBytesLeft, &dest.m_pBytes, &dest.m_nBytesLeft );
|
||||
if ( iconv_ret == (size_t)(-1) )
|
||||
{
|
||||
// If there's no dest bytes left, then treat as E2BIG even if the error
|
||||
// is EILSEQ, etc. We want E2BIG to take precedence like Windows.
|
||||
int err = (0 < dest.m_nBytesLeft ? errno : E2BIG);
|
||||
if ( E2BIG != err && failIfLossy )
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_NO_UNICODE_TRANSLATION;
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch ( err )
|
||||
{
|
||||
case EILSEQ: // Invalid multibyte sequence in input
|
||||
if ( CP_UTF8 == m_srcCodePage )
|
||||
src.SkipUtf8Ch();
|
||||
else if ( 1 == sizeof(SrcType) )
|
||||
src.SkipDoubleCh(); // DBCS
|
||||
else
|
||||
src.SkipSingleCh(); // utf32 or incomplate utf16 surrogate
|
||||
|
||||
if ( !AddDefault(&dest, pHasLoss, pErrorCode) )
|
||||
return 0;
|
||||
|
||||
break;
|
||||
case EINVAL: // Incomplete multibyte sequence in input
|
||||
if ( CP_UTF8 == m_srcCodePage )
|
||||
src.SkipUtf8Ch();
|
||||
else
|
||||
src.SkipSingleCh();
|
||||
|
||||
if ( !AddDefault(&dest, pHasLoss, pErrorCode) )
|
||||
return 0;
|
||||
|
||||
break;
|
||||
case E2BIG: // Output buffer is out of room
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_INSUFFICIENT_BUFFER;
|
||||
return 0;
|
||||
default:
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_INVALID_PARAMETER;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cchDest - (dest.m_nBytesLeft / sizeof(DestType));
|
||||
}
|
||||
|
||||
#elif defined(MPLAT_WWOWH)
|
||||
|
||||
size_t ReturnCchResult( int cch, DWORD * pErrorCode ) const
|
||||
{
|
||||
if ( cch < 0 )
|
||||
cch = 0;
|
||||
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = (0 == cch ? GetLastError() : ERROR_SUCCESS);
|
||||
|
||||
return cch;
|
||||
}
|
||||
|
||||
#endif // defined(MPLAT_WWOWH)
|
||||
|
||||
|
||||
public:
|
||||
EncodingConverter( UINT dstCodePage, UINT srcCodePage );
|
||||
~EncodingConverter();
|
||||
|
||||
bool Initialize();
|
||||
|
||||
// Performs an encoding conversion.
|
||||
// Returns the number of dest chars written.
|
||||
// Input and output buffers should not overlap.
|
||||
template< class DestType, class SrcType, class AllocT >
|
||||
size_t Convert(
|
||||
DestType ** destBuffer,
|
||||
const SrcType * srcBuffer, size_t cchSource,
|
||||
bool failIfLossy = false, bool * pHasLoss = NULL, DWORD * pErrorCode = NULL ) const
|
||||
{
|
||||
#if defined(MPLAT_UNIX)
|
||||
|
||||
if ( !IsValidIConv() )
|
||||
return 0;
|
||||
|
||||
iconv_buffer<SrcType> src(
|
||||
reinterpret_cast< char * >( const_cast< SrcType * >(srcBuffer) ),
|
||||
cchSource );
|
||||
|
||||
size_t cchDest = cchSource;
|
||||
AutoArray< DestType, AllocT > newDestBuffer( cchDest );
|
||||
|
||||
iconv_buffer<DestType> dest(
|
||||
reinterpret_cast< char * >(newDestBuffer.m_ptr),
|
||||
cchDest );
|
||||
|
||||
size_t cchPrevCvt = 0;
|
||||
DWORD rcCvt;
|
||||
while ( true )
|
||||
{
|
||||
size_t cchCvt = Convert( dest, src, failIfLossy, pHasLoss, &rcCvt );
|
||||
if ( 0 == cchCvt )
|
||||
{
|
||||
if ( ERROR_INSUFFICIENT_BUFFER == rcCvt )
|
||||
{
|
||||
// Alloc more and continue
|
||||
cchPrevCvt = cchDest;
|
||||
cchDest *= 2;
|
||||
if ( !newDestBuffer.Realloc(cchDest) )
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_NOT_ENOUGH_MEMORY;
|
||||
return 0;
|
||||
}
|
||||
// Fill newly allocated part of buffer
|
||||
dest.Reset( reinterpret_cast< char * >(newDestBuffer.m_ptr+cchPrevCvt), cchDest );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = rcCvt;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = rcCvt;
|
||||
*destBuffer = newDestBuffer.Detach();
|
||||
return cchPrevCvt + cchCvt;
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(MPLAT_WWOWH)
|
||||
// WWOWH unit testing code
|
||||
// Can only convert between ansi and utf16
|
||||
if ( 1 == sizeof(DestType) && 2 == sizeof(SrcType) )
|
||||
{
|
||||
// utf16 to ansi
|
||||
const wchar_t * srcPtr = reinterpret_cast< const wchar_t * >( srcBuffer );
|
||||
BOOL loss = FALSE;
|
||||
int converted = WideCharToMultiByte(
|
||||
m_dstCodePage, 0,
|
||||
srcPtr, (int)cchSource,
|
||||
NULL, 0,
|
||||
NULL, &loss );
|
||||
|
||||
if ( 0 < converted )
|
||||
{
|
||||
AutoArray< char, AllocT > newDestBuffer( converted );
|
||||
char * dstPtr = newDestBuffer.m_ptr;
|
||||
converted = WideCharToMultiByte(
|
||||
m_dstCodePage, 0,
|
||||
srcPtr, (int)cchSource,
|
||||
newDestBuffer.m_ptr, converted,
|
||||
NULL, &loss );
|
||||
if ( 0 < converted )
|
||||
*destBuffer = newDestBuffer.Detach();
|
||||
if ( NULL != pHasLoss )
|
||||
*pHasLoss = (FALSE != loss);
|
||||
}
|
||||
return ReturnCchResult( converted, pErrorCode );
|
||||
}
|
||||
else if ( 2 == sizeof(DestType) && 1 == sizeof(SrcType) )
|
||||
{
|
||||
// ansi to utf16
|
||||
const char * srcPtr = reinterpret_cast< const char * >( srcBuffer );
|
||||
int converted = MultiByteToWideChar(
|
||||
m_srcCodePage, (failIfLossy ? MB_ERR_INVALID_CHARS : 0),
|
||||
srcPtr, (int)cchSource,
|
||||
NULL, 0 );
|
||||
|
||||
if ( 0 < converted )
|
||||
{
|
||||
AutoArray< WCHAR, AllocT > newDestBuffer( converted );
|
||||
converted = MultiByteToWideChar(
|
||||
m_srcCodePage, (failIfLossy ? MB_ERR_INVALID_CHARS : 0),
|
||||
srcPtr, (int)cchSource,
|
||||
newDestBuffer.m_ptr, converted );
|
||||
if ( 0 < converted )
|
||||
*destBuffer = newDestBuffer.Detach();
|
||||
if ( NULL != pHasLoss )
|
||||
*pHasLoss = false;
|
||||
}
|
||||
return ReturnCchResult( converted, pErrorCode );
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( false );
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_NOT_SUPPORTED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // defined(MPLAT_WWOWH)
|
||||
}
|
||||
// Performs an encoding conversion.
|
||||
// Returns the number of dest chars written.
|
||||
// Input and output buffers should not overlap.
|
||||
template< class DestType, class SrcType >
|
||||
size_t Convert(
|
||||
DestType * destBuffer, size_t cchDest,
|
||||
const SrcType * srcBuffer, size_t cchSource,
|
||||
bool failIfLossy = false, bool * pHasLoss = NULL, DWORD * pErrorCode = NULL ) const
|
||||
{
|
||||
#if defined(MPLAT_UNIX)
|
||||
|
||||
if ( !IsValidIConv() )
|
||||
return 0;
|
||||
|
||||
iconv_buffer<SrcType> src(
|
||||
reinterpret_cast< char * >( const_cast< SrcType * >(srcBuffer) ),
|
||||
cchSource );
|
||||
if ( 0 < cchDest )
|
||||
{
|
||||
iconv_buffer<DestType> dest(
|
||||
reinterpret_cast< char * >(destBuffer),
|
||||
cchDest );
|
||||
return Convert( dest, src, failIfLossy, pHasLoss, pErrorCode );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use fixed size buffer iteratively to determine final required length
|
||||
const size_t CCH_FIXED_SIZE = 256;
|
||||
char fixed_buf[ CCH_FIXED_SIZE*sizeof(DestType) ];
|
||||
iconv_buffer<DestType> dest(
|
||||
&fixed_buf[0],
|
||||
CCH_FIXED_SIZE );
|
||||
|
||||
bool hasLoss = false;
|
||||
DWORD rcCvt = ERROR_SUCCESS;
|
||||
size_t cchOnce = 0;
|
||||
size_t cchCumulative = 0;
|
||||
|
||||
while ( 0 < src.m_nBytesLeft
|
||||
&& 0 == (cchOnce = Convert(dest, src, failIfLossy, &hasLoss, &rcCvt))
|
||||
&& ERROR_INSUFFICIENT_BUFFER == rcCvt )
|
||||
{
|
||||
cchCumulative += CCH_FIXED_SIZE;
|
||||
cchCumulative -= dest.m_nBytesLeft;
|
||||
dest.Reset( &fixed_buf[0], CCH_FIXED_SIZE );
|
||||
}
|
||||
if ( 0 < cchOnce )
|
||||
cchCumulative += cchOnce;
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = (0 < cchCumulative ? ERROR_SUCCESS : rcCvt);
|
||||
if ( NULL != pHasLoss )
|
||||
*pHasLoss |= hasLoss;
|
||||
return cchCumulative;
|
||||
}
|
||||
|
||||
#elif defined(MPLAT_WWOWH)
|
||||
// WWOWH unit testing code
|
||||
// Can only convert between ansi and utf16
|
||||
if ( 1 == sizeof(DestType) && 2 == sizeof(SrcType) )
|
||||
{
|
||||
// utf16 to ansi
|
||||
char * dstPtr = reinterpret_cast< char * >( destBuffer );
|
||||
const wchar_t * srcPtr = reinterpret_cast< const wchar_t * >( srcBuffer );
|
||||
BOOL loss = FALSE;
|
||||
int converted = WideCharToMultiByte(
|
||||
m_dstCodePage, 0,
|
||||
srcPtr, (int)cchSource,
|
||||
dstPtr, (int)cchDest,
|
||||
NULL, &loss );
|
||||
if ( NULL != pHasLoss )
|
||||
*pHasLoss = (FALSE != loss);
|
||||
return ReturnCchResult( converted, pErrorCode );
|
||||
}
|
||||
else if ( 2 == sizeof(DestType) && 1 == sizeof(SrcType) )
|
||||
{
|
||||
// ansi to utf16
|
||||
wchar_t * dstPtr = reinterpret_cast< wchar_t * >( destBuffer );
|
||||
const char * srcPtr = reinterpret_cast< const char * >( srcBuffer );
|
||||
int converted = MultiByteToWideChar(
|
||||
m_srcCodePage, (failIfLossy ? MB_ERR_INVALID_CHARS : 0),
|
||||
srcPtr, (int)cchSource,
|
||||
dstPtr, (int)cchDest );
|
||||
if ( NULL != pHasLoss )
|
||||
*pHasLoss = false;
|
||||
return ReturnCchResult( converted, pErrorCode );
|
||||
}
|
||||
else
|
||||
{
|
||||
assert( false );
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_NOT_SUPPORTED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // defined(MPLAT_WWOWH)
|
||||
}
|
||||
};
|
||||
|
||||
#endif // _GLOBALIZATION_H_
|
62
source/shared/interlockedatomic.h
Normal file
62
source/shared/interlockedatomic.h
Normal file
|
@ -0,0 +1,62 @@
|
|||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
// File: InterlockedAtomic.h
|
||||
//
|
||||
// Contents: Contains a portable abstraction for interlocked, atomic
|
||||
// operations on int32_t and pointer types.
|
||||
//
|
||||
// Microsoft Drivers 4.0 for PHP for SQL Server
|
||||
// Copyright(c) Microsoft Corporation
|
||||
// All rights reserved.
|
||||
// MIT License
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""),
|
||||
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef __INTERLOCKEDATOMIC_H__
|
||||
#define __INTERLOCKEDATOMIC_H__
|
||||
|
||||
// Forward references and contract specifications
|
||||
//
|
||||
|
||||
// Increments and returns new value
|
||||
LONG InterlockedIncrement( LONG volatile * atomic );
|
||||
|
||||
// Decrements and returns new value
|
||||
LONG InterlockedDecrement( LONG volatile * atomic );
|
||||
|
||||
// Always returns old value
|
||||
// Sets to new value if old value equals compareTo
|
||||
LONG InterlockedCompareExchange( LONG volatile * atomic, LONG newValue, LONG compareTo );
|
||||
|
||||
// Sets to new value and returns old value
|
||||
LONG InterlockedExchange( LONG volatile * atomic, LONG newValue );
|
||||
|
||||
// Sets to new value and returns old value
|
||||
PVOID InterlockedExchangePointer( PVOID volatile * atomic, PVOID newValue);
|
||||
|
||||
// Adds the amount and returns the old value
|
||||
LONG InterlockedExchangeAdd( LONG volatile * atomic, LONG add );
|
||||
|
||||
// Always returns the old value
|
||||
// Sets the new value if old value equals compareTo
|
||||
PVOID InterlockedCompareExchangePointer( PVOID volatile * atomic, PVOID newValue, PVOID compareTo );
|
||||
|
||||
|
||||
|
||||
// Use conditional compilation to load the implementation
|
||||
//
|
||||
#if defined(_MSC_VER)
|
||||
#include "InterlockedAtomic_WwoWH.h"
|
||||
#elif defined(__GNUC__)
|
||||
#include "interlockedatomic_gcc.h"
|
||||
#else
|
||||
#error "Unsupported compiler"
|
||||
#endif
|
||||
|
||||
#endif // __INTERLOCKEDATOMIC_H__
|
63
source/shared/interlockedatomic_gcc.h
Normal file
63
source/shared/interlockedatomic_gcc.h
Normal file
|
@ -0,0 +1,63 @@
|
|||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
// File: InterlockedAtomic_gcc.h
|
||||
//
|
||||
// Contents: Contains a portable abstraction for interlocked, atomic
|
||||
// operations on int32_t and pointer types.
|
||||
//
|
||||
// Microsoft Drivers 4.0 for PHP for SQL Server
|
||||
// Copyright(c) Microsoft Corporation
|
||||
// All rights reserved.
|
||||
// MIT License
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""),
|
||||
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef __INTERLOCKEDATOMIC_GCC_H__
|
||||
#define __INTERLOCKEDATOMIC_GCC_H__
|
||||
|
||||
#if !defined(__GNUC__)
|
||||
#error "Incorrect compiler configuration in InterlockedAtomic.h. Was expecting GCC."
|
||||
#endif
|
||||
|
||||
inline LONG InterlockedIncrement( LONG volatile * atomic )
|
||||
{
|
||||
return __sync_add_and_fetch( atomic, 1 );
|
||||
}
|
||||
|
||||
inline LONG InterlockedDecrement( LONG volatile * atomic )
|
||||
{
|
||||
return __sync_sub_and_fetch( atomic, 1 );
|
||||
}
|
||||
|
||||
inline LONG InterlockedCompareExchange( LONG volatile * atomic, LONG newValue, LONG compareTo )
|
||||
{
|
||||
return __sync_val_compare_and_swap( atomic, compareTo, newValue );
|
||||
}
|
||||
|
||||
inline LONG InterlockedExchange( LONG volatile * atomic, LONG newValue )
|
||||
{
|
||||
return __sync_lock_test_and_set( atomic, newValue );
|
||||
}
|
||||
|
||||
inline PVOID InterlockedExchangePointer( PVOID volatile * atomic, PVOID newValue)
|
||||
{
|
||||
return __sync_lock_test_and_set( atomic, newValue );
|
||||
}
|
||||
|
||||
inline LONG InterlockedExchangeAdd( LONG volatile * atomic, LONG add )
|
||||
{
|
||||
return __sync_fetch_and_add( atomic, add );
|
||||
}
|
||||
|
||||
inline PVOID InterlockedCompareExchangePointer( PVOID volatile * atomic, PVOID newValue, PVOID compareTo )
|
||||
{
|
||||
return __sync_val_compare_and_swap( atomic, compareTo, newValue );
|
||||
}
|
||||
|
||||
#endif // __INTERLOCKEDATOMIC_GCC_H__
|
142
source/shared/interlockedslist.h
Normal file
142
source/shared/interlockedslist.h
Normal file
|
@ -0,0 +1,142 @@
|
|||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
// File: InterlockedSList.h
|
||||
//
|
||||
// Contents: Contains a portable abstraction for interlocked, singly
|
||||
// linked list.
|
||||
//
|
||||
// Microsoft Drivers 4.0 for PHP for SQL Server
|
||||
// Copyright(c) Microsoft Corporation
|
||||
// All rights reserved.
|
||||
// MIT License
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""),
|
||||
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef __INTERLOCKEDSLIST_H__
|
||||
#define __INTERLOCKEDSLIST_H__
|
||||
|
||||
#include "interlockedatomic.h"
|
||||
|
||||
#define SLIST_ENTRY SINGLE_LIST_ENTRY
|
||||
|
||||
#define PSLIST_ENTRY PSINGLE_LIST_ENTRY
|
||||
|
||||
typedef struct _SINGLE_LIST_ENTRY {
|
||||
// Want a volatile pointer to non-volatile data so place after all type info
|
||||
struct _SINGLE_LIST_ENTRY * volatile Next;
|
||||
} SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY;
|
||||
|
||||
typedef union _SLIST_HEADER {
|
||||
// Provides 8 byte alignment for 32-bit builds. Technically, not needed for
|
||||
// current implementation below but leaving for future use.
|
||||
ULONGLONG Alignment;
|
||||
struct {
|
||||
// Want a volatile pointer to non-volatile data so place after all type info
|
||||
PSLIST_ENTRY volatile Head;
|
||||
volatile LONG Depth;
|
||||
volatile LONG Mutex;
|
||||
} List;
|
||||
} SLIST_HEADER, *PSLIST_HEADER;
|
||||
|
||||
|
||||
inline VOID InitializeSListHead( PSLIST_HEADER slist )
|
||||
{
|
||||
assert( NULL != slist );
|
||||
|
||||
slist->List.Head = NULL;
|
||||
slist->List.Depth = 0;
|
||||
slist->List.Mutex = 0;
|
||||
}
|
||||
|
||||
inline PSLIST_ENTRY InterlockedPopEntrySList( PSLIST_HEADER slist )
|
||||
{
|
||||
assert( NULL != slist );
|
||||
|
||||
// Exit prior to 'mutex' if we think it is empty
|
||||
// Some callers (like sqlncli/msdart/dll/dynslist.h) rely on a NULL
|
||||
// result from Pop to indicate the list is empty. This early exit
|
||||
// is an optimization and not technically needed for correctness.
|
||||
PSLIST_ENTRY oldHead = slist->List.Head;
|
||||
if ( NULL == oldHead )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while ( 0 != slist->List.Mutex || 0 != InterlockedCompareExchange( &slist->List.Mutex, 1, 0 ) )
|
||||
{
|
||||
// Spin until 'mutex' is free
|
||||
}
|
||||
|
||||
// We have the 'mutex' so proceed with update
|
||||
oldHead = slist->List.Head;
|
||||
if ( NULL != oldHead )
|
||||
{
|
||||
slist->List.Head = oldHead->Next;
|
||||
--(slist->List.Depth);
|
||||
assert( 0 <= slist->List.Depth );
|
||||
}
|
||||
|
||||
// Free the 'mutex'
|
||||
slist->List.Mutex = 0;
|
||||
|
||||
return oldHead;
|
||||
}
|
||||
|
||||
inline PSLIST_ENTRY InterlockedPushEntrySList( PSLIST_HEADER slist, PSLIST_ENTRY newEntry )
|
||||
{
|
||||
assert( NULL != slist );
|
||||
|
||||
while ( 0 != slist->List.Mutex || 0 != InterlockedCompareExchange( &slist->List.Mutex, 1, 0 ) )
|
||||
{
|
||||
// Spin until 'mutex' is free
|
||||
}
|
||||
|
||||
// We have the 'mutex' so proceed with update
|
||||
PSLIST_ENTRY oldHead = slist->List.Head;
|
||||
newEntry->Next = oldHead;
|
||||
slist->List.Head = newEntry;
|
||||
++(slist->List.Depth);
|
||||
|
||||
// Free the 'mutex'
|
||||
slist->List.Mutex = 0;
|
||||
|
||||
return oldHead;
|
||||
}
|
||||
|
||||
inline PSLIST_ENTRY InterlockedFlushSList( PSLIST_HEADER slist )
|
||||
{
|
||||
assert( NULL != slist );
|
||||
|
||||
while ( 0 != slist->List.Mutex || 0 != InterlockedCompareExchange( &slist->List.Mutex, 1, 0 ) )
|
||||
{
|
||||
// Spin until 'mutex' is free
|
||||
}
|
||||
|
||||
// We have the 'mutex' so proceed with update
|
||||
PSLIST_ENTRY oldHead = slist->List.Head;
|
||||
slist->List.Head = NULL;
|
||||
slist->List.Depth = 0;
|
||||
|
||||
// Free the 'mutex'
|
||||
slist->List.Mutex = 0;
|
||||
|
||||
return oldHead;
|
||||
}
|
||||
|
||||
// If the list has more than USHORT nodes then this method
|
||||
// will not return reliable results.
|
||||
inline USHORT QueryDepthSList( PSLIST_HEADER slist )
|
||||
{
|
||||
assert( NULL != slist );
|
||||
|
||||
return static_cast<USHORT>(slist->List.Depth);
|
||||
}
|
||||
|
||||
|
||||
#endif // __INTERLOCKEDSLIST_H__
|
7635
source/shared/intsafe.h
Normal file
7635
source/shared/intsafe.h
Normal file
|
@ -0,0 +1,7635 @@
|
|||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
// File: intsafe.h
|
||||
//
|
||||
// Contents: This module defines helper functions to prevent
|
||||
// integer overflow bugs.
|
||||
//
|
||||
// Microsoft Drivers 4.0 for PHP for SQL Server
|
||||
// Copyright(c) Microsoft Corporation
|
||||
// All rights reserved.
|
||||
// MIT License
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""),
|
||||
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef XPLAT_INTSAFE_H
|
||||
#define XPLAT_INTSAFE_H
|
||||
|
||||
#if (_MSC_VER > 1000)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if !defined(_W64)
|
||||
#if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && (_MSC_VER >= 1300)
|
||||
#define _W64 __w64
|
||||
#else
|
||||
#define _W64
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "sal.h"
|
||||
#include <limits.h>
|
||||
|
||||
//
|
||||
// typedefs
|
||||
//
|
||||
typedef char CHAR;
|
||||
typedef signed char INT8;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef unsigned char UINT8;
|
||||
typedef unsigned char BYTE;
|
||||
typedef short SHORT;
|
||||
typedef signed short INT16;
|
||||
typedef unsigned short USHORT;
|
||||
typedef unsigned short UINT16;
|
||||
typedef unsigned short WORD;
|
||||
typedef int INT;
|
||||
typedef signed int INT32;
|
||||
typedef unsigned int UINT;
|
||||
typedef unsigned int UINT32;
|
||||
typedef windowsLong_t LONG;
|
||||
typedef windowsULong_t DWORD;
|
||||
typedef windowsLongLong_t LONGLONG;
|
||||
typedef windowsLongLong_t LONG64;
|
||||
typedef windowsLongLong_t INT64;
|
||||
typedef windowsULongLong_t ULONGLONG;
|
||||
typedef windowsULongLong_t DWORDLONG;
|
||||
typedef windowsULongLong_t ULONG64;
|
||||
typedef windowsULongLong_t DWORD64;
|
||||
typedef windowsULongLong_t UINT64;
|
||||
|
||||
#if (__midl > 501)
|
||||
typedef [public] __int3264 INT_PTR;
|
||||
typedef [public] unsigned __int3264 UINT_PTR;
|
||||
typedef [public] __int3264 LONG_PTR;
|
||||
typedef [public] unsigned __int3264 ULONG_PTR;
|
||||
#else
|
||||
#ifdef _WIN64
|
||||
typedef __int64 INT_PTR, *PINT_PTR;
|
||||
typedef unsigned __int64 UINT_PTR, *PUINT_PTR;
|
||||
typedef __int64 LONG_PTR, *PLONG_PTR;
|
||||
typedef unsigned __int64 ULONG_PTR, *PULONG_PTR;
|
||||
#else
|
||||
typedef _W64 int INT_PTR, *PINT_PTR;
|
||||
typedef _W64 unsigned int UINT_PTR, *PUINT_PTR;
|
||||
typedef _W64 windowsLong_t LONG_PTR, *PLONG_PTR;
|
||||
typedef _W64 windowsULong_t ULONG_PTR, *PULONG_PTR;
|
||||
#endif // WIN64
|
||||
#endif // (__midl > 501)
|
||||
|
||||
typedef ULONG_PTR DWORD_PTR;
|
||||
typedef LONG_PTR SSIZE_T;
|
||||
typedef ULONG_PTR SIZE_T;
|
||||
|
||||
#if defined(_AMD64_)
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define UnsignedMultiply128 _umul128
|
||||
|
||||
ULONG64
|
||||
UnsignedMultiply128 (
|
||||
__inn ULONG64 Multiplier,
|
||||
__inn ULONG64 Multiplicand,
|
||||
__outt __deref_out_range(==,Multiplier * Multiplicand) ULONG64 *HighProduct
|
||||
);
|
||||
#pragma intrinsic(_umul128)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // _AMD64_
|
||||
|
||||
|
||||
|
||||
typedef __success(return >= 0) windowsLong_t HRESULT;
|
||||
|
||||
#define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0)
|
||||
#define FAILED(hr) (((HRESULT)(hr)) < 0)
|
||||
|
||||
#define S_OK ((HRESULT)0L)
|
||||
|
||||
#define INTSAFE_E_ARITHMETIC_OVERFLOW ((HRESULT)0x80070216L) // 0x216 = 534 = ERROR_ARITHMETIC_OVERFLOW
|
||||
#ifndef SORTPP_PASS
|
||||
// compiletime asserts (failure results in error C2118: negative subscript)
|
||||
#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
|
||||
#else
|
||||
#define C_ASSERT(e)
|
||||
#endif
|
||||
|
||||
//
|
||||
// UInt32x32To64 macro
|
||||
//
|
||||
#define UInt32x32To64(a, b) ((windowsULongLong_t)(((windowsULongLong_t)(a)) * ((windowsULong_t)(b))))
|
||||
|
||||
//
|
||||
// Min/Max type values
|
||||
//
|
||||
//#define INT8_MIN (-127 - 1)
|
||||
#define SHORT_MIN (-32768)
|
||||
//#define INT16_MIN (-32767 - 1)
|
||||
//#define INT_MIN (-2147483647 - 1)
|
||||
//#define INT32_MIN (-2147483647l - 1)
|
||||
//#define LONG_MIN (-2147483647L - 1)
|
||||
#define LONGLONG_MIN (-9223372036854775807ll - 1)
|
||||
#define LONG64_MIN (-9223372036854775807ll - 1)
|
||||
//#define INT64_MIN (-9223372036854775807ll - 1)
|
||||
#define INT128_MIN (-170141183460469231731687303715884105727i128 - 1)
|
||||
|
||||
#ifdef _WIN64
|
||||
#define INT_PTR_MIN (-9223372036854775807ll - 1)
|
||||
#define LONG_PTR_MIN (-9223372036854775807ll - 1)
|
||||
#define PTRDIFF_T_MIN (-9223372036854775807ll - 1)
|
||||
#define SSIZE_T_MIN (-9223372036854775807ll - 1)
|
||||
#else
|
||||
#define INT_PTR_MIN (-2147483647 - 1)
|
||||
#define LONG_PTR_MIN (-2147483647L - 1)
|
||||
#define PTRDIFF_T_MIN (-2147483647 - 1)
|
||||
#define SSIZE_T_MIN (-2147483647L - 1)
|
||||
#endif
|
||||
|
||||
//#define INT8_MAX 127
|
||||
//#define UINT8_MAX 0xff
|
||||
#define BYTE_MAX 0xff
|
||||
#define SHORT_MAX 32767
|
||||
//#define INT16_MAX 32767
|
||||
#define USHORT_MAX 0xffff
|
||||
//#define UINT16_MAX 0xffff
|
||||
#define WORD_MAX 0xffff
|
||||
//#define INT_MAX 2147483647
|
||||
//#define INT32_MAX 2147483647l
|
||||
//#define UINT_MAX 0xffffffff
|
||||
//#define UINT32_MAX 0xfffffffful
|
||||
//#define LONG_MAX 2147483647L
|
||||
//#define ULONG_MAX 0xffffffffUL
|
||||
#define DWORD_MAX 0xffffffffUL
|
||||
#define LONGLONG_MAX 9223372036854775807ll
|
||||
#define LONG64_MAX 9223372036854775807ll
|
||||
//#define INT64_MAX 9223372036854775807ll
|
||||
#define ULONGLONG_MAX 0xffffffffffffffffull
|
||||
#define DWORDLONG_MAX 0xffffffffffffffffull
|
||||
#define ULONG64_MAX 0xffffffffffffffffull
|
||||
#define DWORD64_MAX 0xffffffffffffffffull
|
||||
//#define UINT64_MAX 0xffffffffffffffffull
|
||||
#define INT128_MAX 170141183460469231731687303715884105727i128
|
||||
#define UINT128_MAX 0xffffffffffffffffffffffffffffffffui128
|
||||
|
||||
#ifndef _I64_MIN
|
||||
#define _I64_MIN INT64_MIN
|
||||
#define _I64_MAX INT64_MAX
|
||||
#define _UI64_MIN UINT64_MIN
|
||||
#define _UI64_MAX UINT64_MAX
|
||||
#endif
|
||||
|
||||
#undef SIZE_T_MAX
|
||||
|
||||
#ifdef _WIN64
|
||||
#define INT_PTR_MAX 9223372036854775807ll
|
||||
#define UINT_PTR_MAX 0xffffffffffffffffull
|
||||
#define LONG_PTR_MAX 9223372036854775807ll
|
||||
#define ULONG_PTR_MAX 0xffffffffffffffffull
|
||||
#define DWORD_PTR_MAX 0xffffffffffffffffull
|
||||
#define PTRDIFF_T_MAX 9223372036854775807ll
|
||||
#define SIZE_T_MAX 0xffffffffffffffffull
|
||||
#define SSIZE_T_MAX 9223372036854775807ll
|
||||
#define _SIZE_T_MAX 0xffffffffffffffffull
|
||||
#else
|
||||
#define INT_PTR_MAX 2147483647
|
||||
#define UINT_PTR_MAX 0xffffffff
|
||||
#define LONG_PTR_MAX 2147483647L
|
||||
#define ULONG_PTR_MAX 0xffffffffUL
|
||||
#define DWORD_PTR_MAX 0xffffffffUL
|
||||
#define PTRDIFF_T_MAX 2147483647
|
||||
#define SIZE_T_MAX 0xffffffff
|
||||
#define SSIZE_T_MAX 2147483647L
|
||||
#define _SIZE_T_MAX 0xffffffffUL
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// It is common for -1 to be used as an error value
|
||||
//
|
||||
#define INT8_ERROR (-1)
|
||||
#define UINT8_ERROR 0xff
|
||||
#define BYTE_ERROR 0xff
|
||||
#define SHORT_ERROR (-1)
|
||||
#define INT16_ERROR (-1)
|
||||
#define USHORT_ERROR 0xffff
|
||||
#define UINT16_ERROR 0xffff
|
||||
#define WORD_ERROR 0xffff
|
||||
#define INT_ERROR (-1)
|
||||
#define INT32_ERROR (-1l)
|
||||
#define UINT_ERROR 0xffffffff
|
||||
#define UINT32_ERROR 0xfffffffful
|
||||
#define LONG_ERROR (-1L)
|
||||
#define ULONG_ERROR 0xffffffffUL
|
||||
#define DWORD_ERROR 0xffffffffUL
|
||||
#define LONGLONG_ERROR (-1ll)
|
||||
#define LONG64_ERROR (-1ll)
|
||||
#define INT64_ERROR (-1ll)
|
||||
#define ULONGLONG_ERROR 0xffffffffffffffffull
|
||||
#define DWORDLONG_ERROR 0xffffffffffffffffull
|
||||
#define ULONG64_ERROR 0xffffffffffffffffull
|
||||
#define UINT64_ERROR 0xffffffffffffffffull
|
||||
|
||||
#ifdef _WIN64
|
||||
#define INT_PTR_ERROR (-1ll)
|
||||
#define UINT_PTR_ERROR 0xffffffffffffffffull
|
||||
#define LONG_PTR_ERROR (-1ll)
|
||||
#define ULONG_PTR_ERROR 0xffffffffffffffffull
|
||||
#define DWORD_PTR_ERROR 0xffffffffffffffffull
|
||||
#define PTRDIFF_T_ERROR (-1ll)
|
||||
#define SIZE_T_ERROR 0xffffffffffffffffull
|
||||
#define SSIZE_T_ERROR (-1ll)
|
||||
#define _SIZE_T_ERROR 0xffffffffffffffffull
|
||||
#else
|
||||
#define INT_PTR_ERROR (-1)
|
||||
#define UINT_PTR_ERROR 0xffffffff
|
||||
#define LONG_PTR_ERROR (-1L)
|
||||
#define ULONG_PTR_ERROR 0xffffffffUL
|
||||
#define DWORD_PTR_ERROR 0xffffffffUL
|
||||
#define PTRDIFF_T_ERROR (-1)
|
||||
#define SIZE_T_ERROR 0xffffffff
|
||||
#define SSIZE_T_ERROR (-1L)
|
||||
#define _SIZE_T_ERROR 0xffffffffUL
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// We make some assumptions about the sizes of various types. Let's be
|
||||
// explicit about those assumptions and check them.
|
||||
//
|
||||
C_ASSERT(sizeof(USHORT) == 2);
|
||||
C_ASSERT(sizeof(INT) == 4);
|
||||
C_ASSERT(sizeof(UINT) == 4);
|
||||
C_ASSERT(sizeof(LONG) == 4);
|
||||
C_ASSERT(sizeof(ULONG) == 8);
|
||||
C_ASSERT(sizeof(UINT_PTR) == sizeof(ULONG_PTR));
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// Conversion functions
|
||||
//
|
||||
// There are three reasons for having conversion functions:
|
||||
//
|
||||
// 1. We are converting from a signed type to an unsigned type of the same
|
||||
// size, or vice-versa.
|
||||
//
|
||||
// Since we only have unsigned math functions, this allows people to convert
|
||||
// to unsigned, do the math, and then convert back to signed.
|
||||
//
|
||||
// 2. We are converting to a smaller type, and we could therefore possibly
|
||||
// overflow.
|
||||
//
|
||||
// 3. We are converting to a bigger type, and we are signed and the type we are
|
||||
// converting to is unsigned.
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
//
|
||||
// INT8 -> UCHAR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
Int8ToUChar(
|
||||
__inn INT8 i8Operand,
|
||||
__outt __deref_out_range(==,i8Operand) UCHAR* pch)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (i8Operand >= 0)
|
||||
{
|
||||
*pch = (UCHAR)i8Operand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pch = '\0';
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// INT8 -> UINT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
Int8ToUInt8(
|
||||
__inn INT8 i8Operand,
|
||||
__outt __deref_out_range(==,i8Operand) UINT8* pu8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (i8Operand >= 0)
|
||||
{
|
||||
*pu8Result = (UINT8)i8Operand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pu8Result = UINT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// INT8 -> BYTE conversion
|
||||
//
|
||||
#define Int8ToByte Int8ToUInt8
|
||||
|
||||
//
|
||||
// INT8 -> USHORT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
Int8ToUShort(
|
||||
__inn INT8 i8Operand,
|
||||
__outt __deref_out_range(==,i8Operand) USHORT* pusResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (i8Operand >= 0)
|
||||
{
|
||||
*pusResult = (USHORT)i8Operand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pusResult = USHORT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// INT8 -> UINT16 conversion
|
||||
//
|
||||
#define Int8ToUInt16 Int8ToUShort
|
||||
|
||||
//
|
||||
// INT8 -> WORD conversion
|
||||
//
|
||||
#define Int8ToWord Int8ToUShort
|
||||
|
||||
//
|
||||
// INT8 -> UINT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
Int8ToUInt(
|
||||
__inn INT8 i8Operand,
|
||||
__outt __deref_out_range(==,i8Operand) UINT* puResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (i8Operand >= 0)
|
||||
{
|
||||
*puResult = (UINT)i8Operand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*puResult = UINT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// INT8 -> UINT32 conversion
|
||||
//
|
||||
#define Int8ToUInt32 Int8ToUInt
|
||||
|
||||
//
|
||||
// INT8 -> UINT_PTR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
Int8ToUIntPtr(
|
||||
__inn INT8 i8Operand,
|
||||
__outt __deref_out_range(==,i8Operand) UINT_PTR* puResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (i8Operand >= 0)
|
||||
{
|
||||
*puResult = (UINT_PTR)i8Operand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*puResult = UINT_PTR_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// INT8 -> ULONG conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
Int8ToULong(
|
||||
__inn INT8 i8Operand,
|
||||
__outt __deref_out_range(==,i8Operand) ULONG* pulResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (i8Operand >= 0)
|
||||
{
|
||||
*pulResult = (ULONG)i8Operand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pulResult = ULONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// INT8 -> ULONG_PTR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
Int8ToULongPtr(
|
||||
__inn INT8 i8Operand,
|
||||
__outt __deref_out_range(==,i8Operand) ULONG_PTR* pulResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (i8Operand >= 0)
|
||||
{
|
||||
*pulResult = (ULONG_PTR)i8Operand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pulResult = ULONG_PTR_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// INT8 -> DWORD conversion
|
||||
//
|
||||
#define Int8ToDWord Int8ToULong
|
||||
|
||||
//
|
||||
// INT8 -> DWORD_PTR conversion
|
||||
//
|
||||
#define Int8ToDWordPtr Int8ToULongPtr
|
||||
|
||||
//
|
||||
// INT8 -> ULONGLONG conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
Int8ToULongLong(
|
||||
__inn INT8 i8Operand,
|
||||
__outt __deref_out_range(==,i8Operand) ULONGLONG* pullResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (i8Operand >= 0)
|
||||
{
|
||||
*pullResult = (ULONGLONG)i8Operand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pullResult = ULONGLONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// INT8 -> DWORDLONG conversion
|
||||
//
|
||||
#define Int8ToDWordLong Int8ToULongLong
|
||||
|
||||
//
|
||||
// INT8 -> ULONG64 conversion
|
||||
//
|
||||
#define Int8ToULong64 Int8ToULongLong
|
||||
|
||||
//
|
||||
// INT8 -> DWORD64 conversion
|
||||
//
|
||||
#define Int8ToDWord64 Int8ToULongLong
|
||||
|
||||
//
|
||||
// INT8 -> UINT64 conversion
|
||||
//
|
||||
#define Int8ToUInt64 Int8ToULongLong
|
||||
|
||||
//
|
||||
// INT8 -> size_t conversion
|
||||
//
|
||||
#define Int8ToSizeT Int8ToUIntPtr
|
||||
|
||||
//
|
||||
// INT8 -> SIZE_T conversion
|
||||
//
|
||||
#define Int8ToSIZET Int8ToULongPtr
|
||||
|
||||
//
|
||||
// UINT8 -> INT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UInt8ToInt8(
|
||||
__inn UINT8 u8Operand,
|
||||
__outt __deref_out_range(==,u8Operand) INT8* pi8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (u8Operand <= INT8_MAX)
|
||||
{
|
||||
*pi8Result = (INT8)u8Operand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pi8Result = INT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// UINT8 -> CHAR conversion
|
||||
//
|
||||
__forceinline
|
||||
HRESULT
|
||||
UInt8ToChar(
|
||||
__inn UINT8 u8Operand,
|
||||
__outt __deref_out_range(==,u8Operand) CHAR* pch)
|
||||
{
|
||||
#ifdef _CHAR_UNSIGNED
|
||||
*pch = (CHAR)u8Operand;
|
||||
return S_OK;
|
||||
#else
|
||||
return UInt8ToInt8(u8Operand, (INT8*)pch);
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// BYTE -> INT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ByteToInt8(
|
||||
__inn BYTE bOperand,
|
||||
__outt __deref_out_range(==,bOperand) INT8* pi8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (bOperand <= INT8_MAX)
|
||||
{
|
||||
*pi8Result = (INT8)bOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pi8Result = INT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// BYTE -> CHAR conversion
|
||||
//
|
||||
__forceinline
|
||||
HRESULT
|
||||
ByteToChar(
|
||||
__inn BYTE bOperand,
|
||||
__outt __deref_out_range(==,bOperand) CHAR* pch)
|
||||
{
|
||||
#ifdef _CHAR_UNSIGNED
|
||||
*pch = (CHAR)bOperand;
|
||||
return S_OK;
|
||||
#else
|
||||
return ByteToInt8(bOperand, (INT8*)pch);
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// SHORT -> INT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ShortToInt8(
|
||||
__inn SHORT sOperand,
|
||||
__outt __deref_out_range(==,sOperand) INT8* pi8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((sOperand >= INT8_MIN) && (sOperand <= INT8_MAX))
|
||||
{
|
||||
*pi8Result = (INT8)sOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pi8Result = INT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// SHORT -> UCHAR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ShortToUChar(
|
||||
__inn SHORT sOperand,
|
||||
__outt __deref_out_range(==,sOperand) UCHAR* pch)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((sOperand >= 0) && (sOperand <= 255))
|
||||
{
|
||||
*pch = (UCHAR)sOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pch = '\0';
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// SHORT -> CHAR conversion
|
||||
//
|
||||
__forceinline
|
||||
HRESULT
|
||||
ShortToChar(
|
||||
__inn SHORT sOperand,
|
||||
__outt __deref_out_range(==,sOperand) CHAR* pch)
|
||||
{
|
||||
#ifdef _CHAR_UNSIGNED
|
||||
return ShortToUChar(sOperand, (UCHAR*)pch);
|
||||
#else
|
||||
return ShortToInt8(sOperand, (INT8*)pch);
|
||||
#endif // _CHAR_UNSIGNED
|
||||
}
|
||||
|
||||
//
|
||||
// SHORT -> UINT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ShortToUInt8(
|
||||
__inn SHORT sOperand,
|
||||
__outt __deref_out_range(==,sOperand) UINT8* pui8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((sOperand >= 0) && (sOperand <= UINT8_MAX))
|
||||
{
|
||||
*pui8Result = (UINT8)sOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pui8Result = UINT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// SHORT -> BYTE conversion
|
||||
//
|
||||
#define ShortToByte ShortToUInt8
|
||||
|
||||
//
|
||||
// SHORT -> USHORT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ShortToUShort(
|
||||
__inn SHORT sOperand,
|
||||
__outt __deref_out_range(==,sOperand) USHORT* pusResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (sOperand >= 0)
|
||||
{
|
||||
*pusResult = (USHORT)sOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pusResult = USHORT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// SHORT -> UINT16 conversion
|
||||
//
|
||||
#define ShortToUInt16 ShortToUShort
|
||||
|
||||
//
|
||||
// SHORT -> WORD conversion
|
||||
//
|
||||
#define ShortToWord ShortToUShort
|
||||
|
||||
//
|
||||
// SHORT -> UINT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ShortToUInt(
|
||||
__inn SHORT sOperand,
|
||||
__outt __deref_out_range(==,sOperand) UINT* puResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (sOperand >= 0)
|
||||
{
|
||||
*puResult = (UINT)sOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*puResult = UINT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// SHORT -> UINT32 conversion
|
||||
//
|
||||
#define ShortToUInt32 ShortToUInt
|
||||
|
||||
//
|
||||
// SHORT -> UINT_PTR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ShortToUIntPtr(
|
||||
__inn SHORT sOperand,
|
||||
__outt __deref_out_range(==,sOperand) UINT_PTR* puResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (sOperand >= 0)
|
||||
{
|
||||
*puResult = (UINT_PTR)sOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*puResult = UINT_PTR_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// SHORT -> ULONG conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ShortToULong(
|
||||
__inn SHORT sOperand,
|
||||
__outt __deref_out_range(==,sOperand) ULONG* pulResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (sOperand >= 0)
|
||||
{
|
||||
*pulResult = (ULONG)sOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pulResult = ULONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// SHORT -> ULONG_PTR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ShortToULongPtr(
|
||||
__inn SHORT sOperand,
|
||||
__outt __deref_out_range(==,sOperand) ULONG_PTR* pulResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (sOperand >= 0)
|
||||
{
|
||||
*pulResult = (ULONG_PTR)sOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pulResult = ULONG_PTR_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// SHORT -> DWORD conversion
|
||||
//
|
||||
#define ShortToDWord ShortToULong
|
||||
|
||||
//
|
||||
// SHORT -> DWORD_PTR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ShortToDWordPtr(
|
||||
__inn SHORT sOperand,
|
||||
__outt __deref_out_range(==,sOperand) DWORD_PTR* pdwResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (sOperand >= 0)
|
||||
{
|
||||
*pdwResult = (DWORD_PTR)sOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pdwResult = DWORD_PTR_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// SHORT -> ULONGLONG conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ShortToULongLong(
|
||||
__inn SHORT sOperand,
|
||||
__outt __deref_out_range(==,sOperand) ULONGLONG* pullResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (sOperand >= 0)
|
||||
{
|
||||
*pullResult = (ULONGLONG)sOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pullResult = ULONGLONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// SHORT -> DWORDLONG conversion
|
||||
//
|
||||
#define ShortToDWordLong ShortToULongLong
|
||||
|
||||
//
|
||||
// SHORT -> ULONG64 conversion
|
||||
//
|
||||
#define ShortToULong64 ShortToULongLong
|
||||
|
||||
//
|
||||
// SHORT -> DWORD64 conversion
|
||||
//
|
||||
#define ShortToDWord64 ShortToULongLong
|
||||
|
||||
//
|
||||
// SHORT -> UINT64 conversion
|
||||
//
|
||||
#define ShortToUInt64 ShortToULongLong
|
||||
|
||||
//
|
||||
// SHORT -> size_t conversion
|
||||
//
|
||||
#define ShortToSizeT ShortToUIntPtr
|
||||
|
||||
//
|
||||
// SHORT -> SIZE_T conversion
|
||||
//
|
||||
#define ShortToSIZET ShortToULongPtr
|
||||
|
||||
//
|
||||
// INT16 -> CHAR conversion
|
||||
//
|
||||
#define Int16ToChar ShortToChar
|
||||
|
||||
//
|
||||
// INT16 -> INT8 conversion
|
||||
//
|
||||
#define Int16ToInt8 ShortToInt8
|
||||
|
||||
//
|
||||
// INT16 -> UCHAR conversion
|
||||
//
|
||||
#define Int16ToUChar ShortToUChar
|
||||
|
||||
//
|
||||
// INT16 -> UINT8 conversion
|
||||
//
|
||||
#define Int16ToUInt8 ShortToUInt8
|
||||
|
||||
//
|
||||
// INT16 -> BYTE conversion
|
||||
//
|
||||
#define Int16ToByte ShortToUInt8
|
||||
|
||||
//
|
||||
// INT16 -> USHORT conversion
|
||||
//
|
||||
#define Int16ToUShort ShortToUShort
|
||||
|
||||
//
|
||||
// INT16 -> UINT16 conversion
|
||||
//
|
||||
#define Int16ToUInt16 ShortToUShort
|
||||
|
||||
//
|
||||
// INT16 -> WORD conversion
|
||||
//
|
||||
#define Int16ToWord ShortToUShort
|
||||
|
||||
//
|
||||
// INT16 -> UINT conversion
|
||||
//
|
||||
#define Int16ToUInt ShortToUInt
|
||||
|
||||
//
|
||||
// INT16 -> UINT32 conversion
|
||||
//
|
||||
#define Int16ToUInt32 ShortToUInt
|
||||
|
||||
//
|
||||
// INT16 -> UINT_PTR conversion
|
||||
//
|
||||
#define Int16ToUIntPtr ShortToUIntPtr
|
||||
|
||||
//
|
||||
// INT16 -> ULONG conversion
|
||||
//
|
||||
#define Int16ToULong ShortToULong
|
||||
|
||||
//
|
||||
// INT16 -> ULONG_PTR conversion
|
||||
//
|
||||
#define Int16ToULongPtr ShortToULongPtr
|
||||
|
||||
//
|
||||
// INT16 -> DWORD conversion
|
||||
//
|
||||
#define Int16ToDWord ShortToULong
|
||||
|
||||
//
|
||||
// INT16 -> DWORD_PTR conversion
|
||||
//
|
||||
#define Int16ToDWordPtr ShortToULongPtr
|
||||
|
||||
//
|
||||
// INT16 -> ULONGLONG conversion
|
||||
//
|
||||
#define Int16ToULongLong ShortToULongLong
|
||||
|
||||
//
|
||||
// INT16 -> DWORDLONG conversion
|
||||
//
|
||||
#define Int16ToDWordLong ShortToULongLong
|
||||
|
||||
//
|
||||
// INT16 -> ULONG64 conversion
|
||||
//
|
||||
#define Int16ToULong64 ShortToULongLong
|
||||
|
||||
//
|
||||
// INT16 -> DWORD64 conversion
|
||||
//
|
||||
#define Int16ToDWord64 ShortToULongLong
|
||||
|
||||
//
|
||||
// INT16 -> UINT64 conversion
|
||||
//
|
||||
#define Int16ToUInt64 ShortToULongLong
|
||||
|
||||
//
|
||||
// INT16 -> size_t conversion
|
||||
//
|
||||
#define Int16ToSizeT ShortToUIntPtr
|
||||
|
||||
//
|
||||
// INT16 -> SIZE_T conversion
|
||||
//
|
||||
#define Int16ToSIZET ShortToULongPtr
|
||||
|
||||
//
|
||||
// USHORT -> INT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UShortToInt8(
|
||||
__inn USHORT usOperand,
|
||||
__outt __deref_out_range(==,usOperand) INT8* pi8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (usOperand <= INT8_MAX)
|
||||
{
|
||||
*pi8Result = (INT8)usOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pi8Result = INT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// USHORT -> UCHAR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UShortToUChar(
|
||||
__inn USHORT usOperand,
|
||||
__outt __deref_out_range(==,usOperand) UCHAR* pch)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (usOperand <= 255)
|
||||
{
|
||||
*pch = (UCHAR)usOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pch = '\0';
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// USHORT -> CHAR conversion
|
||||
//
|
||||
__forceinline
|
||||
HRESULT
|
||||
UShortToChar(
|
||||
__inn USHORT usOperand,
|
||||
__outt __deref_out_range(==,usOperand) CHAR* pch)
|
||||
{
|
||||
#ifdef _CHAR_UNSIGNED
|
||||
return UShortToUChar(usOperand, (UCHAR*)pch);
|
||||
#else
|
||||
return UShortToInt8(usOperand, (INT8*)pch);
|
||||
#endif // _CHAR_UNSIGNED
|
||||
}
|
||||
|
||||
//
|
||||
// USHORT -> UINT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UShortToUInt8(
|
||||
__inn USHORT usOperand,
|
||||
__outt __deref_out_range(==,usOperand) UINT8* pui8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (usOperand <= UINT8_MAX)
|
||||
{
|
||||
*pui8Result = (UINT8)usOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pui8Result = UINT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// USHORT -> BYTE conversion
|
||||
//
|
||||
#define UShortToByte UShortToUInt8
|
||||
|
||||
//
|
||||
// USHORT -> SHORT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UShortToShort(
|
||||
__inn USHORT usOperand,
|
||||
__outt __deref_out_range(==,usOperand) SHORT* psResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (usOperand <= SHORT_MAX)
|
||||
{
|
||||
*psResult = (SHORT)usOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*psResult = SHORT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// USHORT -> INT16 conversion
|
||||
//
|
||||
#define UShortToInt16 UShortToShort
|
||||
|
||||
//
|
||||
// UINT16 -> CHAR conversion
|
||||
//
|
||||
#define UInt16ToChar UShortToChar
|
||||
|
||||
//
|
||||
// UINT16 -> INT8 conversion
|
||||
//
|
||||
#define UInt16ToInt8 UShortToInt8
|
||||
|
||||
//
|
||||
// UINT16 -> UCHAR conversion
|
||||
//
|
||||
#define UInt16ToUChar UShortToUChar
|
||||
|
||||
//
|
||||
// UINT16 -> UINT8 conversion
|
||||
//
|
||||
#define UInt16ToUInt8 UShortToUInt8
|
||||
|
||||
//
|
||||
// UINT16 -> BYTE conversion
|
||||
//
|
||||
#define UInt16ToByte UShortToUInt8
|
||||
|
||||
//
|
||||
// UINT16 -> SHORT conversion
|
||||
//
|
||||
#define UInt16ToShort UShortToShort
|
||||
|
||||
//
|
||||
// UINT16 -> INT16 conversion
|
||||
//
|
||||
#define UInt16ToInt16 UShortToShort
|
||||
|
||||
//
|
||||
// WORD -> INT8 conversion
|
||||
//
|
||||
#define WordToInt8 UShortToInt8
|
||||
|
||||
//
|
||||
// WORD -> CHAR conversion
|
||||
//
|
||||
#define WordToChar UShortToChar
|
||||
|
||||
//
|
||||
// WORD -> UCHAR conversion
|
||||
//
|
||||
#define WordToUChar UShortToUChar
|
||||
|
||||
//
|
||||
// WORD -> UINT8 conversion
|
||||
//
|
||||
#define WordToUInt8 UShortToUInt8
|
||||
|
||||
//
|
||||
// WORD -> BYTE conversion
|
||||
//
|
||||
#define WordToByte UShortToUInt8
|
||||
|
||||
//
|
||||
// WORD -> SHORT conversion
|
||||
//
|
||||
#define WordToShort UShortToShort
|
||||
|
||||
//
|
||||
// WORD -> INT16 conversion
|
||||
//
|
||||
#define WordToInt16 UShortToShort
|
||||
|
||||
//
|
||||
// INT -> INT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
IntToInt8(
|
||||
__inn INT iOperand,
|
||||
__outt __deref_out_range(==,iOperand) INT8* pi8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((iOperand >= INT8_MIN) && (iOperand <= INT8_MAX))
|
||||
{
|
||||
*pi8Result = (INT8)iOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pi8Result = INT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// INT -> UCHAR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
IntToUChar(
|
||||
__inn INT iOperand,
|
||||
__outt __deref_out_range(==,iOperand) UCHAR* pch)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((iOperand >= 0) && (iOperand <= 255))
|
||||
{
|
||||
*pch = (UCHAR)iOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pch = '\0';
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// INT -> CHAR conversion
|
||||
//
|
||||
__forceinline
|
||||
HRESULT
|
||||
IntToChar(
|
||||
__inn INT iOperand,
|
||||
__outt __deref_out_range(==,iOperand) CHAR* pch)
|
||||
{
|
||||
#ifdef _CHAR_UNSIGNED
|
||||
return IntToUChar(iOperand, (UCHAR*)pch);
|
||||
#else
|
||||
return IntToInt8(iOperand, (INT8*)pch);
|
||||
#endif // _CHAR_UNSIGNED
|
||||
}
|
||||
|
||||
//
|
||||
// INT -> BYTE conversion
|
||||
//
|
||||
#define IntToByte IntToUInt8
|
||||
|
||||
//
|
||||
// INT -> UINT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
IntToUInt8(
|
||||
__inn INT iOperand,
|
||||
__outt __deref_out_range(==,iOperand) UINT8* pui8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((iOperand >= 0) && (iOperand <= UINT8_MAX))
|
||||
{
|
||||
*pui8Result = (UINT8)iOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pui8Result = UINT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// INT -> SHORT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
IntToShort(
|
||||
__inn INT iOperand,
|
||||
__outt __deref_out_range(==,iOperand) SHORT* psResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((iOperand >= SHORT_MIN) && (iOperand <= SHORT_MAX))
|
||||
{
|
||||
*psResult = (SHORT)iOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*psResult = SHORT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// INT -> INT16 conversion
|
||||
//
|
||||
#define IntToInt16 IntToShort
|
||||
|
||||
//
|
||||
// INT -> USHORT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
IntToUShort(
|
||||
__inn INT iOperand,
|
||||
__outt __deref_out_range(==,iOperand) USHORT* pusResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((iOperand >= 0) && (iOperand <= USHORT_MAX))
|
||||
{
|
||||
*pusResult = (USHORT)iOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pusResult = USHORT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// INT -> UINT16 conversion
|
||||
//
|
||||
#define IntToUInt16 IntToUShort
|
||||
|
||||
//
|
||||
// INT -> WORD conversion
|
||||
//
|
||||
#define IntToWord IntToUShort
|
||||
|
||||
//
|
||||
// INT -> UINT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
IntToUInt(
|
||||
__inn INT iOperand,
|
||||
__outt __deref_out_range(==,iOperand) UINT* puResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (iOperand >= 0)
|
||||
{
|
||||
*puResult = (UINT)iOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*puResult = UINT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// INT -> UINT_PTR conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define IntToUIntPtr IntToULongLong
|
||||
#else
|
||||
#define IntToUIntPtr IntToUInt
|
||||
#endif
|
||||
|
||||
//
|
||||
// INT -> ULONG conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
IntToULong(
|
||||
__inn INT iOperand,
|
||||
__outt __deref_out_range(==,iOperand) ULONG* pulResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (iOperand >= 0)
|
||||
{
|
||||
*pulResult = (ULONG)iOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pulResult = ULONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// INT -> ULONG_PTR conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define IntToULongPtr IntToULongLong
|
||||
#else
|
||||
#define IntToULongPtr IntToULong
|
||||
#endif
|
||||
|
||||
//
|
||||
// INT -> DWORD conversion
|
||||
//
|
||||
#define IntToDWord IntToULong
|
||||
|
||||
//
|
||||
// INT -> DWORD_PTR conversion
|
||||
//
|
||||
#define IntToDWordPtr IntToULongPtr
|
||||
|
||||
//
|
||||
// INT -> ULONGLONG conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
IntToULongLong(
|
||||
__inn INT iOperand,
|
||||
__outt __deref_out_range(==,iOperand) ULONGLONG* pullResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (iOperand >= 0)
|
||||
{
|
||||
*pullResult = (ULONGLONG)iOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pullResult = ULONGLONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// INT -> DWORDLONG conversion
|
||||
//
|
||||
#define IntToDWordLong IntToULongLong
|
||||
|
||||
//
|
||||
// INT -> ULONG64 conversion
|
||||
//
|
||||
#define IntToULong64 IntToULongLong
|
||||
|
||||
//
|
||||
// INT -> DWORD64 conversion
|
||||
//
|
||||
#define IntToDWord64 IntToULongLong
|
||||
|
||||
//
|
||||
// INT -> UINT64 conversion
|
||||
//
|
||||
#define IntToUInt64 IntToULongLong
|
||||
|
||||
//
|
||||
// INT -> size_t conversion
|
||||
//
|
||||
#define IntToSizeT IntToUIntPtr
|
||||
|
||||
//
|
||||
// INT -> SIZE_T conversion
|
||||
//
|
||||
#define IntToSIZET IntToULongPtr
|
||||
|
||||
//
|
||||
// INT32 -> CHAR conversion
|
||||
//
|
||||
#define Int32ToChar IntToChar
|
||||
|
||||
//
|
||||
// INT32 -> INT328 conversion
|
||||
//
|
||||
#define Int32ToInt8 IntToInt8
|
||||
|
||||
//
|
||||
// INT32 -> UCHAR conversion
|
||||
//
|
||||
#define Int32ToUChar IntToUChar
|
||||
|
||||
//
|
||||
// INT32 -> BYTE conversion
|
||||
//
|
||||
#define Int32ToByte IntToUInt8
|
||||
|
||||
//
|
||||
// INT32 -> UINT8 conversion
|
||||
//
|
||||
#define Int32ToUInt8 IntToUInt8
|
||||
|
||||
//
|
||||
// INT32 -> SHORT conversion
|
||||
//
|
||||
#define Int32ToShort IntToShort
|
||||
|
||||
//
|
||||
// INT32 -> INT16 conversion
|
||||
//
|
||||
#define Int32ToInt16 IntToShort
|
||||
|
||||
//
|
||||
// INT32 -> USHORT conversion
|
||||
//
|
||||
#define Int32ToUShort IntToUShort
|
||||
|
||||
//
|
||||
// INT32 -> UINT16 conversion
|
||||
//
|
||||
#define Int32ToUInt16 IntToUShort
|
||||
|
||||
//
|
||||
// INT32 -> WORD conversion
|
||||
//
|
||||
#define Int32ToWord IntToUShort
|
||||
|
||||
//
|
||||
// INT32 -> UINT conversion
|
||||
//
|
||||
#define Int32ToUInt IntToUInt
|
||||
|
||||
//
|
||||
// INT32 -> UINT32 conversion
|
||||
//
|
||||
#define Int32ToUInt32 IntToUInt
|
||||
|
||||
//
|
||||
// INT32 -> UINT_PTR conversion
|
||||
//
|
||||
#define Int32ToUIntPtr IntToUIntPtr
|
||||
|
||||
//
|
||||
// INT32 -> ULONG conversion
|
||||
//
|
||||
#define Int32ToULong IntToULong
|
||||
|
||||
//
|
||||
// INT32 -> ULONG_PTR conversion
|
||||
//
|
||||
#define Int32ToULongPtr IntToULongPtr
|
||||
|
||||
//
|
||||
// INT32 -> DWORD conversion
|
||||
//
|
||||
#define Int32ToDWord IntToULong
|
||||
|
||||
//
|
||||
// INT32 -> DWORD_PTR conversion
|
||||
//
|
||||
#define Int32ToDWordPtr IntToULongPtr
|
||||
|
||||
//
|
||||
// INT32 -> ULONGLONG conversion
|
||||
//
|
||||
#define Int32ToULongLong IntToULongLong
|
||||
|
||||
//
|
||||
// INT32 -> DWORDLONG conversion
|
||||
//
|
||||
#define Int32ToDWordLong IntToULongLong
|
||||
|
||||
//
|
||||
// INT32 -> ULONG64 conversion
|
||||
//
|
||||
#define Int32ToULong64 IntToULongLong
|
||||
|
||||
//
|
||||
// INT32 -> DWORD64 conversion
|
||||
//
|
||||
#define Int32ToDWord64 IntToULongLong
|
||||
|
||||
//
|
||||
// INT32 -> UINT64 conversion
|
||||
//
|
||||
#define Int32ToUInt64 IntToULongLong
|
||||
|
||||
//
|
||||
// INT32 -> size_t conversion
|
||||
//
|
||||
#define Int32ToSizeT IntToUIntPtr
|
||||
|
||||
//
|
||||
// INT32 -> SIZE_T conversion
|
||||
//
|
||||
#define Int32ToSIZET IntToULongPtr
|
||||
|
||||
//
|
||||
// INT_PTR -> INT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
IntPtrToInt8(
|
||||
__inn INT_PTR iOperand,
|
||||
__outt __deref_out_range(==,iOperand) INT8* pi8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((iOperand >= INT8_MIN) && (iOperand <= INT8_MAX))
|
||||
{
|
||||
*pi8Result = (INT8)iOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pi8Result = INT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// INT_PTR -> UCHAR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
IntPtrToUChar(
|
||||
__inn INT_PTR iOperand,
|
||||
__outt __deref_out_range(==,iOperand) UCHAR* pch)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((iOperand >= 0) && (iOperand <= 255))
|
||||
{
|
||||
*pch = (UCHAR)iOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pch = '\0';
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// INT_PTR -> CHAR conversion
|
||||
//
|
||||
__forceinline
|
||||
HRESULT
|
||||
IntPtrToChar(
|
||||
__inn INT_PTR iOperand,
|
||||
__outt __deref_out_range(==,iOperand) CHAR* pch)
|
||||
{
|
||||
#ifdef _CHAR_UNSIGNED
|
||||
return IntPtrToUChar(iOperand, (UCHAR*)pch);
|
||||
#else
|
||||
return IntPtrToInt8(iOperand, (INT8*)pch);
|
||||
#endif // _CHAR_UNSIGNED
|
||||
}
|
||||
|
||||
//
|
||||
// INT_PTR -> UINT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
IntPtrToUInt8(
|
||||
__inn INT_PTR iOperand,
|
||||
__outt __deref_out_range(==,iOperand) UINT8* pui8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((iOperand >= 0) && (iOperand <= UINT8_MAX))
|
||||
{
|
||||
*pui8Result = (UINT8)iOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pui8Result = UINT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// INT_PTR -> BYTE conversion
|
||||
//
|
||||
#define IntPtrToByte IntPtrToUInt8
|
||||
|
||||
//
|
||||
// INT_PTR -> SHORT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
IntPtrToShort(
|
||||
__inn INT_PTR iOperand,
|
||||
__outt __deref_out_range(==,iOperand) SHORT* psResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((iOperand >= SHORT_MIN) && (iOperand <= SHORT_MAX))
|
||||
{
|
||||
*psResult = (SHORT)iOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*psResult = SHORT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// INT_PTR -> INT16 conversion
|
||||
//
|
||||
#define IntPtrToInt16 IntPtrToShort
|
||||
|
||||
//
|
||||
// INT_PTR -> USHORT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
IntPtrToUShort(
|
||||
__inn INT_PTR iOperand,
|
||||
__outt __deref_out_range(==,iOperand) USHORT* pusResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((iOperand >= 0) && (iOperand <= USHORT_MAX))
|
||||
{
|
||||
*pusResult = (USHORT)iOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pusResult = USHORT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// INT_PTR -> UINT16 conversion
|
||||
//
|
||||
#define IntPtrToUInt16 IntPtrToUShort
|
||||
|
||||
//
|
||||
// INT_PTR -> WORD conversion
|
||||
//
|
||||
#define IntPtrToWord IntPtrToUShort
|
||||
|
||||
//
|
||||
// INT_PTR -> INT conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define IntPtrToInt LongLongToInt
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
IntPtrToInt(
|
||||
__inn INT_PTR iOperand,
|
||||
__outt __deref_out_range(==,iOperand) INT* piResult)
|
||||
{
|
||||
*piResult = (INT)iOperand;
|
||||
return S_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// INT_PTR -> INT32 conversion
|
||||
//
|
||||
#define IntPtrToInt32 IntPtrToInt
|
||||
|
||||
//
|
||||
// INT_PTR -> UINT conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define IntPtrToUInt LongLongToUInt
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
IntPtrToUInt(
|
||||
__inn INT_PTR iOperand,
|
||||
__outt __deref_out_range(==,iOperand) UINT* puResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (iOperand >= 0)
|
||||
{
|
||||
*puResult = (UINT)iOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*puResult = UINT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// INT_PTR -> UINT32 conversion
|
||||
//
|
||||
#define IntPtrToUInt32 IntPtrToUInt
|
||||
|
||||
//
|
||||
// INT_PTR -> UINT_PTR conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define IntPtrToUIntPtr LongLongToULongLong
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
IntPtrToUIntPtr(
|
||||
__inn INT_PTR iOperand,
|
||||
__outt __deref_out_range(==,iOperand) UINT_PTR* puResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (iOperand >= 0)
|
||||
{
|
||||
*puResult = (UINT_PTR)iOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*puResult = UINT_PTR_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// INT_PTR -> LONG conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define IntPtrToLong LongLongToLong
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
IntPtrToLong(
|
||||
__inn INT_PTR iOperand,
|
||||
__outt __deref_out_range(==,iOperand) LONG* plResult)
|
||||
{
|
||||
*plResult = (LONG)iOperand;
|
||||
return S_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// INT_PTR -> LONG_PTR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
IntPtrToLongPtr(
|
||||
__inn INT_PTR iOperand,
|
||||
__outt __deref_out_range(==,iOperand) LONG_PTR* plResult)
|
||||
{
|
||||
*plResult = (LONG_PTR)iOperand;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// INT_PTR -> ULONG conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define IntPtrToULong LongLongToULong
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
IntPtrToULong(
|
||||
__inn INT_PTR iOperand,
|
||||
__outt __deref_out_range(==,iOperand) ULONG* pulResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (iOperand >= 0)
|
||||
{
|
||||
*pulResult = (ULONG)iOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pulResult = ULONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// INT_PTR -> ULONG_PTR conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define IntPtrToULongPtr LongLongToULongLong
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
IntPtrToULongPtr(
|
||||
__inn INT_PTR iOperand,
|
||||
__outt __deref_out_range(==,iOperand) ULONG_PTR* pulResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (iOperand >= 0)
|
||||
{
|
||||
*pulResult = (ULONG_PTR)iOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pulResult = ULONG_PTR_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// INT_PTR -> DWORD conversion
|
||||
//
|
||||
#define IntPtrToDWord IntPtrToULong
|
||||
|
||||
//
|
||||
// INT_PTR -> DWORD_PTR conversion
|
||||
//
|
||||
#define IntPtrToDWordPtr IntPtrToULongPtr
|
||||
|
||||
//
|
||||
// INT_PTR -> ULONGLONG conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define IntPtrToULongLong LongLongToULongLong
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
IntPtrToULongLong(
|
||||
__inn INT_PTR iOperand,
|
||||
__outt __deref_out_range(==,iOperand) ULONGLONG* pullResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (iOperand >= 0)
|
||||
{
|
||||
*pullResult = (ULONGLONG)iOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pullResult = ULONGLONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// INT_PTR -> DWORDLONG conversion
|
||||
//
|
||||
#define IntPtrToDWordLong IntPtrToULongLong
|
||||
|
||||
//
|
||||
// INT_PTR -> ULONG64 conversion
|
||||
//
|
||||
#define IntPtrToULong64 IntPtrToULongLong
|
||||
|
||||
//
|
||||
// INT_PTR -> DWORD64 conversion
|
||||
//
|
||||
#define IntPtrToDWord64 IntPtrToULongLong
|
||||
|
||||
//
|
||||
// INT_PTR -> UINT64 conversion
|
||||
//
|
||||
#define IntPtrToUInt64 IntPtrToULongLong
|
||||
|
||||
//
|
||||
// INT_PTR -> size_t conversion
|
||||
//
|
||||
#define IntPtrToSizeT IntPtrToUIntPtr
|
||||
|
||||
//
|
||||
// INT_PTR -> SIZE_T conversion
|
||||
//
|
||||
#define IntPtrToSIZET IntPtrToULongPtr
|
||||
|
||||
//
|
||||
// UINT -> INT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UIntToInt8(
|
||||
__inn UINT uOperand,
|
||||
__outt __deref_out_range(==,uOperand) INT8* pi8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (uOperand <= INT8_MAX)
|
||||
{
|
||||
*pi8Result = (INT8)uOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pi8Result = INT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// UINT -> UCHAR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UIntToUChar(
|
||||
__inn UINT uOperand,
|
||||
__outt __deref_out_range(==,uOperand) UCHAR* pch)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (uOperand <= 255)
|
||||
{
|
||||
*pch = (UCHAR)uOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pch = '\0';
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// UINT -> CHAR conversion
|
||||
//
|
||||
__forceinline
|
||||
HRESULT
|
||||
UIntToChar(
|
||||
__inn UINT uOperand,
|
||||
__outt __deref_out_range(==,uOperand) CHAR* pch)
|
||||
{
|
||||
#ifdef _CHAR_UNSIGNED
|
||||
return UIntToUChar(uOperand, (UCHAR*)pch);
|
||||
#else
|
||||
return UIntToInt8(uOperand, (INT8*)pch);
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// UINT -> UINT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UIntToUInt8(
|
||||
__inn UINT uOperand,
|
||||
__outt __deref_out_range(==,uOperand) UINT8* pui8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (uOperand <= UINT8_MAX)
|
||||
{
|
||||
*pui8Result = (UINT8)uOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pui8Result = UINT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// UINT -> BYTE conversion
|
||||
//
|
||||
#define UIntToByte UIntToUInt8
|
||||
|
||||
//
|
||||
// UINT -> SHORT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UIntToShort(
|
||||
__inn UINT uOperand,
|
||||
__outt __deref_out_range(==,uOperand) SHORT* psResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (uOperand <= SHORT_MAX)
|
||||
{
|
||||
*psResult = (SHORT)uOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*psResult = SHORT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// UINT -> INT16 conversion
|
||||
//
|
||||
#define UIntToInt16 UIntToShort
|
||||
|
||||
//
|
||||
// UINT -> USHORT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UIntToUShort(
|
||||
__inn UINT uOperand,
|
||||
__outt __deref_out_range(==,uOperand) USHORT* pusResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (uOperand <= USHORT_MAX)
|
||||
{
|
||||
*pusResult = (USHORT)uOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pusResult = USHORT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// UINT -> UINT16 conversion
|
||||
//
|
||||
#define UIntToUInt16 UIntToUShort
|
||||
|
||||
//
|
||||
// UINT -> WORD conversion
|
||||
//
|
||||
#define UIntToWord UIntToUShort
|
||||
|
||||
//
|
||||
// UINT -> INT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UIntToInt(
|
||||
__inn UINT uOperand,
|
||||
__outt __deref_out_range(==,uOperand) INT* piResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (uOperand <= INT_MAX)
|
||||
{
|
||||
*piResult = (INT)uOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*piResult = INT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// UINT -> INT32 conversion
|
||||
//
|
||||
#define UIntToInt32 UIntToInt
|
||||
|
||||
//
|
||||
// UINT -> INT_PTR conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
__inline
|
||||
HRESULT
|
||||
UIntToIntPtr(
|
||||
__inn UINT uOperand,
|
||||
__outt __deref_out_range(==,uOperand) INT_PTR* piResult)
|
||||
{
|
||||
*piResult = uOperand;
|
||||
return S_OK;
|
||||
}
|
||||
#else
|
||||
#define UIntToIntPtr UIntToInt
|
||||
#endif
|
||||
|
||||
//
|
||||
// UINT -> LONG conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UIntToLong(
|
||||
__inn UINT uOperand,
|
||||
__outt __deref_out_range(==,uOperand) LONG* plResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (uOperand <= INT32_MAX)
|
||||
{
|
||||
*plResult = (LONG)uOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*plResult = LONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// UINT -> LONG_PTR conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
__inline
|
||||
HRESULT
|
||||
UIntToLongPtr(
|
||||
__inn UINT uOperand,
|
||||
__outt __deref_out_range(==,uOperand) LONG_PTR* plResult)
|
||||
{
|
||||
*plResult = uOperand;
|
||||
return S_OK;
|
||||
}
|
||||
#else
|
||||
#define UIntToLongPtr UIntToLong
|
||||
#endif
|
||||
|
||||
//
|
||||
// UINT -> ptrdiff_t conversion
|
||||
//
|
||||
#define UIntToPtrdiffT UIntToIntPtr
|
||||
|
||||
//
|
||||
// UINT -> SSIZE_T conversion
|
||||
//
|
||||
#define UIntToSSIZET UIntToLongPtr
|
||||
|
||||
//
|
||||
// UINT32 -> CHAR conversion
|
||||
//
|
||||
#define UInt32ToChar UIntToChar
|
||||
|
||||
//
|
||||
// UINT32 -> INT8 conversion
|
||||
//
|
||||
#define UInt32ToInt8 UIntToInt8
|
||||
|
||||
//
|
||||
// UINT32 -> UCHAR conversion
|
||||
//
|
||||
#define UInt32ToUChar UIntToUChar
|
||||
|
||||
//
|
||||
// UINT32 -> UINT8 conversion
|
||||
//
|
||||
#define UInt32ToUInt8 UIntToUInt8
|
||||
|
||||
//
|
||||
// UINT32 -> BYTE conversion
|
||||
//
|
||||
#define UInt32ToByte UInt32ToUInt8
|
||||
|
||||
//
|
||||
// UINT32 -> SHORT conversion
|
||||
//
|
||||
#define UInt32ToShort UIntToShort
|
||||
|
||||
//
|
||||
// UINT32 -> INT16 conversion
|
||||
//
|
||||
#define UInt32ToInt16 UIntToShort
|
||||
|
||||
//
|
||||
// UINT32 -> USHORT conversion
|
||||
//
|
||||
#define UInt32ToUShort UIntToUShort
|
||||
|
||||
//
|
||||
// UINT32 -> UINT16 conversion
|
||||
//
|
||||
#define UInt32ToUInt16 UIntToUShort
|
||||
|
||||
//
|
||||
// UINT32 -> WORD conversion
|
||||
//
|
||||
#define UInt32ToWord UIntToUShort
|
||||
|
||||
//
|
||||
// UINT32 -> INT conversion
|
||||
//
|
||||
#define UInt32ToInt UIntToInt
|
||||
|
||||
//
|
||||
// UINT32 -> INT_PTR conversion
|
||||
//
|
||||
#define UInt32ToIntPtr UIntToIntPtr
|
||||
|
||||
//
|
||||
// UINT32 -> INT32 conversion
|
||||
//
|
||||
#define UInt32ToInt32 UIntToInt
|
||||
|
||||
//
|
||||
// UINT32 -> LONG conversion
|
||||
//
|
||||
#define UInt32ToLong UIntToLong
|
||||
|
||||
//
|
||||
// UINT32 -> LONG_PTR conversion
|
||||
//
|
||||
#define UInt32ToLongPtr UIntToLongPtr
|
||||
|
||||
//
|
||||
// UINT32 -> ptrdiff_t conversion
|
||||
//
|
||||
#define UInt32ToPtrdiffT UIntToPtrdiffT
|
||||
|
||||
//
|
||||
// UINT32 -> SSIZE_T conversion
|
||||
//
|
||||
#define UInt32ToSSIZET UIntToSSIZET
|
||||
|
||||
//
|
||||
// UINT_PTR -> INT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UIntPtrToInt8(
|
||||
__inn UINT_PTR uOperand,
|
||||
__outt __deref_out_range(==,uOperand) INT8* pi8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (uOperand <= INT8_MAX)
|
||||
{
|
||||
*pi8Result = (INT8)uOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pi8Result = INT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// UINT_PTR -> UCHAR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UIntPtrToUChar(
|
||||
__inn UINT_PTR uOperand,
|
||||
__outt __deref_out_range(==,uOperand) UCHAR* pch)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (uOperand <= 255)
|
||||
{
|
||||
*pch = (UCHAR)uOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pch = '\0';
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// UINT_PTR -> CHAR conversion
|
||||
//
|
||||
__forceinline
|
||||
HRESULT
|
||||
UIntPtrToChar(
|
||||
__inn UINT_PTR uOperand,
|
||||
__outt __deref_out_range(==,uOperand) CHAR* pch)
|
||||
{
|
||||
#ifdef _CHAR_UNSIGNED
|
||||
return UIntPtrToUChar(uOperand, (UCHAR*)pch);
|
||||
#else
|
||||
return UIntPtrToInt8(uOperand, (INT8*)pch);
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// UINT_PTR -> UINT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UIntPtrToUInt8(
|
||||
__inn UINT_PTR uOperand,
|
||||
__outt __deref_out_range(==,uOperand) UINT8* pu8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (uOperand <= UINT8_MAX)
|
||||
{
|
||||
*pu8Result = (UINT8)uOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pu8Result = UINT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// UINT_PTR -> BYTE conversion
|
||||
//
|
||||
#define UIntPtrToByte UIntPtrToUInt8
|
||||
|
||||
//
|
||||
// UINT_PTR -> SHORT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UIntPtrToShort(
|
||||
__inn UINT_PTR uOperand,
|
||||
__outt __deref_out_range(==,uOperand) SHORT* psResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (uOperand <= SHORT_MAX)
|
||||
{
|
||||
*psResult = (SHORT)uOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*psResult = SHORT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// UINT_PTR -> INT16 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UIntPtrToInt16(
|
||||
__inn UINT_PTR uOperand,
|
||||
__outt __deref_out_range(==,uOperand) INT16* pi16Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (uOperand <= INT16_MAX)
|
||||
{
|
||||
*pi16Result = (INT16)uOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pi16Result = INT16_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// UINT_PTR -> USHORT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UIntPtrToUShort(
|
||||
__inn UINT_PTR uOperand,
|
||||
__outt __deref_out_range(==,uOperand) USHORT* pusResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (uOperand <= USHORT_MAX)
|
||||
{
|
||||
*pusResult = (USHORT)uOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pusResult = USHORT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// UINT_PTR -> UINT16 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UIntPtrToUInt16(
|
||||
__inn UINT_PTR uOperand,
|
||||
__outt __deref_out_range(==,uOperand) UINT16* pu16Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (uOperand <= UINT16_MAX)
|
||||
{
|
||||
*pu16Result = (UINT16)uOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pu16Result = UINT16_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// UINT_PTR -> WORD conversion
|
||||
//
|
||||
#define UIntPtrToWord UIntPtrToUShort
|
||||
|
||||
//
|
||||
// UINT_PTR -> INT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UIntPtrToInt(
|
||||
__inn UINT_PTR uOperand,
|
||||
__outt __deref_out_range(==,uOperand) INT* piResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (uOperand <= INT_MAX)
|
||||
{
|
||||
*piResult = (INT)uOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*piResult = INT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// UINT_PTR -> INT32 conversion
|
||||
//
|
||||
#define UIntPtrToInt32 UIntPtrToInt
|
||||
|
||||
//
|
||||
// UINT_PTR -> INT_PTR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UIntPtrToIntPtr(
|
||||
__inn UINT_PTR uOperand,
|
||||
__outt __deref_out_range(==,uOperand) INT_PTR* piResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (uOperand <= INT_PTR_MAX)
|
||||
{
|
||||
*piResult = (INT_PTR)uOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*piResult = INT_PTR_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// UINT_PTR -> UINT conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define UIntPtrToUInt ULongLongToUInt
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
UIntPtrToUInt(
|
||||
__inn UINT_PTR uOperand,
|
||||
__outt __deref_out_range(==,uOperand) UINT* puResult)
|
||||
{
|
||||
*puResult = (UINT)uOperand;
|
||||
return S_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// UINT_PTR -> UINT32 conversion
|
||||
//
|
||||
#define UIntPtrToUInt32 UIntPtrToUInt
|
||||
|
||||
//
|
||||
// UINT_PTR -> LONG conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UIntPtrToLong(
|
||||
__inn UINT_PTR uOperand,
|
||||
__outt __deref_out_range(==,uOperand) LONG* plResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (uOperand <= INT32_MAX)
|
||||
{
|
||||
*plResult = (LONG)uOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*plResult = LONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// UINT_PTR -> LONG_PTR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UIntPtrToLongPtr(
|
||||
__inn UINT_PTR uOperand,
|
||||
__outt __deref_out_range(==,uOperand) LONG_PTR* plResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (uOperand <= LONG_PTR_MAX)
|
||||
{
|
||||
*plResult = (LONG_PTR)uOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*plResult = LONG_PTR_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// UINT_PTR -> ULONG conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define UIntPtrToULong ULongLongToULong
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
UIntPtrToULong(
|
||||
__inn UINT_PTR uOperand,
|
||||
__outt __deref_out_range(==,uOperand) ULONG* pulResult)
|
||||
{
|
||||
*pulResult = (ULONG)uOperand;
|
||||
return S_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// UINT_PTR -> DWORD conversion
|
||||
//
|
||||
#define UIntPtrToDWord UIntPtrToULong
|
||||
|
||||
//
|
||||
// UINT_PTR -> LONGLONG conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define UIntPtrToLongLong ULongLongToLongLong
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
UIntPtrToLongLong(
|
||||
__inn UINT_PTR uOperand,
|
||||
__outt __deref_out_range(==,uOperand) LONGLONG* pllResult)
|
||||
{
|
||||
*pllResult = (LONGLONG)uOperand;
|
||||
return S_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// UINT_PTR -> LONG64 conversion
|
||||
//
|
||||
#define UIntPtrToLong64 UIntPtrToLongLong
|
||||
|
||||
//
|
||||
// UINT_PTR -> INT64 conversion
|
||||
//
|
||||
#define UIntPtrToInt64 UIntPtrToLongLong
|
||||
|
||||
//
|
||||
// UINT_PTR -> ptrdiff_t conversion
|
||||
//
|
||||
#define UIntPtrToPtrdiffT UIntPtrToIntPtr
|
||||
|
||||
//
|
||||
// UINT_PTR -> SSIZE_T conversion
|
||||
//
|
||||
#define UIntPtrToSSIZET UIntPtrToLongPtr
|
||||
|
||||
//
|
||||
// LONG -> INT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongToInt8(
|
||||
__inn LONG lOperand,
|
||||
__outt __deref_out_range(==,lOperand) INT8* pi8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((lOperand >= INT8_MIN) && (lOperand <= INT8_MAX))
|
||||
{
|
||||
*pi8Result = (INT8)lOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pi8Result = INT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// LONG -> UCHAR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongToUChar(
|
||||
__inn LONG lOperand,
|
||||
__outt __deref_out_range(==,lOperand) UCHAR* pch)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((lOperand >= 0) && (lOperand <= 255))
|
||||
{
|
||||
*pch = (UCHAR)lOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pch = '\0';
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// LONG -> CHAR conversion
|
||||
//
|
||||
__forceinline
|
||||
HRESULT
|
||||
LongToChar(
|
||||
__inn LONG lOperand,
|
||||
__outt __deref_out_range(==,lOperand) CHAR* pch)
|
||||
{
|
||||
#ifdef _CHAR_UNSIGNED
|
||||
return LongToUChar(lOperand, (UCHAR*)pch);
|
||||
#else
|
||||
return LongToInt8(lOperand, (INT8*)pch);
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// LONG -> UINT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongToUInt8(
|
||||
__inn LONG lOperand,
|
||||
__outt __deref_out_range(==,lOperand) UINT8* pui8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((lOperand >= 0) && (lOperand <= UINT8_MAX))
|
||||
{
|
||||
*pui8Result = (UINT8)lOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pui8Result = UINT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// LONG -> BYTE conversion
|
||||
//
|
||||
#define LongToByte LongToUInt8
|
||||
|
||||
//
|
||||
// LONG -> SHORT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongToShort(
|
||||
__inn LONG lOperand,
|
||||
__outt __deref_out_range(==,lOperand) SHORT* psResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((lOperand >= SHORT_MIN) && (lOperand <= SHORT_MAX))
|
||||
{
|
||||
*psResult = (SHORT)lOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*psResult = SHORT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// LONG -> INT16 conversion
|
||||
//
|
||||
#define LongToInt16 LongToShort
|
||||
|
||||
//
|
||||
// LONG -> USHORT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongToUShort(
|
||||
__inn LONG lOperand,
|
||||
__outt __deref_out_range(==,lOperand) USHORT* pusResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((lOperand >= 0) && (lOperand <= USHORT_MAX))
|
||||
{
|
||||
*pusResult = (USHORT)lOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pusResult = USHORT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// LONG -> UINT16 conversion
|
||||
//
|
||||
#define LongToUInt16 LongToUShort
|
||||
|
||||
//
|
||||
// LONG -> WORD conversion
|
||||
//
|
||||
#define LongToWord LongToUShort
|
||||
|
||||
//
|
||||
// LONG -> INT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongToInt(
|
||||
__inn LONG lOperand,
|
||||
__outt __deref_out_range(==,lOperand) INT* piResult)
|
||||
{
|
||||
C_ASSERT(sizeof(INT) == sizeof(LONG));
|
||||
*piResult = (INT)lOperand;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// LONG -> INT32 conversion
|
||||
//
|
||||
#define LongToInt32 LongToInt
|
||||
|
||||
//
|
||||
// LONG -> INT_PTR conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
__inline
|
||||
HRESULT
|
||||
LongToIntPtr(
|
||||
__inn LONG lOperand,
|
||||
__outt __deref_out_range(==,lOperand) INT_PTR* piResult)
|
||||
{
|
||||
*piResult = lOperand;
|
||||
return S_OK;
|
||||
}
|
||||
#else
|
||||
#define LongToIntPtr LongToInt
|
||||
#endif
|
||||
|
||||
//
|
||||
// LONG -> UINT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongToUInt(
|
||||
__inn LONG lOperand,
|
||||
__outt __deref_out_range(==,lOperand) UINT* puResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (lOperand >= 0)
|
||||
{
|
||||
*puResult = (UINT)lOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*puResult = UINT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// LONG -> UINT32 conversion
|
||||
//
|
||||
#define LongToUInt32 LongToUInt
|
||||
|
||||
//
|
||||
// LONG -> UINT_PTR conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
__inline
|
||||
HRESULT
|
||||
LongToUIntPtr(
|
||||
__inn LONG lOperand,
|
||||
__outt __deref_out_range(==,lOperand) UINT_PTR* puResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (lOperand >= 0)
|
||||
{
|
||||
*puResult = (UINT_PTR)lOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*puResult = UINT_PTR_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
#else
|
||||
#define LongToUIntPtr LongToUInt
|
||||
#endif
|
||||
|
||||
//
|
||||
// LONG -> ULONG conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongToULong(
|
||||
__inn LONG lOperand,
|
||||
__outt __deref_out_range(==,lOperand) ULONG* pulResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (lOperand >= 0)
|
||||
{
|
||||
*pulResult = (ULONG)lOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pulResult = ULONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// LONG -> ULONG_PTR conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
__inline
|
||||
HRESULT
|
||||
LongToULongPtr(
|
||||
__inn LONG lOperand,
|
||||
__outt __deref_out_range(==,lOperand) ULONG_PTR* pulResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (lOperand >= 0)
|
||||
{
|
||||
*pulResult = (ULONG_PTR)lOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pulResult = ULONG_PTR_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
#else
|
||||
#define LongToULongPtr LongToULong
|
||||
#endif
|
||||
|
||||
//
|
||||
// LONG -> DWORD conversion
|
||||
//
|
||||
#define LongToDWord LongToULong
|
||||
|
||||
//
|
||||
// LONG -> DWORD_PTR conversion
|
||||
//
|
||||
#define LongToDWordPtr LongToULongPtr
|
||||
|
||||
//
|
||||
// LONG -> ULONGLONG conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongToULongLong(
|
||||
__inn LONG lOperand,
|
||||
__outt __deref_out_range(==,lOperand) ULONGLONG* pullResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (lOperand >= 0)
|
||||
{
|
||||
*pullResult = (ULONGLONG)lOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pullResult = ULONGLONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// LONG -> DWORDLONG conversion
|
||||
//
|
||||
#define LongToDWordLong LongToULongLong
|
||||
|
||||
//
|
||||
// LONG -> ULONG64 conversion
|
||||
//
|
||||
#define LongToULong64 LongToULongLong
|
||||
|
||||
//
|
||||
// LONG -> DWORD64 conversion
|
||||
//
|
||||
#define LongToDWord64 LongToULongLong
|
||||
|
||||
//
|
||||
// LONG -> UINT64 conversion
|
||||
//
|
||||
#define LongToUInt64 LongToULongLong
|
||||
|
||||
//
|
||||
// LONG -> ptrdiff_t conversion
|
||||
//
|
||||
#define LongToPtrdiffT LongToIntPtr
|
||||
|
||||
//
|
||||
// LONG -> size_t conversion
|
||||
//
|
||||
#define LongToSizeT LongToUIntPtr
|
||||
|
||||
//
|
||||
// LONG -> SIZE_T conversion
|
||||
//
|
||||
#define LongToSIZET LongToULongPtr
|
||||
|
||||
//
|
||||
// LONG_PTR -> INT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongPtrToInt8(
|
||||
__inn LONG_PTR lOperand,
|
||||
__outt __deref_out_range(==,lOperand) INT8* pi8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((lOperand >= INT8_MIN) && (lOperand <= INT8_MAX))
|
||||
{
|
||||
*pi8Result = (INT8)lOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pi8Result = INT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// LONG_PTR -> UCHAR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongPtrToUChar(
|
||||
__inn LONG_PTR lOperand,
|
||||
__outt __deref_out_range(==,lOperand) UCHAR* pch)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((lOperand >= 0) && (lOperand <= 255))
|
||||
{
|
||||
*pch = (UCHAR)lOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pch = '\0';
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// LONG_PTR -> CHAR conversion
|
||||
//
|
||||
__forceinline
|
||||
HRESULT
|
||||
LongPtrToChar(
|
||||
__inn LONG_PTR lOperand,
|
||||
__outt __deref_out_range(==,lOperand) CHAR* pch)
|
||||
{
|
||||
#ifdef _CHAR_UNSIGNED
|
||||
return LongPtrToUChar(lOperand, (UCHAR*)pch);
|
||||
#else
|
||||
return LongPtrToInt8(lOperand, (INT8*)pch);
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// LONG_PTR -> UINT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongPtrToUInt8(
|
||||
__inn LONG_PTR lOperand,
|
||||
__outt __deref_out_range(==,lOperand) UINT8* pui8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((lOperand >= 0) && (lOperand <= UINT8_MAX))
|
||||
{
|
||||
*pui8Result = (UINT8)lOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pui8Result = UINT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// LONG_PTR -> BYTE conversion
|
||||
//
|
||||
#define LongPtrToByte LongPtrToUInt8
|
||||
|
||||
//
|
||||
// LONG_PTR -> SHORT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongPtrToShort(
|
||||
__inn LONG_PTR lOperand,
|
||||
__outt __deref_out_range(==,lOperand) SHORT* psResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((lOperand >= SHORT_MIN) && (lOperand <= SHORT_MAX))
|
||||
{
|
||||
*psResult = (SHORT)lOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*psResult = SHORT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// LONG_PTR -> INT16 conversion
|
||||
//
|
||||
#define LongPtrToInt16 LongPtrToShort
|
||||
|
||||
//
|
||||
// LONG_PTR -> USHORT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongPtrToUShort(
|
||||
__inn LONG_PTR lOperand,
|
||||
__outt __deref_out_range(==,lOperand) USHORT* pusResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((lOperand >= 0) && (lOperand <= USHORT_MAX))
|
||||
{
|
||||
*pusResult = (USHORT)lOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pusResult = USHORT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// LONG_PTR -> UINT16 conversion
|
||||
//
|
||||
#define LongPtrToUInt16 LongPtrToUShort
|
||||
|
||||
//
|
||||
// LONG_PTR -> WORD conversion
|
||||
//
|
||||
#define LongPtrToWord LongPtrToUShort
|
||||
|
||||
//
|
||||
// LONG_PTR -> INT conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define LongPtrToInt LongLongToInt
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
LongPtrToInt(
|
||||
__inn LONG_PTR lOperand,
|
||||
__outt __deref_out_range(==,lOperand) INT* piResult)
|
||||
{
|
||||
C_ASSERT(sizeof(INT) == sizeof(LONG_PTR));
|
||||
*piResult = (INT)lOperand;
|
||||
return S_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// LONG_PTR -> INT32 conversion
|
||||
//
|
||||
#define LongPtrToInt32 LongPtrToInt
|
||||
|
||||
//
|
||||
// LONG_PTR -> INT_PTR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongPtrToIntPtr(
|
||||
__inn LONG_PTR lOperand,
|
||||
__outt __deref_out_range(==,lOperand) INT_PTR* piResult)
|
||||
{
|
||||
C_ASSERT(sizeof(LONG_PTR) == sizeof(INT_PTR));
|
||||
*piResult = (INT_PTR)lOperand;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// LONG_PTR -> UINT conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define LongPtrToUInt LongLongToUInt
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
LongPtrToUInt(
|
||||
__inn LONG_PTR lOperand,
|
||||
__outt __deref_out_range(==,lOperand) UINT* puResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (lOperand >= 0)
|
||||
{
|
||||
*puResult = (UINT)lOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*puResult = UINT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// LONG_PTR -> UINT32 conversion
|
||||
//
|
||||
#define LongPtrToUInt32 LongPtrToUInt
|
||||
|
||||
//
|
||||
// LONG_PTR -> UINT_PTR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongPtrToUIntPtr(
|
||||
__inn LONG_PTR lOperand,
|
||||
__outt __deref_out_range(==,lOperand) UINT_PTR* puResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (lOperand >= 0)
|
||||
{
|
||||
*puResult = (UINT_PTR)lOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*puResult = UINT_PTR_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// LONG_PTR -> LONG conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define LongPtrToLong LongLongToLong
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
LongPtrToLong(
|
||||
__inn LONG_PTR lOperand,
|
||||
__outt __deref_out_range(==,lOperand) LONG* plResult)
|
||||
{
|
||||
*plResult = (LONG)lOperand;
|
||||
return S_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// LONG_PTR -> ULONG conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define LongPtrToULong LongLongToULong
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
LongPtrToULong(
|
||||
__inn LONG_PTR lOperand,
|
||||
__outt __deref_out_range(==,lOperand) ULONG* pulResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (lOperand >= 0)
|
||||
{
|
||||
*pulResult = (ULONG)lOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pulResult = ULONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// LONG_PTR -> ULONG_PTR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongPtrToULongPtr(
|
||||
__inn LONG_PTR lOperand,
|
||||
__outt __deref_out_range(==,lOperand) ULONG_PTR* pulResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (lOperand >= 0)
|
||||
{
|
||||
*pulResult = (ULONG_PTR)lOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pulResult = ULONG_PTR_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// LONG_PTR -> DWORD conversion
|
||||
//
|
||||
#define LongPtrToDWord LongPtrToULong
|
||||
|
||||
//
|
||||
// LONG_PTR -> DWORD_PTR conversion
|
||||
//
|
||||
#define LongPtrToDWordPtr LongPtrToULongPtr
|
||||
|
||||
//
|
||||
// LONG_PTR -> ULONGLONG conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongPtrToULongLong(
|
||||
__inn LONG_PTR lOperand,
|
||||
__outt __deref_out_range(==,lOperand) ULONGLONG* pullResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (lOperand >= 0)
|
||||
{
|
||||
*pullResult = (ULONGLONG)lOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pullResult = ULONGLONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// LONG_PTR -> DWORDLONG conversion
|
||||
//
|
||||
#define LongPtrToDWordLong LongPtrToULongLong
|
||||
|
||||
//
|
||||
// LONG_PTR -> ULONG64 conversion
|
||||
//
|
||||
#define LongPtrToULong64 LongPtrToULongLong
|
||||
|
||||
//
|
||||
// LONG_PTR -> DWORD64 conversion
|
||||
//
|
||||
#define LongPtrToDWord64 LongPtrToULongLong
|
||||
|
||||
//
|
||||
// LONG_PTR -> UINT64 conversion
|
||||
//
|
||||
#define LongPtrToUInt64 LongPtrToULongLong
|
||||
|
||||
//
|
||||
// LONG_PTR -> size_t conversion
|
||||
//
|
||||
#define LongPtrToSizeT LongPtrToUIntPtr
|
||||
|
||||
//
|
||||
// LONG_PTR -> SIZE_T conversion
|
||||
//
|
||||
#define LongPtrToSIZET LongPtrToULongPtr
|
||||
|
||||
//
|
||||
// ULONG -> INT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongToInt8(
|
||||
__inn ULONG ulOperand,
|
||||
__outt __deref_out_range(==,ulOperand) INT8* pi8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ulOperand <= INT8_MAX)
|
||||
{
|
||||
*pi8Result = (INT8)ulOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pi8Result = INT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONG -> UCHAR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongToUChar(
|
||||
__inn ULONG ulOperand,
|
||||
__outt __deref_out_range(==,ulOperand) UCHAR* pch)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ulOperand <= 255)
|
||||
{
|
||||
*pch = (UCHAR)ulOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pch = '\0';
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONG -> CHAR conversion
|
||||
//
|
||||
__forceinline
|
||||
HRESULT
|
||||
ULongToChar(
|
||||
__inn ULONG ulOperand,
|
||||
__outt __deref_out_range(==,ulOperand) CHAR* pch)
|
||||
{
|
||||
#ifdef _CHAR_UNSIGNED
|
||||
return ULongToUChar(ulOperand, (UCHAR*)pch);
|
||||
#else
|
||||
return ULongToInt8(ulOperand, (INT8*)pch);
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// ULONG -> UINT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongToUInt8(
|
||||
__inn ULONG ulOperand,
|
||||
__outt __deref_out_range(==,ulOperand) UINT8* pui8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ulOperand <= UINT8_MAX)
|
||||
{
|
||||
*pui8Result = (UINT8)ulOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pui8Result = UINT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONG -> BYTE conversion
|
||||
//
|
||||
#define ULongToByte ULongToUInt8
|
||||
|
||||
//
|
||||
// ULONG -> SHORT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongToShort(
|
||||
__inn ULONG ulOperand,
|
||||
__outt __deref_out_range(==,ulOperand) SHORT* psResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ulOperand <= SHORT_MAX)
|
||||
{
|
||||
*psResult = (SHORT)ulOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*psResult = SHORT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONG -> INT16 conversion
|
||||
//
|
||||
#define ULongToInt16 ULongToShort
|
||||
|
||||
//
|
||||
// ULONG -> USHORT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongToUShort(
|
||||
__inn ULONG ulOperand,
|
||||
__outt __deref_out_range(==,ulOperand) USHORT* pusResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ulOperand <= USHORT_MAX)
|
||||
{
|
||||
*pusResult = (USHORT)ulOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pusResult = USHORT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONG -> UINT16 conversion
|
||||
//
|
||||
#define ULongToUInt16 ULongToUShort
|
||||
|
||||
//
|
||||
// ULONG -> WORD conversion
|
||||
//
|
||||
#define ULongToWord ULongToUShort
|
||||
|
||||
//
|
||||
// ULONG -> INT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongToInt(
|
||||
__inn ULONG ulOperand,
|
||||
__outt __deref_out_range(==,ulOperand) INT* piResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ulOperand <= INT_MAX)
|
||||
{
|
||||
*piResult = (INT)ulOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*piResult = INT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONG -> INT32 conversion
|
||||
//
|
||||
#define ULongToInt32 ULongToInt
|
||||
|
||||
//
|
||||
// ULONG -> INT_PTR conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
__inline
|
||||
HRESULT
|
||||
ULongToIntPtr(
|
||||
__inn ULONG ulOperand,
|
||||
__outt __deref_out_range(==,ulOperand) INT_PTR* piResult)
|
||||
{
|
||||
*piResult = (INT_PTR)ulOperand;
|
||||
return S_OK;
|
||||
}
|
||||
#else
|
||||
#define ULongToIntPtr ULongToInt
|
||||
#endif
|
||||
|
||||
//
|
||||
// ULONG -> UINT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongToUInt(
|
||||
__inn ULONG ulOperand,
|
||||
__outt __deref_out_range(==,ulOperand) UINT* puResult)
|
||||
{
|
||||
//C_ASSERT(sizeof(ULONG) == sizeof(UINT));
|
||||
*puResult = (UINT)ulOperand;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONG -> UINT32 conversion
|
||||
//
|
||||
#define ULongToUInt32 ULongToUInt
|
||||
|
||||
//
|
||||
// ULONG -> UINT_PTR conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
__inline
|
||||
HRESULT
|
||||
ULongToUIntPtr(
|
||||
__inn ULONG ulOperand,
|
||||
__outt __deref_out_range(==,ulOperand) UINT_PTR* puiResult)
|
||||
{
|
||||
C_ASSERT(sizeof(UINT_PTR) > sizeof(ULONG));
|
||||
*puiResult = (UINT_PTR)ulOperand;
|
||||
return S_OK;
|
||||
}
|
||||
#else
|
||||
#define ULongToUIntPtr ULongToUInt
|
||||
#endif
|
||||
|
||||
//
|
||||
// ULONG -> LONG conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongToLong(
|
||||
__inn ULONG ulOperand,
|
||||
__outt __deref_out_range(==,ulOperand) LONG* plResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ulOperand <= INT32_MAX)
|
||||
{
|
||||
*plResult = (LONG)ulOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*plResult = LONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONG -> LONG_PTR conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
__inline
|
||||
HRESULT
|
||||
ULongToLongPtr(
|
||||
__inn ULONG ulOperand,
|
||||
__outt __deref_out_range(==,ulOperand) LONG_PTR* plResult)
|
||||
{
|
||||
C_ASSERT(sizeof(LONG_PTR) > sizeof(ULONG));
|
||||
*plResult = (LONG_PTR)ulOperand;
|
||||
return S_OK;
|
||||
}
|
||||
#else
|
||||
#define ULongToLongPtr ULongToLong
|
||||
#endif
|
||||
|
||||
//
|
||||
// ULONG -> ptrdiff_t conversion
|
||||
//
|
||||
#define ULongToPtrdiffT ULongToIntPtr
|
||||
|
||||
//
|
||||
// ULONG -> SSIZE_T conversion
|
||||
//
|
||||
#define ULongToSSIZET ULongToLongPtr
|
||||
|
||||
//
|
||||
// ULONG_PTR -> INT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongPtrToInt8(
|
||||
__inn ULONG_PTR ulOperand,
|
||||
__outt __deref_out_range(==,ulOperand) INT8* pi8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ulOperand <= INT8_MAX)
|
||||
{
|
||||
*pi8Result = (INT8)ulOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pi8Result = INT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONG_PTR -> UCHAR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongPtrToUChar(
|
||||
__inn ULONG_PTR ulOperand,
|
||||
__outt __deref_out_range(==,ulOperand) UCHAR* pch)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ulOperand <= 255)
|
||||
{
|
||||
*pch = (UCHAR)ulOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pch = '\0';
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONG_PTR -> CHAR conversion
|
||||
//
|
||||
__forceinline
|
||||
HRESULT
|
||||
ULongPtrToChar(
|
||||
__inn ULONG_PTR ulOperand,
|
||||
__outt __deref_out_range(==,ulOperand) CHAR* pch)
|
||||
{
|
||||
#ifdef _CHAR_UNSIGNED
|
||||
return ULongPtrToUChar(ulOperand, (UCHAR*)pch);
|
||||
#else
|
||||
return ULongPtrToInt8(ulOperand, (INT8*)pch);
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// ULONG_PTR -> UINT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongPtrToUInt8(
|
||||
__inn ULONG_PTR ulOperand,
|
||||
__outt __deref_out_range(==,ulOperand) UINT8* pui8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ulOperand <= UINT8_MAX)
|
||||
{
|
||||
*pui8Result = (UINT8)ulOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pui8Result = UINT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONG_PTR -> BYTE conversion
|
||||
//
|
||||
#define ULongPtrToByte ULongPtrToUInt8
|
||||
|
||||
//
|
||||
// ULONG_PTR -> SHORT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongPtrToShort(
|
||||
__inn ULONG_PTR ulOperand,
|
||||
__outt __deref_out_range(==,ulOperand) SHORT* psResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ulOperand <= SHORT_MAX)
|
||||
{
|
||||
*psResult = (SHORT)ulOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*psResult = SHORT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONG_PTR -> INT16 conversion
|
||||
//
|
||||
#define ULongPtrToInt16 ULongPtrToShort
|
||||
|
||||
//
|
||||
// ULONG_PTR -> USHORT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongPtrToUShort(
|
||||
__inn ULONG_PTR ulOperand,
|
||||
__outt __deref_out_range(==,ulOperand) USHORT* pusResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ulOperand <= USHORT_MAX)
|
||||
{
|
||||
*pusResult = (USHORT)ulOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pusResult = USHORT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONG_PTR -> UINT16 conversion
|
||||
//
|
||||
#define ULongPtrToUInt16 ULongPtrToUShort
|
||||
|
||||
//
|
||||
// ULONG_PTR -> WORD conversion
|
||||
//
|
||||
#define ULongPtrToWord ULongPtrToUShort
|
||||
|
||||
//
|
||||
// ULONG_PTR -> INT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongPtrToInt(
|
||||
__inn ULONG_PTR ulOperand,
|
||||
__outt __deref_out_range(==,ulOperand) INT* piResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ulOperand <= INT_MAX)
|
||||
{
|
||||
*piResult = (INT)ulOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*piResult = INT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONG_PTR -> INT32 conversion
|
||||
//
|
||||
#define ULongPtrToInt32 ULongPtrToInt
|
||||
|
||||
//
|
||||
// ULONG_PTR -> INT_PTR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongPtrToIntPtr(
|
||||
__inn ULONG_PTR ulOperand,
|
||||
__outt __deref_out_range(==,ulOperand) INT_PTR* piResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ulOperand <= INT_PTR_MAX)
|
||||
{
|
||||
*piResult = (INT_PTR)ulOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*piResult = INT_PTR_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONG_PTR -> UINT conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define ULongPtrToUInt ULongLongToUInt
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
ULongPtrToUInt(
|
||||
__inn ULONG_PTR ulOperand,
|
||||
__outt __deref_out_range(==,ulOperand) UINT* puResult)
|
||||
{
|
||||
C_ASSERT(sizeof(ULONG_PTR) == sizeof(UINT));
|
||||
*puResult = (UINT)ulOperand;
|
||||
return S_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// ULONG_PTR -> UINT32 conversion
|
||||
//
|
||||
#define ULongPtrToUInt32 ULongPtrToUInt
|
||||
|
||||
//
|
||||
// ULONG_PTR -> UINT_PTR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongPtrToUIntPtr(
|
||||
__inn ULONG_PTR ulOperand,
|
||||
__outt __deref_out_range(==,ulOperand) UINT_PTR* puResult)
|
||||
{
|
||||
*puResult = (UINT_PTR)ulOperand;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONG_PTR -> LONG conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongPtrToLong(
|
||||
__inn ULONG_PTR ulOperand,
|
||||
__outt __deref_out_range(==,ulOperand) LONG* plResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ulOperand <= INT32_MAX)
|
||||
{
|
||||
*plResult = (LONG)ulOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*plResult = LONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONG_PTR -> LONG_PTR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongPtrToLongPtr(
|
||||
__inn ULONG_PTR ulOperand,
|
||||
__outt __deref_out_range(==,ulOperand) LONG_PTR* plResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ulOperand <= LONG_PTR_MAX)
|
||||
{
|
||||
*plResult = (LONG_PTR)ulOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*plResult = LONG_PTR_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONG_PTR -> ULONG conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define ULongPtrToULong ULongLongToULong
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
ULongPtrToULong(
|
||||
__inn ULONG_PTR ulOperand,
|
||||
__outt __deref_out_range(==,ulOperand) ULONG* pulResult)
|
||||
{
|
||||
*pulResult = (ULONG)ulOperand;
|
||||
return S_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// ULONG_PTR -> DWORD conversion
|
||||
//
|
||||
#define ULongPtrToDWord ULongPtrToULong
|
||||
|
||||
//
|
||||
// ULONG_PTR -> LONGLONG conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define ULongPtrToLongLong ULongLongToLongLong
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
ULongPtrToLongLong(
|
||||
__inn ULONG_PTR ulOperand,
|
||||
__outt __deref_out_range(==,ulOperand) LONGLONG* pllResult)
|
||||
{
|
||||
*pllResult = (LONGLONG)ulOperand;
|
||||
return S_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// ULONG_PTR -> LONG64 conversion
|
||||
//
|
||||
#define ULongPtrToLong64 ULongPtrToLongLong
|
||||
|
||||
//
|
||||
// ULONG_PTR -> INT64
|
||||
//
|
||||
#define ULongPtrToInt64 ULongPtrToLongLong
|
||||
|
||||
//
|
||||
// ULONG_PTR -> ptrdiff_t conversion
|
||||
//
|
||||
#define ULongPtrToPtrdiffT ULongPtrToIntPtr
|
||||
|
||||
//
|
||||
// ULONG_PTR -> SSIZE_T conversion
|
||||
//
|
||||
#define ULongPtrToSSIZET ULongPtrToLongPtr
|
||||
|
||||
//
|
||||
// DWORD -> INT8 conversion
|
||||
//
|
||||
#define DWordToInt8 ULongToInt8
|
||||
|
||||
//
|
||||
// DWORD -> CHAR conversion
|
||||
//
|
||||
#define DWordToChar ULongToChar
|
||||
|
||||
//
|
||||
// DWORD -> UCHAR conversion
|
||||
//
|
||||
#define DWordToUChar ULongToUChar
|
||||
|
||||
//
|
||||
// DWORD -> UINT8 conversion
|
||||
//
|
||||
#define DWordToUInt8 ULongToUInt8
|
||||
|
||||
//
|
||||
// DWORD -> BYTE conversion
|
||||
//
|
||||
#define DWordToByte ULongToUInt8
|
||||
|
||||
//
|
||||
// DWORD -> SHORT conversion
|
||||
//
|
||||
#define DWordToShort ULongToShort
|
||||
|
||||
//
|
||||
// DWORD -> INT16 conversion
|
||||
//
|
||||
#define DWordToInt16 ULongToShort
|
||||
|
||||
//
|
||||
// DWORD -> USHORT conversion
|
||||
//
|
||||
#define DWordToUShort ULongToUShort
|
||||
|
||||
//
|
||||
// DWORD -> UINT16 conversion
|
||||
//
|
||||
#define DWordToUInt16 ULongToUShort
|
||||
|
||||
//
|
||||
// DWORD -> WORD conversion
|
||||
//
|
||||
#define DWordToWord ULongToUShort
|
||||
|
||||
//
|
||||
// DWORD -> INT conversion
|
||||
//
|
||||
#define DWordToInt ULongToInt
|
||||
|
||||
//
|
||||
// DWORD -> INT32 conversion
|
||||
//
|
||||
#define DWordToInt32 ULongToInt
|
||||
|
||||
//
|
||||
// DWORD -> INT_PTR conversion
|
||||
//
|
||||
#define DWordToIntPtr ULongToIntPtr
|
||||
|
||||
//
|
||||
// DWORD -> UINT conversion
|
||||
//
|
||||
#define DWordToUInt ULongToUInt
|
||||
|
||||
//
|
||||
// DWORD -> UINT32 conversion
|
||||
//
|
||||
#define DWordToUInt32 ULongToUInt
|
||||
|
||||
//
|
||||
// DWORD -> UINT_PTR conversion
|
||||
//
|
||||
#define DWordToUIntPtr ULongToUIntPtr
|
||||
|
||||
//
|
||||
// DWORD -> LONG conversion
|
||||
//
|
||||
#define DWordToLong ULongToLong
|
||||
|
||||
//
|
||||
// DWORD -> LONG_PTR conversion
|
||||
//
|
||||
#define DWordToLongPtr ULongToLongPtr
|
||||
|
||||
//
|
||||
// DWORD -> ptrdiff_t conversion
|
||||
//
|
||||
#define DWordToPtrdiffT ULongToIntPtr
|
||||
|
||||
//
|
||||
// DWORD -> SSIZE_T conversion
|
||||
//
|
||||
#define DWordToSSIZET ULongToLongPtr
|
||||
|
||||
//
|
||||
// DWORD_PTR -> INT8 conversion
|
||||
//
|
||||
#define DWordPtrToInt8 ULongPtrToInt8
|
||||
|
||||
//
|
||||
// DWORD_PTR -> UCHAR conversion
|
||||
//
|
||||
#define DWordPtrToUChar ULongPtrToUChar
|
||||
|
||||
//
|
||||
// DWORD_PTR -> CHAR conversion
|
||||
//
|
||||
#define DWordPtrToChar ULongPtrToChar
|
||||
|
||||
//
|
||||
// DWORD_PTR -> UINT8 conversion
|
||||
//
|
||||
#define DWordPtrToUInt8 ULongPtrToUInt8
|
||||
|
||||
//
|
||||
// DWORD_PTR -> BYTE conversion
|
||||
//
|
||||
#define DWordPtrToByte ULongPtrToUInt8
|
||||
|
||||
//
|
||||
// DWORD_PTR -> SHORT conversion
|
||||
//
|
||||
#define DWordPtrToShort ULongPtrToShort
|
||||
|
||||
//
|
||||
// DWORD_PTR -> INT16 conversion
|
||||
//
|
||||
#define DWordPtrToInt16 ULongPtrToShort
|
||||
|
||||
//
|
||||
// DWORD_PTR -> USHORT conversion
|
||||
//
|
||||
#define DWordPtrToUShort ULongPtrToUShort
|
||||
|
||||
//
|
||||
// DWORD_PTR -> UINT16 conversion
|
||||
//
|
||||
#define DWordPtrToUInt16 ULongPtrToUShort
|
||||
|
||||
//
|
||||
// DWORD_PTR -> WORD conversion
|
||||
//
|
||||
#define DWordPtrToWord ULongPtrToUShort
|
||||
|
||||
//
|
||||
// DWORD_PTR -> INT conversion
|
||||
//
|
||||
#define DWordPtrToInt ULongPtrToInt
|
||||
|
||||
//
|
||||
// DWORD_PTR -> INT32 conversion
|
||||
//
|
||||
#define DWordPtrToInt32 ULongPtrToInt
|
||||
|
||||
//
|
||||
// DWORD_PTR -> INT_PTR conversion
|
||||
//
|
||||
#define DWordPtrToIntPtr ULongPtrToIntPtr
|
||||
|
||||
//
|
||||
// DWORD_PTR -> UINT conversion
|
||||
//
|
||||
#define DWordPtrToUInt ULongPtrToUInt
|
||||
|
||||
//
|
||||
// DWORD_PTR -> UINT32 conversion
|
||||
//
|
||||
#define DWordPtrToUInt32 ULongPtrToUInt
|
||||
|
||||
//
|
||||
// DWODR_PTR -> UINT_PTR conversion
|
||||
//
|
||||
#define DWordPtrToUIntPtr ULongPtrToUIntPtr
|
||||
|
||||
//
|
||||
// DWORD_PTR -> LONG conversion
|
||||
//
|
||||
#define DWordPtrToLong ULongPtrToLong
|
||||
|
||||
//
|
||||
// DWORD_PTR -> LONG_PTR conversion
|
||||
//
|
||||
#define DWordPtrToLongPtr ULongPtrToLongPtr
|
||||
|
||||
//
|
||||
// DWORD_PTR -> ULONG conversion
|
||||
//
|
||||
#define DWordPtrToULong ULongPtrToULong
|
||||
|
||||
//
|
||||
// DWORD_PTR -> DWORD conversion
|
||||
//
|
||||
#define DWordPtrToDWord ULongPtrToULong
|
||||
|
||||
//
|
||||
// DWORD_PTR -> LONGLONG conversion
|
||||
//
|
||||
#define DWordPtrToLongLong ULongPtrToLongLong
|
||||
|
||||
//
|
||||
// DWORD_PTR -> LONG64 conversion
|
||||
//
|
||||
#define DWordPtrToLong64 ULongPtrToLongLong
|
||||
|
||||
//
|
||||
// DWORD_PTR -> INT64 conversion
|
||||
//
|
||||
#define DWordPtrToInt64 ULongPtrToLongLong
|
||||
|
||||
//
|
||||
// DWORD_PTR -> ptrdiff_t conversion
|
||||
//
|
||||
#define DWordPtrToPtrdiffT ULongPtrToIntPtr
|
||||
|
||||
//
|
||||
// DWORD_PTR -> SSIZE_T conversion
|
||||
//
|
||||
#define DWordPtrToSSIZET ULongPtrToLongPtr
|
||||
|
||||
//
|
||||
// LONGLONG -> INT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongLongToInt8(
|
||||
__inn LONGLONG llOperand,
|
||||
__outt __deref_out_range(==,llOperand) INT8* pi8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((llOperand >= INT8_MIN) && (llOperand <= INT8_MAX))
|
||||
{
|
||||
*pi8Result = (INT8)llOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pi8Result = INT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// LONGLONG -> UCHAR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongLongToUChar(
|
||||
__inn LONGLONG llOperand,
|
||||
__outt __deref_out_range(==,llOperand) UCHAR* pch)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((llOperand >= 0) && (llOperand <= 255))
|
||||
{
|
||||
*pch = (UCHAR)llOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pch = '\0';
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// LONGLONG -> CHAR conversion
|
||||
//
|
||||
__forceinline
|
||||
HRESULT
|
||||
LongLongToChar(
|
||||
__inn LONGLONG llOperand,
|
||||
__outt __deref_out_range(==,llOperand) CHAR* pch)
|
||||
{
|
||||
#ifdef _CHAR_UNSIGNED
|
||||
return LongLongToUChar(llOperand, (UCHAR*)pch);
|
||||
#else
|
||||
return LongLongToInt8(llOperand, (INT8*)pch);
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// LONGLONG -> UINT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongLongToUInt8(
|
||||
__inn LONGLONG llOperand,
|
||||
__outt __deref_out_range(==,llOperand) UINT8* pu8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((llOperand >= 0) && (llOperand <= UINT8_MAX))
|
||||
{
|
||||
*pu8Result = (UINT8)llOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pu8Result = UINT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// LONGLONG -> BYTE conversion
|
||||
//
|
||||
#define LongLongToByte LongLongToUInt8
|
||||
|
||||
//
|
||||
// LONGLONG -> SHORT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongLongToShort(
|
||||
__inn LONGLONG llOperand,
|
||||
__outt __deref_out_range(==,llOperand) SHORT* psResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((llOperand >= SHORT_MIN) && (llOperand <= SHORT_MAX))
|
||||
{
|
||||
*psResult = (SHORT)llOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*psResult = SHORT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// LONGLONG -> INT16 conversion
|
||||
//
|
||||
#define LongLongToInt16 LongLongToShort
|
||||
|
||||
//
|
||||
// LONGLONG -> USHORT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongLongToUShort(
|
||||
__inn LONGLONG llOperand,
|
||||
__outt __deref_out_range(==,llOperand) USHORT* pusResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((llOperand >= 0) && (llOperand <= USHORT_MAX))
|
||||
{
|
||||
*pusResult = (USHORT)llOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pusResult = USHORT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// LONGLONG -> UINT16 conversion
|
||||
//
|
||||
#define LongLongToUInt16 LongLongToUShort
|
||||
|
||||
//
|
||||
// LONGLONG -> WORD conversion
|
||||
//
|
||||
#define LongLongToWord LongLongToUShort
|
||||
|
||||
//
|
||||
// LONGLONG -> INT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongLongToInt(
|
||||
__inn LONGLONG llOperand,
|
||||
__outt __deref_out_range(==,llOperand) INT* piResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((llOperand >= INT_MIN) && (llOperand <= INT_MAX))
|
||||
{
|
||||
*piResult = (INT)llOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*piResult = INT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// LONGLONG -> INT32 conversion
|
||||
//
|
||||
#define LongLongToInt32 LongLongToInt
|
||||
|
||||
//
|
||||
// LONGLONG -> INT_PTR conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
__inline
|
||||
HRESULT
|
||||
LongLongToIntPtr(
|
||||
__inn LONGLONG llOperand,
|
||||
__outt __deref_out_range(==,llOperand) INT_PTR* piResult)
|
||||
{
|
||||
*piResult = llOperand;
|
||||
return S_OK;
|
||||
}
|
||||
#else
|
||||
#define LongLongToIntPtr LongLongToInt
|
||||
#endif
|
||||
|
||||
//
|
||||
// LONGLONG -> UINT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongLongToUInt(
|
||||
__inn LONGLONG llOperand,
|
||||
__outt __deref_out_range(==,llOperand) UINT* puResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((llOperand >= 0) && (llOperand <= UINT_MAX))
|
||||
{
|
||||
*puResult = (UINT)llOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*puResult = UINT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// LONGLONG -> UINT32 conversion
|
||||
//
|
||||
#define LongLongToUInt32 LongLongToUInt
|
||||
|
||||
//
|
||||
// LONGLONG -> UINT_PTR conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define LongLongToUIntPtr LongLongToULongLong
|
||||
#else
|
||||
#define LongLongToUIntPtr LongLongToUInt
|
||||
#endif
|
||||
|
||||
//
|
||||
// LONGLONG -> LONG conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongLongToLong(
|
||||
__inn LONGLONG llOperand,
|
||||
__outt __deref_out_range(==,llOperand) LONG* plResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((llOperand >= INT32_MIN) && (llOperand <= INT32_MAX))
|
||||
{
|
||||
*plResult = (LONG)llOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*plResult = LONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// LONGLONG -> LONG_PTR conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
__inline
|
||||
HRESULT
|
||||
LongLongToLongPtr(
|
||||
__inn LONGLONG llOperand,
|
||||
__outt __deref_out_range(==,llOperand) LONG_PTR* plResult)
|
||||
{
|
||||
*plResult = (LONG_PTR)llOperand;
|
||||
return S_OK;
|
||||
}
|
||||
#else
|
||||
#define LongLongToLongPtr LongLongToLong
|
||||
#endif
|
||||
|
||||
//
|
||||
// LONGLONG -> ULONG conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongLongToULong(
|
||||
__inn LONGLONG llOperand,
|
||||
__outt __deref_out_range(==,llOperand) ULONG* pulResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((llOperand >= 0) && (llOperand <= (LONGLONG)(ULONGLONG)UINT32_MAX))
|
||||
{
|
||||
*pulResult = (ULONG)llOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pulResult = ULONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// LONGLONG -> ULONG_PTR conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define LongLongToULongPtr LongLongToULongLong
|
||||
#else
|
||||
#define LongLongToULongPtr LongLongToULong
|
||||
#endif
|
||||
|
||||
//
|
||||
// LONGLONG -> DWORD conversion
|
||||
//
|
||||
#define LongLongToDWord LongLongToULong
|
||||
|
||||
//
|
||||
// LONGLONG -> DWORD_PTR conversion
|
||||
//
|
||||
#define LongLongToDWordPtr LongLongToULongPtr
|
||||
|
||||
//
|
||||
// LONGLONG -> ULONGLONG conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
LongLongToULongLong(
|
||||
__inn LONGLONG llOperand,
|
||||
__outt __deref_out_range(==,llOperand) ULONGLONG* pullResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (llOperand >= 0)
|
||||
{
|
||||
*pullResult = (ULONGLONG)llOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pullResult = ULONGLONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// LONGLONG -> DWORDLONG conversion
|
||||
//
|
||||
#define LongLongToDWordLong LongLongToULongLong
|
||||
|
||||
//
|
||||
// LONGLONG -> ULONG64 conversion
|
||||
//
|
||||
#define LongLongToULong64 LongLongToULongLong
|
||||
|
||||
//
|
||||
// LONGLONG -> DWORD64 conversion
|
||||
//
|
||||
#define LongLongToDWord64 LongLongToULongLong
|
||||
|
||||
//
|
||||
// LONGLONG -> UINT64 conversion
|
||||
//
|
||||
#define LongLongToUInt64 LongLongToULongLong
|
||||
|
||||
//
|
||||
// LONGLONG -> ptrdiff_t conversion
|
||||
//
|
||||
#define LongLongToPtrdiffT LongLongToIntPtr
|
||||
|
||||
//
|
||||
// LONGLONG -> size_t conversion
|
||||
//
|
||||
#define LongLongToSizeT LongLongToUIntPtr
|
||||
|
||||
//
|
||||
// LONGLONG -> SSIZE_T conversion
|
||||
//
|
||||
#define LongLongToSSIZET LongLongToLongPtr
|
||||
|
||||
//
|
||||
// LONGLONG -> SIZE_T conversion
|
||||
//
|
||||
#define LongLongToSIZET LongLongToULongPtr
|
||||
|
||||
//
|
||||
// LONG64 -> CHAR conversion
|
||||
//
|
||||
#define Long64ToChar LongLongToChar
|
||||
|
||||
//
|
||||
// LONG64 -> INT8 conversion
|
||||
//
|
||||
#define Long64ToInt8 LongLongToInt8
|
||||
|
||||
//
|
||||
// LONG64 -> UCHAR conversion
|
||||
//
|
||||
#define Long64ToUChar LongLongToUChar
|
||||
|
||||
//
|
||||
// LONG64 -> UINT8 conversion
|
||||
//
|
||||
#define Long64ToUInt8 LongLongToUInt8
|
||||
|
||||
//
|
||||
// LONG64 -> BYTE conversion
|
||||
//
|
||||
#define Long64ToByte LongLongToUInt8
|
||||
|
||||
//
|
||||
// LONG64 -> SHORT conversion
|
||||
//
|
||||
#define Long64ToShort LongLongToShort
|
||||
|
||||
//
|
||||
// LONG64 -> INT16 conversion
|
||||
//
|
||||
#define Long64ToInt16 LongLongToShort
|
||||
|
||||
//
|
||||
// LONG64 -> USHORT conversion
|
||||
//
|
||||
#define Long64ToUShort LongLongToUShort
|
||||
|
||||
//
|
||||
// LONG64 -> UINT16 conversion
|
||||
//
|
||||
#define Long64ToUInt16 LongLongToUShort
|
||||
|
||||
//
|
||||
// LONG64 -> WORD conversion
|
||||
//
|
||||
#define Long64ToWord LongLongToUShort
|
||||
|
||||
//
|
||||
// LONG64 -> INT conversion
|
||||
//
|
||||
#define Long64ToInt LongLongToInt
|
||||
|
||||
//
|
||||
// LONG64 -> INT32 conversion
|
||||
//
|
||||
#define Long64ToInt32 LongLongToInt
|
||||
|
||||
//
|
||||
// LONG64 -> INT_PTR conversion
|
||||
//
|
||||
#define Long64ToIntPtr LongLongToIntPtr
|
||||
|
||||
//
|
||||
// LONG64 -> UINT conversion
|
||||
//
|
||||
#define Long64ToUInt LongLongToUInt
|
||||
|
||||
//
|
||||
// LONG64 -> UINT32 conversion
|
||||
//
|
||||
#define Long64ToUInt32 LongLongToUInt
|
||||
|
||||
//
|
||||
// LONG64 -> UINT_PTR conversion
|
||||
//
|
||||
#define Long64ToUIntPtr LongLongToUIntPtr
|
||||
|
||||
//
|
||||
// LONG64 -> LONG conversion
|
||||
//
|
||||
#define Long64ToLong LongLongToLong
|
||||
|
||||
//
|
||||
// LONG64 -> LONG_PTR conversion
|
||||
//
|
||||
#define Long64ToLongPtr LongLongToLongPtr
|
||||
|
||||
//
|
||||
// LONG64 -> ULONG conversion
|
||||
//
|
||||
#define Long64ToULong LongLongToULong
|
||||
|
||||
//
|
||||
// LONG64 -> ULONG_PTR conversion
|
||||
//
|
||||
#define Long64ToULongPtr LongLongToULongPtr
|
||||
|
||||
//
|
||||
// LONG64 -> DWORD conversion
|
||||
//
|
||||
#define Long64ToDWord LongLongToULong
|
||||
|
||||
//
|
||||
// LONG64 -> DWORD_PTR conversion
|
||||
//
|
||||
#define Long64ToDWordPtr LongLongToULongPtr
|
||||
|
||||
//
|
||||
// LONG64 -> ULONGLONG conversion
|
||||
//
|
||||
#define Long64ToULongLong LongLongToULongLong
|
||||
|
||||
//
|
||||
// LONG64 -> ptrdiff_t conversion
|
||||
//
|
||||
#define Long64ToPtrdiffT LongLongToIntPtr
|
||||
|
||||
//
|
||||
// LONG64 -> size_t conversion
|
||||
//
|
||||
#define Long64ToSizeT LongLongToUIntPtr
|
||||
|
||||
//
|
||||
// LONG64 -> SSIZE_T conversion
|
||||
//
|
||||
#define Long64ToSSIZET LongLongToLongPtr
|
||||
|
||||
//
|
||||
// LONG64 -> SIZE_T conversion
|
||||
//
|
||||
#define Long64ToSIZET LongLongToULongPtr
|
||||
|
||||
//
|
||||
// INT64 -> CHAR conversion
|
||||
//
|
||||
#define Int64ToChar LongLongToChar
|
||||
|
||||
//
|
||||
// INT64 -> INT8 conversion
|
||||
//
|
||||
#define Int64ToInt8 LongLongToInt8
|
||||
|
||||
//
|
||||
// INT64 -> UCHAR conversion
|
||||
//
|
||||
#define Int64ToUChar LongLongToUChar
|
||||
|
||||
//
|
||||
// INT64 -> UINT8 conversion
|
||||
//
|
||||
#define Int64ToUInt8 LongLongToUInt8
|
||||
|
||||
//
|
||||
// INT64 -> BYTE conversion
|
||||
//
|
||||
#define Int64ToByte LongLongToUInt8
|
||||
|
||||
//
|
||||
// INT64 -> SHORT conversion
|
||||
//
|
||||
#define Int64ToShort LongLongToShort
|
||||
|
||||
//
|
||||
// INT64 -> INT16 conversion
|
||||
//
|
||||
#define Int64ToInt16 LongLongToShort
|
||||
|
||||
//
|
||||
// INT64 -> USHORT conversion
|
||||
//
|
||||
#define Int64ToUShort LongLongToUShort
|
||||
|
||||
//
|
||||
// INT64 -> UINT16 conversion
|
||||
//
|
||||
#define Int64ToUInt16 LongLongToUShort
|
||||
|
||||
//
|
||||
// INT64 -> WORD conversion
|
||||
//
|
||||
#define Int64ToWord LongLongToUShort
|
||||
|
||||
//
|
||||
// INT64 -> INT conversion
|
||||
//
|
||||
#define Int64ToInt LongLongToInt
|
||||
|
||||
//
|
||||
// INT64 -> INT32 conversion
|
||||
//
|
||||
#define Int64ToInt32 LongLongToInt
|
||||
|
||||
//
|
||||
// INT64 -> INT_PTR conversion
|
||||
//
|
||||
#define Int64ToIntPtr LongLongToIntPtr
|
||||
|
||||
//
|
||||
// INT64 -> UINT conversion
|
||||
//
|
||||
#define Int64ToUInt LongLongToUInt
|
||||
|
||||
//
|
||||
// INT64 -> UINT32 conversion
|
||||
//
|
||||
#define Int64ToUInt32 LongLongToUInt
|
||||
|
||||
//
|
||||
// INT64 -> UINT_PTR conversion
|
||||
//
|
||||
#define Int64ToUIntPtr LongLongToUIntPtr
|
||||
|
||||
//
|
||||
// INT64 -> LONG conversion
|
||||
//
|
||||
#define Int64ToLong LongLongToLong
|
||||
|
||||
//
|
||||
// INT64 -> LONG_PTR conversion
|
||||
//
|
||||
#define Int64ToLongPtr LongLongToLongPtr
|
||||
|
||||
//
|
||||
// INT64 -> ULONG conversion
|
||||
//
|
||||
#define Int64ToULong LongLongToULong
|
||||
|
||||
//
|
||||
// INT64 -> ULONG_PTR conversion
|
||||
//
|
||||
#define Int64ToULongPtr LongLongToULongPtr
|
||||
|
||||
//
|
||||
// INT64 -> DWORD conversion
|
||||
//
|
||||
#define Int64ToDWord LongLongToULong
|
||||
|
||||
//
|
||||
// INT64 -> DWORD_PTR conversion
|
||||
//
|
||||
#define Int64ToDWordPtr LongLongToULongPtr
|
||||
|
||||
//
|
||||
// INT64 -> ULONGLONG conversion
|
||||
//
|
||||
#define Int64ToULongLong LongLongToULongLong
|
||||
|
||||
//
|
||||
// INT64 -> DWORDLONG conversion
|
||||
//
|
||||
#define Int64ToDWordLong LongLongToULongLong
|
||||
|
||||
//
|
||||
// INT64 -> ULONG64 conversion
|
||||
//
|
||||
#define Int64ToULong64 LongLongToULongLong
|
||||
|
||||
//
|
||||
// INT64 -> DWORD64 conversion
|
||||
//
|
||||
#define Int64ToDWord64 LongLongToULongLong
|
||||
|
||||
//
|
||||
// INT64 -> UINT64 conversion
|
||||
//
|
||||
#define Int64ToUInt64 LongLongToULongLong
|
||||
|
||||
//
|
||||
// INT64 -> ptrdiff_t conversion
|
||||
//
|
||||
#define Int64ToPtrdiffT LongLongToIntPtr
|
||||
|
||||
//
|
||||
// INT64 -> size_t conversion
|
||||
//
|
||||
#define Int64ToSizeT LongLongToUIntPtr
|
||||
|
||||
//
|
||||
// INT64 -> SSIZE_T conversion
|
||||
//
|
||||
#define Int64ToSSIZET LongLongToLongPtr
|
||||
|
||||
//
|
||||
// INT64 -> SIZE_T conversion
|
||||
//
|
||||
#define Int64ToSIZET LongLongToULongPtr
|
||||
|
||||
//
|
||||
// ULONGLONG -> INT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongLongToInt8(
|
||||
__inn ULONGLONG ullOperand,
|
||||
__outt __deref_out_range(==,ullOperand) INT8* pi8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ullOperand <= INT8_MAX)
|
||||
{
|
||||
*pi8Result = (INT8)ullOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pi8Result = INT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONGLONG -> UCHAR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongLongToUChar(
|
||||
__inn ULONGLONG ullOperand,
|
||||
__outt __deref_out_range(==,ullOperand) UCHAR* pch)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ullOperand <= 255)
|
||||
{
|
||||
*pch = (UCHAR)ullOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pch = '\0';
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONGLONG -> CHAR conversion
|
||||
//
|
||||
__forceinline
|
||||
HRESULT
|
||||
ULongLongToChar(
|
||||
__inn ULONGLONG ullOperand,
|
||||
__outt __deref_out_range(==,ullOperand) CHAR* pch)
|
||||
{
|
||||
#ifdef _CHAR_UNSIGNED
|
||||
return ULongLongToUChar(ullOperand, (UCHAR*)pch);
|
||||
#else
|
||||
return ULongLongToInt8(ullOperand, (INT8*)pch);
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// ULONGLONG -> UINT8 conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongLongToUInt8(
|
||||
__inn ULONGLONG ullOperand,
|
||||
__outt __deref_out_range(==,ullOperand) UINT8* pu8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ullOperand <= UINT8_MAX)
|
||||
{
|
||||
*pu8Result = (UINT8)ullOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pu8Result = UINT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONGLONG -> BYTE conversion
|
||||
//
|
||||
#define ULongLongToByte ULongLongToUInt8
|
||||
|
||||
//
|
||||
// ULONGLONG -> SHORT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongLongToShort(
|
||||
__inn ULONGLONG ullOperand,
|
||||
__outt __deref_out_range(==,ullOperand) SHORT* psResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ullOperand <= SHORT_MAX)
|
||||
{
|
||||
*psResult = (SHORT)ullOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*psResult = SHORT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONGLONG -> INT16 conversion
|
||||
//
|
||||
#define ULongLongToInt16 ULongLongToShort
|
||||
|
||||
//
|
||||
// ULONGLONG -> USHORT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongLongToUShort(
|
||||
__inn ULONGLONG ullOperand,
|
||||
__outt __deref_out_range(==,ullOperand) USHORT* pusResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ullOperand <= USHORT_MAX)
|
||||
{
|
||||
*pusResult = (USHORT)ullOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pusResult = USHORT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONGLONG -> UINT16 conversion
|
||||
//
|
||||
#define ULongLongToUInt16 ULongLongToUShort
|
||||
|
||||
//
|
||||
// ULONGLONG -> WORD conversion
|
||||
//
|
||||
#define ULongLongToWord ULongLongToUShort
|
||||
|
||||
//
|
||||
// ULONGLONG -> INT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongLongToInt(
|
||||
__inn ULONGLONG ullOperand,
|
||||
__outt __deref_out_range(==,ullOperand) INT* piResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ullOperand <= INT_MAX)
|
||||
{
|
||||
*piResult = (INT)ullOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*piResult = INT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONGLONG -> INT32 conversion
|
||||
//
|
||||
#define ULongLongToInt32 ULongLongToInt
|
||||
|
||||
//
|
||||
// ULONGLONG -> INT_PTR conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define ULongLongToIntPtr ULongLongToLongLong
|
||||
#else
|
||||
#define ULongLongToIntPtr ULongLongToInt
|
||||
#endif
|
||||
|
||||
//
|
||||
// ULONGLONG -> UINT conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongLongToUInt(
|
||||
__inn ULONGLONG ullOperand,
|
||||
__outt __deref_out_range(==,ullOperand) UINT* puResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ullOperand <= UINT_MAX)
|
||||
{
|
||||
*puResult = (UINT)ullOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*puResult = UINT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONGLONG -> UINT32 conversion
|
||||
//
|
||||
#define ULongLongToUInt32 ULongLongToUInt
|
||||
|
||||
//
|
||||
// ULONGLONG -> UINT_PTR conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
__inline
|
||||
HRESULT
|
||||
ULongLongToUIntPtr(
|
||||
__inn ULONGLONG ullOperand,
|
||||
__outt __deref_out_range(==,ullOperand) UINT_PTR* puResult)
|
||||
{
|
||||
*puResult = ullOperand;
|
||||
return S_OK;
|
||||
}
|
||||
#else
|
||||
#define ULongLongToUIntPtr ULongLongToUInt
|
||||
#endif
|
||||
|
||||
//
|
||||
// ULONGLONG -> LONG conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongLongToLong(
|
||||
__inn ULONGLONG ullOperand,
|
||||
__outt __deref_out_range(==,ullOperand) LONG* plResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ullOperand <= INT32_MAX)
|
||||
{
|
||||
*plResult = (LONG)ullOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*plResult = LONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONGLONG -> LONG_PTR conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongLongToLongPtr(
|
||||
__inn ULONGLONG ullOperand,
|
||||
__outt __deref_out_range(==,ullOperand) LONG_PTR* plResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ullOperand <= LONG_PTR_MAX)
|
||||
{
|
||||
*plResult = (LONG_PTR)ullOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*plResult = LONG_PTR_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONGLONG -> ULONG conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongLongToULong(
|
||||
__inn ULONGLONG ullOperand,
|
||||
__outt __deref_out_range(==,ullOperand) ULONG* pulResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ullOperand <= UINT32_MAX)
|
||||
{
|
||||
*pulResult = (ULONG)ullOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pulResult = ULONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONGLONG -> ULONG_PTR conversion
|
||||
//
|
||||
#ifdef _WIN64
|
||||
__inline
|
||||
HRESULT
|
||||
ULongLongToULongPtr(
|
||||
__inn ULONGLONG ullOperand,
|
||||
__outt __deref_out_range(==,ullOperand) ULONG_PTR* pulResult)
|
||||
{
|
||||
*pulResult = ullOperand;
|
||||
return S_OK;
|
||||
}
|
||||
#else
|
||||
#define ULongLongToULongPtr ULongLongToULong
|
||||
#endif
|
||||
|
||||
//
|
||||
// ULONGLONG -> DWORD conversion
|
||||
//
|
||||
#define ULongLongToDWord ULongLongToULong
|
||||
|
||||
//
|
||||
// ULONGLONG -> DWORD_PTR conversion
|
||||
//
|
||||
#define ULongLongToDWordPtr ULongLongToULongPtr
|
||||
|
||||
//
|
||||
// ULONGLONG -> LONGLONG conversion
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongLongToLongLong(
|
||||
__inn ULONGLONG ullOperand,
|
||||
__outt __deref_out_range(==,ullOperand) LONGLONG* pllResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ullOperand <= LONGLONG_MAX)
|
||||
{
|
||||
*pllResult = (LONGLONG)ullOperand;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pllResult = LONGLONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONGLONG -> INT64 conversion
|
||||
//
|
||||
#define ULongLongToInt64 ULongLongToLongLong
|
||||
|
||||
//
|
||||
// ULONGLONG -> LONG64 conversion
|
||||
//
|
||||
#define ULongLongToLong64 ULongLongToLongLong
|
||||
|
||||
//
|
||||
// ULONGLONG -> ptrdiff_t conversion
|
||||
//
|
||||
#define ULongLongToPtrdiffT ULongLongToIntPtr
|
||||
|
||||
//
|
||||
// ULONGLONG -> size_t conversion
|
||||
//
|
||||
#define ULongLongToSizeT ULongLongToUIntPtr
|
||||
|
||||
//
|
||||
// ULONGLONG -> SSIZE_T conversion
|
||||
//
|
||||
#define ULongLongToSSIZET ULongLongToLongPtr
|
||||
|
||||
//
|
||||
// ULONGLONG -> SIZE_T conversion
|
||||
//
|
||||
#define ULongLongToSIZET ULongLongToULongPtr
|
||||
|
||||
//
|
||||
// DWORDLONG -> CHAR conversion
|
||||
//
|
||||
#define DWordLongToChar ULongLongToChar
|
||||
|
||||
//
|
||||
// DWORDLONG -> INT8 conversion
|
||||
//
|
||||
#define DWordLongToInt8 ULongLongToInt8
|
||||
|
||||
//
|
||||
// DWORDLONG -> UCHAR conversion
|
||||
//
|
||||
#define DWordLongToUChar ULongLongToUChar
|
||||
|
||||
//
|
||||
// DWORDLONG -> UINT8 conversion
|
||||
//
|
||||
#define DWordLongToUInt8 ULongLongToUInt8
|
||||
|
||||
//
|
||||
// DWORDLONG -> BYTE conversion
|
||||
//
|
||||
#define DWordLongToByte ULongLongToUInt8
|
||||
|
||||
//
|
||||
// DWORDLONG -> SHORT conversion
|
||||
//
|
||||
#define DWordLongToShort ULongLongToShort
|
||||
|
||||
//
|
||||
// DWORDLONG -> INT16 conversion
|
||||
//
|
||||
#define DWordLongToInt16 ULongLongToShort
|
||||
|
||||
//
|
||||
// DWORDLONG -> USHORT conversion
|
||||
//
|
||||
#define DWordLongToUShort ULongLongToUShort
|
||||
|
||||
//
|
||||
// DWORDLONG -> UINT16 conversion
|
||||
//
|
||||
#define DWordLongToUInt16 ULongLongToUShort
|
||||
|
||||
//
|
||||
// DWORDLONG -> WORD conversion
|
||||
//
|
||||
#define DWordLongToWord ULongLongToUShort
|
||||
|
||||
//
|
||||
// DWORDLONG -> INT conversion
|
||||
//
|
||||
#define DWordLongToInt ULongLongToInt
|
||||
|
||||
//
|
||||
// DWORDLONG -> INT32 conversion
|
||||
//
|
||||
#define DWordLongToInt32 ULongLongToInt
|
||||
|
||||
//
|
||||
// DWORDLONG -> INT_PTR conversion
|
||||
//
|
||||
#define DWordLongToIntPtr ULongLongToIntPtr
|
||||
|
||||
//
|
||||
// DWORDLONG -> UINT conversion
|
||||
//
|
||||
#define DWordLongToUInt ULongLongToUInt
|
||||
|
||||
//
|
||||
// DWORDLONG -> UINT32 conversion
|
||||
//
|
||||
#define DWordLongToUInt32 ULongLongToUInt
|
||||
|
||||
//
|
||||
// DWORDLONG -> UINT_PTR conversion
|
||||
//
|
||||
#define DWordLongToUIntPtr ULongLongToUIntPtr
|
||||
|
||||
//
|
||||
// DWORDLONG -> LONG conversion
|
||||
//
|
||||
#define DWordLongToLong ULongLongToLong
|
||||
|
||||
//
|
||||
// DWORDLONG -> LONG_PTR conversion
|
||||
//
|
||||
#define DWordLongToLongPtr ULongLongToLongPtr
|
||||
|
||||
//
|
||||
// DWORDLONG -> ULONG conversion
|
||||
//
|
||||
#define DWordLongToULong ULongLongToULong
|
||||
|
||||
//
|
||||
// DWORDLONG -> ULONG_PTR conversion
|
||||
//
|
||||
#define DWordLongToULongPtr ULongLongToULongPtr
|
||||
|
||||
//
|
||||
// DWORDLONG -> DWORD conversion
|
||||
//
|
||||
#define DWordLongToDWord ULongLongToULong
|
||||
|
||||
//
|
||||
// DWORDLONG -> DWORD_PTR conversion
|
||||
//
|
||||
#define DWordLongToDWordPtr ULongLongToULongPtr
|
||||
|
||||
//
|
||||
// DWORDLONG -> LONGLONG conversion
|
||||
//
|
||||
#define DWordLongToLongLong ULongLongToLongLong
|
||||
|
||||
//
|
||||
// DWORDLONG -> LONG64 conversion
|
||||
//
|
||||
#define DWordLongToLong64 ULongLongToLongLong
|
||||
|
||||
//
|
||||
// DWORDLONG -> INT64 conversion
|
||||
//
|
||||
#define DWordLongToInt64 ULongLongToLongLong
|
||||
|
||||
//
|
||||
// DWORDLONG -> ptrdiff_t conversion
|
||||
//
|
||||
#define DWordLongToPtrdiffT ULongLongToIntPtr
|
||||
|
||||
//
|
||||
// DWORDLONG -> size_t conversion
|
||||
//
|
||||
#define DWordLongToSizeT ULongLongToUIntPtr
|
||||
|
||||
//
|
||||
// DWORDLONG -> SSIZE_T conversion
|
||||
//
|
||||
#define DWordLongToSSIZET ULongLongToLongPtr
|
||||
|
||||
//
|
||||
// DWORDLONG -> SIZE_T conversion
|
||||
//
|
||||
#define DWordLongToSIZET ULongLongToULongPtr
|
||||
|
||||
//
|
||||
// ULONG64 -> CHAR conversion
|
||||
//
|
||||
#define ULong64ToChar ULongLongToChar
|
||||
|
||||
//
|
||||
// ULONG64 -> INT8 conversion
|
||||
//
|
||||
#define ULong64ToInt8 ULongLongToInt8
|
||||
|
||||
//
|
||||
// ULONG64 -> UCHAR conversion
|
||||
//
|
||||
#define ULong64ToUChar ULongLongToUChar
|
||||
|
||||
//
|
||||
// ULONG64 -> UINT8 conversion
|
||||
//
|
||||
#define ULong64ToUInt8 ULongLongToUInt8
|
||||
|
||||
//
|
||||
// ULONG64 -> BYTE conversion
|
||||
//
|
||||
#define ULong64ToByte ULongLongToUInt8
|
||||
|
||||
//
|
||||
// ULONG64 -> SHORT conversion
|
||||
//
|
||||
#define ULong64ToShort ULongLongToShort
|
||||
|
||||
//
|
||||
// ULONG64 -> INT16 conversion
|
||||
//
|
||||
#define ULong64ToInt16 ULongLongToShort
|
||||
|
||||
//
|
||||
// ULONG64 -> USHORT conversion
|
||||
//
|
||||
#define ULong64ToUShort ULongLongToUShort
|
||||
|
||||
//
|
||||
// ULONG64 -> UINT16 conversion
|
||||
//
|
||||
#define ULong64ToUInt16 ULongLongToUShort
|
||||
|
||||
//
|
||||
// ULONG64 -> WORD conversion
|
||||
//
|
||||
#define ULong64ToWord ULongLongToUShort
|
||||
|
||||
//
|
||||
// ULONG64 -> INT conversion
|
||||
//
|
||||
#define ULong64ToInt ULongLongToInt
|
||||
|
||||
//
|
||||
// ULONG64 -> INT32 conversion
|
||||
//
|
||||
#define ULong64ToInt32 ULongLongToInt
|
||||
|
||||
//
|
||||
// ULONG64 -> INT_PTR conversion
|
||||
//
|
||||
#define ULong64ToIntPtr ULongLongToIntPtr
|
||||
|
||||
//
|
||||
// ULONG64 -> UINT conversion
|
||||
//
|
||||
#define ULong64ToUInt ULongLongToUInt
|
||||
|
||||
//
|
||||
// ULONG64 -> UINT32 conversion
|
||||
//
|
||||
#define ULong64ToUInt32 ULongLongToUInt
|
||||
|
||||
//
|
||||
// ULONG64 -> UINT_PTR conversion
|
||||
//
|
||||
#define ULong64ToUIntPtr ULongLongToUIntPtr
|
||||
|
||||
//
|
||||
// ULONG64 -> LONG conversion
|
||||
//
|
||||
#define ULong64ToLong ULongLongToLong
|
||||
|
||||
//
|
||||
// ULONG64 -> LONG_PTR conversion
|
||||
//
|
||||
#define ULong64ToLongPtr ULongLongToLongPtr
|
||||
|
||||
//
|
||||
// ULONG64 -> ULONG conversion
|
||||
//
|
||||
#define ULong64ToULong ULongLongToULong
|
||||
|
||||
//
|
||||
// ULONG64 -> ULONG_PTR conversion
|
||||
//
|
||||
#define ULong64ToULongPtr ULongLongToULongPtr
|
||||
|
||||
//
|
||||
// ULONG64 -> DWORD conversion
|
||||
//
|
||||
#define ULong64ToDWord ULongLongToULong
|
||||
|
||||
//
|
||||
// ULONG64 -> DWORD_PTR conversion
|
||||
//
|
||||
#define ULong64ToDWordPtr ULongLongToULongPtr
|
||||
|
||||
//
|
||||
// ULONG64 -> LONGLONG conversion
|
||||
//
|
||||
#define ULong64ToLongLong ULongLongToLongLong
|
||||
|
||||
//
|
||||
// ULONG64 -> LONG64 conversion
|
||||
//
|
||||
#define ULong64ToLong64 ULongLongToLongLong
|
||||
|
||||
//
|
||||
// ULONG64 -> INT64 conversion
|
||||
//
|
||||
#define ULong64ToInt64 ULongLongToLongLong
|
||||
|
||||
//
|
||||
// ULONG64 -> ptrdiff_t conversion
|
||||
//
|
||||
#define ULong64ToPtrdiffT ULongLongToIntPtr
|
||||
|
||||
//
|
||||
// ULONG64 -> size_t conversion
|
||||
//
|
||||
#define ULong64ToSizeT ULongLongToUIntPtr
|
||||
|
||||
//
|
||||
// ULONG64 -> SSIZE_T conversion
|
||||
//
|
||||
#define ULong64ToSSIZET ULongLongToLongPtr
|
||||
|
||||
//
|
||||
// ULONG64 -> SIZE_T conversion
|
||||
//
|
||||
#define ULong64ToSIZET ULongLongToULongPtr
|
||||
|
||||
//
|
||||
// DWORD64 -> CHAR conversion
|
||||
//
|
||||
#define DWord64ToChar ULongLongToChar
|
||||
|
||||
//
|
||||
// DWORD64 -> INT8 conversion
|
||||
//
|
||||
#define DWord64ToInt8 ULongLongToInt8
|
||||
|
||||
//
|
||||
// DWORD64 -> UCHAR conversion
|
||||
//
|
||||
#define DWord64ToUChar ULongLongToUChar
|
||||
|
||||
//
|
||||
// DWORD64 -> UINT8 conversion
|
||||
//
|
||||
#define DWord64ToUInt8 ULongLongToUInt8
|
||||
|
||||
//
|
||||
// DWORD64 -> BYTE conversion
|
||||
//
|
||||
#define DWord64ToByte ULongLongToUInt8
|
||||
|
||||
//
|
||||
// DWORD64 -> SHORT conversion
|
||||
//
|
||||
#define DWord64ToShort ULongLongToShort
|
||||
|
||||
//
|
||||
// DWORD64 -> INT16 conversion
|
||||
//
|
||||
#define DWord64ToInt16 ULongLongToShort
|
||||
|
||||
//
|
||||
// DWORD64 -> USHORT conversion
|
||||
//
|
||||
#define DWord64ToUShort ULongLongToUShort
|
||||
|
||||
//
|
||||
// DWORD64 -> UINT16 conversion
|
||||
//
|
||||
#define DWord64ToUInt16 ULongLongToUShort
|
||||
|
||||
//
|
||||
// DWORD64 -> WORD conversion
|
||||
//
|
||||
#define DWord64ToWord ULongLongToUShort
|
||||
|
||||
//
|
||||
// DWORD64 -> INT conversion
|
||||
//
|
||||
#define DWord64ToInt ULongLongToInt
|
||||
|
||||
//
|
||||
// DWORD64 -> INT32 conversion
|
||||
//
|
||||
#define DWord64ToInt32 ULongLongToInt
|
||||
|
||||
//
|
||||
// DWORD64 -> INT_PTR conversion
|
||||
//
|
||||
#define DWord64ToIntPtr ULongLongToIntPtr
|
||||
|
||||
//
|
||||
// DWORD64 -> UINT conversion
|
||||
//
|
||||
#define DWord64ToUInt ULongLongToUInt
|
||||
|
||||
//
|
||||
// DWORD64 -> UINT32 conversion
|
||||
//
|
||||
#define DWord64ToUInt32 ULongLongToUInt
|
||||
|
||||
//
|
||||
// DWORD64 -> UINT_PTR conversion
|
||||
//
|
||||
#define DWord64ToUIntPtr ULongLongToUIntPtr
|
||||
|
||||
//
|
||||
// DWORD64 -> LONG conversion
|
||||
//
|
||||
#define DWord64ToLong ULongLongToLong
|
||||
|
||||
//
|
||||
// DWORD64 -> LONG_PTR conversion
|
||||
//
|
||||
#define DWord64ToLongPtr ULongLongToLongPtr
|
||||
|
||||
//
|
||||
// DWORD64 -> ULONG conversion
|
||||
//
|
||||
#define DWord64ToULong ULongLongToULong
|
||||
|
||||
//
|
||||
// DWORD64 -> ULONG_PTR conversion
|
||||
//
|
||||
#define DWord64ToULongPtr ULongLongToULongPtr
|
||||
|
||||
//
|
||||
// DWORD64 -> DWORD conversion
|
||||
//
|
||||
#define DWord64ToDWord ULongLongToULong
|
||||
|
||||
//
|
||||
// DWORD64 -> DWORD_PTR conversion
|
||||
//
|
||||
#define DWord64ToDWordPtr ULongLongToULongPtr
|
||||
|
||||
//
|
||||
// DWORD64 -> LONGLONG conversion
|
||||
//
|
||||
#define DWord64ToLongLong ULongLongToLongLong
|
||||
|
||||
//
|
||||
// DWORD64 -> LONG64 conversion
|
||||
//
|
||||
#define DWord64ToLong64 ULongLongToLongLong
|
||||
|
||||
//
|
||||
// DWORD64 -> INT64 conversion
|
||||
//
|
||||
#define DWord64ToInt64 ULongLongToLongLong
|
||||
|
||||
//
|
||||
// DWORD64 -> ptrdiff_t conversion
|
||||
//
|
||||
#define DWord64ToPtrdiffT ULongLongToIntPtr
|
||||
|
||||
//
|
||||
// DWORD64 -> size_t conversion
|
||||
//
|
||||
#define DWord64ToSizeT ULongLongToUIntPtr
|
||||
|
||||
//
|
||||
// DWORD64 -> SSIZE_T conversion
|
||||
//
|
||||
#define DWord64ToSSIZET ULongLongToLongPtr
|
||||
|
||||
//
|
||||
// DWORD64 -> SIZE_T conversion
|
||||
//
|
||||
#define DWord64ToSIZET ULongLongToULongPtr
|
||||
|
||||
//
|
||||
// UINT64 -> CHAR conversion
|
||||
//
|
||||
#define UInt64ToChar ULongLongToChar
|
||||
|
||||
//
|
||||
// UINT64 -> INT8 conversion
|
||||
//
|
||||
#define UInt64ToInt8 ULongLongToInt8
|
||||
|
||||
//
|
||||
// UINT64 -> UCHAR conversion
|
||||
//
|
||||
#define UInt64ToUChar ULongLongToUChar
|
||||
|
||||
//
|
||||
// UINT64 -> UINT8 conversion
|
||||
//
|
||||
#define UInt64ToUInt8 ULongLongToUInt8
|
||||
|
||||
//
|
||||
// UINT64 -> BYTE conversion
|
||||
//
|
||||
#define UInt64ToByte ULongLongToUInt8
|
||||
|
||||
//
|
||||
// UINT64 -> SHORT conversion
|
||||
//
|
||||
#define UInt64ToShort ULongLongToShort
|
||||
|
||||
//
|
||||
// UINT64 -> INT16 conversion
|
||||
//
|
||||
//
|
||||
#define UInt64ToInt16 ULongLongToShort
|
||||
|
||||
//
|
||||
// UINT64 -> USHORT conversion
|
||||
//
|
||||
#define UInt64ToUShort ULongLongToUShort
|
||||
|
||||
//
|
||||
// UINT64 -> UINT16 conversion
|
||||
//
|
||||
#define UInt64ToUInt16 ULongLongToUShort
|
||||
|
||||
//
|
||||
// UINT64 -> WORD conversion
|
||||
//
|
||||
#define UInt64ToWord ULongLongToUShort
|
||||
|
||||
//
|
||||
// UINT64 -> INT conversion
|
||||
//
|
||||
#define UInt64ToInt ULongLongToInt
|
||||
|
||||
//
|
||||
// UINT64 -> INT32 conversion
|
||||
//
|
||||
#define UInt64ToInt32 ULongLongToInt
|
||||
|
||||
//
|
||||
// UINT64 -> INT_PTR conversion
|
||||
//
|
||||
#define UInt64ToIntPtr ULongLongToIntPtr
|
||||
|
||||
//
|
||||
// UINT64 -> UINT conversion
|
||||
//
|
||||
#define UInt64ToUInt ULongLongToUInt
|
||||
|
||||
//
|
||||
// UINT64 -> UINT32 conversion
|
||||
//
|
||||
#define UInt64ToUInt32 ULongLongToUInt
|
||||
|
||||
//
|
||||
// UINT64 -> UINT_PTR conversion
|
||||
//
|
||||
#define UInt64ToUIntPtr ULongLongToUIntPtr
|
||||
|
||||
//
|
||||
// UINT64 -> LONG conversion
|
||||
//
|
||||
#define UInt64ToLong ULongLongToLong
|
||||
|
||||
//
|
||||
// UINT64 -> LONG_PTR conversion
|
||||
//
|
||||
#define UInt64ToLongPtr ULongLongToLongPtr
|
||||
|
||||
//
|
||||
// UINT64 -> ULONG conversion
|
||||
//
|
||||
#define UInt64ToULong ULongLongToULong
|
||||
|
||||
//
|
||||
// UINT64 -> ULONG_PTR conversion
|
||||
//
|
||||
#define UInt64ToULongPtr ULongLongToULongPtr
|
||||
|
||||
//
|
||||
// UINT64 -> DWORD conversion
|
||||
//
|
||||
#define UInt64ToDWord ULongLongToULong
|
||||
|
||||
//
|
||||
// UINT64 -> DWORD_PTR conversion
|
||||
//
|
||||
#define UInt64ToDWordPtr ULongLongToULongPtr
|
||||
|
||||
//
|
||||
// UINT64 -> LONGLONG conversion
|
||||
//
|
||||
#define UInt64ToLongLong ULongLongToLongLong
|
||||
|
||||
//
|
||||
// UINT64 -> LONG64 conversion
|
||||
//
|
||||
#define UInt64ToLong64 ULongLongToLongLong
|
||||
|
||||
//
|
||||
// UINT64 -> INT64 conversion
|
||||
//
|
||||
#define UInt64ToInt64 ULongLongToLongLong
|
||||
|
||||
//
|
||||
// UINT64 -> ptrdiff_t conversion
|
||||
//
|
||||
#define UInt64ToPtrdiffT ULongLongToIntPtr
|
||||
|
||||
//
|
||||
// UINT64 -> size_t conversion
|
||||
//
|
||||
#define UInt64ToSizeT ULongLongToUIntPtr
|
||||
|
||||
//
|
||||
// UINT64 -> SSIZE_T conversion
|
||||
//
|
||||
#define UInt64ToSSIZET ULongLongToLongPtr
|
||||
|
||||
//
|
||||
// UINT64 -> SIZE_T conversion
|
||||
//
|
||||
#define UInt64ToSIZET ULongLongToULongPtr
|
||||
|
||||
//
|
||||
// ptrdiff_t -> CHAR conversion
|
||||
//
|
||||
#define PtrdiffTToChar IntPtrToChar
|
||||
|
||||
//
|
||||
// ptrdiff_t -> INT8 conversion
|
||||
//
|
||||
#define PtrdiffTToInt8 IntPtrToInt8
|
||||
|
||||
//
|
||||
// ptrdiff_t -> UCHAR conversion
|
||||
//
|
||||
#define PtrdiffTToUChar IntPtrToUChar
|
||||
|
||||
//
|
||||
// ptrdiff_t -> UINT8 conversion
|
||||
//
|
||||
#define PtrdiffTToUInt8 IntPtrToUInt8
|
||||
|
||||
//
|
||||
// ptrdiff_t -> BYTE conversion
|
||||
//
|
||||
#define PtrdiffTToByte IntPtrToUInt8
|
||||
|
||||
//
|
||||
// ptrdiff_t -> SHORT conversion
|
||||
//
|
||||
#define PtrdiffTToShort IntPtrToShort
|
||||
|
||||
//
|
||||
// ptrdiff_t -> INT16 conversion
|
||||
//
|
||||
#define PtrdiffTToInt16 IntPtrToShort
|
||||
|
||||
//
|
||||
// ptrdiff_t -> USHORT conversion
|
||||
//
|
||||
#define PtrdiffTToUShort IntPtrToUShort
|
||||
|
||||
//
|
||||
// ptrdiff_t -> UINT16 conversion
|
||||
//
|
||||
#define PtrdiffTToUInt16 IntPtrToUShort
|
||||
|
||||
//
|
||||
// ptrdiff_t -> WORD conversion
|
||||
//
|
||||
#define PtrdiffTToWord IntPtrToUShort
|
||||
|
||||
//
|
||||
// ptrdiff_t -> INT conversion
|
||||
//
|
||||
#define PtrdiffTToInt IntPtrToInt
|
||||
|
||||
//
|
||||
// ptrdiff_t -> INT32 conversion
|
||||
//
|
||||
#define PtrdiffTToInt32 IntPtrToInt
|
||||
|
||||
//
|
||||
// ptrdiff_t -> UINT conversion
|
||||
//
|
||||
#define PtrdiffTToUInt IntPtrToUInt
|
||||
|
||||
//
|
||||
// ptrdiff_t -> UINT32 conversion
|
||||
//
|
||||
#define PtrdiffTToUInt32 IntPtrToUInt
|
||||
|
||||
//
|
||||
// ptrdiff_t -> UINT_PTR conversion
|
||||
//
|
||||
#define PtrdiffTToUIntPtr IntPtrToUIntPtr
|
||||
|
||||
//
|
||||
// ptrdiff_t -> LONG conversion
|
||||
//
|
||||
#define PtrdiffTToLong IntPtrToLong
|
||||
|
||||
//
|
||||
// ptrdiff_t -> LONG_PTR conversion
|
||||
//
|
||||
#define PtrdiffTToLongPtr IntPtrToLongPtr
|
||||
|
||||
//
|
||||
// ptrdiff_t -> ULONG conversion
|
||||
//
|
||||
#define PtrdiffTToULong IntPtrToULong
|
||||
|
||||
//
|
||||
// ptrdiff_t -> ULONG_PTR conversion
|
||||
//
|
||||
#define PtrdiffTToULongPtr IntPtrToULongPtr
|
||||
|
||||
//
|
||||
// ptrdiff_t -> DWORD conversion
|
||||
//
|
||||
#define PtrdiffTToDWord IntPtrToULong
|
||||
|
||||
//
|
||||
// ptrdiff_t -> DWORD_PTR conversion
|
||||
//
|
||||
#define PtrdiffTToDWordPtr IntPtrToULongPtr
|
||||
|
||||
//
|
||||
// ptrdiff_t -> ULONGLONG conversion
|
||||
//
|
||||
#define PtrdiffTToULongLong IntPtrToULongLong
|
||||
|
||||
//
|
||||
// ptrdiff_t -> DWORDLONG conversion
|
||||
//
|
||||
#define PtrdiffTToDWordLong IntPtrToULongLong
|
||||
|
||||
//
|
||||
// ptrdiff_t -> ULONG64 conversion
|
||||
//
|
||||
#define PtrdiffTToULong64 IntPtrToULongLong
|
||||
|
||||
//
|
||||
// ptrdiff_t -> DWORD64 conversion
|
||||
//
|
||||
#define PtrdiffTToDWord64 IntPtrToULongLong
|
||||
|
||||
//
|
||||
// ptrdiff_t -> UINT64 conversion
|
||||
//
|
||||
#define PtrdiffTToUInt64 IntPtrToULongLong
|
||||
|
||||
//
|
||||
// ptrdiff_t -> size_t conversion
|
||||
//
|
||||
#define PtrdiffTToSizeT IntPtrToUIntPtr
|
||||
|
||||
//
|
||||
// ptrdiff_t -> SIZE_T conversion
|
||||
//
|
||||
#define PtrdiffTToSIZET IntPtrToULongPtr
|
||||
|
||||
//
|
||||
// size_t -> INT8 conversion
|
||||
//
|
||||
#define SizeTToInt8 UIntPtrToInt8
|
||||
|
||||
//
|
||||
// size_t -> UCHAR conversion
|
||||
//
|
||||
#define SizeTToUChar UIntPtrToUChar
|
||||
|
||||
//
|
||||
// size_t -> CHAR conversion
|
||||
//
|
||||
#define SizeTToChar UIntPtrToChar
|
||||
|
||||
//
|
||||
// size_t -> UINT8 conversion
|
||||
//
|
||||
#define SizeTToUInt8 UIntPtrToUInt8
|
||||
|
||||
//
|
||||
// size_t -> BYTE conversion
|
||||
//
|
||||
#define SizeTToByte UIntPtrToUInt8
|
||||
|
||||
//
|
||||
// size_t -> SHORT conversion
|
||||
//
|
||||
#define SizeTToShort UIntPtrToShort
|
||||
|
||||
//
|
||||
// size_t -> INT16 conversion
|
||||
//
|
||||
#define SizeTToInt16 UIntPtrToShort
|
||||
|
||||
//
|
||||
// size_t -> USHORT conversion
|
||||
//
|
||||
#define SizeTToUShort UIntPtrToUShort
|
||||
|
||||
//
|
||||
// size_t -> UINT16 conversion
|
||||
//
|
||||
#define SizeTToUInt16 UIntPtrToUShort
|
||||
|
||||
//
|
||||
// size_t -> WORD
|
||||
//
|
||||
#define SizeTToWord UIntPtrToUShort
|
||||
|
||||
//
|
||||
// size_t -> INT conversion
|
||||
//
|
||||
#define SizeTToInt UIntPtrToInt
|
||||
|
||||
//
|
||||
// size_t -> INT32 conversion
|
||||
//
|
||||
#define SizeTToInt32 UIntPtrToInt
|
||||
|
||||
//
|
||||
// size_t -> INT_PTR conversion
|
||||
//
|
||||
#define SizeTToIntPtr UIntPtrToIntPtr
|
||||
|
||||
//
|
||||
// size_t -> UINT conversion
|
||||
//
|
||||
#define SizeTToUInt UIntPtrToUInt
|
||||
|
||||
//
|
||||
// size_t -> UINT32 conversion
|
||||
//
|
||||
#define SizeTToUInt32 UIntPtrToUInt
|
||||
|
||||
//
|
||||
// size_t -> LONG conversion
|
||||
//
|
||||
#define SizeTToLong UIntPtrToLong
|
||||
|
||||
//
|
||||
// size_t -> LONG_PTR conversion
|
||||
//
|
||||
#define SizeTToLongPtr UIntPtrToLongPtr
|
||||
|
||||
//
|
||||
// size_t -> ULONG conversion
|
||||
//
|
||||
#define SizeTToULong UIntPtrToULong
|
||||
|
||||
//
|
||||
// size_t -> DWORD conversion
|
||||
//
|
||||
#define SizeTToDWord UIntPtrToULong
|
||||
|
||||
//
|
||||
// size_t -> LONGLONG conversion
|
||||
//
|
||||
#define SizeTToLongLong UIntPtrToLongLong
|
||||
|
||||
//
|
||||
// size_t -> LONG64 conversion
|
||||
//
|
||||
#define SizeTToLong64 UIntPtrToLongLong
|
||||
|
||||
//
|
||||
// size_t -> INT64
|
||||
//
|
||||
#define SizeTToInt64 UIntPtrToLongLong
|
||||
|
||||
//
|
||||
// size_t -> ptrdiff_t conversion
|
||||
//
|
||||
#define SizeTToPtrdiffT UIntPtrToIntPtr
|
||||
|
||||
//
|
||||
// size_t -> SSIZE_T conversion
|
||||
//
|
||||
#define SizeTToSSIZET UIntPtrToLongPtr
|
||||
|
||||
//
|
||||
// SSIZE_T -> INT8 conversion
|
||||
//
|
||||
#define SSIZETToInt8 LongPtrToInt8
|
||||
|
||||
//
|
||||
// SSIZE_T -> UCHAR conversion
|
||||
//
|
||||
#define SSIZETToUChar LongPtrToUChar
|
||||
|
||||
//
|
||||
// SSIZE_T -> CHAR conversion
|
||||
//
|
||||
#define SSIZETToChar LongPtrToChar
|
||||
|
||||
//
|
||||
// SSIZE_T -> UINT8 conversion
|
||||
//
|
||||
#define SSIZETToUInt8 LongPtrToUInt8
|
||||
|
||||
//
|
||||
// SSIZE_T -> BYTE conversion
|
||||
//
|
||||
#define SSIZETToByte LongPtrToUInt8
|
||||
|
||||
//
|
||||
// SSIZE_T -> SHORT conversion
|
||||
//
|
||||
#define SSIZETToShort LongPtrToShort
|
||||
|
||||
//
|
||||
// SSIZE_T -> INT16 conversion
|
||||
//
|
||||
#define SSIZETToInt16 LongPtrToShort
|
||||
|
||||
//
|
||||
// SSIZE_T -> USHORT conversion
|
||||
//
|
||||
#define SSIZETToUShort LongPtrToUShort
|
||||
|
||||
//
|
||||
// SSIZE_T -> UINT16 conversion
|
||||
//
|
||||
#define SSIZETToUInt16 LongPtrToUShort
|
||||
|
||||
//
|
||||
// SSIZE_T -> WORD conversion
|
||||
//
|
||||
#define SSIZETToWord LongPtrToUShort
|
||||
|
||||
//
|
||||
// SSIZE_T -> INT conversion
|
||||
//
|
||||
#define SSIZETToInt LongPtrToInt
|
||||
|
||||
//
|
||||
// SSIZE_T -> INT32 conversion
|
||||
//
|
||||
#define SSIZETToInt32 LongPtrToInt
|
||||
|
||||
//
|
||||
// SSIZE_T -> INT_PTR conversion
|
||||
//
|
||||
#define SSIZETToIntPtr LongPtrToIntPtr
|
||||
|
||||
//
|
||||
// SSIZE_T -> UINT conversion
|
||||
//
|
||||
#define SSIZETToUInt LongPtrToUInt
|
||||
|
||||
//
|
||||
// SSIZE_T -> UINT32 conversion
|
||||
//
|
||||
#define SSIZETToUInt32 LongPtrToUInt
|
||||
|
||||
//
|
||||
// SSIZE_T -> UINT_PTR conversion
|
||||
//
|
||||
#define SSIZETToUIntPtr LongPtrToUIntPtr
|
||||
|
||||
//
|
||||
// SSIZE_T -> LONG conversion
|
||||
//
|
||||
#define SSIZETToLong LongPtrToLong
|
||||
|
||||
//
|
||||
// SSIZE_T -> ULONG conversion
|
||||
//
|
||||
#define SSIZETToULong LongPtrToULong
|
||||
|
||||
//
|
||||
// SSIZE_T -> ULONG_PTR conversion
|
||||
//
|
||||
#define SSIZETToULongPtr LongPtrToULongPtr
|
||||
|
||||
//
|
||||
// SSIZE_T -> DWORD conversion
|
||||
//
|
||||
#define SSIZETToDWord LongPtrToULong
|
||||
|
||||
//
|
||||
// SSIZE_T -> DWORD_PTR conversion
|
||||
//
|
||||
#define SSIZETToDWordPtr LongPtrToULongPtr
|
||||
|
||||
//
|
||||
// SSIZE_T -> ULONGLONG conversion
|
||||
//
|
||||
#define SSIZETToULongLong LongPtrToULongLong
|
||||
|
||||
//
|
||||
// SSIZE_T -> DWORDLONG conversion
|
||||
//
|
||||
#define SSIZETToDWordLong LongPtrToULongLong
|
||||
|
||||
//
|
||||
// SSIZE_T -> ULONG64 conversion
|
||||
//
|
||||
#define SSIZETToULong64 LongPtrToULongLong
|
||||
|
||||
//
|
||||
// SSIZE_T -> DWORD64 conversion
|
||||
//
|
||||
#define SSIZETToDWord64 LongPtrToULongLong
|
||||
|
||||
//
|
||||
// SSIZE_T -> UINT64 conversion
|
||||
//
|
||||
#define SSIZETToUInt64 LongPtrToULongLong
|
||||
|
||||
//
|
||||
// SSIZE_T -> size_t conversion
|
||||
//
|
||||
#define SSIZETToSizeT LongPtrToUIntPtr
|
||||
|
||||
//
|
||||
// SSIZE_T -> SIZE_T conversion
|
||||
//
|
||||
#define SSIZETToSIZET LongPtrToULongPtr
|
||||
|
||||
//
|
||||
// SIZE_T -> INT8 conversion
|
||||
//
|
||||
#define SIZETToInt8 ULongPtrToInt8
|
||||
|
||||
//
|
||||
// SIZE_T -> UCHAR conversion
|
||||
//
|
||||
#define SIZETToUChar ULongPtrToUChar
|
||||
|
||||
//
|
||||
// SIZE_T -> CHAR conversion
|
||||
//
|
||||
#define SIZETToChar ULongPtrToChar
|
||||
|
||||
//
|
||||
// SIZE_T -> UINT8 conversion
|
||||
//
|
||||
#define SIZETToUInt8 ULongPtrToUInt8
|
||||
|
||||
//
|
||||
// SIZE_T -> BYTE conversion
|
||||
//
|
||||
#define SIZETToByte ULongPtrToUInt8
|
||||
|
||||
//
|
||||
// SIZE_T -> SHORT conversion
|
||||
//
|
||||
#define SIZETToShort ULongPtrToShort
|
||||
|
||||
//
|
||||
// SIZE_T -> INT16 conversion
|
||||
//
|
||||
#define SIZETToInt16 ULongPtrToShort
|
||||
|
||||
//
|
||||
// SIZE_T -> USHORT conversion
|
||||
//
|
||||
#define SIZETToUShort ULongPtrToUShort
|
||||
|
||||
//
|
||||
// SIZE_T -> UINT16 conversion
|
||||
//
|
||||
#define SIZETToUInt16 ULongPtrToUShort
|
||||
|
||||
//
|
||||
// SIZE_T -> WORD
|
||||
//
|
||||
#define SIZETToWord ULongPtrToUShort
|
||||
|
||||
//
|
||||
// SIZE_T -> INT conversion
|
||||
//
|
||||
#define SIZETToInt ULongPtrToInt
|
||||
|
||||
//
|
||||
// SIZE_T -> INT32 conversion
|
||||
//
|
||||
#define SIZETToInt32 ULongPtrToInt
|
||||
|
||||
//
|
||||
// SIZE_T -> INT_PTR conversion
|
||||
//
|
||||
#define SIZETToIntPtr ULongPtrToIntPtr
|
||||
|
||||
//
|
||||
// SIZE_T -> UINT conversion
|
||||
//
|
||||
#define SIZETToUInt ULongPtrToUInt
|
||||
|
||||
//
|
||||
// SIZE_T -> UINT32 conversion
|
||||
//
|
||||
#define SIZETToUInt32 ULongPtrToUInt
|
||||
|
||||
//
|
||||
// SIZE_T -> UINT_PTR conversion
|
||||
//
|
||||
#define SIZETToUIntPtr ULongPtrToUIntPtr
|
||||
|
||||
//
|
||||
// SIZE_T -> LONG conversion
|
||||
//
|
||||
#define SIZETToLong ULongPtrToLong
|
||||
|
||||
//
|
||||
// SIZE_T -> LONG_PTR conversion
|
||||
//
|
||||
#define SIZETToLongPtr ULongPtrToLongPtr
|
||||
|
||||
//
|
||||
// SIZE_T -> ULONG conversion
|
||||
//
|
||||
#define SIZETToULong ULongPtrToULong
|
||||
|
||||
//
|
||||
// SIZE_T -> DWORD conversion
|
||||
//
|
||||
#define SIZETToDWord ULongPtrToULong
|
||||
|
||||
//
|
||||
// SIZE_T -> LONGLONG conversion
|
||||
//
|
||||
#define SIZETToLongLong ULongPtrToLongLong
|
||||
|
||||
//
|
||||
// SIZE_T -> LONG64 conversion
|
||||
//
|
||||
#define SIZETToLong64 ULongPtrToLongLong
|
||||
|
||||
//
|
||||
// SIZE_T -> INT64
|
||||
//
|
||||
#define SIZETToInt64 ULongPtrToLongLong
|
||||
|
||||
//
|
||||
// SIZE_T -> ptrdiff_t conversion
|
||||
//
|
||||
#define SIZETToPtrdiffT ULongPtrToIntPtr
|
||||
|
||||
//
|
||||
// SIZE_T -> SSIZE_T conversion
|
||||
//
|
||||
#define SIZETToSSIZET ULongPtrToLongPtr
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// Addition functions
|
||||
//=============================================================================
|
||||
|
||||
//
|
||||
// UINT8 addition
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UInt8Add(
|
||||
__inn UINT8 u8Augend,
|
||||
__inn UINT8 u8Addend,
|
||||
__outt __deref_out_range(==,u8Augend + u8Addend) UINT8* pu8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (((UINT8)(u8Augend + u8Addend)) >= u8Augend)
|
||||
{
|
||||
*pu8Result = (UINT8)(u8Augend + u8Addend);
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pu8Result = UINT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// USHORT addition
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UShortAdd(
|
||||
__inn USHORT usAugend,
|
||||
__inn USHORT usAddend,
|
||||
__outt __deref_out_range(==,usAugend + usAddend) USHORT* pusResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (((USHORT)(usAugend + usAddend)) >= usAugend)
|
||||
{
|
||||
*pusResult = (USHORT)(usAugend + usAddend);
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pusResult = USHORT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// UINT16 addition
|
||||
//
|
||||
#define UInt16Add UShortAdd
|
||||
|
||||
//
|
||||
// WORD addtition
|
||||
//
|
||||
#define WordAdd UShortAdd
|
||||
|
||||
//
|
||||
// UINT addition
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UIntAdd(
|
||||
__inn UINT uAugend,
|
||||
__inn UINT uAddend,
|
||||
__outt __deref_out_range(==,uAugend + uAddend) UINT* puResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((uAugend + uAddend) >= uAugend)
|
||||
{
|
||||
*puResult = (uAugend + uAddend);
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*puResult = UINT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// UINT32 addition
|
||||
//
|
||||
#define UInt32Add UIntAdd
|
||||
|
||||
//
|
||||
// UINT_PTR addition
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define UIntPtrAdd ULongLongAdd
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
UIntPtrAdd(
|
||||
__inn UINT_PTR uAugend,
|
||||
__inn UINT_PTR uAddend,
|
||||
__outt __deref_out_range(==,uAugend + uAddend) UINT_PTR* puResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((uAugend + uAddend) >= uAugend)
|
||||
{
|
||||
*puResult = (uAugend + uAddend);
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*puResult = UINT_PTR_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
#endif // _WIN64
|
||||
|
||||
//
|
||||
// ULONG addition
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongAdd(
|
||||
__inn ULONG ulAugend,
|
||||
__inn ULONG ulAddend,
|
||||
__outt __deref_out_range(==,ulAugend + ulAddend) ULONG* pulResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((ulAugend + ulAddend) >= ulAugend)
|
||||
{
|
||||
*pulResult = (ulAugend + ulAddend);
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pulResult = ULONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONG_PTR addition
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define ULongPtrAdd ULongLongAdd
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
ULongPtrAdd(
|
||||
__inn ULONG_PTR ulAugend,
|
||||
__inn ULONG_PTR ulAddend,
|
||||
__outt __deref_out_range(==,ulAugend + ulAddend) ULONG_PTR* pulResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((ulAugend + ulAddend) >= ulAugend)
|
||||
{
|
||||
*pulResult = (ulAugend + ulAddend);
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pulResult = ULONG_PTR_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
#endif // _WIN64
|
||||
|
||||
//
|
||||
// DWORD addition
|
||||
//
|
||||
#define DWordAdd ULongAdd
|
||||
|
||||
//
|
||||
// DWORD_PTR addition
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define DWordPtrAdd ULongLongAdd
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
DWordPtrAdd(
|
||||
__inn DWORD_PTR dwAugend,
|
||||
__inn DWORD_PTR dwAddend,
|
||||
__outt __deref_out_range(==,dwAugend + dwAddend) DWORD_PTR* pdwResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((dwAugend + dwAddend) >= dwAugend)
|
||||
{
|
||||
*pdwResult = (dwAugend + dwAddend);
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pdwResult = DWORD_PTR_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
#endif // _WIN64
|
||||
|
||||
//
|
||||
// size_t addition
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
SizeTAdd(
|
||||
__inn size_t Augend,
|
||||
__inn size_t Addend,
|
||||
__outt __deref_out_range(==,Augend + Addend) size_t* pResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((Augend + Addend) >= Augend)
|
||||
{
|
||||
*pResult = (Augend + Addend);
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pResult = SIZE_T_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// SIZE_T addition
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define SIZETAdd ULongLongAdd
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
SIZETAdd(
|
||||
__inn SIZE_T Augend,
|
||||
__inn SIZE_T Addend,
|
||||
__outt __deref_out_range(==,Augend + Addend) SIZE_T* pResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((Augend + Addend) >= Augend)
|
||||
{
|
||||
*pResult = (Augend + Addend);
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pResult = _SIZE_T_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
#endif // _WIN64
|
||||
|
||||
//
|
||||
// ULONGLONG addition
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongLongAdd(
|
||||
__inn ULONGLONG ullAugend,
|
||||
__inn ULONGLONG ullAddend,
|
||||
__outt __deref_out_range(==,ullAugend + ullAddend) ULONGLONG* pullResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if ((ullAugend + ullAddend) >= ullAugend)
|
||||
{
|
||||
*pullResult = (ullAugend + ullAddend);
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pullResult = ULONGLONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// DWORDLONG addition
|
||||
//
|
||||
#define DWordLongAdd ULongLongAdd
|
||||
|
||||
//
|
||||
// ULONG64 addition
|
||||
//
|
||||
#define ULong64Add ULongLongAdd
|
||||
|
||||
//
|
||||
// DWORD64 addition
|
||||
//
|
||||
#define DWord64Add ULongLongAdd
|
||||
|
||||
//
|
||||
// UINT64 addition
|
||||
//
|
||||
#define UInt64Add ULongLongAdd
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// Subtraction functions
|
||||
//=============================================================================
|
||||
|
||||
//
|
||||
// UINT8 subtraction
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UInt8Sub(
|
||||
__inn UINT8 u8Minuend,
|
||||
__inn UINT8 u8Subtrahend,
|
||||
__outt __deref_out_range(==,u8Minuend - u8Subtrahend) UINT8* pu8Result)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (u8Minuend >= u8Subtrahend)
|
||||
{
|
||||
*pu8Result = (UINT8)(u8Minuend - u8Subtrahend);
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pu8Result = UINT8_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// USHORT subtraction
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UShortSub(
|
||||
__inn USHORT usMinuend,
|
||||
__inn USHORT usSubtrahend,
|
||||
__outt __deref_out_range(==,usMinuend - usSubtrahend) USHORT* pusResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (usMinuend >= usSubtrahend)
|
||||
{
|
||||
*pusResult = (USHORT)(usMinuend - usSubtrahend);
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pusResult = USHORT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// UINT16 subtraction
|
||||
//
|
||||
#define UInt16Sub UShortSub
|
||||
|
||||
//
|
||||
// WORD subtraction
|
||||
//
|
||||
#define WordSub UShortSub
|
||||
|
||||
|
||||
//
|
||||
// UINT subtraction
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UIntSub(
|
||||
__inn UINT uMinuend,
|
||||
__inn UINT uSubtrahend,
|
||||
__outt __deref_out_range(==,uMinuend - uSubtrahend) UINT* puResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (uMinuend >= uSubtrahend)
|
||||
{
|
||||
*puResult = (uMinuend - uSubtrahend);
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*puResult = UINT_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// UINT32 subtraction
|
||||
//
|
||||
#define UInt32Sub UIntSub
|
||||
|
||||
//
|
||||
// UINT_PTR subtraction
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define UIntPtrSub ULongLongSub
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
UIntPtrSub(
|
||||
__inn UINT_PTR uMinuend,
|
||||
__inn UINT_PTR uSubtrahend,
|
||||
__outt __deref_out_range(==,uMinuend - uSubtrahend) UINT_PTR* puResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (uMinuend >= uSubtrahend)
|
||||
{
|
||||
*puResult = (uMinuend - uSubtrahend);
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*puResult = UINT_PTR_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
#endif // _WIN64
|
||||
|
||||
//
|
||||
// ULONG subtraction
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongSub(
|
||||
__inn ULONG ulMinuend,
|
||||
__inn ULONG ulSubtrahend,
|
||||
__outt __deref_out_range(==,ulMinuend - ulSubtrahend) ULONG* pulResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ulMinuend >= ulSubtrahend)
|
||||
{
|
||||
*pulResult = (ulMinuend - ulSubtrahend);
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pulResult = ULONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// ULONG_PTR subtraction
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define ULongPtrSub ULongLongSub
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
ULongPtrSub(
|
||||
__inn ULONG_PTR ulMinuend,
|
||||
__inn ULONG_PTR ulSubtrahend,
|
||||
__outt __deref_out_range(==,ulMinuend - ulSubtrahend) ULONG_PTR* pulResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ulMinuend >= ulSubtrahend)
|
||||
{
|
||||
*pulResult = (ulMinuend - ulSubtrahend);
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pulResult = ULONG_PTR_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
#endif // _WIN64
|
||||
|
||||
|
||||
//
|
||||
// DWORD subtraction
|
||||
//
|
||||
#define DWordSub ULongSub
|
||||
|
||||
//
|
||||
// DWORD_PTR subtraction
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define DWordPtrSub ULongLongSub
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
DWordPtrSub(
|
||||
__inn DWORD_PTR dwMinuend,
|
||||
__inn DWORD_PTR dwSubtrahend,
|
||||
__outt __deref_out_range(==,dwMinuend - dwSubtrahend) DWORD_PTR* pdwResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (dwMinuend >= dwSubtrahend)
|
||||
{
|
||||
*pdwResult = (dwMinuend - dwSubtrahend);
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pdwResult = DWORD_PTR_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
#endif // _WIN64
|
||||
|
||||
//
|
||||
// size_t subtraction
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
SizeTSub(
|
||||
__inn size_t Minuend,
|
||||
__inn size_t Subtrahend,
|
||||
__outt __deref_out_range(==,Minuend - Subtrahend) size_t* pResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (Minuend >= Subtrahend)
|
||||
{
|
||||
*pResult = (Minuend - Subtrahend);
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pResult = SIZE_T_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// SIZE_T subtraction
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define SIZETSub ULongLongSub
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
SIZETSub(
|
||||
__inn SIZE_T Minuend,
|
||||
__inn SIZE_T Subtrahend,
|
||||
__outt __deref_out_range(==,Minuend - Subtrahend) SIZE_T* pResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (Minuend >= Subtrahend)
|
||||
{
|
||||
*pResult = (Minuend - Subtrahend);
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pResult = _SIZE_T_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
#endif // _WIN64
|
||||
|
||||
//
|
||||
// ULONGLONG subtraction
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongLongSub(
|
||||
__inn ULONGLONG ullMinuend,
|
||||
__inn ULONGLONG ullSubtrahend,
|
||||
__outt __deref_out_range(==,ullMinuend - ullSubtrahend) ULONGLONG* pullResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (ullMinuend >= ullSubtrahend)
|
||||
{
|
||||
*pullResult = (ullMinuend - ullSubtrahend);
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pullResult = ULONGLONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// DWORDLONG subtraction
|
||||
//
|
||||
#define DWordLongSub ULongLongSub
|
||||
|
||||
//
|
||||
// ULONG64 subtraction
|
||||
//
|
||||
#define ULong64Sub ULongLongSub
|
||||
|
||||
//
|
||||
// DWORD64 subtraction
|
||||
//
|
||||
#define DWord64Sub ULongLongSub
|
||||
|
||||
//
|
||||
// UINT64 subtraction
|
||||
//
|
||||
#define UInt64Sub ULongLongSub
|
||||
|
||||
|
||||
//=============================================================================
|
||||
// Multiplication functions
|
||||
//=============================================================================
|
||||
|
||||
//
|
||||
// UINT8 multiplication
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UInt8Mult(
|
||||
__inn UINT8 u8Multiplicand,
|
||||
__inn UINT8 u8Multiplier,
|
||||
__outt __deref_out_range(==,u8Multiplier * u8Multiplicand) UINT8* pu8Result)
|
||||
{
|
||||
UINT uResult = ((UINT)u8Multiplicand) * ((UINT)u8Multiplier);
|
||||
|
||||
return UIntToUInt8(uResult, pu8Result);
|
||||
}
|
||||
|
||||
//
|
||||
// USHORT multiplication
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UShortMult(
|
||||
__inn USHORT usMultiplicand,
|
||||
__inn USHORT usMultiplier,
|
||||
__outt __deref_out_range(==,usMultiplier * usMultiplicand)USHORT* pusResult)
|
||||
{
|
||||
ULONG ulResult = ((ULONG)usMultiplicand) * ((ULONG)usMultiplier);
|
||||
|
||||
return ULongToUShort(ulResult, pusResult);
|
||||
}
|
||||
|
||||
//
|
||||
// UINT16 multiplication
|
||||
//
|
||||
#define UInt16Mult UShortMult
|
||||
|
||||
//
|
||||
// WORD multiplication
|
||||
//
|
||||
#define WordMult UShortMult
|
||||
|
||||
//
|
||||
// UINT multiplication
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
UIntMult(
|
||||
__inn UINT uMultiplicand,
|
||||
__inn UINT uMultiplier,
|
||||
__outt __deref_out_range(==,uMultiplier * uMultiplicand) UINT* puResult)
|
||||
{
|
||||
ULONGLONG ull64Result = UInt32x32To64(uMultiplicand, uMultiplier);
|
||||
|
||||
return ULongLongToUInt(ull64Result, puResult);
|
||||
}
|
||||
|
||||
//
|
||||
// UINT32 multiplication
|
||||
//
|
||||
#define UInt32Mult UIntMult
|
||||
|
||||
//
|
||||
// UINT_PTR multiplication
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define UIntPtrMult ULongLongMult
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
UIntPtrMult(
|
||||
__inn UINT_PTR uMultiplicand,
|
||||
__inn UINT_PTR uMultiplier,
|
||||
__outt __deref_out_range(==,uMultiplier * uMultiplicand) UINT_PTR* puResult)
|
||||
{
|
||||
ULONGLONG ull64Result = UInt32x32To64(uMultiplicand, uMultiplier);
|
||||
|
||||
return ULongLongToUIntPtr(ull64Result, puResult);
|
||||
}
|
||||
#endif // _WIN64
|
||||
|
||||
//
|
||||
// ULONG multiplication
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongMult(
|
||||
__inn ULONG ulMultiplicand,
|
||||
__inn ULONG ulMultiplier,
|
||||
__outt __deref_out_range(==,ulMultiplier * ulMultiplicand) ULONG* pulResult)
|
||||
{
|
||||
ULONGLONG ull64Result = UInt32x32To64(ulMultiplicand, ulMultiplier);
|
||||
|
||||
return ULongLongToULong(ull64Result, pulResult);
|
||||
}
|
||||
|
||||
//
|
||||
// ULONG_PTR multiplication
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define ULongPtrMult ULongLongMult
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
ULongPtrMult(
|
||||
__inn ULONG_PTR ulMultiplicand,
|
||||
__inn ULONG_PTR ulMultiplier,
|
||||
__outt __deref_out_range(==,ulMultiplier * ulMultiplicand) ULONG_PTR* pulResult)
|
||||
{
|
||||
ULONGLONG ull64Result = UInt32x32To64(ulMultiplicand, ulMultiplier);
|
||||
|
||||
return ULongLongToULongPtr(ull64Result, (unsigned long *)pulResult);
|
||||
}
|
||||
#endif // _WIN64
|
||||
|
||||
//
|
||||
// DWORD multiplication
|
||||
//
|
||||
#define DWordMult ULongMult
|
||||
|
||||
//
|
||||
// DWORD_PTR multiplication
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define DWordPtrMult ULongLongMult
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
DWordPtrMult(
|
||||
__inn DWORD_PTR dwMultiplicand,
|
||||
__inn DWORD_PTR dwMultiplier,
|
||||
__outt __deref_out_range(==,dwMultiplier * dwMultiplicand) DWORD_PTR* pdwResult)
|
||||
{
|
||||
ULONGLONG ull64Result = UInt32x32To64(dwMultiplicand, dwMultiplier);
|
||||
|
||||
return ULongLongToDWordPtr(ull64Result, (unsigned long *)pdwResult);
|
||||
}
|
||||
#endif // _WIN64
|
||||
|
||||
//
|
||||
// size_t multiplication
|
||||
//
|
||||
|
||||
#ifdef _WIN64
|
||||
#define SizeTMult ULongLongMult
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
SizeTMult(
|
||||
__inn size_t Multiplicand,
|
||||
__inn size_t Multiplier,
|
||||
__outt __deref_out_range(==,Multiplier * Multiplicand) UINT* pResult)
|
||||
{
|
||||
ULONGLONG ull64Result = UInt32x32To64(Multiplicand, Multiplier);
|
||||
|
||||
return ULongLongToSizeT(ull64Result, pResult);
|
||||
}
|
||||
#endif // _WIN64
|
||||
|
||||
//
|
||||
// SIZE_T multiplication
|
||||
//
|
||||
#ifdef _WIN64
|
||||
#define SIZETMult ULongLongMult
|
||||
#else
|
||||
__inline
|
||||
HRESULT
|
||||
SIZETMult(
|
||||
__inn SIZE_T Multiplicand,
|
||||
__inn SIZE_T Multiplier,
|
||||
__outt __deref_out_range(==,Multiplier * Multiplicand) SIZE_T* pResult)
|
||||
{
|
||||
ULONGLONG ull64Result = UInt32x32To64(Multiplicand, Multiplier);
|
||||
|
||||
return ULongLongToSIZET(ull64Result, (unsigned long *)pResult);
|
||||
}
|
||||
#endif // _WIN64
|
||||
|
||||
//
|
||||
// ULONGLONG multiplication
|
||||
//
|
||||
__inline
|
||||
HRESULT
|
||||
ULongLongMult(
|
||||
__inn ULONGLONG ullMultiplicand,
|
||||
__inn ULONGLONG ullMultiplier,
|
||||
__outt __deref_out_range(==,ullMultiplier * ullMultiplicand) ULONGLONG* pullResult)
|
||||
{
|
||||
HRESULT hr;
|
||||
#ifdef _AMD64_
|
||||
ULONGLONG u64ResultHigh;
|
||||
ULONGLONG u64ResultLow;
|
||||
|
||||
u64ResultLow = UnsignedMultiply128(ullMultiplicand, ullMultiplier, &u64ResultHigh);
|
||||
if (u64ResultHigh == 0)
|
||||
{
|
||||
*pullResult = u64ResultLow;
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pullResult = ULONGLONG_ERROR;
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
}
|
||||
#else
|
||||
// 64x64 into 128 is like 32.32 x 32.32.
|
||||
//
|
||||
// a.b * c.d = a*(c.d) + .b*(c.d) = a*c + a*.d + .b*c + .b*.d
|
||||
// back in non-decimal notation where A=a*2^32 and C=c*2^32:
|
||||
// A*C + A*d + b*C + b*d
|
||||
// So there are four components to add together.
|
||||
// result = (a*c*2^64) + (a*d*2^32) + (b*c*2^32) + (b*d)
|
||||
//
|
||||
// a * c must be 0 or there would be bits in the high 64-bits
|
||||
// a * d must be less than 2^32 or there would be bits in the high 64-bits
|
||||
// b * c must be less than 2^32 or there would be bits in the high 64-bits
|
||||
// then there must be no overflow of the resulting values summed up.
|
||||
|
||||
ULONG dw_a;
|
||||
ULONG dw_b;
|
||||
ULONG dw_c;
|
||||
ULONG dw_d;
|
||||
ULONGLONG ad = 0;
|
||||
ULONGLONG bc = 0;
|
||||
ULONGLONG bd = 0;
|
||||
ULONGLONG ullResult = 0;
|
||||
|
||||
hr = INTSAFE_E_ARITHMETIC_OVERFLOW;
|
||||
|
||||
dw_a = (ULONG)(ullMultiplicand >> 32);
|
||||
dw_c = (ULONG)(ullMultiplier >> 32);
|
||||
|
||||
// common case -- if high dwords are both zero, no chance for overflow
|
||||
if ((dw_a == 0) && (dw_c == 0))
|
||||
{
|
||||
dw_b = (DWORD)ullMultiplicand;
|
||||
dw_d = (DWORD)ullMultiplier;
|
||||
|
||||
*pullResult = (((ULONGLONG)dw_b) * (ULONGLONG)dw_d);
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
// a * c must be 0 or there would be bits set in the high 64-bits
|
||||
if ((dw_a == 0) ||
|
||||
(dw_c == 0))
|
||||
{
|
||||
dw_d = (DWORD)ullMultiplier;
|
||||
|
||||
// a * d must be less than 2^32 or there would be bits set in the high 64-bits
|
||||
ad = (((ULONGLONG)dw_a) * (ULONGLONG)dw_d);
|
||||
if ((ad & 0xffffffff00000000LL) == 0)
|
||||
{
|
||||
dw_b = (DWORD)ullMultiplicand;
|
||||
|
||||
// b * c must be less than 2^32 or there would be bits set in the high 64-bits
|
||||
bc = (((ULONGLONG)dw_b) * (ULONGLONG)dw_c);
|
||||
if ((bc & 0xffffffff00000000LL) == 0)
|
||||
{
|
||||
// now sum them all up checking for overflow.
|
||||
// shifting is safe because we already checked for overflow above
|
||||
if (SUCCEEDED(ULongLongAdd(bc << 32, ad << 32, &ullResult)))
|
||||
{
|
||||
// b * d
|
||||
bd = (((ULONGLONG)dw_b) * (ULONGLONG)dw_d);
|
||||
|
||||
if (SUCCEEDED(ULongLongAdd(ullResult, bd, &ullResult)))
|
||||
{
|
||||
*pullResult = ullResult;
|
||||
hr = S_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
*pullResult = ULONGLONG_ERROR;
|
||||
}
|
||||
#endif // _AMD64_
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
//
|
||||
// DWORDLONG multiplication
|
||||
//
|
||||
#define DWordLongMult ULongLongMult
|
||||
|
||||
//
|
||||
// ULONG64 multiplication
|
||||
//
|
||||
#define ULong64Mult ULongLongMult
|
||||
|
||||
//
|
||||
// DWORD64 multiplication
|
||||
//
|
||||
#define DWord64Mult ULongLongMult
|
||||
|
||||
//
|
||||
// UINT64 multiplication
|
||||
//
|
||||
#define UInt64Mult ULongLongMult
|
||||
|
||||
//
|
||||
// Macros that are no longer used in this header but which clients may
|
||||
// depend on being defined here.
|
||||
//
|
||||
#define LOWORD(_dw) ((WORD)(((DWORD_PTR)(_dw)) & 0xffff))
|
||||
#define HIWORD(_dw) ((WORD)((((DWORD_PTR)(_dw)) >> 16) & 0xffff))
|
||||
#define LODWORD(_qw) ((DWORD)(_qw))
|
||||
#define HIDWORD(_qw) ((DWORD)(((_qw) >> 32) & 0xffffffff))
|
||||
|
||||
#endif // XPLAT_INTSAFE_H
|
878
source/shared/localization.hpp
Normal file
878
source/shared/localization.hpp
Normal file
|
@ -0,0 +1,878 @@
|
|||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
// File: Localization.hpp
|
||||
//
|
||||
// Contents: Contains portable classes for localization
|
||||
//
|
||||
// Microsoft Drivers 4.0 for PHP for SQL Server
|
||||
// Copyright(c) Microsoft Corporation
|
||||
// All rights reserved.
|
||||
// MIT License
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""),
|
||||
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef __LOCALIZATION_HPP__
|
||||
#define __LOCALIZATION_HPP__
|
||||
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
#include "typedefs_for_linux.h"
|
||||
|
||||
#ifdef MPLAT_UNIX
|
||||
namespace std
|
||||
{
|
||||
// Forward reference
|
||||
class locale;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define CP_UTF8 65001
|
||||
#define CP_UTF16 1200
|
||||
#define CP_UTF32 12000
|
||||
#define CP_ACP 0 // default to ANSI code page
|
||||
|
||||
// This class provides allocation policies for the SystemLocale and AutoArray classes.
|
||||
// This is primarily needed for the self-allocating ToUtf16/FromUtf16 methods.
|
||||
// SNI needs all its allocations to use its own allocator so it would create a separate
|
||||
// class that obeys this interface and provide it as a template parameter.
|
||||
template< typename ArrayT >
|
||||
struct ArrayTAllocator
|
||||
{
|
||||
static ArrayT * Alloc( size_t cch )
|
||||
{
|
||||
return reinterpret_cast< ArrayT * >( malloc(cch*sizeof(ArrayT)) );
|
||||
}
|
||||
// Realloc will free the 'old' memory if new memory was successfully allocated
|
||||
// and copied to.
|
||||
static ArrayT * Realloc( ArrayT * old, size_t cchNewSize )
|
||||
{
|
||||
return reinterpret_cast< ArrayT * >( realloc(old, cchNewSize*sizeof(ArrayT)) );
|
||||
}
|
||||
static void Free( ArrayT * mem )
|
||||
{
|
||||
free( mem );
|
||||
}
|
||||
};
|
||||
|
||||
// This is an auto_ptr-like class that is used with the SystemLocale.
|
||||
// It allows for automatic freeing of the memory using the allocator policy.
|
||||
// Callers would not normally use this class directly but would use one of the
|
||||
// two specializations: AutoCharArray AutoWCharArray.
|
||||
template< typename ArrayT, typename AllocT = ArrayTAllocator< ArrayT > >
|
||||
struct AutoArray
|
||||
{
|
||||
size_t m_cchSize;
|
||||
ArrayT * m_ptr;
|
||||
|
||||
AutoArray( const AutoArray & );
|
||||
AutoArray & operator=( const AutoArray & );
|
||||
|
||||
AutoArray()
|
||||
: m_cchSize( 0 ), m_ptr( NULL )
|
||||
{
|
||||
}
|
||||
explicit AutoArray( size_t cchSize )
|
||||
: m_cchSize( cchSize ), m_ptr( AllocT::Alloc(cchSize) )
|
||||
{
|
||||
}
|
||||
virtual ~AutoArray()
|
||||
{
|
||||
Free();
|
||||
}
|
||||
void Free()
|
||||
{
|
||||
if ( NULL != m_ptr )
|
||||
{
|
||||
AllocT::Free( m_ptr );
|
||||
m_ptr = NULL;
|
||||
m_cchSize = 0;
|
||||
}
|
||||
}
|
||||
bool Realloc( size_t cchSize )
|
||||
{
|
||||
ArrayT * newPtr = AllocT::Realloc( m_ptr, cchSize );
|
||||
if ( NULL != newPtr )
|
||||
{
|
||||
// Safe to overwrite since Realloc freed m_ptr.
|
||||
m_ptr = newPtr;
|
||||
m_cchSize = cchSize;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
ArrayT * Detach()
|
||||
{
|
||||
ArrayT * oldPtr = m_ptr;
|
||||
m_ptr = NULL;
|
||||
m_cchSize = 0;
|
||||
return oldPtr;
|
||||
}
|
||||
void UpdateSize()
|
||||
{
|
||||
if ( NULL == m_ptr )
|
||||
{
|
||||
m_cchSize = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// XPLAT_ODBC_TODO VSTS 819733 MPlat: Reconcile std c++ usage between platforms
|
||||
// Should use char_traits<ArrayT>::length
|
||||
ArrayT * end = m_ptr;
|
||||
while ( (ArrayT)0 != *end++ )
|
||||
;
|
||||
// Want the null terminator included
|
||||
m_cchSize = end - m_ptr;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class SystemLocale
|
||||
{
|
||||
public:
|
||||
// -----------------------------------------------------------------------
|
||||
// Public Static Functions
|
||||
#ifdef MPLAT_UNIX
|
||||
static const SystemLocale & Singleton();
|
||||
#else
|
||||
// Windows returns by value since this is an empty class
|
||||
static const SystemLocale Singleton();
|
||||
#endif
|
||||
|
||||
#ifdef MPLAT_UNIX
|
||||
int GetResourcePath( char * buffer, size_t cchBuffer ) const;
|
||||
|
||||
static const int MINS_PER_HOUR = 60;
|
||||
static const int MINS_PER_DAY = 24 * MINS_PER_HOUR;
|
||||
|
||||
// Returns the bias between the supplied utc and local times.
|
||||
// utc = local + bias
|
||||
static int BiasInMinutes( const struct tm & utc, const struct tm & local )
|
||||
{
|
||||
int bias = 0;
|
||||
if ( utc.tm_mon != local.tm_mon )
|
||||
{
|
||||
// Offset crosses month boundary so one of two must be first day of month
|
||||
if ( 1 == utc.tm_mday )
|
||||
bias += MINS_PER_DAY;
|
||||
else
|
||||
{
|
||||
assert( 1 == local.tm_mday );
|
||||
bias -= MINS_PER_DAY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bias += MINS_PER_DAY * (utc.tm_mday - local.tm_mday);
|
||||
}
|
||||
|
||||
bias += MINS_PER_HOUR * (utc.tm_hour - local.tm_hour);
|
||||
bias += (utc.tm_min - local.tm_min);
|
||||
|
||||
// Round based on diff in secs, in case utc/local straddle a day with leap seconds
|
||||
int secs_diff = (utc.tm_sec - local.tm_sec);
|
||||
if ( 29 < secs_diff )
|
||||
++bias;
|
||||
else if ( secs_diff < -29 )
|
||||
--bias;
|
||||
|
||||
return bias;
|
||||
}
|
||||
|
||||
// Returns both standard and daylight savings biases for the current year
|
||||
// utc = local + bias
|
||||
// Both might be equal if DST is not honored
|
||||
// If platform doesn't know if bias is DST or standard (ie. unknown)
|
||||
// then standard time is assumed.
|
||||
// Note that applying current year's biases to dates from other years may result
|
||||
// in incorrect time adjustments since regions change their rules over time.
|
||||
// The current SNAC driver code uses this approach as well so we are doing this
|
||||
// to preserve consistent behavior. If SNAC changes to lookup the offsets that
|
||||
// were effective for a given date then we should update our logic here as well.
|
||||
static DWORD TimeZoneBiases( int * stdInMinutes, int * dstInMinutes )
|
||||
{
|
||||
struct tm local, utc;
|
||||
// Find current year
|
||||
time_t now = time( NULL );
|
||||
if ( (time_t)(-1) == now || NULL == localtime_r(&now, &local) )
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
// Find bias for first of each month until both STD and DST are found
|
||||
// Possible perf improvements (can wait until perf tests indicate a need):
|
||||
// Just use Dec 21 and Jun 21 (near the two soltices)
|
||||
// Or calc once and cache (must be thread safe)
|
||||
bool foundUNK = false;
|
||||
bool foundSTD = false;
|
||||
bool foundDST = false;
|
||||
int std_bias = 0;
|
||||
int dst_bias = 0;
|
||||
|
||||
local.tm_mday = 1;
|
||||
for ( int mon = 0; mon < 12; ++mon )
|
||||
{
|
||||
local.tm_mon = mon;
|
||||
if ( (time_t)(-1) == (now = mktime(&local)) || NULL == gmtime_r(&now, &utc) )
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
if ( 0 < local.tm_isdst )
|
||||
{
|
||||
if ( !foundDST )
|
||||
{
|
||||
dst_bias = BiasInMinutes( utc, local );
|
||||
foundDST = true;
|
||||
if ( foundSTD )
|
||||
break; // Done checking when both STD & DST are found
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Time is STD or unknown, put in STD
|
||||
if ( !foundSTD )
|
||||
{
|
||||
std_bias = BiasInMinutes( utc, local );
|
||||
if ( local.tm_isdst < 0 )
|
||||
foundUNK = true;
|
||||
else
|
||||
{
|
||||
foundSTD = true;
|
||||
if ( foundDST )
|
||||
break; // Done checking when both STD and DST are found
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// At least one of STD, DST, or unknown must have been set
|
||||
assert( foundSTD || foundDST || foundUNK );
|
||||
|
||||
// For zones that don't observe DST (somewhat common),
|
||||
// report DST bias as the same as STD
|
||||
if ( !foundDST )
|
||||
dst_bias = std_bias;
|
||||
|
||||
// For zones that ONLY observe DST (extremely rare if at all),
|
||||
// report STD bias as the same as DST
|
||||
if ( !foundSTD && !foundUNK )
|
||||
std_bias = dst_bias;
|
||||
|
||||
*stdInMinutes = std_bias;
|
||||
*dstInMinutes = dst_bias;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
static DWORD CurrentLocalTime( LPSYSTEMTIME pTime );
|
||||
|
||||
// Multi-byte UTF8 code points start with '11xx xxxx'
|
||||
static bool IsUtf8LeadByte( BYTE utf8 )
|
||||
{
|
||||
return (0xC0 == (utf8 & 0xC0));
|
||||
}
|
||||
|
||||
// Maximum number of storage units (char or WCHAR)
|
||||
// for a code page (e.g. UTF16 == 2 for surrogates)
|
||||
static UINT MaxCharCchSize( UINT codepage );
|
||||
|
||||
// Inspects the byte at start, and returns the start
|
||||
// of the next code point (possibly multiple bytes later).
|
||||
// If NULL or start points at null terminator, than start is returned.
|
||||
// If start points at a dangling UTF8 trail byte, then (start+1) is
|
||||
// returned since we can't know how large this code point is.
|
||||
static char * NextChar( UINT codepage, const char * start );
|
||||
#ifdef MPLAT_UNIX
|
||||
// This version is for non-null terminated strings.
|
||||
// Last ptr will be one past end of buffer.
|
||||
static char * NextChar( UINT codepage, const char * start, size_t cchBytesLeft );
|
||||
#endif
|
||||
|
||||
// Given the start byte, how many total bytes are expected for
|
||||
// this code point. If start is a UTF8 trail byte, then 1 is returned.
|
||||
static UINT CchExpectedNextChar( UINT codepage, BYTE start )
|
||||
{
|
||||
if ( 0 == (start & (char)0x80) )
|
||||
return 1; // ASCII
|
||||
else if ( CP_UTF8 == codepage )
|
||||
return IsUtf8LeadByte(start) ? CchUtf8CodePt(start) : 1;
|
||||
else if ( IsDBCSLeadByteEx(codepage, start) )
|
||||
return 2;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Returns the number of bytes that need to be trimmed to avoid splitting
|
||||
// a multi-byte code point sequence at the end of the buffer.
|
||||
// Returns zero if a trailing UTF8 code value is found but no
|
||||
// matching lead byte was found for it (ie. invalid, dangling trail byte).
|
||||
_Ret_range_(0, cchBuffer) static UINT TrimPartialCodePt( UINT codepage, _In_count_(cchBuffer) const BYTE * buffer, size_t cchBuffer )
|
||||
{
|
||||
if ( 0 == cchBuffer )
|
||||
return 0;
|
||||
|
||||
if ( CP_UTF8 == codepage )
|
||||
{
|
||||
return TrimPartialUtf8CodePt( buffer, cchBuffer );
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t i = cchBuffer;
|
||||
for ( ; 0 < i; --i )
|
||||
{
|
||||
if ( !IsDBCSLeadByteEx( codepage, buffer[i-1] ) )
|
||||
break;
|
||||
}
|
||||
// If odd, then last byte is truly a lead byte so return 1 byte to trim
|
||||
return ((cchBuffer-i) & 1) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
// For all transcoding functions
|
||||
// Returns zero on error. Do not call GetLastError() since that is not portable (pErrorCode has result of GetLastError()).
|
||||
// pHasDataLoss will be true if an unrecognized code point was encountered in the source and a default output instead.
|
||||
// Replaces calls to MultiByteToWideChar and WideCharToMultiByte
|
||||
|
||||
// Transcode between a code page and UTF16
|
||||
static size_t ToUtf16( UINT srcCodePage, const char * src, SSIZE_T cchSrc,
|
||||
__out_ecount_opt(cchDest) WCHAR * dest, size_t cchDest,
|
||||
DWORD * pErrorCode = NULL );
|
||||
static size_t ToUtf16Strict( UINT srcCodePage, const char * src, SSIZE_T cchSrc,
|
||||
__out_ecount_opt(cchDest) WCHAR * dest, size_t cchDest,
|
||||
DWORD * pErrorCode = NULL );
|
||||
static size_t FromUtf16( UINT destCodePage, const WCHAR * src, SSIZE_T cchSrc,
|
||||
__out_ecount_opt(cchDest) char * dest, size_t cchDest,
|
||||
bool * pHasDataLoss = NULL, DWORD * pErrorCode = NULL );
|
||||
static size_t FromUtf16Strict(UINT destCodePage, const WCHAR * src, SSIZE_T cchSrc,
|
||||
__out_ecount_opt(cchDest) char * dest, size_t cchDest,
|
||||
bool * pHasDataLoss = NULL, DWORD * pErrorCode = NULL);
|
||||
// Allocates destination buffer to match required size
|
||||
// Template is used so call can provide allocation policy
|
||||
// Used instead of the Windows API pattern of calling with zero dest buffer size to find
|
||||
// required buffer size, followed by second call with newly allocated buffer.
|
||||
template< typename AllocT >
|
||||
static size_t ToUtf16( UINT srcCodePage, const char * src, SSIZE_T cchSrc, __deref_out_ecount(1) WCHAR ** dest, DWORD * pErrorCode = NULL );
|
||||
template< typename AllocT >
|
||||
static size_t ToUtf16Strict( UINT srcCodePage, const char * src, SSIZE_T cchSrc, __deref_out_ecount(1) WCHAR ** dest, DWORD * pErrorCode = NULL );
|
||||
template< typename AllocT >
|
||||
static size_t FromUtf16( UINT destCodePage, const WCHAR * src, SSIZE_T cchSrc, __deref_out_ecount(1) char ** dest, bool * pHasDataLoss = NULL, DWORD * pErrorCode = NULL );
|
||||
template< typename AllocT >
|
||||
static size_t FromUtf16Strict(UINT destCodePage, const WCHAR * src, SSIZE_T cchSrc, __deref_out_ecount(1) char ** dest, bool * pHasDataLoss = NULL, DWORD * pErrorCode = NULL);
|
||||
|
||||
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Public Member Functions
|
||||
|
||||
#ifndef TIME_ZONE_ID_UNKNOWN
|
||||
#define TIME_ZONE_ID_UNKNOWN 0
|
||||
#define TIME_ZONE_ID_STANDARD 1
|
||||
#define TIME_ZONE_ID_DAYLIGHT 2
|
||||
#endif
|
||||
// pTZInfo, if supplied, holds one of the above defined values
|
||||
DWORD CurrentTimeZoneBias( LONG * offsetInMinutes, DWORD * pTZInfo = NULL ) const;
|
||||
|
||||
// The Ansi code page, always UTF8 for Linux
|
||||
UINT AnsiCP() const;
|
||||
// Used for files (e.g. returns 437 on US Windows, UTF8 for Linux)
|
||||
UINT OemCP() const;
|
||||
// Returns UTF-16LE for all platforms (LE == Little Endian)
|
||||
UINT WideCP() const
|
||||
{
|
||||
return CP_UTF16;
|
||||
}
|
||||
|
||||
// Performs case folding to lower case using the current system locale
|
||||
// Replaces calls to LCMapStringA
|
||||
size_t ToLower( const char * src, SSIZE_T cchSrc, __out_ecount_opt(cchDest) char * dest, size_t cchDest, DWORD * pErrorCode = NULL ) const;
|
||||
|
||||
#ifndef CSTR_ERROR
|
||||
#define CSTR_ERROR 0 // compare failed
|
||||
#define CSTR_LESS_THAN 1 // string 1 less than string 2
|
||||
#define CSTR_EQUAL 2 // string 1 equal to string 2
|
||||
#define CSTR_GREATER_THAN 3 // string 1 greater than string 2
|
||||
#endif
|
||||
// String comparison using the rules of the current system locale.
|
||||
// Replaces calls to CompareString
|
||||
// Ignoring width (Bing for "Full Width Characters") has no affect on Linux
|
||||
// Return value is one of the above defined values.
|
||||
// On error, pErrorCode has result of GetLastError() (do not call GetLastError directly since it isn't portable).
|
||||
int Compare( const char * left, SSIZE_T cchLeft, const char * right, SSIZE_T cchRight, DWORD * pErrorCode = NULL ) const;
|
||||
int CompareIgnoreCase( const char * left, SSIZE_T cchLeft, const char * right, SSIZE_T cchRight, DWORD * pErrorCode = NULL ) const;
|
||||
int CompareIgnoreWidth( const char * left, SSIZE_T cchLeft, const char * right, SSIZE_T cchRight, DWORD * pErrorCode = NULL ) const;
|
||||
int CompareIgnoreCaseAndWidth( const char * left, SSIZE_T cchLeft, const char * right, SSIZE_T cchRight, DWORD * pErrorCode = NULL ) const;
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
// Prevent copying.
|
||||
// Also prevents misuse of return from Singleton() method.
|
||||
// Since return types are different on Windows vs Linux,
|
||||
// callers should not cache the result of Singleton().
|
||||
SystemLocale( const SystemLocale & );
|
||||
SystemLocale & operator=( const SystemLocale & );
|
||||
|
||||
#ifdef MPLAT_UNIX
|
||||
// MPLAT_UNIX ----------------------------------------------------------------
|
||||
|
||||
std::locale * m_pLocale;
|
||||
|
||||
explicit SystemLocale( const char * localeName );
|
||||
~SystemLocale();
|
||||
|
||||
static UINT ExpandSpecialCP( UINT codepage )
|
||||
{
|
||||
// Convert CP_ACP, CP_OEM to CP_UTF8
|
||||
return (codepage < 2 ? CP_UTF8 : codepage);
|
||||
}
|
||||
|
||||
// MPLAT_UNIX ----------------------------------------------------------------
|
||||
#else
|
||||
// !MPLAT_UNIX ---------------------------------------------------------------
|
||||
|
||||
SystemLocale() {}
|
||||
|
||||
static size_t ReturnCchResult( SSIZE_T cch, DWORD * pErrorCode )
|
||||
{
|
||||
if ( cch < 0 )
|
||||
{
|
||||
cch = 0;
|
||||
}
|
||||
if ( NULL != pErrorCode )
|
||||
{
|
||||
*pErrorCode = (0 == cch ? GetLastError() : ERROR_SUCCESS);
|
||||
}
|
||||
return static_cast<size_t>(cch);
|
||||
}
|
||||
|
||||
static int CompareWithFlags( DWORD flags, const char * left, SSIZE_T cchLeft, const char * right, SSIZE_T cchRight, DWORD * pErrorCode = NULL );
|
||||
|
||||
static size_t FastAsciiMultiByteToWideChar
|
||||
(
|
||||
UINT CodePage,
|
||||
__in_ecount(cch) const char *pch, // IN | source string
|
||||
SSIZE_T cch, // IN | count of characters or -1
|
||||
__out_ecount_opt(cwch) PWCHAR pwch, // IN | Result string
|
||||
size_t cwch, // IN | count of wchars of result buffer or 0
|
||||
DWORD* pErrorCode, // OUT | optional pointer to return error code
|
||||
bool bStrict = false // IN | Return error if invalid chars in src
|
||||
);
|
||||
static size_t FastAsciiWideCharToMultiByte
|
||||
(
|
||||
UINT CodePage,
|
||||
const WCHAR *pwch, // IN | source string
|
||||
SSIZE_T cwch, // IN | count of characters or -1
|
||||
__out_bcount(cch) char *pch, // IN | Result string
|
||||
size_t cch, // IN | Length of result buffer or 0
|
||||
BOOL *pfDataLoss, // OUT | True if there was data loss during CP conversion
|
||||
DWORD *pErrorCode // OUT | optional pointer to return error code
|
||||
);
|
||||
|
||||
// !MPLAT_UNIX ---------------------------------------------------------------
|
||||
#endif
|
||||
|
||||
// Returns the number of bytes this UTF8 code point expects
|
||||
static UINT CchUtf8CodePt( BYTE codept )
|
||||
{
|
||||
assert( IsUtf8LeadByte(codept) );
|
||||
|
||||
// Initial byte of utf8 sequence indicates its length
|
||||
// 110x xxxx = 2 bytes
|
||||
// 1110 xxxx = 3 bytes
|
||||
// 1111 0xxx = 4 bytes
|
||||
// 1111 10xx = 5 bytes, future Unicode extension not covered by this logic
|
||||
// 1111 110x = 6 bytes, future Unicode extension not covered by this logic
|
||||
UINT expected_size = (0xC0 == (codept & 0xE0)) ? 2 : (0xE0 == (codept & 0xF0)) ? 3 : 4;
|
||||
|
||||
// Verify constraints
|
||||
assert( 4 == MaxCharCchSize(CP_UTF8) );
|
||||
|
||||
return expected_size;
|
||||
}
|
||||
|
||||
// Returns the number of bytes that need to be trimmed to avoid splitting
|
||||
// a UTF8 code point sequence at the end of the buffer.
|
||||
// Returns zero for ASCII.
|
||||
// Also returns zero if a trailing UTF8 code value is found but no
|
||||
// matching lead byte was found for it (ie. invalid, dangling trail byte).
|
||||
static UINT TrimPartialUtf8CodePt( const BYTE * buffer, size_t cchBuffer )
|
||||
{
|
||||
if ( 0 == cchBuffer )
|
||||
return 0;
|
||||
|
||||
if ( 0 == (buffer[cchBuffer-1] & 0x80) )
|
||||
{
|
||||
// Last char is ASCII so no trim needed
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Last char is non-initial byte of multibyte utf8 sequence
|
||||
// Need to determine if it is the last (ie. no trim need)
|
||||
UINT cchMax = MaxCharCchSize( CP_UTF8 );
|
||||
for ( UINT i = 1; 0 < cchBuffer && i <= cchMax; --cchBuffer, ++i )
|
||||
{
|
||||
if ( IsUtf8LeadByte(buffer[cchBuffer-1]) )
|
||||
{
|
||||
// Found initial byte, verify size of sequence
|
||||
UINT cchExpected = CchUtf8CodePt( buffer[cchBuffer-1] );
|
||||
if ( i == cchExpected )
|
||||
return 0; // utf8 sequence is complete so no trim needed
|
||||
else
|
||||
{
|
||||
assert( i <= cchBuffer );
|
||||
return i; // trim the incomplete sequence
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Did not find initial utf8 byte so trim nothing
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Convenience wrapper for converting from UTF16 into a newly
|
||||
// allocated char[]. Class behaves like auto_ptr (will free in dtor,
|
||||
// but has Release method so caller can take ownership of memory).
|
||||
template< typename AllocT = ArrayTAllocator< char > >
|
||||
struct AutoCharArray : public AutoArray< char, AllocT >
|
||||
{
|
||||
size_t AllocConvertFromUtf16( UINT destCodePage, const WCHAR * src, SSIZE_T cchSrc, bool * pHasDataLoss = NULL, DWORD * pErrorCode = NULL )
|
||||
{
|
||||
char * converted = NULL;
|
||||
size_t cchCvt = SystemLocale::FromUtf16< AllocT >( destCodePage, src, cchSrc, &converted, pHasDataLoss, pErrorCode );
|
||||
if ( 0 < cchCvt )
|
||||
{
|
||||
this->Free();
|
||||
this->m_ptr = converted;
|
||||
this->m_cchSize = cchCvt;
|
||||
}
|
||||
return cchCvt;
|
||||
}
|
||||
};
|
||||
|
||||
// Convenience wrapper for converting to UTF16 into a newly
|
||||
// allocated WCHAR[]. Class behaves like auto_ptr (will free in dtor,
|
||||
// but has Release method so caller can take ownership of memory).
|
||||
template< typename AllocT = ArrayTAllocator< WCHAR > >
|
||||
struct AutoWCharArray : public AutoArray< WCHAR, AllocT >
|
||||
{
|
||||
size_t AllocConvertToUtf16( UINT destCodePage, const char * src, SSIZE_T cchSrc, bool * pHasDataLoss = NULL, DWORD * pErrorCode = NULL )
|
||||
{
|
||||
WCHAR * converted = NULL;
|
||||
size_t cchCvt = SystemLocale::ToUtf16< AllocT >( destCodePage, src, cchSrc, &converted, pErrorCode );
|
||||
if ( 0 < cchCvt )
|
||||
{
|
||||
this->Free();
|
||||
this->m_ptr = converted;
|
||||
this->m_cchSize = cchCvt;
|
||||
}
|
||||
return cchCvt;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Inlines that vary by platform
|
||||
|
||||
#if defined(MPLAT_UNIX)
|
||||
// MPLAT_UNIX ----------------------------------------------------------------
|
||||
|
||||
#include "globalization.h"
|
||||
|
||||
inline UINT SystemLocale::AnsiCP() const
|
||||
{
|
||||
return CP_UTF8;
|
||||
}
|
||||
|
||||
inline UINT SystemLocale::OemCP() const
|
||||
{
|
||||
return CP_UTF8;
|
||||
}
|
||||
|
||||
inline UINT SystemLocale::MaxCharCchSize( UINT codepage )
|
||||
{
|
||||
codepage = ExpandSpecialCP( codepage );
|
||||
switch ( codepage )
|
||||
{
|
||||
case CP_UTF8:
|
||||
return 4;
|
||||
case 932:
|
||||
case 936:
|
||||
case 949:
|
||||
case 950:
|
||||
case CP_UTF16:
|
||||
return 2;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
inline int SystemLocale::CompareIgnoreWidth( const char * left, SSIZE_T cchLeft, const char * right, SSIZE_T cchRight, DWORD * pErrorCode ) const
|
||||
{
|
||||
// XPLAT_ODBC_TODO: VSTS 806013 MPLAT: Support IgnoreWidth for SNI string comparisons
|
||||
return Compare( left, cchLeft, right, cchRight, pErrorCode );
|
||||
}
|
||||
|
||||
inline int SystemLocale::CompareIgnoreCaseAndWidth( const char * left, SSIZE_T cchLeft, const char * right, SSIZE_T cchRight, DWORD * pErrorCode ) const
|
||||
{
|
||||
// XPLAT_ODBC_TODO: VSTS 806013 MPLAT: Support IgnoreWidth for SNI string comparisons
|
||||
return CompareIgnoreCase( left, cchLeft, right, cchRight, pErrorCode );
|
||||
}
|
||||
|
||||
template< typename AllocT >
|
||||
inline size_t SystemLocale::ToUtf16( UINT srcCodePage, const char * src, SSIZE_T cchSrc, WCHAR ** dest, DWORD * pErrorCode )
|
||||
{
|
||||
srcCodePage = ExpandSpecialCP( srcCodePage );
|
||||
EncodingConverter cvt( CP_UTF16, srcCodePage );
|
||||
if ( !cvt.Initialize() )
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_INVALID_PARAMETER;
|
||||
return 0;
|
||||
}
|
||||
size_t cchSrcActual = (cchSrc < 0 ? (1+strlen(src)) : cchSrc);
|
||||
bool hasLoss;
|
||||
return cvt.Convert< WCHAR, char, AllocT >( dest, src, cchSrcActual, false, &hasLoss, pErrorCode );
|
||||
}
|
||||
|
||||
template< typename AllocT >
|
||||
inline size_t SystemLocale::ToUtf16Strict( UINT srcCodePage, const char * src, SSIZE_T cchSrc, WCHAR ** dest, DWORD * pErrorCode )
|
||||
{
|
||||
srcCodePage = ExpandSpecialCP( srcCodePage );
|
||||
EncodingConverter cvt( CP_UTF16, srcCodePage );
|
||||
if ( !cvt.Initialize() )
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_INVALID_PARAMETER;
|
||||
return 0;
|
||||
}
|
||||
size_t cchSrcActual = (cchSrc < 0 ? (1+strlen(src)) : cchSrc);
|
||||
bool hasLoss;
|
||||
return cvt.Convert< WCHAR, char, AllocT >( dest, src, cchSrcActual, true, &hasLoss, pErrorCode );
|
||||
}
|
||||
|
||||
template< typename AllocT >
|
||||
inline size_t SystemLocale::FromUtf16( UINT destCodePage, const WCHAR * src, SSIZE_T cchSrc, char ** dest, bool * pHasDataLoss, DWORD * pErrorCode )
|
||||
{
|
||||
destCodePage = ExpandSpecialCP( destCodePage );
|
||||
EncodingConverter cvt( destCodePage, CP_UTF16 );
|
||||
if ( !cvt.Initialize() )
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_INVALID_PARAMETER;
|
||||
return 0;
|
||||
}
|
||||
size_t cchSrcActual = (cchSrc < 0 ? (1+mplat_wcslen(src)) : cchSrc);
|
||||
bool hasLoss;
|
||||
return cvt.Convert< char, WCHAR, AllocT >( dest, src, cchSrcActual, false, &hasLoss, pErrorCode );
|
||||
}
|
||||
|
||||
|
||||
// MPLAT_UNIX ----------------------------------------------------------------
|
||||
#else
|
||||
// ! MPLAT_UNIX ----------------------------------------------------------------
|
||||
|
||||
|
||||
inline const SystemLocale SystemLocale::Singleton()
|
||||
{
|
||||
// On Windows, Localization is an empty class so creation of this
|
||||
// should be optimized away. Empty classes have a sizeof 1 so there's
|
||||
// something to take the address of.
|
||||
C_ASSERT( 1 == sizeof(SystemLocale) );
|
||||
return SystemLocale();
|
||||
}
|
||||
|
||||
inline DWORD SystemLocale::CurrentTimeZoneBias( LONG * offsetInMinutes, DWORD * pTZInfo ) const
|
||||
{
|
||||
TIME_ZONE_INFORMATION tzi;
|
||||
DWORD tzInfo;
|
||||
if ( NULL == offsetInMinutes )
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
else if ( TIME_ZONE_ID_INVALID == (tzInfo = GetTimeZoneInformation(&tzi)) )
|
||||
return GetLastError();
|
||||
else
|
||||
{
|
||||
*offsetInMinutes = tzi.Bias;
|
||||
if ( NULL != pTZInfo )
|
||||
*pTZInfo = tzInfo;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
inline DWORD SystemLocale::CurrentLocalTime( LPSYSTEMTIME pTime )
|
||||
{
|
||||
GetLocalTime( pTime );
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
inline UINT SystemLocale::AnsiCP() const
|
||||
{
|
||||
return GetACP();
|
||||
}
|
||||
|
||||
inline UINT SystemLocale::OemCP() const
|
||||
{
|
||||
return GetOEMCP();
|
||||
}
|
||||
|
||||
inline UINT SystemLocale::MaxCharCchSize( UINT codepage )
|
||||
{
|
||||
CPINFO cpinfo;
|
||||
BOOL rc = GetCPInfo( codepage, &cpinfo );
|
||||
return (rc ? cpinfo.MaxCharSize : 0);
|
||||
}
|
||||
|
||||
inline size_t SystemLocale::ToLower( const char * src, SSIZE_T cchSrc, char * dest, size_t cchDest, DWORD * pErrorCode ) const
|
||||
{
|
||||
// Windows API takes 'int' sized parameters
|
||||
if ( cchSrc < -1 || 0x7FFFFFF < cchSrc || 0x7FFFFFF < cchDest )
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_INVALID_PARAMETER;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
OACR_WARNING_PUSH
|
||||
OACR_WARNING_DISABLE(SYSTEM_LOCALE_MISUSE , " INTERNATIONALIZATION BASELINE AT KATMAI RTM. FUTURE ANALYSIS INTENDED. ")
|
||||
OACR_WARNING_DISABLE(ANSI_APICALL, " Keeping the ANSI API for now. ")
|
||||
int cch = LCMapStringA(
|
||||
LOCALE_SYSTEM_DEFAULT,
|
||||
LCMAP_LOWERCASE,
|
||||
src,
|
||||
(int)cchSrc,
|
||||
dest,
|
||||
(int)cchDest );
|
||||
OACR_WARNING_POP
|
||||
|
||||
return ReturnCchResult( cch, pErrorCode );
|
||||
}
|
||||
|
||||
inline int SystemLocale::CompareWithFlags( DWORD flags, const char * left, SSIZE_T cchLeft, const char * right, SSIZE_T cchRight, DWORD * pErrorCode )
|
||||
{
|
||||
// Windows API takes 'int' sized parameters
|
||||
if ( cchLeft < -1 || 0x7FFFFFF < cchLeft || cchRight < -1 || 0x7FFFFFF < cchRight )
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_INVALID_PARAMETER;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
OACR_WARNING_PUSH
|
||||
OACR_WARNING_DISABLE(SYSTEM_LOCALE_MISUSE , " INTERNATIONALIZATION BASELINE AT KATMAI RTM. FUTURE ANALYSIS INTENDED. ")
|
||||
int cmp = CompareStringA( LOCALE_SYSTEM_DEFAULT, flags, left, (int)cchLeft, right, (int)cchRight );
|
||||
OACR_WARNING_POP
|
||||
if ( NULL != pErrorCode )
|
||||
{
|
||||
*pErrorCode = (CSTR_ERROR == cmp ? GetLastError() : ERROR_SUCCESS);
|
||||
}
|
||||
return cmp;
|
||||
}
|
||||
|
||||
inline int SystemLocale::Compare( const char * left, SSIZE_T cchLeft, const char * right, SSIZE_T cchRight, DWORD * pErrorCode ) const
|
||||
{
|
||||
return CompareWithFlags( 0, left, cchLeft, right, cchRight, pErrorCode );
|
||||
}
|
||||
|
||||
inline int SystemLocale::CompareIgnoreCase( const char * left, SSIZE_T cchLeft, const char * right, SSIZE_T cchRight, DWORD * pErrorCode ) const
|
||||
{
|
||||
return CompareWithFlags( NORM_IGNORECASE, left, cchLeft, right, cchRight, pErrorCode );
|
||||
}
|
||||
|
||||
inline int SystemLocale::CompareIgnoreCaseAndWidth( const char * left, SSIZE_T cchLeft, const char * right, SSIZE_T cchRight, DWORD * pErrorCode ) const
|
||||
{
|
||||
return CompareWithFlags( NORM_IGNORECASE|NORM_IGNOREWIDTH, left, cchLeft, right, cchRight, pErrorCode );
|
||||
}
|
||||
|
||||
inline int SystemLocale::CompareIgnoreWidth( const char * left, SSIZE_T cchLeft, const char * right, SSIZE_T cchRight, DWORD * pErrorCode ) const
|
||||
{
|
||||
return CompareWithFlags( NORM_IGNOREWIDTH, left, cchLeft, right, cchRight, pErrorCode );
|
||||
}
|
||||
|
||||
inline char * SystemLocale::NextChar( UINT codepage, const char * start )
|
||||
{
|
||||
return CharNextExA( (WORD)codepage, start, 0 );
|
||||
}
|
||||
|
||||
inline size_t SystemLocale::ToUtf16( UINT srcCodePage, const char * src, SSIZE_T cchSrc, WCHAR * dest, size_t cchDest, DWORD * pErrorCode )
|
||||
{
|
||||
return FastAsciiMultiByteToWideChar( srcCodePage, src, cchSrc, dest, cchDest, pErrorCode );
|
||||
}
|
||||
|
||||
inline size_t SystemLocale::ToUtf16Strict( UINT srcCodePage, const char * src, SSIZE_T cchSrc, WCHAR * dest, size_t cchDest, DWORD * pErrorCode )
|
||||
{
|
||||
return FastAsciiMultiByteToWideChar( srcCodePage, src, cchSrc, dest, cchDest, pErrorCode, true );
|
||||
}
|
||||
|
||||
inline size_t SystemLocale::FromUtf16( UINT destCodePage, const WCHAR * src, SSIZE_T cchSrc, char * dest, size_t cchDest, bool * pHasDataLoss, DWORD * pErrorCode )
|
||||
{
|
||||
BOOL dataloss = FALSE;
|
||||
size_t cchCvt = FastAsciiWideCharToMultiByte( destCodePage, src, cchSrc, dest, cchDest, &dataloss, pErrorCode );
|
||||
if ( NULL != pHasDataLoss )
|
||||
{
|
||||
*pHasDataLoss = (FALSE != dataloss);
|
||||
}
|
||||
return cchCvt;
|
||||
}
|
||||
|
||||
template< typename AllocT >
|
||||
inline size_t SystemLocale::ToUtf16( UINT srcCodePage, const char * src, SSIZE_T cchSrc, WCHAR ** dest, DWORD * pErrorCode )
|
||||
{
|
||||
size_t cchCvt = FastAsciiMultiByteToWideChar( srcCodePage, src, cchSrc, NULL, 0, pErrorCode );
|
||||
if ( 0 < cchCvt )
|
||||
{
|
||||
AutoArray< WCHAR, AllocT > newDestBuffer( cchCvt );
|
||||
cchCvt = FastAsciiMultiByteToWideChar( srcCodePage, src, cchSrc, newDestBuffer.m_ptr, cchCvt, pErrorCode );
|
||||
if ( 0 < cchCvt )
|
||||
*dest = newDestBuffer.Detach();
|
||||
}
|
||||
return cchCvt;
|
||||
}
|
||||
|
||||
template< typename AllocT >
|
||||
inline size_t SystemLocale::ToUtf16Strict( UINT srcCodePage, const char * src, SSIZE_T cchSrc, WCHAR ** dest, DWORD * pErrorCode )
|
||||
{
|
||||
size_t cchCvt = FastAsciiMultiByteToWideChar( srcCodePage, src, cchSrc, NULL, 0, pErrorCode, true );
|
||||
if ( 0 < cchCvt )
|
||||
{
|
||||
AutoArray< WCHAR, AllocT > newDestBuffer( cchCvt );
|
||||
cchCvt = FastAsciiMultiByteToWideChar( srcCodePage, src, cchSrc, newDestBuffer.m_ptr, cchCvt, pErrorCode, true );
|
||||
if ( 0 < cchCvt )
|
||||
*dest = newDestBuffer.Detach();
|
||||
}
|
||||
return cchCvt;
|
||||
}
|
||||
|
||||
template< typename AllocT >
|
||||
inline size_t SystemLocale::FromUtf16( UINT destCodePage, const WCHAR * src, SSIZE_T cchSrc, char ** dest, bool * pHasDataLoss, DWORD * pErrorCode )
|
||||
{
|
||||
BOOL dataloss = FALSE;
|
||||
size_t cchCvt = FastAsciiWideCharToMultiByte( destCodePage, src, cchSrc, NULL, 0, &dataloss, pErrorCode );
|
||||
if ( 0 < cchCvt )
|
||||
{
|
||||
AutoArray< char, AllocT > newDestBuffer( cchCvt );
|
||||
cchCvt = FastAsciiWideCharToMultiByte( destCodePage, src, cchSrc, newDestBuffer.m_ptr, cchCvt, &dataloss, pErrorCode );
|
||||
if ( 0 < cchCvt )
|
||||
*dest = newDestBuffer.Detach();
|
||||
}
|
||||
if ( NULL != pHasDataLoss )
|
||||
{
|
||||
*pHasDataLoss = (FALSE != dataloss);
|
||||
}
|
||||
return cchCvt;
|
||||
}
|
||||
|
||||
// ! MPLAT_UNIX ----------------------------------------------------------------
|
||||
#endif
|
||||
|
||||
#endif // __LOCALIZATION_HPP__
|
1039
source/shared/localizationimpl.cpp
Normal file
1039
source/shared/localizationimpl.cpp
Normal file
|
@ -0,0 +1,1039 @@
|
|||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
// File: LocalizationImpl.hpp
|
||||
//
|
||||
// Contents: Contains non-inline code for the SystemLocale class
|
||||
// Must be included in one c/cpp file per binary
|
||||
// A build error will occur if this inclusion policy is not followed
|
||||
//
|
||||
// Microsoft Drivers 4.0 for PHP for SQL Server
|
||||
// Copyright(c) Microsoft Corporation
|
||||
// All rights reserved.
|
||||
// MIT License
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""),
|
||||
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#include "localization.hpp"
|
||||
|
||||
#include "globalization.h"
|
||||
#include "StringFunctions.h"
|
||||
|
||||
struct cp_iconv
|
||||
{
|
||||
UINT CodePage;
|
||||
const char * IConvEncoding;
|
||||
|
||||
static const cp_iconv g_cp_iconv[];
|
||||
static const size_t g_cp_iconv_count;
|
||||
|
||||
static int GetIndex( UINT codepage )
|
||||
{
|
||||
for ( size_t idx = 0; idx < g_cp_iconv_count; ++idx )
|
||||
{
|
||||
if ( g_cp_iconv[idx].CodePage == codepage )
|
||||
return (int)idx;
|
||||
}
|
||||
// Should never be an unknown code page
|
||||
assert( false );
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
// Array of CodePage-to-IConvEncoding mappings
|
||||
// First few elements are most commonly used
|
||||
const cp_iconv cp_iconv::g_cp_iconv[] = {
|
||||
{ 65001, "UTF-8" },
|
||||
{ 1200, "UTF-16LE" },
|
||||
{ 3, "UTF-8" },
|
||||
{ 1252, "CP1252//TRANSLIT" },
|
||||
{ 850, "CP850//TRANSLIT" },
|
||||
{ 437, "CP437//TRANSLIT" },
|
||||
{ 874, "CP874//TRANSLIT" },
|
||||
{ 932, "CP932//TRANSLIT" },
|
||||
{ 936, "CP936//TRANSLIT" },
|
||||
{ 949, "CP949//TRANSLIT" },
|
||||
{ 950, "CP950//TRANSLIT" },
|
||||
{ 1250, "CP1250//TRANSLIT" },
|
||||
{ 1251, "CP1251//TRANSLIT" },
|
||||
{ 1253, "CP1253//TRANSLIT" },
|
||||
{ 1254, "CP1254//TRANSLIT" },
|
||||
{ 1255, "CP1255//TRANSLIT" },
|
||||
{ 1256, "CP1256//TRANSLIT" },
|
||||
{ 1257, "CP1257//TRANSLIT" },
|
||||
{ 1258, "CP1258//TRANSLIT" },
|
||||
{ 12000, "UTF-32LE" }
|
||||
};
|
||||
const size_t cp_iconv::g_cp_iconv_count = ARRAYSIZE(cp_iconv::g_cp_iconv);
|
||||
|
||||
#ifdef MPLAT_UNIX
|
||||
|
||||
class IConvCachePool
|
||||
{
|
||||
SLIST_HEADER m_Pool[cp_iconv::g_cp_iconv_count][cp_iconv::g_cp_iconv_count];
|
||||
|
||||
IConvCachePool( const IConvCachePool & );
|
||||
IConvCachePool & operator=( const IConvCachePool & );
|
||||
|
||||
// This bool indicates that the iconv pool is no longer available.
|
||||
// For the driver,lis flag indicates the pool can no longer be used.
|
||||
// Global destructors will be called by a single thread so this flag does not
|
||||
// need thread synch protection.
|
||||
static bool s_PoolDestroyed;
|
||||
|
||||
IConvCachePool()
|
||||
{
|
||||
for ( int dstIdx = 0; dstIdx < cp_iconv::g_cp_iconv_count; ++dstIdx )
|
||||
{
|
||||
for ( int srcIdx = 0; srcIdx < cp_iconv::g_cp_iconv_count; ++srcIdx )
|
||||
{
|
||||
InitializeSListHead( &m_Pool[dstIdx][srcIdx] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~IConvCachePool()
|
||||
{
|
||||
IConvCachePool::s_PoolDestroyed = true;
|
||||
|
||||
// Clean up remaining nodes
|
||||
for ( int dstIdx = 0; dstIdx < cp_iconv::g_cp_iconv_count; ++dstIdx )
|
||||
{
|
||||
for ( int srcIdx = 0; srcIdx < cp_iconv::g_cp_iconv_count; ++srcIdx )
|
||||
{
|
||||
IConvCache * pNode = static_cast<IConvCache*>( InterlockedFlushSList(&m_Pool[dstIdx][srcIdx]) );
|
||||
while ( NULL != pNode )
|
||||
{
|
||||
IConvCache * pNext = static_cast<IConvCache*>( pNode->Next );
|
||||
delete pNode;
|
||||
pNode = pNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
USHORT Depth( int dstIdx, int srcIdx )
|
||||
{
|
||||
assert( 0 <= dstIdx && dstIdx < cp_iconv::g_cp_iconv_count );
|
||||
assert( 0 <= srcIdx && srcIdx < cp_iconv::g_cp_iconv_count );
|
||||
return QueryDepthSList( &m_Pool[dstIdx][srcIdx] );
|
||||
}
|
||||
|
||||
// If this returns NULL, then caller must allocate their own iconv_t.
|
||||
// It will return NULL if allocation for a new instance failed (out of memory).
|
||||
const IConvCache * Borrow( int dstIdx, int srcIdx )
|
||||
{
|
||||
assert( 0 <= dstIdx && dstIdx < cp_iconv::g_cp_iconv_count );
|
||||
assert( 0 <= srcIdx && srcIdx < cp_iconv::g_cp_iconv_count );
|
||||
|
||||
const IConvCache * pCache = static_cast<const IConvCache*>( InterlockedPopEntrySList(&m_Pool[dstIdx][srcIdx]) );
|
||||
if ( NULL == pCache )
|
||||
{
|
||||
const IConvCache * pNewCache = new IConvCache( dstIdx, srcIdx );
|
||||
if ( NULL != pNewCache )
|
||||
{
|
||||
if ( INVALID_ICONV != pNewCache->GetIConv() )
|
||||
pCache = pNewCache;
|
||||
else
|
||||
delete pNewCache;
|
||||
}
|
||||
}
|
||||
return pCache;
|
||||
}
|
||||
|
||||
void Return( const IConvCache * pCache, int dstIdx, int srcIdx )
|
||||
{
|
||||
assert( pCache );
|
||||
assert( 0 <= dstIdx && dstIdx < cp_iconv::g_cp_iconv_count );
|
||||
assert( 0 <= srcIdx && srcIdx < cp_iconv::g_cp_iconv_count );
|
||||
|
||||
// Setting an arbitrary limit to prevent unbounded memory use by the pool.
|
||||
// Want this to be large enough for a substantial number of concurrent threads.
|
||||
const USHORT MAX_POOL_SIZE = 1024;
|
||||
|
||||
if ( INVALID_ICONV != pCache->GetIConv() && Depth(dstIdx, srcIdx) < MAX_POOL_SIZE )
|
||||
{
|
||||
SLIST_ENTRY * pNode = const_cast<IConvCache*>( pCache );
|
||||
InterlockedPushEntrySList( &m_Pool[dstIdx][srcIdx], pNode );
|
||||
}
|
||||
else
|
||||
{
|
||||
delete pCache;
|
||||
}
|
||||
}
|
||||
|
||||
static IConvCachePool & Singleton()
|
||||
{
|
||||
// GCC ensures that function scoped static initializers are threadsafe
|
||||
// We must not use the -fno-threadsafe-statics compiler option
|
||||
#if !defined(__GNUC__) || defined(NO_THREADSAFE_STATICS)
|
||||
#error "Relying on GCC's threadsafe initialization of local statics."
|
||||
#endif
|
||||
static IConvCachePool s_Pool;
|
||||
return s_Pool;
|
||||
}
|
||||
|
||||
public:
|
||||
static const IConvCache * BorrowCache( UINT dstCP, UINT srcCP )
|
||||
{
|
||||
int dstIdx = cp_iconv::GetIndex(dstCP);
|
||||
int srcIdx = cp_iconv::GetIndex(srcCP);
|
||||
|
||||
if ( -1 == dstIdx || -1 == srcIdx )
|
||||
return NULL;
|
||||
else if ( !s_PoolDestroyed )
|
||||
return Singleton().Borrow( dstIdx, srcIdx );
|
||||
else
|
||||
return new IConvCache( dstIdx, srcIdx );
|
||||
}
|
||||
|
||||
static void ReturnCache( const IConvCache * pCache, UINT dstCP, UINT srcCP )
|
||||
{
|
||||
int dstIdx = cp_iconv::GetIndex(dstCP);
|
||||
int srcIdx = cp_iconv::GetIndex(srcCP);
|
||||
|
||||
if ( -1 != dstIdx && -1 != srcIdx && !s_PoolDestroyed )
|
||||
Singleton().Return( pCache, dstIdx, srcIdx );
|
||||
else
|
||||
delete pCache;
|
||||
}
|
||||
|
||||
static USHORT Depth( UINT dstCP, UINT srcCP )
|
||||
{
|
||||
if ( IConvCachePool::s_PoolDestroyed )
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
int dstIdx = cp_iconv::GetIndex(dstCP);
|
||||
int srcIdx = cp_iconv::GetIndex(srcCP);
|
||||
|
||||
if ( -1 == dstIdx || -1 == srcIdx )
|
||||
return 0;
|
||||
else
|
||||
return Singleton().Depth( dstIdx, srcIdx );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
bool IConvCachePool::s_PoolDestroyed = false;
|
||||
|
||||
#ifdef DEBUG
|
||||
// This is only used by unit tests.
|
||||
// Product code should directly use IConvCachePool::Depth from
|
||||
// within this translation unit.
|
||||
USHORT GetIConvCachePoolDepth( UINT dstCP, UINT srcCP )
|
||||
{
|
||||
return IConvCachePool::Depth( dstCP, srcCP );
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
IConvCache::IConvCache( int dstIdx, int srcIdx )
|
||||
: m_iconv( iconv_open(
|
||||
cp_iconv::g_cp_iconv[dstIdx].IConvEncoding,
|
||||
cp_iconv::g_cp_iconv[srcIdx].IConvEncoding) )
|
||||
{
|
||||
}
|
||||
|
||||
IConvCache::~IConvCache()
|
||||
{
|
||||
if ( INVALID_ICONV != m_iconv )
|
||||
iconv_close( m_iconv );
|
||||
}
|
||||
|
||||
#endif // MPLAT_UNIX
|
||||
|
||||
EncodingConverter::EncodingConverter( UINT dstCodePage, UINT srcCodePage )
|
||||
: m_dstCodePage( dstCodePage ),
|
||||
m_srcCodePage( srcCodePage )
|
||||
#ifdef MPLAT_UNIX
|
||||
, m_pCvtCache( NULL )
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
EncodingConverter::~EncodingConverter()
|
||||
{
|
||||
#ifdef MPLAT_UNIX
|
||||
if ( NULL != m_pCvtCache )
|
||||
{
|
||||
IConvCachePool::ReturnCache( m_pCvtCache, m_dstCodePage, m_srcCodePage );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool EncodingConverter::Initialize()
|
||||
{
|
||||
#if defined(MPLAT_UNIX)
|
||||
if ( !IsValidIConv() )
|
||||
{
|
||||
m_pCvtCache = IConvCachePool::BorrowCache( m_dstCodePage, m_srcCodePage );
|
||||
}
|
||||
return IsValidIConv();
|
||||
#elif defined(MPLAT_WWOWH)
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
//#endif
|
||||
|
||||
#ifdef MPLAT_UNIX
|
||||
// MPLAT_UNIX ----------------------------------------------------------------
|
||||
#include <locale>
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
||||
|
||||
SystemLocale::SystemLocale( const char * localeName )
|
||||
: m_pLocale( new std::locale(localeName) )
|
||||
{
|
||||
}
|
||||
|
||||
SystemLocale::~SystemLocale()
|
||||
{
|
||||
delete m_pLocale;
|
||||
}
|
||||
|
||||
const SystemLocale & SystemLocale::Singleton()
|
||||
{
|
||||
// GCC ensures that function scoped static initializers are threadsafe
|
||||
// We must not use the -fno-threadsafe-statics compiler option
|
||||
#if !defined(__GNUC__) || defined(NO_THREADSAFE_STATICS)
|
||||
#error "Relying on GCC's threadsafe initialization of local statics."
|
||||
#endif
|
||||
static const SystemLocale s_Default( "en_US.utf8" );
|
||||
return s_Default;
|
||||
}
|
||||
|
||||
int SystemLocale::GetResourcePath( char * buffer, size_t cchBuffer ) const
|
||||
{
|
||||
// XPLAT_ODBC_TODO: VSTS 718708 Localization
|
||||
// Also need to use AdjustLCID logic when handling more locales
|
||||
return snprintf( buffer, cchBuffer, "/opt/microsoft/msodbcsql/share/resources/en_US/");
|
||||
}
|
||||
|
||||
DWORD SystemLocale::CurrentTimeZoneBias( LONG * offsetInMinutes, DWORD * tzinfo ) const
|
||||
{
|
||||
if ( NULL == offsetInMinutes )
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
time_t now = time( NULL );
|
||||
if ( (time_t)(-1) == now )
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
|
||||
struct tm utc, local;
|
||||
if ( NULL == gmtime_r(&now, &utc) || NULL == localtime_r(&now, &local) )
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
*offsetInMinutes = BiasInMinutes( utc, local );
|
||||
|
||||
if ( NULL != tzinfo )
|
||||
{
|
||||
*tzinfo = (0 == local.tm_isdst ? TIME_ZONE_ID_STANDARD : (0 < local.tm_isdst ? TIME_ZONE_ID_DAYLIGHT : TIME_ZONE_ID_UNKNOWN));
|
||||
}
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
DWORD SystemLocale::CurrentLocalTime( LPSYSTEMTIME pTime )
|
||||
{
|
||||
if ( NULL == pTime )
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
|
||||
memset( pTime, 0, sizeof(SYSTEMTIME) );
|
||||
|
||||
time_t now = time( NULL );
|
||||
if ( (time_t)(-1) == now )
|
||||
return ERROR_NOT_SUPPORTED;
|
||||
|
||||
struct tm local;
|
||||
if ( NULL == localtime_r(&now, &local) )
|
||||
return ERROR_INVALID_DATA;
|
||||
|
||||
pTime->wYear = local.tm_year + 1900;
|
||||
pTime->wMonth = local.tm_mon + 1;
|
||||
pTime->wDay = local.tm_mday;
|
||||
pTime->wHour = local.tm_hour;
|
||||
pTime->wMinute = local.tm_min;
|
||||
pTime->wSecond = local.tm_sec;
|
||||
pTime->wMilliseconds = 0;
|
||||
pTime->wDayOfWeek = local.tm_wday;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
size_t SystemLocale::ToUtf16( UINT srcCodePage, const char * src, SSIZE_T cchSrc, WCHAR * dest, size_t cchDest, DWORD * pErrorCode )
|
||||
{
|
||||
srcCodePage = ExpandSpecialCP( srcCodePage );
|
||||
EncodingConverter cvt( CP_UTF16, srcCodePage );
|
||||
if ( !cvt.Initialize() )
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_INVALID_PARAMETER;
|
||||
return 0;
|
||||
}
|
||||
size_t cchSrcActual = (cchSrc < 0 ? (1+strlen(src)) : cchSrc);
|
||||
bool hasLoss;
|
||||
return cvt.Convert( dest, cchDest, src, cchSrcActual, false, &hasLoss, pErrorCode );
|
||||
}
|
||||
|
||||
size_t SystemLocale::ToUtf16Strict( UINT srcCodePage, const char * src, SSIZE_T cchSrc, WCHAR * dest, size_t cchDest, DWORD * pErrorCode )
|
||||
{
|
||||
srcCodePage = ExpandSpecialCP( srcCodePage );
|
||||
EncodingConverter cvt( CP_UTF16, srcCodePage );
|
||||
if ( !cvt.Initialize() )
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_INVALID_PARAMETER;
|
||||
return 0;
|
||||
}
|
||||
size_t cchSrcActual = (cchSrc < 0 ? (1+strlen(src)) : cchSrc);
|
||||
bool hasLoss;
|
||||
return cvt.Convert( dest, cchDest, src, cchSrcActual, true, &hasLoss, pErrorCode );
|
||||
}
|
||||
|
||||
size_t SystemLocale::FromUtf16( UINT destCodePage, const WCHAR * src, SSIZE_T cchSrc, char * dest, size_t cchDest, bool * pHasDataLoss, DWORD * pErrorCode )
|
||||
{
|
||||
destCodePage = ExpandSpecialCP( destCodePage );
|
||||
EncodingConverter cvt( destCodePage, CP_UTF16 );
|
||||
if ( !cvt.Initialize() )
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_INVALID_PARAMETER;
|
||||
return 0;
|
||||
}
|
||||
size_t cchSrcActual = (cchSrc < 0 ? (1+mplat_wcslen(src)) : cchSrc);
|
||||
bool hasLoss;
|
||||
return cvt.Convert( dest, cchDest, src, cchSrcActual, false, &hasLoss, pErrorCode );
|
||||
}
|
||||
|
||||
size_t SystemLocale::FromUtf16Strict(UINT destCodePage, const WCHAR * src, SSIZE_T cchSrc, char * dest, size_t cchDest, bool * pHasDataLoss, DWORD * pErrorCode)
|
||||
{
|
||||
destCodePage = ExpandSpecialCP(destCodePage);
|
||||
EncodingConverter cvt(destCodePage, CP_UTF16);
|
||||
if (!cvt.Initialize())
|
||||
{
|
||||
if (NULL != pErrorCode)
|
||||
*pErrorCode = ERROR_INVALID_PARAMETER;
|
||||
return 0;
|
||||
}
|
||||
size_t cchSrcActual = (cchSrc < 0 ? (1 + mplat_wcslen(src)) : cchSrc);
|
||||
bool hasLoss;
|
||||
return cvt.Convert(dest, cchDest, src, cchSrcActual, true, &hasLoss, pErrorCode);
|
||||
}
|
||||
|
||||
size_t SystemLocale::ToLower( const char * src, SSIZE_T cchSrc, char * dest, size_t cchDest, DWORD * pErrorCode ) const
|
||||
{
|
||||
size_t cchSrcActual = (cchSrc < 0 ? (1+strlen(src)) : cchSrc);
|
||||
if ( 0 == cchSrcActual )
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_INVALID_PARAMETER;
|
||||
return 0;
|
||||
}
|
||||
if ( 0 == cchDest )
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_SUCCESS;
|
||||
return cchSrcActual;
|
||||
}
|
||||
else if ( cchDest < cchSrcActual )
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_INSUFFICIENT_BUFFER;
|
||||
return 0;
|
||||
}
|
||||
memcpy_s( dest, cchSrcActual, src, cchSrcActual );
|
||||
|
||||
use_facet< ctype< char > >(*m_pLocale).tolower( dest, dest+cchSrcActual );
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_SUCCESS;
|
||||
return cchSrcActual;
|
||||
}
|
||||
|
||||
int SystemLocale::Compare( const char * left, SSIZE_T cchLeft, const char * right, SSIZE_T cchRight, DWORD * pErrorCode ) const
|
||||
{
|
||||
if ( NULL == left || NULL == right || 0 == cchLeft || 0 == cchRight )
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_INVALID_PARAMETER;
|
||||
return CSTR_ERROR;
|
||||
}
|
||||
|
||||
size_t cchLeftActual = (cchLeft < 0 ? strlen(left) : cchLeft);
|
||||
size_t cchRightActual = (cchRight < 0 ? strlen(right) : cchRight);
|
||||
|
||||
int cmp = strncmp( left, right, min(cchLeftActual, cchRightActual) );
|
||||
if ( 0 == cmp )
|
||||
{
|
||||
if ( cchLeftActual < cchRightActual )
|
||||
cmp = -1;
|
||||
else if ( cchLeftActual > cchRightActual )
|
||||
cmp = 1;
|
||||
}
|
||||
else if ( cmp < 0 )
|
||||
cmp = 1; // CompareString is inverse of strcmp
|
||||
else
|
||||
cmp = -1; // CompareString is inverse of strcmp
|
||||
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_SUCCESS;
|
||||
return cmp+2;
|
||||
}
|
||||
|
||||
int SystemLocale::CompareIgnoreCase( const char * left, SSIZE_T cchLeft, const char * right, SSIZE_T cchRight, DWORD * pErrorCode ) const
|
||||
{
|
||||
if ( NULL == left || NULL == right || 0 == cchLeft || 0 == cchRight )
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_INVALID_PARAMETER;
|
||||
return CSTR_ERROR;
|
||||
}
|
||||
|
||||
size_t cchLeftActual = (cchLeft < 0 ? strlen(left) : cchLeft);
|
||||
size_t cchRightActual = (cchRight < 0 ? strlen(right) : cchRight);
|
||||
|
||||
int cmp = strncasecmp( left, right, min(cchLeftActual, cchRightActual) );
|
||||
if ( 0 == cmp )
|
||||
{
|
||||
if ( cchLeftActual < cchRightActual )
|
||||
cmp = -1;
|
||||
else if ( cchLeftActual > cchRightActual )
|
||||
cmp = 1;
|
||||
}
|
||||
else if ( cmp < 0 )
|
||||
cmp = 1; // CompareString is inverse of strcmp
|
||||
else
|
||||
cmp = -1; // CompareString is inverse of strcmp
|
||||
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_SUCCESS;
|
||||
return cmp+2;
|
||||
}
|
||||
|
||||
char * SystemLocale::NextChar( UINT codepage, const char * start, size_t cchBytesLeft )
|
||||
{
|
||||
if ( NULL == start || '\0' == *start || 0 == cchBytesLeft )
|
||||
return const_cast<char *>( start );
|
||||
|
||||
char first = *start;
|
||||
codepage = ExpandSpecialCP( codepage );
|
||||
if ( CP_UTF8 != codepage )
|
||||
{
|
||||
if ( !IsDBCSLeadByteEx(codepage, first) || '\0' == *(start+1) )
|
||||
return const_cast<char *>( start+1 ); // single byte char or truncated double byte char
|
||||
else
|
||||
return const_cast<char *>( start+2 ); // double byte char
|
||||
}
|
||||
|
||||
// CP_UTF8
|
||||
// MB utf8 sequences have this format
|
||||
// Lead byte starts with 2 set bits, '11'
|
||||
// Rest of bytes start with one set and one not, '10'
|
||||
|
||||
// ASCII or not first of utf8 sequence
|
||||
// If this isn't the first byte of a utf8 sequence, just move one byte at a time
|
||||
// since we don't know where the correct boundary is located.
|
||||
if ( (char)0 == (first & (char)0x80) || !SystemLocale::IsUtf8LeadByte((BYTE)first) )
|
||||
return const_cast<char *>( start+1 );
|
||||
else
|
||||
{
|
||||
// Initial char tells us how many bytes are supposed to be in this sequence
|
||||
UINT cchExpectedSize = SystemLocale::CchUtf8CodePt( (BYTE)first );
|
||||
|
||||
// Skip lead bye
|
||||
++start;
|
||||
--cchExpectedSize;
|
||||
--cchBytesLeft;
|
||||
|
||||
// Proceed to end of utf8 sequence, null term, or end of expected size
|
||||
while ( 0 < cchExpectedSize && 0 < cchBytesLeft && (char)0x80 == (*start & (char)0xC0) )
|
||||
{
|
||||
++start;
|
||||
--cchExpectedSize;
|
||||
--cchBytesLeft;
|
||||
}
|
||||
return const_cast<char *>( start );
|
||||
}
|
||||
}
|
||||
|
||||
char * SystemLocale::NextChar( UINT codepage, const char * start )
|
||||
{
|
||||
// Just assume some large max buffer size since caller is saying
|
||||
// start is null terminated.
|
||||
return NextChar( codepage, start, DWORD_MAX );
|
||||
}
|
||||
|
||||
// MPLAT_UNIX ----------------------------------------------------------------
|
||||
#else
|
||||
// !MPLAT_UNIX ----------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
// IsW2CZeroFlagCodePage
|
||||
//
|
||||
// @func Does this code page need special handling for WideCharToMultiByte or
|
||||
// MultiByteToWideChar to avoid error code as ERROR_INVALID_PARAMETER to be returned
|
||||
//
|
||||
// @rdesc bool
|
||||
// @flag TRUE | needs special handling
|
||||
// @flag FALSE | doesn't need special handling
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
||||
#define IsW2CZeroFlagCodePage(codePage) (((codePage) < 50220) ? FALSE : _IsW2CZeroFlagCodePage(codePage))
|
||||
|
||||
inline BOOL _IsW2CZeroFlagCodePage
|
||||
(
|
||||
UINT CodePage
|
||||
)
|
||||
{
|
||||
assert(CodePage >= 50220);
|
||||
|
||||
// According to MSDN, these code pages need special handling
|
||||
// during WideCharToMultiByte call w/r its parameter flags
|
||||
if (CodePage == 50220 ||
|
||||
CodePage == 50221 ||
|
||||
CodePage == 50222 ||
|
||||
CodePage == 50225 ||
|
||||
CodePage == 50227 ||
|
||||
CodePage == 50229 ||
|
||||
CodePage == 52936 ||
|
||||
CodePage == 54936 ||
|
||||
CodePage == 65000 ||
|
||||
CodePage == 65001 ||
|
||||
CodePage >= 57002 && CodePage <= 57011)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Custom version of MultiByteToWideChar (faster for all ASCII strings)
|
||||
// Convert ASCII data (0x00-0x7f) until first non-ASCII data,
|
||||
// calling OS MultiByteToWideChar in that case.
|
||||
//
|
||||
size_t SystemLocale::FastAsciiMultiByteToWideChar(
|
||||
UINT CodePage,
|
||||
__in_ecount(cch) const char *pch, // IN | source string
|
||||
SSIZE_T cch, // IN | count of characters or -1
|
||||
__out_ecount_opt(cwch) PWCHAR pwch, // IN | Result string
|
||||
size_t cwch, // IN | counter of wcharacters of result buffer or 0
|
||||
DWORD* pErrorCode, // OUT | optional pointer to return error code
|
||||
bool bStrict // IN | Return error if invalid chars in src
|
||||
)
|
||||
{
|
||||
if ( 0 == cch || cch < -1 || NULL == pch )
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_INVALID_PARAMETER;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *pchStart = pch;
|
||||
|
||||
// Divide into
|
||||
// Case 1a: cch, do convert
|
||||
// Case 1b: cch, just count
|
||||
// Case 2a: null-term, do convert
|
||||
// Case 2b: null-term, just count
|
||||
if (-1 != cch)
|
||||
{
|
||||
// 0 <= cch
|
||||
//
|
||||
// Case 1: We have counter of characters
|
||||
if (0 != cch)
|
||||
{
|
||||
if (0 != cwch)
|
||||
{
|
||||
// Case 1a: Have to convert, not just calculate necessary space
|
||||
|
||||
// Optimization: When converting first cwch characters, it's not
|
||||
// necessary to check for buffer overflow. Also, loop is unrolled.
|
||||
size_t cquads = min((size_t)cch, cwch) >> 2;
|
||||
|
||||
while (0 != cquads)
|
||||
{
|
||||
unsigned quad = *(unsigned UNALIGNED *)pch;
|
||||
|
||||
if (quad & 0x80808080)
|
||||
goto general;
|
||||
|
||||
OACR_WARNING_SUPPRESS ( INCORRECT_VALIDATION, "Due to performance, we suppress this PREFast warning" );
|
||||
*(unsigned UNALIGNED *)pwch = (quad & 0x7F) | ((quad & 0x7F00) << 8);
|
||||
|
||||
quad >>= 16;
|
||||
|
||||
OACR_WARNING_SUPPRESS ( POTENTIAL_BUFFER_OVERFLOW_HIGH_PRIORITY, "PREFast incorrectly warns of buffer overrun for cwch < 4, which won't enter this loop." );
|
||||
*(unsigned UNALIGNED *)(pwch+2) = (quad & 0x7F) | ((quad & 0x7F00) << 8);
|
||||
|
||||
pch += 4;
|
||||
pwch += 4;
|
||||
cch -= 4;
|
||||
cquads --;
|
||||
}
|
||||
|
||||
// Convert end of string - slower, but the loop will be executed 3 times max
|
||||
if (0 != cch)
|
||||
{
|
||||
const char *pchEnd = pchStart + cwch;
|
||||
|
||||
do
|
||||
{
|
||||
unsigned ch = (unsigned)*pch;
|
||||
|
||||
if (pch == pchEnd)
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_INSUFFICIENT_BUFFER;
|
||||
return 0; // Not enough space
|
||||
}
|
||||
|
||||
if (ch > 0x7F)
|
||||
goto general;
|
||||
|
||||
*(pwch++) = (WCHAR)ch;
|
||||
|
||||
pch++;
|
||||
cch--;
|
||||
} while (0 != cch);
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Case 1b: Have to calculate necessary space only
|
||||
if (SystemLocale::MaxCharCchSize(CodePage) == 1) // SBCS code pages 1char = 1 unc char
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_SUCCESS;
|
||||
return static_cast<size_t>(cch);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if ((unsigned)*pch > 0x7F)
|
||||
goto general;
|
||||
|
||||
pch++;
|
||||
} while (0 != --cch);
|
||||
}
|
||||
}
|
||||
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_SUCCESS;
|
||||
return static_cast<size_t>(pch - pchStart);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Case 2: zero-terminated string
|
||||
if (0 != cwch)
|
||||
{
|
||||
// Case 2a: Have to convert, not just calculate necessary space
|
||||
const char *pchEnd = pch + cwch;
|
||||
|
||||
do
|
||||
{
|
||||
unsigned ch = (unsigned)*pch;
|
||||
|
||||
if (ch > 0x7F)
|
||||
goto general;
|
||||
else
|
||||
{
|
||||
*pwch = (WCHAR)ch;
|
||||
pch ++;
|
||||
if (0 == ch)
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_SUCCESS;
|
||||
return static_cast<size_t>(pch - pchStart);
|
||||
}
|
||||
pwch ++;
|
||||
}
|
||||
} while (pch != pchEnd);
|
||||
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_INSUFFICIENT_BUFFER;
|
||||
return 0; // Not enough space
|
||||
}
|
||||
else
|
||||
{
|
||||
// Case 2b: Have to calculate necessary space
|
||||
unsigned ch;
|
||||
|
||||
do
|
||||
{
|
||||
ch = (unsigned)*pch;
|
||||
|
||||
if (ch > 0x7F)
|
||||
goto general;
|
||||
pch ++;
|
||||
} while (0 != ch);
|
||||
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_SUCCESS;
|
||||
return static_cast<size_t>(pch - pchStart);
|
||||
}
|
||||
}
|
||||
|
||||
// Have to call Win32 API
|
||||
general:
|
||||
{
|
||||
size_t cwchConverted;
|
||||
size_t cwchUnicode;
|
||||
|
||||
cwchConverted = (pch - pchStart);
|
||||
|
||||
if ( cwch > cwchConverted )
|
||||
cwch -= cwchConverted;
|
||||
else
|
||||
cwch = 0;
|
||||
|
||||
// Windows MBtoWC takes int inputs
|
||||
if ( INT32_MAX < cch || INT32_MAX < cwch )
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_INVALID_PARAMETER;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
cwchUnicode = (UINT)MultiByteToWideChar(
|
||||
CodePage,
|
||||
(IsW2CZeroFlagCodePage(CodePage) ? 0 : MB_PRECOMPOSED)
|
||||
| (bStrict ? MB_ERR_INVALID_CHARS : 0),
|
||||
pch,
|
||||
(int)cch,
|
||||
pwch,
|
||||
(int)cwch);
|
||||
|
||||
if ( 0 == cwchUnicode )
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = GetLastError();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_SUCCESS;
|
||||
return (cwchConverted + cwchUnicode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Custom version of WideCharToMultiByte (faster for all ASCII strings)
|
||||
// Convert ASCII data (0x00-0x7f) until first non-ASCII data,
|
||||
// calling OS WideCharToMultiByte in that case.
|
||||
size_t SystemLocale::FastAsciiWideCharToMultiByte
|
||||
(
|
||||
UINT CodePage,
|
||||
const WCHAR *pwch, // IN | source string
|
||||
SSIZE_T cwch, // IN | count of characters or -1
|
||||
__out_ecount(cch) char *pch, // IN | Result string
|
||||
size_t cch, // IN | Length of result buffer or 0
|
||||
BOOL *pfDataLoss, // IN | True if there was data loss during CP conversion
|
||||
DWORD *pErrorCode
|
||||
)
|
||||
{
|
||||
if ( 0 == cwch || NULL == pwch || cwch < -1 )
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_INVALID_PARAMETER;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const WCHAR *pwchStart = pwch;
|
||||
const char *pchStart = pch;
|
||||
|
||||
// Divide into
|
||||
// Case 1a: cwch, do convert
|
||||
// Case 1b: cwch, just count
|
||||
// Case 2a: null-term, do convert
|
||||
// Case 2b: null-term, just count
|
||||
if (-1 != cwch)
|
||||
{
|
||||
// Case 1: We have counter of characters
|
||||
if (0 != cwch)
|
||||
{
|
||||
if (0 != cch)
|
||||
{
|
||||
// Case 1a: Have to convert, not just calculate necessary space
|
||||
|
||||
// Optimization: When converting first cch characters, it's not
|
||||
// necessary to check for buffer overflow. Also, loop is unrolled.
|
||||
size_t cquads = cch >> 2;
|
||||
|
||||
while (0 != cquads && 4 <= cwch)
|
||||
{
|
||||
unsigned pairLo = *(unsigned UNALIGNED *)pwch;
|
||||
unsigned pairHi = *(unsigned UNALIGNED *)(pwch+2);
|
||||
|
||||
if ((pairLo | pairHi) & 0xFF80FF80)
|
||||
goto general;
|
||||
|
||||
*(unsigned UNALIGNED *)pch = (pairLo & 0x7F) |
|
||||
((pairLo >> 8) & 0x7F00) |
|
||||
((pairHi & 0x7F) << 16) |
|
||||
((pairHi & 0x7F0000) << 8);
|
||||
pch += 4;
|
||||
pwch += 4;
|
||||
cwch -= 4;
|
||||
cquads --;
|
||||
}
|
||||
// Convert end of string - slower, but the loop will be executed 3 times max
|
||||
if (0 != cwch)
|
||||
{
|
||||
const char *pchEnd = pchStart + cch;
|
||||
|
||||
do
|
||||
{
|
||||
unsigned wch = (unsigned)*pwch;
|
||||
|
||||
if (pch == pchEnd)
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_INSUFFICIENT_BUFFER;
|
||||
return 0; // Not enough space
|
||||
}
|
||||
|
||||
if ((unsigned)*pwch > 0x7F)
|
||||
goto general;
|
||||
|
||||
*(pch ++) = (char) wch;
|
||||
pwch ++;
|
||||
cwch --;
|
||||
} while (0 != cwch);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Case 1b: Have to calculate necessary space
|
||||
do
|
||||
{
|
||||
if ((unsigned)*pwch > 0x7F)
|
||||
goto general;
|
||||
|
||||
pwch ++;
|
||||
cwch --;
|
||||
} while (0 != cwch);
|
||||
}
|
||||
}
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_SUCCESS;
|
||||
return static_cast<size_t>(pwch - pwchStart);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Case 2: zero-terminated string
|
||||
if (0 != cch)
|
||||
{
|
||||
// Case 2a: Have to convert, not just calculate necessary space
|
||||
const char *pchEnd = pch + cch;
|
||||
|
||||
do
|
||||
{
|
||||
unsigned wch = (unsigned)*pwch;
|
||||
|
||||
if (wch > 0x7F)
|
||||
goto general;
|
||||
else
|
||||
{
|
||||
*pch = (char) wch;
|
||||
pwch ++;
|
||||
if (0 == wch)
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_SUCCESS;
|
||||
return static_cast<size_t>(pwch - pwchStart);
|
||||
}
|
||||
pch ++;
|
||||
}
|
||||
} while (pch != pchEnd);
|
||||
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_INSUFFICIENT_BUFFER;
|
||||
return 0; // Not enough space
|
||||
}
|
||||
else
|
||||
{
|
||||
// Case 2b: Have to calculate necessary space
|
||||
unsigned wch;
|
||||
|
||||
do
|
||||
{
|
||||
wch = (unsigned)*pwch;
|
||||
if (wch > 0x7F)
|
||||
goto general;
|
||||
pwch ++;
|
||||
} while (0 != wch);
|
||||
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_SUCCESS;
|
||||
return static_cast<size_t>(pwch - pwchStart);
|
||||
}
|
||||
}
|
||||
|
||||
// Have to call Win32 API
|
||||
general:
|
||||
{
|
||||
size_t cchConverted;
|
||||
size_t cchUnicode;
|
||||
|
||||
// initialize output param if any
|
||||
if (pfDataLoss)
|
||||
*pfDataLoss = FALSE;
|
||||
|
||||
cchConverted = (pwch - pwchStart);
|
||||
|
||||
if ( cch > cchConverted )
|
||||
cch -= cchConverted;
|
||||
else
|
||||
cch = 0;
|
||||
|
||||
// Windows MBtoWC takes int inputs
|
||||
if ( INT32_MAX < cch || INT32_MAX < cwch )
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_INVALID_PARAMETER;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
cchUnicode = (UINT)WideCharToMultiByte (
|
||||
CodePage,
|
||||
0,
|
||||
pwch,
|
||||
(int)cwch,
|
||||
pch,
|
||||
(int)cch,
|
||||
NULL,
|
||||
IsW2CZeroFlagCodePage(CodePage) ? NULL : pfDataLoss);
|
||||
|
||||
if ( 0 == cchUnicode )
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = GetLastError();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( NULL != pErrorCode )
|
||||
*pErrorCode = ERROR_SUCCESS;
|
||||
return (cchConverted + cchUnicode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// !MPLAT_UNIX ----------------------------------------------------------------
|
||||
#endif
|
||||
|
796
source/shared/sal.h
Normal file
796
source/shared/sal.h
Normal file
|
@ -0,0 +1,796 @@
|
|||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
// File: sal_def.h
|
||||
//
|
||||
// Contents: Contains the minimal definitions to build on non-Windows platforms
|
||||
//
|
||||
// Microsoft Drivers 4.0 for PHP for SQL Server
|
||||
// Copyright(c) Microsoft Corporation
|
||||
// All rights reserved.
|
||||
// MIT License
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""),
|
||||
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef XPLAT_SAL_DEFINED
|
||||
#define XPLAT_SAL_DEFINED
|
||||
|
||||
#define __allocator
|
||||
#define __analysis_assert(e)
|
||||
#define __analysis_assume(e)
|
||||
#define __bcount(size)
|
||||
#define __bcount_opt(size)
|
||||
#define __blocksOn(resource)
|
||||
#define __bound
|
||||
#define __callback
|
||||
#define __checkReturn
|
||||
#define __control_entrypoint(category)
|
||||
#define __data_entrypoint(category)
|
||||
#define __deref
|
||||
#define __deref_bcount(size)
|
||||
#define __deref_bcount_opt(size)
|
||||
#define __deref_ecount(size)
|
||||
#define __deref_ecount_opt(size)
|
||||
#define __deref_in
|
||||
#define __deref_in
|
||||
#define __deref_in_bcount(size)
|
||||
#define __deref_in_bcount_opt(size)
|
||||
#define __deref_in_ecount(size)
|
||||
#define __deref_in_ecount_opt(size)
|
||||
#define __deref_in_opt
|
||||
#define __deref_in_range(lb,ub)
|
||||
#define __deref_in_xcount(size)
|
||||
#define __deref_in_xcount_opt(size)
|
||||
#define __deref_inout
|
||||
#define __deref_inout_bcount(size)
|
||||
#define __deref_inout_bcount_full(size)
|
||||
#define __deref_inout_bcount_full_opt(size)
|
||||
#define __deref_inout_bcount_nz(size)
|
||||
#define __deref_inout_bcount_nz_opt(size)
|
||||
#define __deref_inout_bcount_opt(size)
|
||||
#define __deref_inout_bcount_part(size,length)
|
||||
#define __deref_inout_bcount_part_opt(size,length)
|
||||
#define __deref_inout_bcount_z(size)
|
||||
#define __deref_inout_bcount_z_opt(size)
|
||||
#define __deref_inout_ecount(size)
|
||||
#define __deref_inout_ecount_full(size)
|
||||
#define __deref_inout_ecount_full_opt(size)
|
||||
#define __deref_inout_ecount_nz(size)
|
||||
#define __deref_inout_ecount_nz_opt(size)
|
||||
#define __deref_inout_ecount_opt(size)
|
||||
#define __deref_inout_ecount_part(size,length)
|
||||
#define __deref_inout_ecount_part_opt(size,length)
|
||||
#define __deref_inout_ecount_z(size)
|
||||
#define __deref_inout_ecount_z_opt(size)
|
||||
#define __deref_inout_nz
|
||||
#define __deref_inout_nz_opt
|
||||
#define __deref_inout_opt
|
||||
#define __deref_inout_xcount(size)
|
||||
#define __deref_inout_xcount_full(size)
|
||||
#define __deref_inout_xcount_full_opt(size)
|
||||
#define __deref_inout_xcount_opt(size)
|
||||
#define __deref_inout_xcount_part(size,length)
|
||||
#define __deref_inout_xcount_part_opt(size,length)
|
||||
#define __deref_inout_z
|
||||
#define __deref_inout_z_opt
|
||||
#define __deref_opt_bcount(size)
|
||||
#define __deref_opt_bcount_opt(size)
|
||||
#define __deref_opt_ecount(size)
|
||||
#define __deref_opt_ecount_opt(size)
|
||||
#define __deref_opt_in
|
||||
#define __deref_opt_in_bcount(size)
|
||||
#define __deref_opt_in_bcount_opt(size)
|
||||
#define __deref_opt_in_ecount(size)
|
||||
#define __deref_opt_in_ecount_opt(size)
|
||||
#define __deref_opt_in_opt
|
||||
#define __deref_opt_in_xcount(size)
|
||||
#define __deref_opt_in_xcount_opt(size)
|
||||
#define __deref_opt_inout
|
||||
#define __deref_opt_inout_bcount(size)
|
||||
#define __deref_opt_inout_bcount_full(size)
|
||||
#define __deref_opt_inout_bcount_full_opt(size)
|
||||
#define __deref_opt_inout_bcount_nz(size)
|
||||
#define __deref_opt_inout_bcount_nz_opt(size)
|
||||
#define __deref_opt_inout_bcount_opt(size)
|
||||
#define __deref_opt_inout_bcount_part(size,length)
|
||||
#define __deref_opt_inout_bcount_part_opt(size,length)
|
||||
#define __deref_opt_inout_bcount_z(size)
|
||||
#define __deref_opt_inout_bcount_z_opt(size)
|
||||
#define __deref_opt_inout_ecount(size)
|
||||
#define __deref_opt_inout_ecount_full(size)
|
||||
#define __deref_opt_inout_ecount_full_opt(size)
|
||||
#define __deref_opt_inout_ecount_nz(size)
|
||||
#define __deref_opt_inout_ecount_nz_opt(size)
|
||||
#define __deref_opt_inout_ecount_opt(size)
|
||||
#define __deref_opt_inout_ecount_part(size,length)
|
||||
#define __deref_opt_inout_ecount_part_opt(size,length)
|
||||
#define __deref_opt_inout_ecount_z(size)
|
||||
#define __deref_opt_inout_ecount_z_opt(size)
|
||||
#define __deref_opt_inout_nz
|
||||
#define __deref_opt_inout_nz_opt
|
||||
#define __deref_opt_inout_opt
|
||||
#define __deref_opt_inout_xcount(size)
|
||||
#define __deref_opt_inout_xcount_full(size)
|
||||
#define __deref_opt_inout_xcount_full_opt(size)
|
||||
#define __deref_opt_inout_xcount_opt(size)
|
||||
#define __deref_opt_inout_xcount_part(size,length)
|
||||
#define __deref_opt_inout_xcount_part_opt(size,length)
|
||||
#define __deref_opt_inout_z
|
||||
#define __deref_opt_inout_z_opt
|
||||
#define __deref_opt_out
|
||||
#define __deref_opt_out_bcount(size)
|
||||
#define __deref_opt_out_bcount_full(size)
|
||||
#define __deref_opt_out_bcount_full_opt(size)
|
||||
#define __deref_opt_out_bcount_nz_opt(size)
|
||||
#define __deref_opt_out_bcount_opt(size)
|
||||
#define __deref_opt_out_bcount_part(size,length)
|
||||
#define __deref_opt_out_bcount_part_opt(size,length)
|
||||
#define __deref_opt_out_bcount_z_opt(size)
|
||||
#define __deref_opt_out_ecount(size)
|
||||
#define __deref_opt_out_ecount_full(size)
|
||||
#define __deref_opt_out_ecount_full_opt(size)
|
||||
#define __deref_opt_out_ecount_nz_opt(size)
|
||||
#define __deref_opt_out_ecount_opt(size)
|
||||
#define __deref_opt_out_ecount_part(size,length)
|
||||
#define __deref_opt_out_ecount_part_opt(size,length)
|
||||
#define __deref_opt_out_ecount_z_opt(size)
|
||||
#define __deref_opt_out_nz_opt
|
||||
#define __deref_opt_out_opt
|
||||
#define __deref_opt_out_xcount(size)
|
||||
#define __deref_opt_out_xcount_full(size)
|
||||
#define __deref_opt_out_xcount_full_opt(size)
|
||||
#define __deref_opt_out_xcount_opt(size)
|
||||
#define __deref_opt_out_xcount_part(size,length)
|
||||
#define __deref_opt_out_xcount_part_opt(size,length)
|
||||
#define __deref_opt_out_z
|
||||
#define __deref_opt_out_z_opt
|
||||
#define __deref_opt_xcount(size)
|
||||
#define __deref_opt_xcount_opt(size)
|
||||
#define __deref_out
|
||||
#define __deref_out_bcount(size)
|
||||
#define __deref_out_bcount_full(size)
|
||||
#define __deref_out_bcount_full_opt(size)
|
||||
#define __deref_out_bcount_nz(size)
|
||||
#define __deref_out_bcount_nz_opt(size)
|
||||
#define __deref_out_bcount_opt(size)
|
||||
#define __deref_out_bcount_part(size,length)
|
||||
#define __deref_out_bcount_part_opt(size,length)
|
||||
#define __deref_out_bcount_z(size)
|
||||
#define __deref_out_bcount_z_opt(size)
|
||||
#define __deref_out_bound
|
||||
#define __deref_out_ecount(size)
|
||||
#define __deref_out_ecount_full(size)
|
||||
#define __deref_out_ecount_full_opt(size)
|
||||
#define __deref_out_ecount_nz(size)
|
||||
#define __deref_out_ecount_nz_opt(size)
|
||||
#define __deref_out_ecount_opt(size)
|
||||
#define __deref_out_ecount_part(size,length)
|
||||
#define __deref_out_ecount_part_opt(size,length)
|
||||
#define __deref_out_ecount_z(size)
|
||||
#define __deref_out_ecount_z_opt(size)
|
||||
#define __deref_out_nz
|
||||
#define __deref_out_nz_opt
|
||||
#define __deref_out_opt
|
||||
#define __deref_out_range(lb,ub)
|
||||
#define __deref_out_xcount(size)
|
||||
#define __deref_out_xcount_full(size)
|
||||
#define __deref_out_xcount_full_opt(size)
|
||||
#define __deref_out_xcount_opt(size)
|
||||
#define __deref_out_xcount_part(size,length)
|
||||
#define __deref_out_xcount_part_opt(size,length)
|
||||
#define __deref_out_z
|
||||
#define __deref_out_z_opt
|
||||
#define __deref_xcount(size)
|
||||
#define __deref_xcount_opt(size)
|
||||
#define __ecount(size)
|
||||
#define __ecount_opt(size)
|
||||
#define __fallthrough
|
||||
#define __field_bcount(size)
|
||||
#define __field_bcount_full(size)
|
||||
#define __field_bcount_full_opt(size)
|
||||
#define __field_bcount_opt(size)
|
||||
#define __field_bcount_part(size,init)
|
||||
#define __field_bcount_part_opt(size,init)
|
||||
#define __field_data_source(src_sym)
|
||||
#define __field_ecount(size)
|
||||
#define __field_ecount_full(size)
|
||||
#define __field_ecount_full_opt(size)
|
||||
#define __field_ecount_opt(size)
|
||||
#define __field_ecount_part(size,init)
|
||||
#define __field_ecount_part_opt(size,init)
|
||||
#define __field_range(lb,ub)
|
||||
#define __field_xcount(size)
|
||||
#define __field_xcount_full(size)
|
||||
#define __field_xcount_full_opt(size)
|
||||
#define __field_xcount_opt(size)
|
||||
#define __field_xcount_part(size,init)
|
||||
#define __field_xcount_part_opt(size,init)
|
||||
#define __format_string
|
||||
#define __inn
|
||||
#define __in_bcount(size)
|
||||
#define __in_bcount_nz(size)
|
||||
#define __in_bcount_nz_opt(size)
|
||||
#define __in_bcount_opt(size)
|
||||
#define __in_bcount_z(size)
|
||||
#define __in_bcount_z_opt(size)
|
||||
#define __in_bound
|
||||
#define __in_ecount(size)
|
||||
#define __in_ecount_nz(size)
|
||||
#define __in_ecount_nz_opt(size)
|
||||
#define __in_ecount_opt(size)
|
||||
#define __in_ecount_z(size)
|
||||
#define __in_ecount_z_opt(size)
|
||||
#define __in_nz
|
||||
#define __in_nz_opt
|
||||
#define __in_opt
|
||||
#define __in_range(lb,ub)
|
||||
#define __in_xcount(size)
|
||||
#define __in_xcount_opt(size)
|
||||
#define __in_z
|
||||
#define __in_z_opt
|
||||
#define __inexpressible_readableTo(size)
|
||||
#define __inexpressible_writableTo(size)
|
||||
#define __inner_allocator
|
||||
#define __inner_assume_bound(i)
|
||||
#define __inner_assume_bound_dec
|
||||
#define __inner_bound
|
||||
#define __inner_range(lb,ub)
|
||||
#define __inout
|
||||
#define __inout_bcount(size)
|
||||
#define __inout_bcount_full(size)
|
||||
#define __inout_bcount_full_opt(size)
|
||||
#define __inout_bcount_nz(size)
|
||||
#define __inout_bcount_nz_opt(size)
|
||||
#define __inout_bcount_opt(size)
|
||||
#define __inout_bcount_part(size,length)
|
||||
#define __inout_bcount_part_opt(size,length)
|
||||
#define __inout_bcount_z(size)
|
||||
#define __inout_bcount_z_opt(size)
|
||||
#define __inout_ecount(size)
|
||||
#define __inout_ecount_full(size)
|
||||
#define __inout_ecount_full_opt(size)
|
||||
#define __inout_ecount_nz(size)
|
||||
#define __inout_ecount_nz_opt(size)
|
||||
#define __inout_ecount_opt(size)
|
||||
#define __inout_ecount_part(size,length)
|
||||
#define __inout_ecount_part_opt(size,length)
|
||||
#define __inout_ecount_z(size)
|
||||
#define __inout_ecount_z_opt(size)
|
||||
#define __inout_nz
|
||||
#define __inout_nz_opt
|
||||
#define __inout_opt
|
||||
#define __inout_xcount(size)
|
||||
#define __inout_xcount_full(size)
|
||||
#define __inout_xcount_full_opt(size)
|
||||
#define __inout_xcount_opt(size)
|
||||
#define __inout_xcount_opt(size)
|
||||
#define __inout_xcount_part(size,length)
|
||||
#define __inout_xcount_part_opt(size,length)
|
||||
#define __inout_z
|
||||
#define __inout_z_opt
|
||||
#define __nullnullterminated
|
||||
#define __nullterminated
|
||||
#define __outt
|
||||
#define __out_bcount(size)
|
||||
#define __out_bcount_full(size)
|
||||
#define __out_bcount_full_opt(size)
|
||||
#define __out_bcount_full_z(size)
|
||||
#define __out_bcount_full_z_opt(size)
|
||||
#define __out_bcount_nz(size)
|
||||
#define __out_bcount_nz_opt(size)
|
||||
#define __out_bcount_opt(size)
|
||||
#define __out_bcount_part(size,length)
|
||||
#define __out_bcount_part_opt(size,length)
|
||||
#define __out_bcount_part_z(size,length)
|
||||
#define __out_bcount_part_z_opt(size,length)
|
||||
#define __out_bcount_z(size)
|
||||
#define __out_bcount_z_opt(size)
|
||||
#define __out_bound
|
||||
#define __out_ecount(size)
|
||||
#define __out_ecount_full(size)
|
||||
#define __out_ecount_full_opt(size)
|
||||
#define __out_ecount_full_z(size)
|
||||
#define __out_ecount_full_z_opt(size)
|
||||
#define __out_ecount_nz(size)
|
||||
#define __out_ecount_nz_opt(size)
|
||||
#define __out_ecount_opt(size)
|
||||
#define __out_ecount_part(size,length)
|
||||
#define __out_ecount_part_opt(size,length)
|
||||
#define __out_ecount_part_z(size,length)
|
||||
#define __out_ecount_part_z_opt(size,length)
|
||||
#define __out_ecount_z(size)
|
||||
#define __out_ecount_z_opt(size)
|
||||
#define __out_nz
|
||||
#define __out_nz_opt
|
||||
#define __out_opt
|
||||
#define __out_range(lb,ub)
|
||||
#define __out_xcount(size)
|
||||
#define __out_xcount_full(size)
|
||||
#define __out_xcount_full_opt(size)
|
||||
#define __out_xcount_opt(size)
|
||||
#define __out_xcount_part(size,length)
|
||||
#define __out_xcount_part_opt(size,length)
|
||||
#define __out_z
|
||||
#define __out_z_opt
|
||||
#define __override
|
||||
#define __range(lb,ub)
|
||||
#define __reserved
|
||||
#define __sql_escaped_and_delimited_right_bracket
|
||||
#define __struct_bcount(size)
|
||||
#define __struct_xcount(size)
|
||||
#define __success(expr)
|
||||
#define __transfer(formal)
|
||||
#define __typefix(ctype)
|
||||
#define __xcount(size)
|
||||
#define __xcount_opt(size)
|
||||
#define _Analysis_assume_
|
||||
#define _Check_return_
|
||||
#define _Check_return_
|
||||
#define _Deref
|
||||
#define _Deref_in_bound_
|
||||
#define _Deref_in_range_(lb,ub)
|
||||
#define _Deref_inout_bound_
|
||||
#define _Deref_inout_z_
|
||||
#define _Deref_inout_z_bytecap_c_(size)
|
||||
#define _Deref_inout_z_cap_c_(size)
|
||||
#define _Deref_opt_out_
|
||||
#define _Deref_opt_out_opt_
|
||||
#define _Deref_opt_out_opt_z_
|
||||
#define _Deref_opt_out_z_
|
||||
#define _Deref_out_
|
||||
#define _Deref_out_bound_
|
||||
#define _Deref_out_opt_
|
||||
#define _Deref_out_opt_z_
|
||||
#define _Deref_out_range_(lb,ub)
|
||||
#define _Deref_out_z_
|
||||
#define _Deref_out_z_bytecap_c_(size)
|
||||
#define _Deref_out_z_cap_c_(size)
|
||||
#define _Deref_post_bytecap_(size)
|
||||
#define _Deref_post_bytecap_c_(size)
|
||||
#define _Deref_post_bytecap_x_(size)
|
||||
#define _Deref_post_bytecount_(size)
|
||||
#define _Deref_post_bytecount_c_(size)
|
||||
#define _Deref_post_bytecount_x_(size)
|
||||
#define _Deref_post_cap_(size)
|
||||
#define _Deref_post_cap_c_(size)
|
||||
#define _Deref_post_cap_x_(size)
|
||||
#define _Deref_post_count_(size)
|
||||
#define _Deref_post_count_c_(size)
|
||||
#define _Deref_post_count_x_(size)
|
||||
#define _Deref_post_maybenull_
|
||||
#define _Deref_post_notnull_
|
||||
#define _Deref_post_null_
|
||||
#define _Deref_post_opt_bytecap_(size)
|
||||
#define _Deref_post_opt_bytecap_c_(size)
|
||||
#define _Deref_post_opt_bytecap_x_(size)
|
||||
#define _Deref_post_opt_bytecount_(size)
|
||||
#define _Deref_post_opt_bytecount_c_(size)
|
||||
#define _Deref_post_opt_bytecount_x_(size)
|
||||
#define _Deref_post_opt_cap_(size)
|
||||
#define _Deref_post_opt_cap_c_(size)
|
||||
#define _Deref_post_opt_cap_x_(size)
|
||||
#define _Deref_post_opt_count_(size)
|
||||
#define _Deref_post_opt_count_c_(size)
|
||||
#define _Deref_post_opt_count_x_(size)
|
||||
#define _Deref_post_opt_valid_
|
||||
#define _Deref_post_opt_valid_bytecap_(size)
|
||||
#define _Deref_post_opt_valid_bytecap_c_(size)
|
||||
#define _Deref_post_opt_valid_bytecap_x_(size)
|
||||
#define _Deref_post_opt_valid_cap_(size)
|
||||
#define _Deref_post_opt_valid_cap_c_(size)
|
||||
#define _Deref_post_opt_valid_cap_x_(size)
|
||||
#define _Deref_post_opt_z_
|
||||
#define _Deref_post_opt_z_bytecap_(size)
|
||||
#define _Deref_post_opt_z_bytecap_c_(size)
|
||||
#define _Deref_post_opt_z_bytecap_x_(size)
|
||||
#define _Deref_post_opt_z_cap_(size)
|
||||
#define _Deref_post_opt_z_cap_c_(size)
|
||||
#define _Deref_post_opt_z_cap_x_(size)
|
||||
#define _Deref_post_valid_
|
||||
#define _Deref_post_valid_bytecap_(size)
|
||||
#define _Deref_post_valid_bytecap_c_(size)
|
||||
#define _Deref_post_valid_bytecap_x_(size)
|
||||
#define _Deref_post_valid_cap_(size)
|
||||
#define _Deref_post_valid_cap_c_(size)
|
||||
#define _Deref_post_valid_cap_x_(size)
|
||||
#define _Deref_post_z_
|
||||
#define _Deref_post_z_
|
||||
#define _Deref_post_z_bytecap_(size)
|
||||
#define _Deref_post_z_bytecap_c_(size)
|
||||
#define _Deref_post_z_bytecap_x_(size)
|
||||
#define _Deref_post_z_cap_(size)
|
||||
#define _Deref_post_z_cap_c_(size)
|
||||
#define _Deref_post_z_cap_x_(size)
|
||||
#define _Deref_pre_bytecap_(size)
|
||||
#define _Deref_pre_bytecap_c_(size)
|
||||
#define _Deref_pre_bytecap_x_(size)
|
||||
#define _Deref_pre_bytecount_(size)
|
||||
#define _Deref_pre_bytecount_c_(size)
|
||||
#define _Deref_pre_bytecount_x_(size)
|
||||
#define _Deref_pre_cap_(size)
|
||||
#define _Deref_pre_cap_c_(size)
|
||||
#define _Deref_pre_cap_x_(size)
|
||||
#define _Deref_pre_count_(size)
|
||||
#define _Deref_pre_count_c_(size)
|
||||
#define _Deref_pre_count_x_(size)
|
||||
#define _Deref_pre_invalid_
|
||||
#define _Deref_pre_maybenull_
|
||||
#define _Deref_pre_notnull_
|
||||
#define _Deref_pre_null_
|
||||
#define _Deref_pre_opt_bytecap_(size)
|
||||
#define _Deref_pre_opt_bytecap_c_(size)
|
||||
#define _Deref_pre_opt_bytecap_x_(size)
|
||||
#define _Deref_pre_opt_bytecount_(size)
|
||||
#define _Deref_pre_opt_bytecount_c_(size)
|
||||
#define _Deref_pre_opt_bytecount_x_(size)
|
||||
#define _Deref_pre_opt_cap_(size)
|
||||
#define _Deref_pre_opt_cap_c_(size)
|
||||
#define _Deref_pre_opt_cap_x_(size)
|
||||
#define _Deref_pre_opt_count_(size)
|
||||
#define _Deref_pre_opt_count_c_(size)
|
||||
#define _Deref_pre_opt_count_x_(size)
|
||||
#define _Deref_pre_opt_valid_
|
||||
#define _Deref_pre_opt_valid_bytecap_(size)
|
||||
#define _Deref_pre_opt_valid_bytecap_c_(size)
|
||||
#define _Deref_pre_opt_valid_bytecap_x_(size)
|
||||
#define _Deref_pre_opt_valid_cap_(size)
|
||||
#define _Deref_pre_opt_valid_cap_c_(size)
|
||||
#define _Deref_pre_opt_valid_cap_x_(size)
|
||||
#define _Deref_pre_opt_z_
|
||||
#define _Deref_pre_opt_z_bytecap_(size)
|
||||
#define _Deref_pre_opt_z_bytecap_c_(size)
|
||||
#define _Deref_pre_opt_z_bytecap_x_(size)
|
||||
#define _Deref_pre_opt_z_cap_(size)
|
||||
#define _Deref_pre_opt_z_cap_c_(size)
|
||||
#define _Deref_pre_opt_z_cap_x_(size)
|
||||
#define _Deref_pre_readonly_
|
||||
#define _Deref_pre_valid_
|
||||
#define _Deref_pre_valid_bytecap_(size)
|
||||
#define _Deref_pre_valid_bytecap_c_(size)
|
||||
#define _Deref_pre_valid_bytecap_x_(size)
|
||||
#define _Deref_pre_valid_cap_(size)
|
||||
#define _Deref_pre_valid_cap_c_(size)
|
||||
#define _Deref_pre_valid_cap_x_(size)
|
||||
#define _Deref_pre_writeonly_
|
||||
#define _Deref_pre_z_
|
||||
#define _Deref_pre_z_bytecap_(size)
|
||||
#define _Deref_pre_z_bytecap_c_(size)
|
||||
#define _Deref_pre_z_bytecap_x_(size)
|
||||
#define _Deref_pre_z_cap_(size)
|
||||
#define _Deref_pre_z_cap_c_(size)
|
||||
#define _Deref_pre_z_cap_x_(size)
|
||||
#define _Deref_prepost_bytecap_(size)
|
||||
#define _Deref_prepost_bytecap_x_(size)
|
||||
#define _Deref_prepost_bytecount_(size)
|
||||
#define _Deref_prepost_bytecount_x_(size)
|
||||
#define _Deref_prepost_cap_(size)
|
||||
#define _Deref_prepost_cap_x_(size)
|
||||
#define _Deref_prepost_count_(size)
|
||||
#define _Deref_prepost_count_x_(size)
|
||||
#define _Deref_prepost_opt_bytecap_(size)
|
||||
#define _Deref_prepost_opt_bytecap_x_(size)
|
||||
#define _Deref_prepost_opt_bytecount_(size)
|
||||
#define _Deref_prepost_opt_bytecount_x_(size)
|
||||
#define _Deref_prepost_opt_cap_(size)
|
||||
#define _Deref_prepost_opt_cap_x_(size)
|
||||
#define _Deref_prepost_opt_count_(size)
|
||||
#define _Deref_prepost_opt_count_x_(size)
|
||||
#define _Deref_prepost_opt_valid_
|
||||
#define _Deref_prepost_opt_valid_bytecap_(size)
|
||||
#define _Deref_prepost_opt_valid_bytecap_x_(size)
|
||||
#define _Deref_prepost_opt_valid_cap_(size)
|
||||
#define _Deref_prepost_opt_valid_cap_x_(size)
|
||||
#define _Deref_prepost_opt_z_
|
||||
#define _Deref_prepost_opt_z_bytecap_(size)
|
||||
#define _Deref_prepost_opt_z_cap_(size)
|
||||
#define _Deref_prepost_valid_
|
||||
#define _Deref_prepost_valid_bytecap_(size)
|
||||
#define _Deref_prepost_valid_bytecap_x_(size)
|
||||
#define _Deref_prepost_valid_cap_(size)
|
||||
#define _Deref_prepost_valid_cap_x_(size)
|
||||
#define _Deref_prepost_z_
|
||||
#define _Deref_prepost_z_bytecap_(size)
|
||||
#define _Deref_prepost_z_cap_(size)
|
||||
#define _Deref_ret_bound_
|
||||
#define _Deref_ret_opt_z_
|
||||
#define _Deref_ret_range_(lb,ub)
|
||||
#define _Deref_ret_z_
|
||||
#define _FormatMessage_format_string_
|
||||
#define _In_
|
||||
#define _In_bound_
|
||||
#define _In_bytecount_(size)
|
||||
#define _In_bytecount_c_(size)
|
||||
#define _In_bytecount_x_(size)
|
||||
#define _In_count_(size)
|
||||
#define _In_count_c_(size)
|
||||
#define _In_count_x_(size)
|
||||
#define _In_opt_
|
||||
#define _In_opt_
|
||||
#define _In_opt_bytecount_(size)
|
||||
#define _In_opt_bytecount_c_(size)
|
||||
#define _In_opt_bytecount_x_(size)
|
||||
#define _In_opt_count_(size)
|
||||
#define _In_opt_count_c_(size)
|
||||
#define _In_opt_count_x_(size)
|
||||
#define _In_opt_ptrdiff_count_(size)
|
||||
#define _In_opt_z_
|
||||
#define _In_opt_z_bytecount_(size)
|
||||
#define _In_opt_z_bytecount_c_(size)
|
||||
#define _In_opt_z_count_(size)
|
||||
#define _In_opt_z_count_c_(size)
|
||||
#define _In_ptrdiff_count_(size)
|
||||
#define _In_range_(lb,ub)
|
||||
#define _In_reads_bytes_(size)
|
||||
#define _In_z_
|
||||
#define _In_z_bytecount_(size)
|
||||
#define _In_z_bytecount_c_(size)
|
||||
#define _In_z_count_(size)
|
||||
#define _In_z_count_c_(size)
|
||||
#define _Inout_
|
||||
#define _Inout_bytecap_(size)
|
||||
#define _Inout_bytecap_c_(size)
|
||||
#define _Inout_bytecap_x_(size)
|
||||
#define _Inout_bytecount_(size)
|
||||
#define _Inout_bytecount_c_(size)
|
||||
#define _Inout_bytecount_x_(size)
|
||||
#define _Inout_cap_(size)
|
||||
#define _Inout_cap_c_(size)
|
||||
#define _Inout_cap_x_(size)
|
||||
#define _Inout_count_(size)
|
||||
#define _Inout_count_c_(size)
|
||||
#define _Inout_count_x_(size)
|
||||
#define _Inout_opt_
|
||||
#define _Inout_opt_bytecap_(size)
|
||||
#define _Inout_opt_bytecap_c_(size)
|
||||
#define _Inout_opt_bytecap_x_(size)
|
||||
#define _Inout_opt_bytecount_(size)
|
||||
#define _Inout_opt_bytecount_c_(size)
|
||||
#define _Inout_opt_bytecount_x_(size)
|
||||
#define _Inout_opt_cap_(size)
|
||||
#define _Inout_opt_cap_c_(size)
|
||||
#define _Inout_opt_cap_x_(size)
|
||||
#define _Inout_opt_count_(size)
|
||||
#define _Inout_opt_count_c_(size)
|
||||
#define _Inout_opt_count_x_(size)
|
||||
#define _Inout_opt_ptrdiff_count_(size)
|
||||
#define _Inout_opt_z_
|
||||
#define _Inout_opt_z_bytecap_(size)
|
||||
#define _Inout_opt_z_bytecap_c_(size)
|
||||
#define _Inout_opt_z_bytecap_x_(size)
|
||||
#define _Inout_opt_z_bytecount_(size)
|
||||
#define _Inout_opt_z_bytecount_c_(size)
|
||||
#define _Inout_opt_z_cap_(size)
|
||||
#define _Inout_opt_z_cap_c_(size)
|
||||
#define _Inout_opt_z_cap_x_(size)
|
||||
#define _Inout_opt_z_count_(size)
|
||||
#define _Inout_opt_z_count_c_(size)
|
||||
#define _Inout_ptrdiff_count_(size)
|
||||
#define _Inout_z_
|
||||
#define _Inout_z_bytecap_(size)
|
||||
#define _Inout_z_bytecap_c_(size)
|
||||
#define _Inout_z_bytecap_x_(size)
|
||||
#define _Inout_z_bytecount_(size)
|
||||
#define _Inout_z_bytecount_c_(size)
|
||||
#define _Inout_z_cap_(size)
|
||||
#define _Inout_z_cap_c_(size)
|
||||
#define _Inout_z_cap_x_(size)
|
||||
#define _Inout_z_count_(size)
|
||||
#define _Inout_z_count_c_(size)
|
||||
#define _Out_
|
||||
#define _Out_bound_
|
||||
#define _Out_bytecap_(size)
|
||||
#define _Out_bytecap_c_(size)
|
||||
#define _Out_bytecap_post_bytecount_(cap,count)
|
||||
#define _Out_bytecap_x_(size)
|
||||
#define _Out_bytecapcount_(capcount)
|
||||
#define _Out_bytecapcount_x_(capcount)
|
||||
#define _Out_cap_(size)
|
||||
#define _Out_cap_c_(size)
|
||||
#define _Out_cap_m_(mult,size)
|
||||
#define _Out_cap_post_count_(cap,count)
|
||||
#define _Out_cap_x_(size)
|
||||
#define _Out_capcount_(capcount)
|
||||
#define _Out_capcount_x_(capcount)
|
||||
#define _Out_opt_
|
||||
#define _Out_opt_bytecap_(size)
|
||||
#define _Out_opt_bytecap_c_(size)
|
||||
#define _Out_opt_bytecap_post_bytecount_(cap,count)
|
||||
#define _Out_opt_bytecap_x_(size)
|
||||
#define _Out_opt_bytecapcount_(capcount)
|
||||
#define _Out_opt_bytecapcount_x_(capcount)
|
||||
#define _Out_opt_cap_(size)
|
||||
#define _Out_opt_cap_c_(size)
|
||||
#define _Out_opt_cap_m_(mult,size)
|
||||
#define _Out_opt_cap_post_count_(cap,count)
|
||||
#define _Out_opt_cap_x_(size)
|
||||
#define _Out_opt_capcount_(capcount)
|
||||
#define _Out_opt_capcount_x_(capcount)
|
||||
#define _Out_opt_ptrdiff_cap_(size)
|
||||
#define _Out_opt_z_bytecap_(size)
|
||||
#define _Out_opt_z_bytecap_c_(size)
|
||||
#define _Out_opt_z_bytecap_post_bytecount_(cap,count)
|
||||
#define _Out_opt_z_bytecap_x_(size)
|
||||
#define _Out_opt_z_bytecapcount_(capcount)
|
||||
#define _Out_opt_z_cap_(size)
|
||||
#define _Out_opt_z_cap_c_(size)
|
||||
#define _Out_opt_z_cap_m_(mult,size)
|
||||
#define _Out_opt_z_cap_post_count_(cap,count)
|
||||
#define _Out_opt_z_cap_x_(size)
|
||||
#define _Out_opt_z_capcount_(capcount)
|
||||
#define _Out_ptrdiff_cap_(size)
|
||||
#define _Out_range_(lb,ub)
|
||||
#define _Out_writes_(size)
|
||||
#define _Out_writes_bytes_(count)
|
||||
#define _Out_z_bytecap_(size)
|
||||
#define _Out_z_bytecap_c_(size)
|
||||
#define _Out_z_bytecap_post_bytecount_(cap,count)
|
||||
#define _Out_z_bytecap_x_(size)
|
||||
#define _Out_z_bytecapcount_(capcount)
|
||||
#define _Out_z_cap_(size)
|
||||
#define _Out_z_cap_c_(size)
|
||||
#define _Out_z_cap_m_(mult,size)
|
||||
#define _Out_z_cap_post_count_(cap,count)
|
||||
#define _Out_z_cap_x_(size)
|
||||
#define _Out_z_capcount_(capcount)
|
||||
#define _Post_bytecap_(size)
|
||||
#define _Post_bytecount_(size)
|
||||
#define _Post_bytecount_c_(size)
|
||||
#define _Post_bytecount_x_(size)
|
||||
#define _Post_cap_(size)
|
||||
#define _Post_count_(size)
|
||||
#define _Post_count_c_(size)
|
||||
#define _Post_count_x_(size)
|
||||
#define _Post_invalid_
|
||||
#define _Post_maybez_
|
||||
#define _Post_notnull_
|
||||
#define _Post_ptr_invalid_
|
||||
#define _Post_valid_
|
||||
#define _Post_z_
|
||||
#define _Post_z_bytecount_(size)
|
||||
#define _Post_z_bytecount_c_(size)
|
||||
#define _Post_z_bytecount_x_(size)
|
||||
#define _Post_z_count_(size)
|
||||
#define _Post_z_count_c_(size)
|
||||
#define _Post_z_count_x_(size)
|
||||
#define _Pre_bytecap_(size)
|
||||
#define _Pre_bytecap_c_(size)
|
||||
#define _Pre_bytecap_x_(size)
|
||||
#define _Pre_bytecount_(size)
|
||||
#define _Pre_bytecount_c_(size)
|
||||
#define _Pre_bytecount_x_(size)
|
||||
#define _Pre_cap_(size)
|
||||
#define _Pre_cap_c_(size)
|
||||
#define _Pre_cap_for_(param)
|
||||
#define _Pre_cap_m_(mult,size)
|
||||
#define _Pre_cap_x_(size)
|
||||
#define _Pre_count_(size)
|
||||
#define _Pre_count_c_(size)
|
||||
#define _Pre_count_x_(size)
|
||||
#define _Pre_invalid_
|
||||
#define _Pre_maybenull_
|
||||
#define _Pre_notnull_
|
||||
#define _Pre_null_
|
||||
#define _Pre_opt_bytecap_(size)
|
||||
#define _Pre_opt_bytecap_c_(size)
|
||||
#define _Pre_opt_bytecap_x_(size)
|
||||
#define _Pre_opt_bytecount_(size)
|
||||
#define _Pre_opt_bytecount_c_(size)
|
||||
#define _Pre_opt_bytecount_x_(size)
|
||||
#define _Pre_opt_cap_(size)
|
||||
#define _Pre_opt_cap_c_(size)
|
||||
#define _Pre_opt_cap_for_(param)
|
||||
#define _Pre_opt_cap_m_(mult,size)
|
||||
#define _Pre_opt_cap_x_(size)
|
||||
#define _Pre_opt_count_(size)
|
||||
#define _Pre_opt_count_c_(size)
|
||||
#define _Pre_opt_count_x_(size)
|
||||
#define _Pre_opt_ptrdiff_cap_(ptr)
|
||||
#define _Pre_opt_ptrdiff_count_(ptr)
|
||||
#define _Pre_opt_valid_
|
||||
#define _Pre_opt_valid_bytecap_(size)
|
||||
#define _Pre_opt_valid_bytecap_c_(size)
|
||||
#define _Pre_opt_valid_bytecap_x_(size)
|
||||
#define _Pre_opt_valid_cap_(size)
|
||||
#define _Pre_opt_valid_cap_c_(size)
|
||||
#define _Pre_opt_valid_cap_x_(size)
|
||||
#define _Pre_opt_z_
|
||||
#define _Pre_opt_z_bytecap_(size)
|
||||
#define _Pre_opt_z_bytecap_c_(size)
|
||||
#define _Pre_opt_z_bytecap_x_(size)
|
||||
#define _Pre_opt_z_cap_(size)
|
||||
#define _Pre_opt_z_cap_c_(size)
|
||||
#define _Pre_opt_z_cap_x_(size)
|
||||
#define _Pre_ptrdiff_cap_(ptr)
|
||||
#define _Pre_ptrdiff_count_(ptr)
|
||||
#define _Pre_readonly_
|
||||
#define _Pre_valid_
|
||||
#define _Pre_valid_bytecap_(size)
|
||||
#define _Pre_valid_bytecap_c_(size)
|
||||
#define _Pre_valid_bytecap_x_(size)
|
||||
#define _Pre_valid_cap_(size)
|
||||
#define _Pre_valid_cap_c_(size)
|
||||
#define _Pre_valid_cap_x_(size)
|
||||
#define _Pre_writeonly_
|
||||
#define _Pre_z_
|
||||
#define _Pre_z_bytecap_(size)
|
||||
#define _Pre_z_bytecap_c_(size)
|
||||
#define _Pre_z_bytecap_x_(size)
|
||||
#define _Pre_z_cap_(size)
|
||||
#define _Pre_z_cap_c_(size)
|
||||
#define _Pre_z_cap_x_(size)
|
||||
#define _Prepost_bytecount_(size)
|
||||
#define _Prepost_bytecount_c_(size)
|
||||
#define _Prepost_bytecount_x_(size)
|
||||
#define _Prepost_count_(size)
|
||||
#define _Prepost_count_c_(size)
|
||||
#define _Prepost_count_x_(size)
|
||||
#define _Prepost_opt_bytecount_(size)
|
||||
#define _Prepost_opt_bytecount_c_(size)
|
||||
#define _Prepost_opt_bytecount_x_(size)
|
||||
#define _Prepost_opt_count_(size)
|
||||
#define _Prepost_opt_count_c_(size)
|
||||
#define _Prepost_opt_count_x_(size)
|
||||
#define _Prepost_opt_valid_
|
||||
#define _Prepost_opt_z_
|
||||
#define _Prepost_valid_
|
||||
#define _Prepost_z_
|
||||
#define _Printf_format_string_
|
||||
#define _Ret_
|
||||
#define _Ret_bound_
|
||||
#define _Ret_bytecap_(size)
|
||||
#define _Ret_bytecap_c_(size)
|
||||
#define _Ret_bytecap_x_(size)
|
||||
#define _Ret_bytecount_(size)
|
||||
#define _Ret_bytecount_c_(size)
|
||||
#define _Ret_bytecount_x_(size)
|
||||
#define _Ret_cap_(size)
|
||||
#define _Ret_cap_c_(size)
|
||||
#define _Ret_cap_x_(size)
|
||||
#define _Ret_count_(size)
|
||||
#define _Ret_count_c_(size)
|
||||
#define _Ret_count_x_(size)
|
||||
#define _Ret_maybenull_
|
||||
#define _Ret_notnull_
|
||||
#define _Ret_null_
|
||||
#define _Ret_opt_
|
||||
#define _Ret_opt_
|
||||
#define _Ret_opt_bytecap_(size)
|
||||
#define _Ret_opt_bytecap_c_(size)
|
||||
#define _Ret_opt_bytecap_x_(size)
|
||||
#define _Ret_opt_bytecount_(size)
|
||||
#define _Ret_opt_bytecount_c_(size)
|
||||
#define _Ret_opt_bytecount_x_(size)
|
||||
#define _Ret_opt_cap_(size)
|
||||
#define _Ret_opt_cap_c_(size)
|
||||
#define _Ret_opt_cap_x_(size)
|
||||
#define _Ret_opt_count_(size)
|
||||
#define _Ret_opt_count_c_(size)
|
||||
#define _Ret_opt_count_x_(size)
|
||||
#define _Ret_opt_valid_
|
||||
#define _Ret_opt_z_
|
||||
#define _Ret_opt_z_
|
||||
#define _Ret_opt_z_bytecap_(size)
|
||||
#define _Ret_opt_z_bytecount_(size)
|
||||
#define _Ret_opt_z_cap_(size)
|
||||
#define _Ret_opt_z_count_(size)
|
||||
#define _Ret_range_(lb,ub)
|
||||
#define _Ret_valid_
|
||||
#define _Ret_z_
|
||||
#define _Ret_z_
|
||||
#define _Ret_z_bytecap_(size)
|
||||
#define _Ret_z_bytecount_(size)
|
||||
#define _Ret_z_cap_(size)
|
||||
#define _Ret_z_count_(size)
|
||||
#define _Scanf_format_string_
|
||||
#define _Scanf_s_format_string_
|
||||
#define _Success_(expr)
|
||||
#define _Outptr_
|
||||
#define _Notnull_
|
||||
|
||||
#endif // XPLAT_SAL_DEFINED
|
||||
|
109
source/shared/typedefs_for_linux.h
Normal file
109
source/shared/typedefs_for_linux.h
Normal file
|
@ -0,0 +1,109 @@
|
|||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
// File: typedefs_for_linux.h
|
||||
//
|
||||
// Microsoft Drivers 4.0 for PHP for SQL Server
|
||||
// Copyright(c) Microsoft Corporation
|
||||
// All rights reserved.
|
||||
// MIT License
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""),
|
||||
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef __linux_typedefs__
|
||||
#define __linux_typedefs__
|
||||
|
||||
#define MPLAT_UNIX
|
||||
|
||||
#include "xplat.h"
|
||||
#include "interlockedslist.h"
|
||||
|
||||
#define CP_OEMCP 1 // default to OEM code page
|
||||
#define CP_MACCP 2 // default to MAC code page
|
||||
#define CP_THREAD_ACP 3 // current thread's ANSI code page
|
||||
#define CP_SYMBOL 42 // SYMBOL translations
|
||||
|
||||
#define CP_UTF7 65000 // UTF-7 translation
|
||||
|
||||
#define MAKELANGID(p, s) ((((WORD )(s)) << 10) | (WORD )(p))
|
||||
#define LANG_NEUTRAL 0x00
|
||||
#define SUBLANG_DEFAULT 0x01 // user default
|
||||
|
||||
// #ifndef _GETLASTERROR
|
||||
// #define _GETLASTERROR
|
||||
// void SSetLastError(DWORD err);
|
||||
// unsigned int GGetLastError();
|
||||
// #endif
|
||||
|
||||
DWORD FormatMessageA(
|
||||
DWORD dwFlags,
|
||||
LPCVOID lpSource,
|
||||
DWORD dwMessageId,
|
||||
DWORD dwLanguageId,
|
||||
LPTSTR lpBuffer,
|
||||
DWORD nSize,
|
||||
va_list *Arguments
|
||||
);
|
||||
|
||||
DWORD FormatMessageW(
|
||||
DWORD dwFlags,
|
||||
LPCVOID lpSource,
|
||||
DWORD dwMessageId,
|
||||
DWORD dwLanguageId,
|
||||
LPWSTR lpBuffer,
|
||||
DWORD nSize,
|
||||
va_list *Arguments
|
||||
);
|
||||
|
||||
#ifdef __linux__
|
||||
#define FormatMessage FormatMessageA
|
||||
#else
|
||||
#define FormatMessage FormatMessageW
|
||||
#endif
|
||||
|
||||
#define FORMAT_MESSAGE_ALLOCATE_BUFFER 0x00000100
|
||||
#define FORMAT_MESSAGE_IGNORE_INSERTS 0x00000200
|
||||
#define FORMAT_MESSAGE_FROM_STRING 0x00000400
|
||||
#define FORMAT_MESSAGE_FROM_HMODULE 0x00000800
|
||||
#define FORMAT_MESSAGE_FROM_SYSTEM 0x00001000
|
||||
#define FORMAT_MESSAGE_ARGUMENT_ARRAY 0x00002000
|
||||
#define FORMAT_MESSAGE_MAX_WIDTH_MASK 0x000000FF
|
||||
|
||||
#define ERROR_NO_UNICODE_TRANSLATION 1113L
|
||||
#define ERROR_SUCCESS 0L
|
||||
#define ERROR_INVALID_DATA 13L
|
||||
|
||||
typedef int errno_t;
|
||||
int mplat_snwprintf_s(WCHAR *str, size_t sizeOfBuffer, size_t count, const WCHAR *format, ...);
|
||||
int mplat_vsnwprintf( WCHAR * buffer, size_t count, const WCHAR * format, va_list args );
|
||||
int mplat_snprintf_s(char *str, size_t sizeOfBuffer, size_t count, const char *format, ...);
|
||||
int mplat_vsnprintf( char * buffer, size_t count, const char * format, va_list args );
|
||||
errno_t mplat_wctomb_s(int *pRetValue, char *mbchar, size_t sizeInBytes, WCHAR wchar);
|
||||
WCHAR * mplat_wcscpy(WCHAR * _Dst, const WCHAR * _Src);
|
||||
char * mplat_cscpy(char * _Dst, const char * _Src);
|
||||
BOOL IsDBCSLeadByteEx(__inn UINT CodePage, __inn BYTE TestChar);
|
||||
|
||||
typedef struct _SYSTEMTIME {
|
||||
WORD wYear;
|
||||
WORD wMonth;
|
||||
WORD wDayOfWeek;
|
||||
WORD wDay;
|
||||
WORD wHour;
|
||||
WORD wMinute;
|
||||
WORD wSecond;
|
||||
WORD wMilliseconds;
|
||||
} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;
|
||||
|
||||
typedef HINSTANCE HMODULE; /* HMODULEs can be used in place of HINSTANCEs */
|
||||
|
||||
//From sqlext.h
|
||||
#define SQL_GUID (-11)
|
||||
|
||||
size_t mplat_wcslen( const WCHAR * );
|
||||
|
||||
#endif // __linux_typedefs__
|
132
source/shared/winerror.h
Normal file
132
source/shared/winerror.h
Normal file
|
@ -0,0 +1,132 @@
|
|||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
// File: winerror.h
|
||||
//
|
||||
// Contents: Contains the minimal definitions to build on non-Windows platforms
|
||||
//
|
||||
// Microsoft Drivers 4.0 for PHP for SQL Server
|
||||
// Copyright(c) Microsoft Corporation
|
||||
// All rights reserved.
|
||||
// MIT License
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""),
|
||||
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef XPLAT_WINERROR_H
|
||||
#define XPLAT_WINERROR_H
|
||||
|
||||
#define NOERROR 0
|
||||
#define WAIT_TIMEOUT 258L // dderror
|
||||
#define S_OK ((HRESULT)0L)
|
||||
#define S_FALSE ((HRESULT)1L)
|
||||
#define E_NOTIMPL ((HRESULT) 0x80004001L)
|
||||
#define E_FAIL ((HRESULT) 0x80004005L)
|
||||
#define E_ABORT _HRESULT_TYPEDEF_(0x80004004L)
|
||||
#define ERROR_HANDLE_EOF 38L
|
||||
#define E_UNEXPECTED ((HRESULT) 0x8000FFFFL)
|
||||
#define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0)
|
||||
#define FAILED(hr) (((HRESULT)(hr)) < 0)
|
||||
#define ERROR_SUCCESS 0L
|
||||
#define ERROR_ACCESS_DENIED 5L
|
||||
#define ERROR_TIMEOUT 1460L
|
||||
#define E_POINTER _HRESULT_TYPEDEF_(0x80004003L)
|
||||
#define _HRESULT_TYPEDEF_(_sc) ((HRESULT)_sc)
|
||||
#define E_OUTOFMEMORY _HRESULT_TYPEDEF_(0x8007000EL)
|
||||
#define NO_ERROR 0L
|
||||
#define ERROR_CANCELLED 1223L
|
||||
#define E_INVALIDARG _HRESULT_TYPEDEF_(0x80070057L)
|
||||
#define DISP_E_TYPEMISMATCH _HRESULT_TYPEDEF_(0x80020005L)
|
||||
#define DISP_E_OVERFLOW _HRESULT_TYPEDEF_(0x8002000AL)
|
||||
#define ERROR_INSUFFICIENT_BUFFER 122L // dderror
|
||||
#define FACILITY_WIN32 7
|
||||
#define __HRESULT_FROM_WIN32(x) ((HRESULT)(x) <= 0 ? ((HRESULT)(x)) : ((HRESULT) (((x) & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000)))
|
||||
#define HRESULT_FROM_WIN32(x) __HRESULT_FROM_WIN32(x)
|
||||
#define SEVERITY_ERROR 1
|
||||
#define FACILITY_ITF 4
|
||||
#define MAKE_HRESULT(sev,fac,code) \
|
||||
((HRESULT) (((windowsULong_t)(sev)<<31) | ((windowsULong_t)(fac)<<16) | ((windowsULong_t)(code))) )
|
||||
#define ERROR_INVALID_DATA 13L
|
||||
#define ERROR_INVALID_PARAMETER 87L // dderror
|
||||
#define ERROR_POSSIBLE_DEADLOCK 1131L
|
||||
#define ERROR_INVALID_FLAGS 1004L
|
||||
#define ERROR_NO_UNICODE_TRANSLATION 1113L
|
||||
|
||||
#define ERROR_FILE_NOT_FOUND 2L
|
||||
#define ERROR_PATH_NOT_FOUND 3L
|
||||
#define ERROR_TOO_MANY_OPEN_FILES 4L
|
||||
#define E_NOINTERFACE _HRESULT_TYPEDEF_(0x80004002L)
|
||||
|
||||
#define ERROR_MOD_NOT_FOUND 126L
|
||||
#define ERROR_NO_MORE_FILES 18L
|
||||
#define ERROR_FILE_EXISTS 80L
|
||||
#define ERROR_ALREADY_EXISTS 183L
|
||||
#define ERROR_SHARING_VIOLATION 32L
|
||||
#define SCODE_CODE(sc) ((sc) & 0xFFFF)
|
||||
#define ERROR_READ_FAULT 30L
|
||||
#define ERROR_INTERNAL_ERROR 1359L
|
||||
//----------------------------------------------------------------------------
|
||||
// Error codes used by SNI
|
||||
//
|
||||
#define ERROR_NOT_ENOUGH_MEMORY 8L // dderror
|
||||
#define ERROR_IO_PENDING 997L
|
||||
#define WSA_IO_PENDING (ERROR_IO_PENDING)
|
||||
#define WSAHOST_NOT_FOUND 11001L
|
||||
#define WSATRY_AGAIN 11002L
|
||||
#define WSANO_RECOVERY 11003L
|
||||
#define WSANO_DATA 11004L
|
||||
#define WSATYPE_NOT_FOUND 10109L
|
||||
#define WSA_NOT_ENOUGH_MEMORY 8L
|
||||
#define WSAEINTR 10004L
|
||||
#define WSAEACCES 10013L
|
||||
#define WSAEFAULT 10014L
|
||||
#define WSAEINVAL 10022L
|
||||
#define WSAEMFILE 10024L
|
||||
#define WSAEWOULDBLOCK 10035L
|
||||
#define WSAEALREADY 10037L
|
||||
#define WSAENOTSOCK 10038L
|
||||
#define WSAEMSGSIZE 10040L
|
||||
#define WSAENOPROTOOPT 10042L
|
||||
#define WSAEPROTONOSUPPORT 10043L
|
||||
#define WSAESOCKTNOSUPPORT 10044L
|
||||
#define WSAEOPNOTSUPP 10045L
|
||||
#define WSAEAFNOSUPPORT 10047L
|
||||
#define WSAEADDRINUSE 10048L
|
||||
#define WSAEADDRNOTAVAIL 10049L
|
||||
#define WSAENETUNREACH 10051L
|
||||
#define WSAECONNRESET 10054L
|
||||
#define WSAENOBUFS 10055L
|
||||
#define WSAEISCONN 10056L
|
||||
#define WSAENOTCONN 10057L
|
||||
#define WSAETIMEDOUT 10060L
|
||||
#define WSAECONNREFUSED 10061L
|
||||
#define WSANOTINITIALISED 10093L
|
||||
#define ERROR_OUTOFMEMORY 14L
|
||||
#define ERROR_NOT_SUPPORTED 50L
|
||||
#define ERROR_BUFFER_OVERFLOW 111L
|
||||
#define ERROR_MAX_THRDS_REACHED 164L
|
||||
#define ERROR_INVALID_OPERATION 4317L
|
||||
#define ERROR_INVALID_STATE 5023L
|
||||
#define SEC_E_BAD_BINDINGS _HRESULT_TYPEDEF_(0x80090346L)
|
||||
#define ERROR_MORE_DATA 234L // dderror
|
||||
#define ERROR_ARITHMETIC_OVERFLOW 534L
|
||||
#define SEC_E_INCOMPLETE_MESSAGE _HRESULT_TYPEDEF_(0x80090318L)
|
||||
#define ERROR_OPERATION_ABORTED 995L
|
||||
#define ERROR_CONNECTION_REFUSED 1225L
|
||||
#define SEC_E_OK ((HRESULT)0x00000000L)
|
||||
#define SEC_E_UNSUPPORTED_FUNCTION _HRESULT_TYPEDEF_(0x80090302L)
|
||||
#define SEC_E_TARGET_UNKNOWN _HRESULT_TYPEDEF_(0x80090303L)
|
||||
#define SEC_E_OUT_OF_SEQUENCE _HRESULT_TYPEDEF_(0x80090310L)
|
||||
#define SEC_E_INVALID_TOKEN _HRESULT_TYPEDEF_(0x80090308L)
|
||||
#define SEC_I_CONTINUE_NEEDED _HRESULT_TYPEDEF_(0x00090312L)
|
||||
#define ERROR_INVALID_FUNCTION 1L // dderror
|
||||
#define TRUST_E_TIME_STAMP _HRESULT_TYPEDEF_(0x80096005L)
|
||||
#define CRYPT_E_NOT_FOUND _HRESULT_TYPEDEF_(0x80092004L)
|
||||
#define WAIT_TIMEOUT 258L // dderror
|
||||
|
||||
|
||||
#endif // XPLAT_WINERROR_H
|
144
source/shared/winnls.h
Normal file
144
source/shared/winnls.h
Normal file
|
@ -0,0 +1,144 @@
|
|||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
// File: winnls.h
|
||||
//
|
||||
// Contents: Contains the minimal definitions to build on non-Windows platforms
|
||||
//
|
||||
// Microsoft Drivers 4.0 for PHP for SQL Server
|
||||
// Copyright(c) Microsoft Corporation
|
||||
// All rights reserved.
|
||||
// MIT License
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""),
|
||||
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef XPLAT_WINNLS_H
|
||||
#define XPLAT_WINNLS_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "typedefs_for_linux.h"
|
||||
|
||||
struct threadlocaleinfostruct;
|
||||
struct threadmbcinfostruct;
|
||||
typedef struct threadlocaleinfostruct * pthreadlocinfo;
|
||||
typedef struct threadmbcinfostruct * pthreadmbcinfo;
|
||||
|
||||
typedef struct localeinfo_struct
|
||||
{
|
||||
pthreadlocinfo locinfo;
|
||||
pthreadmbcinfo mbcinfo;
|
||||
} _locale_tstruct, *_locale_t;
|
||||
|
||||
#define LOCALE_SDECIMAL 0x0000000E // decimal separator
|
||||
#define LOCALE_SCURRENCY 0x00000014 // local monetary symbol
|
||||
#define LOCALE_SMONDECIMALSEP 0x00000016 // monetary decimal separator
|
||||
#define LOCALE_SMONTHOUSANDSEP 0x00000017 // monetary thousand separator
|
||||
#define LOCALE_SMONGROUPING 0x00000018 // monetary grouping
|
||||
#define LOCALE_ILDATE 0x00000022 // long date format ordering (derived from LOCALE_SLONGDATE, use that instead)
|
||||
#define LOCALE_ITIME 0x00000023 // time format specifier (derived from LOCALE_STIMEFORMAT, use that instead)
|
||||
#define LOCALE_SABBREVMONTHNAME1 0x00000044 // abbreviated name for January
|
||||
|
||||
#define LOCALE_IDEFAULTLANGUAGE 0x00000009 // default language id
|
||||
#define LOCALE_IDEFAULTCOUNTRY 0x0000000A // default country/region code, deprecated
|
||||
#define LOCALE_IDEFAULTCODEPAGE 0x0000000B // default oem code page
|
||||
#define LOCALE_IDEFAULTANSICODEPAGE 0x00001004 // default ansi code page
|
||||
#define LOCALE_IDEFAULTMACCODEPAGE 0x00001011 // default mac code page
|
||||
|
||||
#define LOCALE_STIMEFORMAT 0x00001003 // time format string, eg "HH:mm:ss"
|
||||
|
||||
typedef DWORD LCTYPE;
|
||||
|
||||
#define NORM_IGNORECASE 0x00000001 // ignore case
|
||||
#define NORM_IGNORENONSPACE 0x00000002 // ignore nonspacing chars
|
||||
#define NORM_IGNORESYMBOLS 0x00000004 // ignore symbols
|
||||
|
||||
#define LINGUISTIC_IGNORECASE 0x00000010 // linguistically appropriate 'ignore case'
|
||||
#define LINGUISTIC_IGNOREDIACRITIC 0x00000020 // linguistically appropriate 'ignore nonspace'
|
||||
|
||||
#define NORM_IGNOREKANATYPE 0x00010000 // ignore kanatype
|
||||
#define NORM_IGNOREWIDTH 0x00020000 // ignore width
|
||||
#define NORM_LINGUISTIC_CASING 0x08000000 // use linguistic rules for casing
|
||||
|
||||
|
||||
#define NORM_IGNORECASE 0x00000001 // ignore case
|
||||
|
||||
#define MB_PRECOMPOSED 0x00000001 // use precomposed chars
|
||||
#define MB_COMPOSITE 0x00000002 // use composite chars
|
||||
#define MB_USEGLYPHCHARS 0x00000004 // use glyph chars, not ctrl chars
|
||||
#define MB_ERR_INVALID_CHARS 0x00000008 // error for invalid chars
|
||||
|
||||
#define WC_COMPOSITECHECK 0x00000200 // convert composite to precomposed
|
||||
#define WC_DISCARDNS 0x00000010 // discard non-spacing chars
|
||||
#define WC_SEPCHARS 0x00000020 // generate separate chars
|
||||
#define WC_DEFAULTCHAR 0x00000040 // replace w/ default char
|
||||
|
||||
|
||||
typedef WORD LANGID;
|
||||
|
||||
|
||||
|
||||
|
||||
#define NLS_VALID_LOCALE_MASK 0x000fffff
|
||||
|
||||
#define MAKELANGID(p, s) ((((WORD )(s)) << 10) | (WORD )(p))
|
||||
#define MAKELCID(lgid, srtid) ((DWORD)((((DWORD)((WORD )(srtid))) << 16) | \
|
||||
((DWORD)((WORD )(lgid)))))
|
||||
#define LANG_NEUTRAL 0x00
|
||||
#define SUBLANG_DEFAULT 0x01 // user default
|
||||
#define SUBLANG_SYS_DEFAULT 0x02 // system default
|
||||
#define SORT_DEFAULT 0x0 // sorting default
|
||||
#define LANG_USER_DEFAULT (MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT))
|
||||
#define LOCALE_USER_DEFAULT (MAKELCID(LANG_USER_DEFAULT, SORT_DEFAULT))
|
||||
#define SUBLANG_ENGLISH_US 0x01 // English (USA)
|
||||
#define LANG_ENGLISH 0x09
|
||||
#define LOCALE_ENGLISH_US MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)
|
||||
#define LANG_SYSTEM_DEFAULT (MAKELANGID(LANG_NEUTRAL, SUBLANG_SYS_DEFAULT))
|
||||
#define LOCALE_SYSTEM_DEFAULT (MAKELCID(LANG_SYSTEM_DEFAULT, SORT_DEFAULT))
|
||||
|
||||
BOOL
|
||||
WINAPI
|
||||
IsDBCSLeadByte(
|
||||
__inn BYTE TestChar);
|
||||
|
||||
|
||||
#ifdef MPLAT_UNIX
|
||||
// XPLAT_ODBC_TODO: VSTS 718708 Localization
|
||||
// Find way to remove this
|
||||
LCID GetUserDefaultLCID();
|
||||
#endif
|
||||
|
||||
|
||||
BOOL IsValidCodePage(UINT CodePage);
|
||||
|
||||
#define HIGH_SURROGATE_START 0xd800
|
||||
#define HIGH_SURROGATE_END 0xdbff
|
||||
#define LOW_SURROGATE_START 0xdc00
|
||||
#define LOW_SURROGATE_END 0xdfff
|
||||
#define IS_HIGH_SURROGATE(wch) (((wch) >= HIGH_SURROGATE_START) && ((wch) <= HIGH_SURROGATE_END))
|
||||
#define IS_LOW_SURROGATE(wch) (((wch) >= LOW_SURROGATE_START) && ((wch) <= LOW_SURROGATE_END))
|
||||
|
||||
int
|
||||
GetLocaleInfoA(
|
||||
__inn LCID Locale,
|
||||
__inn LCTYPE LCType,
|
||||
__out_ecount_opt(cchData) LPSTR lpLCData,
|
||||
__inn int cchData);
|
||||
int
|
||||
GetLocaleInfoW(
|
||||
__inn LCID Locale,
|
||||
__inn LCTYPE LCType,
|
||||
__out_ecount_opt(cchData) LPWSTR lpLCData,
|
||||
__inn int cchData);
|
||||
#ifdef UNICODE
|
||||
#define GetLocaleInfo GetLocaleInfoW
|
||||
#else
|
||||
#define GetLocaleInfo GetLocaleInfoA
|
||||
#endif // !UNICODE
|
||||
|
||||
|
||||
#endif // XPLAT_WINNLS_H
|
509
source/shared/xplat.h
Normal file
509
source/shared/xplat.h
Normal file
|
@ -0,0 +1,509 @@
|
|||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
// File: xplat.h
|
||||
//
|
||||
// Contents: include for definition of Windows types for non-Windows platforms
|
||||
//
|
||||
// Microsoft Drivers 4.0 for PHP for SQL Server
|
||||
// Copyright(c) Microsoft Corporation
|
||||
// All rights reserved.
|
||||
// MIT License
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""),
|
||||
// to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions :
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
// THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//---------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef __XPLAT_H__
|
||||
#define __XPLAT_H__
|
||||
|
||||
#ifndef _WCHART_DEFINED
|
||||
#define _WCHART_DEFINED
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <errno.h>
|
||||
#include <sql.h>
|
||||
#include <sqlext.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdlib>
|
||||
#include <limits.h>
|
||||
#include <cstdio>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "msodbcsql.h"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// Turned on all warnings in WwoWH projects
|
||||
// These warnings need to be disabled to be build warning free
|
||||
// Note that some of these should be enabled and the code fixed
|
||||
#pragma warning( disable : 4668 ) // preprocessor macro not defined
|
||||
#pragma warning( disable : 4820 ) // padding after data member
|
||||
#pragma warning( disable : 4201 ) // nonstandard: nameless union
|
||||
#pragma warning( disable : 4100 ) // unreferenced formal parameter
|
||||
#pragma warning( disable : 4514 ) // unreferenced inline function
|
||||
#pragma warning( disable : 4505 ) // unreferenced inline function
|
||||
#pragma warning( disable : 4710 ) // function not inlined
|
||||
#pragma warning( disable : 4191 ) // unsafe conversion
|
||||
#pragma warning( disable : 4365 ) // signed/unsigned argument conversion
|
||||
#pragma warning( disable : 4245 ) // signed/unsigned assignment conversion
|
||||
#pragma warning( disable : 4389 ) // signed/unsigned ==
|
||||
#pragma warning( disable : 4987 ) // nonstandard: throw(...)
|
||||
#pragma warning( disable : 4510 ) // default ctor could not be generated
|
||||
#pragma warning( disable : 4512 ) // operator= could not be generated
|
||||
#pragma warning( disable : 4626 ) // operator= could not be generated
|
||||
#pragma warning( disable : 4625 ) // copy ctor could not be generated or accessed
|
||||
#pragma warning( disable : 4189 ) // unused initialized local variable
|
||||
#pragma warning( disable : 4127 ) // constant conditional test
|
||||
#pragma warning( disable : 4061 ) // Unused enum values in switch
|
||||
#pragma warning( disable : 4062 ) // Unused enum values in switch
|
||||
#pragma warning( disable : 4706 ) // assignment within conditional
|
||||
#pragma warning( disable : 4610 ) // can never be instantiated
|
||||
#pragma warning( disable : 4244 ) // possible loss of data in conversion
|
||||
#pragma warning( disable : 4701 ) // possible use of uninitialized variable
|
||||
#pragma warning( disable : 4918 ) // invalid pragma optimization parameter
|
||||
#pragma warning( disable : 4702 ) // unreachable code
|
||||
#pragma warning( disable : 4265 ) // class with virtual fxns has non-virtual dtor
|
||||
#pragma warning( disable : 4238 ) // nonstandard: class rvalue used as lvalue
|
||||
#pragma warning( disable : 4310 ) // cast truncates constant value
|
||||
#pragma warning( disable : 4946 ) // reinterpret_cast between related classes
|
||||
#pragma warning( disable : 4264 ) // no matching override, hides base fxn
|
||||
#pragma warning( disable : 4242 ) // conversion: possible loss of data
|
||||
#pragma warning( disable : 4820 ) // added padding bytes
|
||||
#endif
|
||||
|
||||
// Compiler specific items
|
||||
#define _cdecl
|
||||
#define __cdecl
|
||||
#define __fastcall
|
||||
#define _inline inline
|
||||
#define __inline inline
|
||||
#define __forceinline inline
|
||||
#define __stdcall
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
#define __declspec__noinline __attribute__((noinline))
|
||||
#define __declspec__selectany
|
||||
#define __declspec(a) __declspec__##a
|
||||
#define __FUNCTION__ __func__
|
||||
|
||||
#define __int8 char
|
||||
#define __int32 int
|
||||
|
||||
// __int64
|
||||
// This type must be defined in a way that allows "unsigned __int64" as a valid type declaration.
|
||||
// That precludes using the obvious "int64_t" from stdint.h, because "unsigned int64_t" is not allowed
|
||||
// (one should use "uint64_t" for unsigned 64-bit integers). As a result, we must use compiler-specific
|
||||
// types such as GCC's "long long" instead
|
||||
#if defined(_LP64)
|
||||
#define __int64 long
|
||||
#elif defined(__GNUC__)
|
||||
#define __int64 long long
|
||||
#else
|
||||
#error "Compiler-specific definition required for __int64 in 32-bit builds"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// GCC-specific definitions
|
||||
#if defined(__GNUC__)
|
||||
#define MPLAT_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
||||
#endif // defined(__GNUC__)
|
||||
|
||||
// For compilers that don't support cross-module inlining (part of whole-program/link-time
|
||||
// optimization), such as the current MPLAT compilers (GCC 4.1.2 for RHEL5 and GCC 4.4 for RHEL6),
|
||||
// we must force the generation of out-of-line definitions for functions that otherwise
|
||||
// are only defined inline when those functions are called from other translation units.
|
||||
// There are a handful of instances of these in SNI code as well as ODBC code.
|
||||
//
|
||||
// To force the compiler to emit an out-of-line definition for a function, just add an otherwise
|
||||
// unused global (external linkage) non-const pointer pointing to the function:
|
||||
//
|
||||
// #if defined(MPLAT_NO_LTO)
|
||||
// void (* g_pfnMyFunctionUnused)(MyFunctionArguments *) = MyFunction;
|
||||
// #endif // defined(MPLAT_NO_LTO)
|
||||
//
|
||||
// This works because, absent whole-program optimization, the compiler cannot determine that the
|
||||
// pointers are never called through, and the out-of-line definition cannot be optimized out,
|
||||
// giving calling translation units something to link to.
|
||||
//
|
||||
// GCC adds LTO as of version 4.5
|
||||
//JL - TODO: this version check doesn't work in Ubuntu
|
||||
//#if defined(__GNUC__) && MPLAT_GCC_VERSION < 40500
|
||||
#define MPLAT_NO_LTO
|
||||
//#endif
|
||||
|
||||
#ifdef MPLAT_UNIX
|
||||
|
||||
// Needed to use the standard library min and max
|
||||
#include <algorithm>
|
||||
using std::min;
|
||||
using std::max;
|
||||
|
||||
#elif MPLAT_WWOWH
|
||||
|
||||
#ifndef max
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef min
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#endif // MPLAT_WWOWH
|
||||
|
||||
// Deal with differences between Windows and *nix interpretations of the C/C++ 'long' data type.
|
||||
//
|
||||
// On 64-bit Windows, 'long' is 32 bits. On 64-bit Linux, 'long' is 64 bits. Assuming the Windows code
|
||||
// depends on it being 32 bits, use a definition that provides a guaranteed 32-bit type definition.
|
||||
//
|
||||
// Similarly, because 'long long' (and its cousin 'unsigned long long') are not portable across
|
||||
// Linux/UNIX platforms and compilers, provide common definitions for 64-bit types as well.
|
||||
//
|
||||
// These types are used in this file primarily to define common Windows types (DWORD, LONG, etc.)
|
||||
// Cross-platform code should use either the Windows types or appropriate types from <stdint.h>.
|
||||
#if defined(_MSC_VER) // WwoWH
|
||||
typedef long windowsLong_t;
|
||||
typedef unsigned long windowsULong_t;
|
||||
typedef __int64 windowsLongLong_t;
|
||||
typedef unsigned __int64 windowsULongLong_t;
|
||||
#else // *nix (!WwoWH)
|
||||
#include <stdint.h> // Use standard bit-specific types (signed/unsigned integrated)
|
||||
typedef int32_t windowsLong_t;
|
||||
typedef uint32_t windowsULong_t;
|
||||
typedef int64_t windowsLongLong_t;
|
||||
typedef uint64_t windowsULongLong_t;
|
||||
#endif
|
||||
typedef windowsLong_t LONG, *PLONG, *LPLONG;
|
||||
typedef windowsLongLong_t LONGLONG;
|
||||
typedef windowsULongLong_t ULONGLONG;
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <intsafe.h>
|
||||
|
||||
// Exclude these headers in Windows machines (just for building on Windows w/o Windows headers)
|
||||
#define SPECSTRINGS_H // specstrings.h
|
||||
#define ASOSHOST_DEFINED // asoshost.h
|
||||
#define _WINDOWS_ // windows.h
|
||||
#define _INC_WINDOWSX // windowsx.h
|
||||
#define _WINBASE_ // winbase.h
|
||||
#define _WINNLS_ // winnls.h
|
||||
#define _WINERROR_ // winerror.h
|
||||
#define NETCONS_INCLUDED // lmcons.h
|
||||
#define __WINCRYPT_H__ // wincrypt.h
|
||||
#define _INC_TCHAR // tchar.h
|
||||
#define _INC_FCNTL // fcntl.h
|
||||
#define _INC_SHARE // share.h
|
||||
#define _INC_IO // io.h
|
||||
#define _INC_TYPES // sys/types.h
|
||||
#define _INC_STAT // sys/stat.h
|
||||
#define _INC_TIMEB // sys/timeb.h
|
||||
#define __unknwn_h__ // unknwn.h
|
||||
#define __objidl_h__ // objidl.h
|
||||
#define _OBJBASE_H_ // objbase.h
|
||||
#define __RPC_H__ // rpc.h
|
||||
#define __RPCNDR_H__ // rpcndr.h
|
||||
#define _NP_HPP_ // np.hpp (no named pipes)
|
||||
#define _SM_HPP_ // sm.hpp (no shared memory)
|
||||
#define VIA_HEADER // via.hpp (no via)
|
||||
#define _WINUSER_ // winuser.h
|
||||
|
||||
#define interface struct
|
||||
|
||||
// What we need from dlgattr.h
|
||||
#define OPTIONON L"Yes"
|
||||
#define OPTIONOFF L"No"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Definitions for UnixODBC Driver Manager
|
||||
|
||||
// Define this to enable driver code to conditionalize around UnixODBC Driver
|
||||
// Manager "quirks"...
|
||||
#ifndef MPLAT_WWOWH
|
||||
#define UNIXODBC
|
||||
#endif
|
||||
|
||||
/* can be defined in php sources */
|
||||
#ifdef ODBCVER
|
||||
#undef ODBCVER
|
||||
#endif
|
||||
// Build the mplat driver as an ODBC 3.8 driver, so that all of the
|
||||
// source code shared with Windows SNAC (which is ODBC 3.8) compiles.
|
||||
#define ODBCVER 0x0380
|
||||
|
||||
// Define this to indicate that we provide our own definitions for Windows types
|
||||
#define ALLREADY_HAVE_WINDOWS_TYPE
|
||||
|
||||
// Definitions not otherwise provided in sqltypes.h, given that we define our own Windows types
|
||||
#define SQL_API
|
||||
typedef signed char SCHAR;
|
||||
typedef SCHAR SQLSCHAR;
|
||||
typedef int SDWORD;
|
||||
typedef unsigned int UDWORD;
|
||||
typedef signed short int SWORD;
|
||||
typedef signed short SSHORT;
|
||||
typedef double SDOUBLE;
|
||||
typedef double LDOUBLE;
|
||||
typedef float SFLOAT;
|
||||
typedef void* PTR;
|
||||
typedef signed short RETCODE;
|
||||
typedef void* SQLHWND;
|
||||
|
||||
// Definitions missing from sql.h
|
||||
#define SQL_PARAM_DATA_AVAILABLE 101
|
||||
#define SQL_APD_TYPE (-100)
|
||||
|
||||
// Bid control bit, only for xplat
|
||||
// It traces everything we current enabled for bid.
|
||||
// The correlated tracing feature is not enabled.
|
||||
#define DEFAULT_BID_CORT_BIT 0xFFFFBFFFF
|
||||
|
||||
// End definitions for UnixODBC SQL headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#define UNREFERENCED_PARAMETER(arg)
|
||||
|
||||
// From share.h
|
||||
#define _SH_DENYNO 0x40 /* deny none mode */
|
||||
|
||||
|
||||
// WinNT.h
|
||||
#define CONST const
|
||||
#define VOID void
|
||||
#define DLL_PROCESS_ATTACH 1
|
||||
#define DLL_THREAD_ATTACH 2
|
||||
#define DLL_THREAD_DETACH 3
|
||||
#define DLL_PROCESS_DETACH 0
|
||||
#define VER_GREATER_EQUAL 3
|
||||
#define VER_MINORVERSION 0x0000001
|
||||
#define VER_MAJORVERSION 0x0000002
|
||||
#define VER_SERVICEPACKMINOR 0x0000010
|
||||
#define VER_SERVICEPACKMAJOR 0x0000020
|
||||
#define VER_SET_CONDITION(_m_,_t_,_c_) \
|
||||
((_m_)=VerSetConditionMask((_m_),(_t_),(_c_)))
|
||||
|
||||
|
||||
// Predeclared types from windef needed for remaining WinNT types
|
||||
// to break circular dependency between WinNT.h and windef.h types.
|
||||
//typedef ULONG DWORD;
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef UCHAR *PUCHAR;
|
||||
|
||||
typedef DWORD LCID;
|
||||
typedef LONG HRESULT;
|
||||
typedef char CHAR;
|
||||
typedef CHAR *LPSTR, *PSTR;
|
||||
typedef CHAR *PCHAR, *LPCH, *PCH;
|
||||
typedef CONST CHAR *LPCCH, *PCCH;
|
||||
#ifdef SQL_WCHART_CONVERT
|
||||
typedef wchar_t WCHAR;
|
||||
#else
|
||||
typedef unsigned short WCHAR;
|
||||
#endif
|
||||
typedef WCHAR *LPWSTR;
|
||||
typedef WCHAR *PWSTR;
|
||||
typedef CONST WCHAR *LPCWSTR;
|
||||
typedef CONST WCHAR *PCWSTR;
|
||||
typedef CONST CHAR *LPCSTR, *PCSTR;
|
||||
typedef void *PVOID;
|
||||
typedef PVOID HANDLE;
|
||||
typedef BYTE BOOLEAN;
|
||||
typedef BOOLEAN *PBOOLEAN;
|
||||
typedef HANDLE *PHANDLE;
|
||||
typedef WCHAR *PWCHAR, *LPWCH, *PWCH;
|
||||
typedef CONST WCHAR *LPCWCH, *PCWCH;
|
||||
typedef int HFILE;
|
||||
|
||||
typedef short SHORT;
|
||||
typedef CONST CHAR *LPCCH, *PCCH;
|
||||
|
||||
typedef unsigned short WORD;
|
||||
|
||||
#define RTL_NUMBER_OF_V1(A) (sizeof(A)/sizeof((A)[0]))
|
||||
#define ARRAYSIZE(A) RTL_NUMBER_OF_V1(A)
|
||||
#define STATUS_STACK_OVERFLOW ((DWORD )0xC00000FDL)
|
||||
typedef union _LARGE_INTEGER {
|
||||
struct {
|
||||
DWORD LowPart;
|
||||
LONG HighPart;
|
||||
};
|
||||
struct {
|
||||
DWORD LowPart;
|
||||
LONG HighPart;
|
||||
} u;
|
||||
LONGLONG QuadPart;
|
||||
} LARGE_INTEGER;
|
||||
typedef LARGE_INTEGER *PLARGE_INTEGER;
|
||||
typedef void * RPC_IF_HANDLE;
|
||||
|
||||
typedef WORD LANGID;
|
||||
|
||||
typedef enum _HEAP_INFORMATION_CLASS {
|
||||
|
||||
HeapCompatibilityInformation,
|
||||
HeapEnableTerminationOnCorruption
|
||||
|
||||
|
||||
} HEAP_INFORMATION_CLASS;
|
||||
|
||||
|
||||
#define REG_SZ ( 1 ) // Unicode nul terminated string
|
||||
#define REG_DWORD ( 4 ) // 32-bit number
|
||||
|
||||
#define RTL_NUMBER_OF_V1(A) (sizeof(A)/sizeof((A)[0]))
|
||||
#define RTL_NUMBER_OF(A) RTL_NUMBER_OF_V1(A)
|
||||
|
||||
|
||||
// windef.h
|
||||
typedef VOID *LPVOID;
|
||||
typedef CONST void *LPCVOID;
|
||||
typedef int INT;
|
||||
typedef int *LPINT;
|
||||
typedef unsigned int UINT;
|
||||
typedef ULONGLONG UINT64;
|
||||
typedef unsigned int *PUINT;
|
||||
typedef unsigned char BYTE;
|
||||
typedef BYTE *PBYTE;
|
||||
typedef BYTE *LPBYTE;
|
||||
typedef const BYTE *LPCBYTE;
|
||||
#define _LPCBYTE_DEFINED
|
||||
//typedef int BOOL;
|
||||
typedef BOOL * LPBOOL;
|
||||
typedef unsigned short WORD;
|
||||
typedef WORD * LPWORD;
|
||||
typedef WORD UWORD;
|
||||
typedef DWORD * LPDWORD;
|
||||
typedef DWORD * PDWORD;
|
||||
typedef unsigned short USHORT;
|
||||
#define CDECL // TODO _cdecl and cdecl not portable?
|
||||
#define WINAPI // TODO __stdcall not portable?
|
||||
#define MAX_PATH 260
|
||||
typedef HANDLE HINSTANCE;
|
||||
typedef HANDLE HGLOBAL;
|
||||
typedef ULONGLONG DWORDLONG;
|
||||
typedef DWORDLONG *PDWORDLONG;
|
||||
typedef float FLOAT;
|
||||
|
||||
typedef struct _FILETIME {
|
||||
DWORD dwLowDateTime;
|
||||
DWORD dwHighDateTime;
|
||||
} FILETIME, *PFILETIME, *LPFILETIME;
|
||||
typedef double DOUBLE;
|
||||
#define MAKELONG(a, b) ((LONG)(((WORD)(((DWORD_PTR)(a)) & 0xffff)) | ((DWORD)((WORD)(((DWORD_PTR)(b)) & 0xffff))) << 16))
|
||||
|
||||
// INT_PTR - http://msdn.microsoft.com/en-us/library/aa384154(VS.85).aspx
|
||||
#ifdef _WIN64
|
||||
typedef __int64 INT_PTR;
|
||||
#else
|
||||
typedef int INT_PTR;
|
||||
#endif
|
||||
|
||||
typedef INT_PTR (*FARPROC)();
|
||||
typedef INT_PTR (*NEARPROC)();
|
||||
typedef INT_PTR (*PROC)();
|
||||
|
||||
|
||||
DWORD GetFileSize(
|
||||
__inn HANDLE hFile,
|
||||
__out_opt LPDWORD lpFileSizeHigh
|
||||
);
|
||||
|
||||
typedef union _ULARGE_INTEGER {
|
||||
struct {
|
||||
DWORD LowPart;
|
||||
DWORD HighPart;
|
||||
};
|
||||
struct {
|
||||
DWORD LowPart;
|
||||
DWORD HighPart;
|
||||
} u;
|
||||
ULONGLONG QuadPart;
|
||||
} ULARGE_INTEGER;
|
||||
|
||||
typedef ULARGE_INTEGER *PULARGE_INTEGER;
|
||||
|
||||
#ifndef IN
|
||||
#define IN
|
||||
#endif
|
||||
|
||||
#ifndef OUT
|
||||
#define OUT
|
||||
#endif
|
||||
|
||||
#ifndef OPTIONAL
|
||||
#define OPTIONAL
|
||||
#endif
|
||||
|
||||
|
||||
ULONGLONG
|
||||
VerSetConditionMask(
|
||||
IN ULONGLONG ConditionMask,
|
||||
IN DWORD TypeMask,
|
||||
IN BYTE Condition
|
||||
);
|
||||
|
||||
|
||||
|
||||
//#include <basetsd.h>
|
||||
|
||||
//// ntdef.h
|
||||
#define __unaligned
|
||||
#ifndef UNALIGNED
|
||||
#define UNALIGNED
|
||||
#endif
|
||||
//typedef __nullterminated WCHAR UNALIGNED *LPUWSTR;
|
||||
|
||||
//// crtdefs.h
|
||||
//#if !defined(_TRUNCATE)
|
||||
//#define _TRUNCATE ((size_t)-1)
|
||||
//#endif
|
||||
|
||||
//// ??
|
||||
//typedef ULONG_PTR DWORD_PTR;
|
||||
#define FALSE ((BOOL)0)
|
||||
#define TRUE ((BOOL)1)
|
||||
|
||||
|
||||
//// asoshost.h (excluded above)
|
||||
//struct ISOSHost_MemObj;
|
||||
//struct ISOSHost;
|
||||
//extern ISOSHost_MemObj *g_pMO;
|
||||
//extern ISOSHost *g_pISOSHost;
|
||||
//inline HRESULT CreateSQLSOSHostInterface() { return 0; }
|
||||
//inline HRESULT CreateGlobalSOSHostInterface() { return 0; }
|
||||
|
||||
//// These are temporary solution versions of the real files that contain the minimal declarations
|
||||
//// needed to compile for non-Windows platforms. See the special include path for the
|
||||
//// location of these files.
|
||||
//#include <guiddef.h>
|
||||
//#include <objbase.h>
|
||||
//#include <winbase.h>
|
||||
//#include <winnls.h>
|
||||
#include <winerror.h>
|
||||
//#include <wtypes.h>
|
||||
//#include <wctype.h>
|
||||
//#include <winuser.h>
|
||||
//#include <stdio.h>
|
||||
//#include <tchar.h>
|
||||
//#include <winuser.h>
|
||||
//#include <wincon.h>
|
||||
|
||||
//#define LMEM_FIXED 0
|
||||
typedef void * HLOCAL;
|
||||
HLOCAL LocalAlloc(UINT uFlags, SIZE_T uBytes);
|
||||
//HLOCAL LocalReAlloc(HLOCAL hMem, SIZE_T uBytes, UINT uFlags);
|
||||
HLOCAL LocalFree(HLOCAL hMem);
|
||||
|
||||
// End of xplat.h
|
||||
#endif //__XPLAT_H__
|
Loading…
Reference in a new issue