Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

600 lines
17 KiB

/*
* Adobe Universal Font Library
*
* Copyright (c) 1996 Adobe Systems Inc.
* All Rights Reserved
*
* UFLSProc.h
*
* This file contents standard C procedure implementation.
*
*
* $Header:
*/
#include "UFLCnfig.h"
#include "UFLTypes.h"
#include "UFLStd.h"
#ifdef UNIX
#include <sys/varargs.h>
#include <assert.h>
#else
#ifdef MAC_ENV
#include <assert.h>
#endif
#include <stdarg.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
int strcmpW( unsigned short *str1, unsigned short *str2 )
{
int retVal = 0;
if( str1 == NULL || str2 == NULL )
retVal = (int)(str1 - str2);
else
{
while( *str1 != 0 && *str2 != 0 && *str1 == *str2 )
{
str1++;
str2++;
}
retVal = *str1 - *str2;
}
return retVal;
}
/* Digit characters used for converting numbers to ASCII */
const char DigitString[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
#define HexDigit(n) DigitString[(n) & 0x0F]
int
UFLvsprintf(
char *buf,
size_t cchDest,
const char *fmtstr,
va_list arglist
)
/*++
Routine Description:
Takes a pointer to an argument list, then formats and writes
the given data to the memory pointed to by buffer.
Arguments:
buf Storage location for output
cchDest size (in chars) of the destination buffer
fmtstr Format specification
arglist Pointer to list of arguments
Return Value:
Return the number of characters written, not including
the terminating null character, or a negative value if
an output error occurs.
[Note:]
This is NOT a full implementation of "vsprintf" as found
in the C runtime library. Specifically, the only form of
format specification allowed is %type, where "type" can
be one of the following characters:
d int signed decimal integer
l long signed decimal integer
ld long signed decimal integer
lu unsigned long unsigned decimal integer
u unsigned int unsigned decimal integer
s char* character string
c char character
x,X unsigned long hex number (emits at least two digits, uppercase)
b UFLBool boolean (true or false)
f long 24.8 fixed-pointed number
--*/
{
char *ptr, *ptrEnd;
char achTmp[36]; // for _ltoa/_ultoa use
if (buf == 0 || cchDest == 0 || fmtstr == 0)
return 0;
ptr = buf;
ptrEnd = ptr + cchDest;
while (*fmtstr != '\0')
{
if (*fmtstr != '%')
{
/* Normal character */
*ptr++ = *fmtstr++;
}
else
{
/* Format specification */
switch (*++fmtstr) {
case 'd': /* signed decimal integer */
_ltoa((long) va_arg(arglist, int), achTmp, 10);
KStringCchCopyA(ptr, ptrEnd - ptr, achTmp);
ptr += UFLstrlen(ptr);
break;
case 'l': /* signed decimal integer */
if (*++fmtstr != '\0')
{
if (*fmtstr == 'u')
{
_ultoa(va_arg(arglist, unsigned long), achTmp, 10);
KStringCchCopyA(ptr, ptrEnd - ptr, achTmp);
ptr += UFLstrlen(ptr);
break;
}
else if (*fmtstr == 'd')
{
_ltoa((long) va_arg(arglist, long), achTmp, 10);
KStringCchCopyA(ptr, ptrEnd - ptr, achTmp);
ptr += UFLstrlen(ptr);
break;
}
}
/* Default to unsigned long */
_ltoa(va_arg(arglist, long), achTmp, 10);
KStringCchCopyA(ptr, ptrEnd - ptr, achTmp);
ptr += UFLstrlen(ptr);
fmtstr--;
break;
case 'u': /* unsigned decimal integer */
_ultoa((unsigned long)va_arg(arglist, unsigned int), achTmp, 10);
KStringCchCopyA(ptr, ptrEnd - ptr, achTmp);
ptr += UFLstrlen(ptr);
break;
case 's': /* character string */
{
char *s = va_arg(arglist, char *);
while (*s)
{
*ptr++ = *s++;
if (ptr >= ptrEnd)
{
break;
}
}
}
break;
case 'c': /* character */
*ptr++ = va_arg(arglist, char);
break;
case 'x':
case 'X': /* hexdecimal number */
{
unsigned long ul = va_arg(arglist, unsigned long);
int ndigits = 8;
while (ndigits > 2 && ((ul >> (ndigits-1)*4) & 0xf) == 0)
ndigits--;
while (ndigits-- > 0)
{
*ptr++ = HexDigit(ul >> ndigits*4);
if (ptr >= ptrEnd)
{
break;
}
}
}
break;
case 'b': /* boolean */
KStringCchCopyA(ptr, ptrEnd - ptr, (va_arg(arglist, UFLBool)) ? "true" : "false");
ptr += UFLstrlen(ptr);
break;
case 'f': /* 24.8 fixed-pointed number */
{
long l = va_arg(arglist, long);
unsigned long ul, scale;
/* sign character */
if (l < 0)
{
*ptr++ = '-';
if (ptr >= ptrEnd)
{
break;
}
ul = -l;
} else
ul = l;
// integer portion
_ultoa(ul >> 8, achTmp, 10);
KStringCchCopyA(ptr, ptrEnd - ptr, achTmp);
ptr += UFLstrlen(ptr);
if (ptr >= ptrEnd)
{
break;
}
// fraction
ul &= 0xff;
if (ul != 0)
{
// We output a maximum of 3 digits after the
// decimal point, but we'll compute to the 5th
// decimal point and round it to 3rd.
ul = ((ul*100000 >> 8) + 50) / 100;
scale = 100;
*ptr++ = '.';
do {
if (ptr >= ptrEnd)
{
break;
}
*ptr++ = (char) (ul/scale + '0');
ul %= scale;
scale /= 10;
} while (scale != 0 && ul != 0) ;
}
}
break;
default:
if (*fmtstr != '\0')
*ptr++ = *fmtstr;
else
{
fmtstr--;
}
break;
}
/* Skip the type characterr */
fmtstr++;
}
//
// If we are beyond the end of dest buffer,
// we need to go back so the dest buffer will
// be null terminated.
//
if (ptr >= ptrEnd)
{
ptr = ptrEnd - 1;
break;
}
}
*ptr = '\0';
return (int)(ptr - buf);
}
/*
This is NOT a full implementation of "sprintf" as found
in the C runtime library. Specifically, the only form of
format specification allowed is %type, where "type" can
be one of the following characters:
d int signed decimal integer
l long signed decimal integer
ld long signed decimal integer
lu unsigned long unsigned decimal integer
u unsigned int unsigned decimal integer
s char* character string
c char character
x,X unsigned long hex number (emits at least two digits, uppercase)
b UFLBool boolean (true or false)
f long 24.8 fixed-pointed number
Normally, you should use UFLsprintf. Use this function
only when you want to sprintf with %f in the form of 24.8 fixed point
number.
*/
int
UFLsprintfEx(
char *buf,
size_t cchDest,
const char *fmtstr,
...
)
{
va_list arglist;
int retval;
va_start(arglist, fmtstr);
retval = UFLvsprintf(buf, cchDest, fmtstr, arglist);
va_end(arglist);
return retval;
}
/****************************************************************************/
#if defined(UNIX) || defined(MAC_ENV) /* Define needed functions */
/****************************************************************************/
char *_ltoa( long val, char *str, int radix )
{
/* This is the only supported radix: */
assert( radix == 10 );
sprintf( str, "%ld", val );
return str;
}
char *_ultoa( unsigned long val, char *str, int radix )
{
/* This is the only supported radix: */
assert( radix == 10 );
sprintf( str, "%lu", val );
return str;
}
#endif
/****************************************************************************/
#ifdef WIN32KERNEL
/****************************************************************************/
#include <stdio.h>
int
UFLsprintf(
char *buf,
size_t cchDest,
const char *fmtstr,
...
)
{
va_list arglist;
int retval;
va_start(arglist, fmtstr);
retval = vsprintf(buf, fmtstr, arglist);
va_end(arglist);
return retval;
}
/***
*strtol, strtoul(nptr,endptr,ibase) - Convert ascii string to long un/signed
* int.
*
*Purpose:
* Convert an ascii string to a long 32-bit value. The base
* used for the caculations is supplied by the caller. The base
* must be in the range 0, 2-36. If a base of 0 is supplied, the
* ascii string must be examined to determine the base of the
* number:
* (a) First char = '0', second char = 'x' or 'X',
* use base 16.
* (b) First char = '0', use base 8
* (c) First char in range '1' - '9', use base 10.
*
* If the 'endptr' value is non-NULL, then strtol/strtoul places
* a pointer to the terminating character in this value.
* See ANSI standard for details
*
*Entry:
* nptr == NEAR/FAR pointer to the start of string.
* endptr == NEAR/FAR pointer to the end of the string.
* ibase == integer base to use for the calculations.
*
* string format: [whitespace] [sign] [0] [x] [digits/letters]
*
*Exit:
* Good return:
* result
*
* Overflow return:
* strtol -- LONG_MAX or LONG_MIN
* strtoul -- ULONG_MAX
* strtol/strtoul -- errno == ERANGE
*
* No digits or bad base return:
* 0
* endptr = nptr*
*
*Exceptions:
* None.
*******************************************************************************/
/* flag values */
#include <limits.h>
#include <errno.h>
#define FL_UNSIGNED 1 /* strtoul called */
#define FL_NEG 2 /* negative sign found */
#define FL_OVERFLOW 4 /* overflow occured */
#define FL_READDIGIT 8 /* we've read at least one correct digit */
static unsigned long UFLstrtolx (
const char *nptr,
const char **endptr,
int ibase,
int flags
)
{
const char *p;
char c;
unsigned long number;
unsigned digval;
unsigned long maxval;
p = nptr; /* p is our scanning pointer */
number = 0; /* start with zero */
c = *p++; /* read char */
while ( isspace((int)(unsigned char)c) )
c = *p++; /* skip whitespace */
if (c == '-') {
flags |= FL_NEG; /* remember minus sign */
c = *p++;
}
else if (c == '+')
c = *p++; /* skip sign */
if (ibase < 0 || ibase == 1 || ibase > 36) {
/* bad base! */
if (endptr)
/* store beginning of string in endptr */
*endptr = nptr;
return 0L; /* return 0 */
}
else if (ibase == 0) {
/* determine base free-lance, based on first two chars of
string */
if (c != '0')
ibase = 10;
else if (*p == 'x' || *p == 'X')
ibase = 16;
else
ibase = 8;
}
if (ibase == 16) {
/* we might have 0x in front of number; remove if there */
if (c == '0' && (*p == 'x' || *p == 'X')) {
++p;
c = *p++; /* advance past prefix */
}
}
/* if our number exceeds this, we will overflow on multiply */
maxval = ULONG_MAX / ibase;
for (;;) { /* exit in middle of loop */
/* convert c to value */
if ( isdigit((int)(unsigned char)c) )
digval = c - '0';
else if ( isalpha((int)(unsigned char)c) )
digval = toupper(c) - 'A' + 10;
else
break;
if (digval >= (unsigned)ibase)
break; /* exit loop if bad digit found */
/* record the fact we have read one digit */
flags |= FL_READDIGIT;
/* we now need to compute number = number * base + digval,
but we need to know if overflow occured. This requires
a tricky pre-check. */
if (number < maxval || (number == maxval &&
(unsigned long)digval <= ULONG_MAX % ibase)) {
/* we won't overflow, go ahead and multiply */
number = number * ibase + digval;
}
else {
/* we would have overflowed -- set the overflow flag */
flags |= FL_OVERFLOW;
}
c = *p++; /* read next digit */
}
--p; /* point to place that stopped scan */
if (!(flags & FL_READDIGIT)) {
/* no number there; return 0 and point to beginning of
string */
if (endptr)
/* store beginning of string in endptr later on */
p = nptr;
number = 0L; /* return 0 */
}
else if ( (flags & FL_OVERFLOW) ||
( !(flags & FL_UNSIGNED) &&
( ( (flags & FL_NEG) && (number > -LONG_MIN) ) ||
( !(flags & FL_NEG) && (number > LONG_MAX) ) ) ) )
{
/* overflow or signed overflow occurred */
errno = ERANGE;
if ( flags & FL_UNSIGNED )
number = ULONG_MAX;
else if ( flags & FL_NEG )
number = (unsigned long)(-LONG_MIN);
else
number = LONG_MAX;
}
if (endptr != NULL)
/* store pointer to char that stopped the scan */
*endptr = p;
if (flags & FL_NEG)
/* negate result if there was a neg sign */
number = (unsigned long)(-(long)number);
return number; /* done. */
}
long UFLstrtol (
const char *nptr,
char **endptr,
int ibase
)
{
return (long) UFLstrtolx(nptr, endptr, ibase, 0);
}
#endif // ifdef WIN32KERNEL
#ifdef __cplusplus
}
#endif