Windows NT 4.0 source code leak
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.
 
 
 
 
 
 

305 lines
5.6 KiB

/* ULong64 Class
*
* This class implements 64 bit integers for use with the GUID allocator.
* The operators all allows both other ULong64's and longs for addition
* and subtraction. Typecasting to long is allowed, however anything
* greater in value than 0xFFFFFFFF is mapped to 0xFFFFFFFF.
*
* Revision History
*
* richardw, 17 July 1990, Initial Coding
* richardw, 10 Aug 1990, Amended from code review
* davidst, 5 Mar 1992, Added ToHexString and FromHexString, >>=
* mariogo, 25 May 1994, Fixed amazing bugs in To/FromHexString, >>= and *=
*/
#include <sysinc.h>
#include <rpc.h>
#include "ulong64.hxx"
#define DIGITS_IN_A_ULONG64 16
//
// Puts the current value of 'this' out to a string in hex
//
char PAPI *
ULong64::ToHexString(
char PAPI *OutString
)
{
ULong64 Tmp = *this;
int i;
for (i=0 ; i<DIGITS_IN_A_ULONG64 ; i++)
{
OutString[DIGITS_IN_A_ULONG64-1-i] =
"0123456789abcdef"[ Tmp.lo() & 0x0000000f ];
Tmp >>= 4;
}
OutString[DIGITS_IN_A_ULONG64] = '\0';
return OutString;
}
//
// Sets the value based on the hex string passed in.
//
void
ULong64::FromHexString(
char PAPI *String
)
{
char TmpChar;
long val;
*this=0;
for ( ; *String ; String++)
{
(*this) <<= 4; // this *= 16
TmpChar = *String;
if ( (TmpChar >= 'a') && (TmpChar <= 'f') )
{
val = TmpChar - 'a' + 10;
}
else if ( (TmpChar >= 'A') && (TmpChar <= 'F') )
{
val = TmpChar - 'A' + 10;
}
else if ( (TmpChar >= '0') && (TmpChar <= '9') )
{
val = TmpChar - '0';
}
else
{
ASSERT(!"Bad hex string\n");
val = 0;
}
*this += val;
}
}
//
// maximum unsigned long integer
//
#define MAX_ULONG 0xffffffff
#ifndef TRUE
#define TRUE 1==1
#define FALSE 1==0
#endif /* TRUE */
//
// addition operators
//
void operator+=(ULong64 PAPI & a, ULong64 PAPI & b)
{
if (MAX_ULONG - a.low < b.low) {
a.high++; // carry
}
a.high += b.high;
a.low += b.low;
}
void operator+=(ULong64 PAPI & a, unsigned long b)
{
if (MAX_ULONG - a.low < b) {
a.high++; // carry
}
a.low += b;
}
//
// subtraction operator
//
void operator-=(ULong64 & a, ULong64 & b)
{
if (b.low > a.low) {
a.high--; // "borrow"
}
a.high -= b.high;
a.low -= b.low;
}
void operator-= (ULong64 & a, unsigned long b)
{
if (b > a.low) {
a.high--;
}
a.low -= b;
}
//ULong64 ULong64 :: operator-(ULong64 & a)
//{
// return ULong64(high - a.high, low - a.low);
//}
/*
Here we are multiplying a 64 bit number by a 32 bit number. We do this
by doing a base 65535 multiplication. In this, we can think of the
ulong64 as having four digits and the 32 bit having two. In this case,
we have:
abcd
x ef
----
(f*d)
(f*c)0
(f*b)00
(f*a)000
(e*d)0
(e*c)00
(e*b)000
+ (e*a)0000 <-- can throw this one out as overflow.
-------
(Answer)
*/
#define ushort unsigned short
#define ulong unsigned long
void operator*= (ULong64 & x, unsigned long y)
{
//unsigned long t1,t2; // temporary storage
ULong64 t3;
unsigned short a,b,c,d,e,f;
a = (ushort) (x.high >>16 );
b = (ushort) (x.high & 0xffff);
c = (ushort) (x.low >> 16);
d = (ushort) (x.low & 0xffff);
e = (ushort) (y >> 16);
f = (ushort) (y & 0xffff);
// f * d
x = (ulong)f * (ulong)d;
ASSERT(t3.high == 0);
// + f * c << 16
t3.low = (ulong)f * (ulong)c;
t3 <<= 16;
x += t3;
// + f * b << 32
t3.low = 0;
t3.high = (ulong)f * (ulong)b;
x += t3;
// + f * a << 48
t3.high = (ulong)f * (ulong)a;
t3.high <<= 16;
x += t3;
// + e * d << 16
t3.high == 0;
t3.low = (ulong)e * (ulong)d;
t3 <<= 16;
x += t3;
// + e*c << 32
t3.low = 0;
t3.high = (ulong)e * (ulong)c;
x += t3;
// + e * b << 48
t3.high = (ulong)e * (ulong)b;
t3.high <<= 16;
x += t3;
}
//
// left shift operator (valid for n <= 63. for n >= 64, n is reduced
// to n <= 63.
//
void operator<<=(ULong64 PAPI & a, unsigned int n)
{
if (n >= 64) {
a = ULong64(0);
} else {
if (n > 31) {
a.high = a.low << (n - 32);
a.low = 0;
} else {
a.high <<= n;
a.high |= a.low >> (32-n);
a.low <<= n;
}
}
}
//
// right shift operator (valid for n <= 63. for n >= 64, n is reduced
// to n <= 63.
//
void operator>>=(ULong64 PAPI & a, unsigned int n)
{
if (n >= 64) {
a = ULong64(0);
} else {
if (n > 31) {
a.low = a.high >> (n - 32);
a.high = 0;
} else {
a.low >>= n;
a.low |= a.high << (32-n);
a.high >>= n;
}
}
}
//
// a >= b comparision operator
//
int operator>=(ULong64 & a, ULong64 & b)
{
if (a.high > b.high) {
return TRUE;
}
if (a.high < b.high) {
return FALSE;
}
// a.high == b.high
if (a.low >= b.low) {
return TRUE;
}
return FALSE;
}
//
// a <= b comparision operator
//
int operator<=(ULong64 & a, ULong64 & b)
{
if (a.high < b.high) {
return TRUE;
}
if (a.high > b.high) {
return FALSE;
}
// a.high == b.high
if (a.low <= b.low) {
return TRUE;
}
return FALSE;
}